aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD52
-rw-r--r--CMakeLists.txt286
-rw-r--r--Makefile301
-rw-r--r--README.md2
-rw-r--r--bazel/grpc_deps.bzl8
-rw-r--r--build.yaml79
-rw-r--r--config.m412
-rw-r--r--config.w3212
-rw-r--r--doc/PROTOCOL-HTTP2.md2
-rw-r--r--doc/g_stands_for.md1
-rw-r--r--examples/android/helloworld/.gitignore9
-rw-r--r--examples/android/helloworld/README.md24
-rw-r--r--examples/android/helloworld/app/.gitignore1
-rw-r--r--examples/android/helloworld/app/CMakeLists.txt123
-rw-r--r--examples/android/helloworld/app/build.gradle53
-rw-r--r--examples/android/helloworld/app/proguard-rules.pro21
-rw-r--r--examples/android/helloworld/app/src/main/AndroidManifest.xml22
-rw-r--r--examples/android/helloworld/app/src/main/cpp/grpc-helloworld.cc142
-rw-r--r--examples/android/helloworld/app/src/main/java/io/grpc/helloworldexample/cpp/HelloworldActivity.java167
-rw-r--r--examples/android/helloworld/app/src/main/res/layout/activity_helloworld.xml86
-rw-r--r--examples/android/helloworld/app/src/main/res/mipmap-hdpi/ic_launcher.pngbin0 -> 3418 bytes
-rw-r--r--examples/android/helloworld/app/src/main/res/mipmap-mdpi/ic_launcher.pngbin0 -> 2206 bytes
-rw-r--r--examples/android/helloworld/app/src/main/res/mipmap-xhdpi/ic_launcher.pngbin0 -> 4842 bytes
-rw-r--r--examples/android/helloworld/app/src/main/res/mipmap-xxhdpi/ic_launcher.pngbin0 -> 7718 bytes
-rw-r--r--examples/android/helloworld/app/src/main/res/values/strings.xml3
-rw-r--r--examples/android/helloworld/build.gradle24
-rw-r--r--examples/android/helloworld/gradle.properties17
-rw-r--r--examples/android/helloworld/gradle/wrapper/gradle-wrapper.jarbin0 -> 53636 bytes
-rw-r--r--examples/android/helloworld/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xexamples/android/helloworld/gradlew160
-rw-r--r--examples/android/helloworld/gradlew.bat90
-rw-r--r--examples/android/helloworld/settings.gradle1
-rw-r--r--examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.mm6
-rw-r--r--gRPC-C++.podspec222
-rw-r--r--gRPC-Core.podspec44
-rw-r--r--gRPC-ProtoRPC.podspec2
-rw-r--r--gRPC-RxLibrary.podspec2
-rw-r--r--gRPC.podspec2
-rw-r--r--grpc.gemspec79
-rw-r--r--grpc.gyp53
-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.h2
-rw-r--r--include/grpc/grpc_cronet.h2
-rw-r--r--include/grpc/grpc_posix.h3
-rw-r--r--include/grpc/grpc_security.h2
-rw-r--r--include/grpc/impl/codegen/byte_buffer.h2
-rw-r--r--include/grpc/impl/codegen/grpc_types.h13
-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/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/time.h2
-rw-r--r--package.xml83
-rwxr-xr-xsrc/boringssl/gen_build_yaml.py4
-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/compiler/php_generator.cc14
-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.cc2197
-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/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.cc2
-rw-r--r--src/core/ext/filters/client_channel/http_proxy.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.h2
-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.cc117
-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.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/subchannel_list.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_factory.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_factory.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_registry.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_registry.h2
-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.cc17
-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.cc2
-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.cc91
-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.cc41
-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.cc16
-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.cc4
-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.h2
-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/cpu_posix.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.cc2
-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.cc49
-rw-r--r--src/core/lib/gpr/thd.h71
-rw-r--r--src/core/lib/gpr/thd_posix.cc154
-rw-r--r--src/core/lib/gpr/thd_windows.cc107
-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.h8
-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/gprpp/thd.h135
-rw-r--r--src/core/lib/gprpp/thd_posix.cc209
-rw-r--r--src/core/lib/gprpp/thd_windows.cc162
-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.cc2
-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.cc68
-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.cc24
-rw-r--r--src/core/lib/iomgr/executor.h2
-rw-r--r--src/core/lib/iomgr/fork_posix.cc6
-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.cc2
-rw-r--r--src/core/lib/iomgr/iomgr_uv.h2
-rw-r--r--src/core/lib/iomgr/iomgr_windows.cc2
-rw-r--r--src/core/lib/iomgr/is_epollexclusive_available.cc2
-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.cc32
-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.h2
-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.cc13
-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.h2
-rw-r--r--src/core/lib/security/credentials/credentials_metadata.cc2
-rw-r--r--src/core/lib/security/credentials/fake/fake_credentials.cc5
-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.cc15
-rw-r--r--src/core/lib/security/security_connector/security_connector.h2
-rw-r--r--src/core/lib/security/transport/auth_filters.h2
-rw-r--r--src/core/lib/security/transport/client_auth_filter.cc2
-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.h2
-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.cc4
-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.cc2
-rw-r--r--src/core/lib/transport/byte_stream.h2
-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.h (renamed from src/core/lib/security/transport/lb_targets_info.h)18
-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.cc4
-rw-r--r--src/core/tsi/alts_transport_security.h6
-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.cc4
-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.cc2
-rw-r--r--src/cpp/common/version_cc.cc2
-rw-r--r--src/cpp/server/dynamic_thread_pool.cc16
-rw-r--r--src/cpp/server/dynamic_thread_pool.h4
-rw-r--r--src/cpp/thread_manager/thread_manager.cc15
-rw-r--r--src/cpp/thread_manager/thread_manager.h10
-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/experimental/README.md16
-rwxr-xr-xsrc/csharp/experimental/build_native_ext_for_android.sh37
-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.m22
-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/_grpcio_metadata.py2
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py11
-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/lib/grpc/version.rb2
-rw-r--r--src/ruby/tools/version.rb2
-rw-r--r--summerofcode/ideas.md4
-rw-r--r--templates/CMakeLists.txt.template26
-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--test/core/bad_client/bad_client.cc8
-rw-r--r--test/core/client_channel/BUILD11
-rw-r--r--test/core/client_channel/resolvers/fake_resolver_test.cc5
-rw-r--r--test/core/client_channel/status_util_test.cc49
-rw-r--r--test/core/end2end/bad_server_response_test.cc17
-rw-r--r--test/core/end2end/end2end_nosec_tests.cc120
-rw-r--r--test/core/end2end/end2end_tests.cc120
-rw-r--r--test/core/end2end/fixtures/h2_census.cc1
-rw-r--r--test/core/end2end/fixtures/h2_compress.cc1
-rw-r--r--test/core/end2end/fixtures/h2_full+pipe.cc1
-rw-r--r--test/core/end2end/fixtures/h2_full+trace.cc1
-rw-r--r--test/core/end2end/fixtures/h2_full+workarounds.cc1
-rw-r--r--test/core/end2end/fixtures/h2_full.cc1
-rw-r--r--test/core/end2end/fixtures/h2_http_proxy.cc1
-rw-r--r--test/core/end2end/fixtures/h2_load_reporting.cc1
-rw-r--r--test/core/end2end/fixtures/h2_proxy.cc13
-rw-r--r--test/core/end2end/fixtures/h2_sockpair+trace.cc1
-rw-r--r--test/core/end2end/fixtures/h2_sockpair.cc1
-rw-r--r--test/core/end2end/fixtures/h2_sockpair_1byte.cc1
-rw-r--r--test/core/end2end/fixtures/h2_uds.cc1
-rw-r--r--test/core/end2end/fixtures/http_proxy_fixture.cc12
-rw-r--r--test/core/end2end/fixtures/inproc.cc1
-rw-r--r--test/core/end2end/fixtures/proxy.cc12
-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.bzl65
-rw-r--r--test/core/end2end/tests/bad_ping.cc1
-rw-r--r--test/core/end2end/tests/connectivity.cc11
-rw-r--r--test/core/end2end/tests/ping.cc1
-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/BUILD20
-rw-r--r--test/core/gpr/arena_test.cc20
-rw-r--r--test/core/gpr/cpu_test.cc26
-rw-r--r--test/core/gpr/mpscq_test.cc38
-rw-r--r--test/core/gpr/spinlock_test.cc22
-rw-r--r--test/core/gpr/sync_test.cc61
-rw-r--r--test/core/gpr/time_test.cc1
-rw-r--r--test/core/gpr/tls_test.cc25
-rw-r--r--test/core/gprpp/BUILD29
-rw-r--r--test/core/gprpp/manual_constructor_test.cc1
-rw-r--r--test/core/gprpp/thd_test.cc (renamed from test/core/gpr/thd_test.cc)67
-rw-r--r--test/core/handshake/client_ssl.cc13
-rw-r--r--test/core/handshake/readahead_handshaker_server_ssl.cc1
-rw-r--r--test/core/handshake/server_ssl.cc1
-rw-r--r--test/core/handshake/server_ssl_common.cc13
-rw-r--r--test/core/handshake/server_ssl_common.h1
-rw-r--r--test/core/iomgr/BUILD13
-rw-r--r--test/core/iomgr/combiner_test.cc12
-rw-r--r--test/core/iomgr/error_test.cc1
-rw-r--r--test/core/iomgr/ev_epollsig_linux_test.cc15
-rw-r--r--test/core/iomgr/resolve_address_posix_test.cc10
-rw-r--r--test/core/iomgr/wakeup_fd_cv_test.cc162
-rw-r--r--test/core/network_benchmarks/low_level_ping_pong.cc8
-rw-r--r--test/core/security/BUILD25
-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.cc1
-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.cc34
-rw-r--r--test/core/surface/concurrent_connectivity_test.cc143
-rw-r--r--test/core/surface/num_external_connectivity_watchers_test.cc2
-rw-r--r--test/core/surface/sequential_connectivity_test.cc10
-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/transport_security_test_lib.cc1
-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/end2end/BUILD21
-rw-r--r--test/cpp/end2end/async_end2end_test.cc1
-rw-r--r--test/cpp/end2end/client_crash_test.cc1
-rw-r--r--test/cpp/end2end/client_lb_end2end_test.cc1
-rw-r--r--test/cpp/end2end/end2end_test.cc1
-rw-r--r--test/cpp/end2end/filter_end2end_test.cc1
-rw-r--r--test/cpp/end2end/generic_end2end_test.cc1
-rw-r--r--test/cpp/end2end/grpclb_end2end_test.cc104
-rw-r--r--test/cpp/end2end/mock_test.cc1
-rw-r--r--test/cpp/end2end/server_crash_test.cc1
-rw-r--r--test/cpp/end2end/server_early_return_test.cc1
-rw-r--r--test/cpp/end2end/streaming_throughput_test.cc1
-rw-r--r--test/cpp/end2end/thread_stress_test.cc1
-rw-r--r--test/cpp/grpclb/BUILD39
-rw-r--r--test/cpp/test/BUILD39
-rw-r--r--test/cpp/thread_manager/BUILD40
-rwxr-xr-xtools/codegen/core/gen_static_metadata.py8
-rwxr-xr-xtools/distrib/check_copyright.py3
-rw-r--r--tools/distrib/python/grpcio_tools/grpc_version.py2
-rw-r--r--tools/doxygen/Doxyfile.c++2
-rw-r--r--tools/doxygen/Doxyfile.c++.internal6
-rw-r--r--tools/doxygen/Doxyfile.core.internal19
-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.py3
-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.json198
-rw-r--r--tools/run_tests/generated/tests.json7275
-rwxr-xr-xtools/run_tests/run_tests_matrix.py6
-rwxr-xr-xtools/run_tests/sanity/check_deprecated_grpc++.py18
-rwxr-xr-xtools/run_tests/sanity/check_port_platform.py64
-rw-r--r--tools/run_tests/sanity/sanity_tests.yaml1
750 files changed, 23179 insertions, 3910 deletions
diff --git a/BUILD b/BUILD
index 1d5b021652..4fe3dc660e 100644
--- a/BUILD
+++ b/BUILD
@@ -55,7 +55,7 @@ config_setting(
config_setting(
name = "windows",
- values = { "cpu": "x64_windows" },
+ values = {"cpu": "x64_windows"},
)
config_setting(
@@ -64,11 +64,11 @@ config_setting(
)
# 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",
@@ -527,9 +527,6 @@ grpc_cc_library(
"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_posix.cc",
- "src/core/lib/gpr/thd_windows.cc",
"src/core/lib/gpr/time.cc",
"src/core/lib/gpr/time_posix.cc",
"src/core/lib/gpr/time_precise.cc",
@@ -539,6 +536,8 @@ grpc_cc_library(
"src/core/lib/gpr/tmpfile_posix.cc",
"src/core/lib/gpr/tmpfile_windows.cc",
"src/core/lib/gpr/wrap_memcpy.cc",
+ "src/core/lib/gprpp/thd_posix.cc",
+ "src/core/lib/gprpp/thd_windows.cc",
"src/core/lib/profiling/basic_timers.cc",
"src/core/lib/profiling/stap_timers.cc",
],
@@ -552,7 +551,6 @@ 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.h",
"src/core/lib/gpr/time_precise.h",
"src/core/lib/gpr/tls.h",
"src/core/lib/gpr/tls_gcc.h",
@@ -560,6 +558,10 @@ grpc_cc_library(
"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/manual_constructor.h",
+ "src/core/lib/gprpp/memory.h",
+ "src/core/lib/gprpp/thd.h",
"src/core/lib/profiling/timers.h",
],
language = "c++",
@@ -602,16 +604,6 @@ grpc_cc_library(
)
grpc_cc_library(
- name = "gpr++_base",
- language = "c++",
- public_hdrs = [
- "src/core/lib/gprpp/abstract.h",
- "src/core/lib/gprpp/manual_constructor.h",
- "src/core/lib/gprpp/memory.h",
- ],
-)
-
-grpc_cc_library(
name = "atomic",
hdrs = [
"src/core/lib/gprpp/atomic_with_atm.h",
@@ -633,7 +625,7 @@ grpc_cc_library(
"src/core/lib/gprpp/inlined_vector.h",
],
deps = [
- "gpr++_base",
+ "gpr_base",
],
)
@@ -649,7 +641,7 @@ grpc_cc_library(
public_hdrs = ["src/core/lib/gprpp/orphanable.h"],
deps = [
"debug_location",
- "gpr++_base",
+ "gpr_base",
"grpc_trace",
"ref_counted_ptr",
],
@@ -661,7 +653,7 @@ grpc_cc_library(
public_hdrs = ["src/core/lib/gprpp/ref_counted.h"],
deps = [
"debug_location",
- "gpr++_base",
+ "gpr_base",
"grpc_trace",
"ref_counted_ptr",
],
@@ -672,7 +664,7 @@ grpc_cc_library(
language = "c++",
public_hdrs = ["src/core/lib/gprpp/ref_counted_ptr.h"],
deps = [
- "gpr++_base",
+ "gpr_base",
],
)
@@ -779,7 +771,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",
@@ -809,6 +800,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",
@@ -907,6 +899,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",
@@ -931,6 +924,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",
@@ -941,10 +935,12 @@ grpc_cc_library(
language = "c++",
public_hdrs = GRPC_PUBLIC_HDRS,
deps = [
- "gpr++_base",
"gpr_base",
"grpc_codegen",
"grpc_trace",
+ "inlined_vector",
+ "ref_counted",
+ "ref_counted_ptr",
],
)
@@ -999,12 +995,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",
@@ -1019,6 +1017,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",
@@ -1026,6 +1025,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",
@@ -1328,10 +1328,10 @@ grpc_cc_library(
"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_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",
@@ -1351,9 +1351,9 @@ grpc_cc_library(
"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_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",
],
@@ -1416,7 +1416,7 @@ grpc_cc_library(
],
language = "c++",
deps = [
- "gpr++_base",
+ "gpr_base",
"grpc_base",
"grpc_http_filters",
"grpc_transport_chttp2_alpn",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 64a7dc7890..ab4fa8a253 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/")
@@ -37,6 +37,7 @@ set(gRPC_INSTALL_CMAKEDIR "lib/cmake/${PACKAGE_NAME}" CACHE STRING "Installation
# Options
option(gRPC_BUILD_TESTS "Build tests" OFF)
+option(gRPC_BUILD_CODEGEN "Build codegen" ON)
set(gRPC_INSTALL_default ON)
if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
@@ -78,6 +79,8 @@ if(UNIX)
set(_gRPC_PLATFORM_LINUX ON)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(_gRPC_PLATFORM_MAC ON)
+ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Android")
+ set(_gRPC_PLATFORM_ANDROID ON)
else()
set(_gRPC_PLATFORM_POSIX ON)
endif()
@@ -120,6 +123,8 @@ endif()
if(_gRPC_PLATFORM_MAC)
set(_gRPC_ALLTARGETS_LIBRARIES ${CMAKE_DL_LIBS} m pthread)
+elseif(_gRPC_PLATFORM_ANDROID)
+ set(_gRPC_ALLTARGETS_LIBRARIES ${CMAKE_DL_LIBS} m)
elseif(UNIX)
set(_gRPC_ALLTARGETS_LIBRARIES ${CMAKE_DL_LIBS} rt m pthread)
endif()
@@ -344,7 +349,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)
@@ -594,8 +598,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()
@@ -651,9 +659,6 @@ add_library(gpr
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_posix.cc
- src/core/lib/gpr/thd_windows.cc
src/core/lib/gpr/time.cc
src/core/lib/gpr/time_posix.cc
src/core/lib/gpr/time_precise.cc
@@ -663,6 +668,8 @@ add_library(gpr
src/core/lib/gpr/tmpfile_posix.cc
src/core/lib/gpr/tmpfile_windows.cc
src/core/lib/gpr/wrap_memcpy.cc
+ src/core/lib/gprpp/thd_posix.cc
+ src/core/lib/gprpp/thd_windows.cc
src/core/lib/profiling/basic_timers.cc
src/core/lib/profiling/stap_timers.cc
)
@@ -693,6 +700,12 @@ target_include_directories(gpr
target_link_libraries(gpr
${_gRPC_ALLTARGETS_LIBRARIES}
)
+if (_gRPC_PLATFORM_ANDROID)
+ target_link_libraries(gpr
+ android
+ log
+ )
+endif (_gRPC_PLATFORM_ANDROID)
foreach(_hdr
include/grpc/support/alloc.h
@@ -881,7 +894,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
@@ -912,6 +924,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
@@ -961,10 +974,10 @@ add_library(grpc
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_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
@@ -987,12 +1000,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
@@ -1221,7 +1236,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
@@ -1252,6 +1266,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
@@ -1298,12 +1313,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
@@ -1325,10 +1342,10 @@ add_library(grpc_cronet
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_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
@@ -1547,7 +1564,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
@@ -1578,6 +1594,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
@@ -1593,12 +1610,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
@@ -1834,7 +1853,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
@@ -1865,6 +1883,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
@@ -1880,12 +1899,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
@@ -2101,7 +2122,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
@@ -2132,6 +2152,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
@@ -2180,12 +2201,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
@@ -2687,6 +2710,7 @@ endif()
if (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_CODEGEN)
add_library(grpc++_core_stats
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/core/stats.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/core/stats.grpc.pb.cc
@@ -2732,6 +2756,7 @@ target_link_libraries(grpc++_core_stats
grpc++
)
+endif (gRPC_BUILD_CODEGEN)
endif (gRPC_BUILD_TESTS)
@@ -2900,7 +2925,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
@@ -2931,6 +2955,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
@@ -2951,12 +2976,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
@@ -3224,6 +3251,7 @@ if (gRPC_INSTALL)
endif()
+if (gRPC_BUILD_CODEGEN)
add_library(grpc++_error_details
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/status/status.grpc.pb.cc
@@ -3276,6 +3304,7 @@ foreach(_hdr
DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}"
)
endforeach()
+endif (gRPC_BUILD_CODEGEN)
if (gRPC_INSTALL)
@@ -3288,6 +3317,7 @@ endif()
if (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_CODEGEN)
add_library(grpc++_proto_reflection_desc_db
test/cpp/util/proto_reflection_descriptor_database.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc
@@ -3344,9 +3374,11 @@ foreach(_hdr
DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}"
)
endforeach()
+endif (gRPC_BUILD_CODEGEN)
endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_CODEGEN)
add_library(grpc++_reflection
src/cpp/ext/proto_server_reflection.cc
src/cpp/ext/proto_server_reflection_plugin.cc
@@ -3400,6 +3432,7 @@ foreach(_hdr
DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}"
)
endforeach()
+endif (gRPC_BUILD_CODEGEN)
if (gRPC_INSTALL)
@@ -3453,6 +3486,7 @@ target_link_libraries(grpc++_test_config
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_CODEGEN)
add_library(grpc++_test_util
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.grpc.pb.cc
@@ -3621,10 +3655,12 @@ foreach(_hdr
DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}"
)
endforeach()
+endif (gRPC_BUILD_CODEGEN)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_CODEGEN)
add_library(grpc++_test_util_unsecure
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.grpc.pb.cc
@@ -3791,6 +3827,7 @@ foreach(_hdr
DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}"
)
endforeach()
+endif (gRPC_BUILD_CODEGEN)
endif (gRPC_BUILD_TESTS)
@@ -4133,6 +4170,7 @@ target_link_libraries(grpc_benchmark
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_CODEGEN)
add_library(grpc_cli_libs
test/cpp/util/cli_call.cc
test/cpp/util/cli_credentials.cc
@@ -4194,6 +4232,7 @@ foreach(_hdr
DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}"
)
endforeach()
+endif (gRPC_BUILD_CODEGEN)
endif (gRPC_BUILD_TESTS)
@@ -4259,6 +4298,7 @@ endif()
if (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_CODEGEN)
add_library(http2_client_main
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc
@@ -4322,10 +4362,12 @@ target_link_libraries(http2_client_main
grpc++_test_config
)
+endif (gRPC_BUILD_CODEGEN)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_CODEGEN)
add_library(interop_client_helper
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc
@@ -4375,10 +4417,12 @@ target_link_libraries(interop_client_helper
gpr
)
+endif (gRPC_BUILD_CODEGEN)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_CODEGEN)
add_library(interop_client_main
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc
@@ -4446,6 +4490,7 @@ target_link_libraries(interop_client_main
grpc++_test_config
)
+endif (gRPC_BUILD_CODEGEN)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
@@ -4496,6 +4541,7 @@ target_link_libraries(interop_server_helper
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_CODEGEN)
add_library(interop_server_lib
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/empty.grpc.pb.cc
@@ -4562,6 +4608,7 @@ target_link_libraries(interop_server_lib
grpc++_test_config
)
+endif (gRPC_BUILD_CODEGEN)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
@@ -4608,6 +4655,7 @@ target_link_libraries(interop_server_main
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_CODEGEN)
add_library(qps
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/messages.grpc.pb.cc
@@ -4694,6 +4742,7 @@ target_link_libraries(qps
grpc
)
+endif (gRPC_BUILD_CODEGEN)
endif (gRPC_BUILD_TESTS)
@@ -4868,6 +4917,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
@@ -4968,6 +5032,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
@@ -6204,7 +6283,7 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(gpr_thd_test
- test/core/gpr/thd_test.cc
+ test/core/gprpp/thd_test.cc
)
@@ -7880,33 +7959,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
)
@@ -10247,6 +10299,7 @@ target_link_libraries(grpc_cli
)
endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_CODEGEN)
add_executable(grpc_cpp_plugin
src/compiler/cpp_plugin.cc
@@ -10281,6 +10334,8 @@ if (gRPC_INSTALL)
)
endif()
+endif (gRPC_BUILD_CODEGEN)
+if (gRPC_BUILD_CODEGEN)
add_executable(grpc_csharp_plugin
src/compiler/csharp_plugin.cc
@@ -10315,6 +10370,8 @@ if (gRPC_INSTALL)
)
endif()
+endif (gRPC_BUILD_CODEGEN)
+if (gRPC_BUILD_CODEGEN)
add_executable(grpc_node_plugin
src/compiler/node_plugin.cc
@@ -10349,6 +10406,8 @@ if (gRPC_INSTALL)
)
endif()
+endif (gRPC_BUILD_CODEGEN)
+if (gRPC_BUILD_CODEGEN)
add_executable(grpc_objective_c_plugin
src/compiler/objective_c_plugin.cc
@@ -10383,6 +10442,8 @@ if (gRPC_INSTALL)
)
endif()
+endif (gRPC_BUILD_CODEGEN)
+if (gRPC_BUILD_CODEGEN)
add_executable(grpc_php_plugin
src/compiler/php_plugin.cc
@@ -10417,6 +10478,8 @@ if (gRPC_INSTALL)
)
endif()
+endif (gRPC_BUILD_CODEGEN)
+if (gRPC_BUILD_CODEGEN)
add_executable(grpc_python_plugin
src/compiler/python_plugin.cc
@@ -10451,6 +10514,8 @@ if (gRPC_INSTALL)
)
endif()
+endif (gRPC_BUILD_CODEGEN)
+if (gRPC_BUILD_CODEGEN)
add_executable(grpc_ruby_plugin
src/compiler/ruby_plugin.cc
@@ -10485,6 +10550,7 @@ if (gRPC_INSTALL)
)
endif()
+endif (gRPC_BUILD_CODEGEN)
if (gRPC_BUILD_TESTS)
add_executable(grpc_tool_test
@@ -12104,6 +12170,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
@@ -12141,6 +12279,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
@@ -12177,6 +12348,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 ba6c51a7ce..b090b9fb94 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)
@@ -1067,7 +1067,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
@@ -1181,8 +1180,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
@@ -1469,7 +1472,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 \
@@ -1639,8 +1641,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 \
@@ -1783,8 +1789,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 \
@@ -1994,8 +2004,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"
@@ -2208,10 +2216,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"
@@ -2904,9 +2920,6 @@ LIBGPR_SRC = \
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_posix.cc \
- src/core/lib/gpr/thd_windows.cc \
src/core/lib/gpr/time.cc \
src/core/lib/gpr/time_posix.cc \
src/core/lib/gpr/time_precise.cc \
@@ -2916,6 +2929,8 @@ LIBGPR_SRC = \
src/core/lib/gpr/tmpfile_posix.cc \
src/core/lib/gpr/tmpfile_windows.cc \
src/core/lib/gpr/wrap_memcpy.cc \
+ src/core/lib/gprpp/thd_posix.cc \
+ src/core/lib/gprpp/thd_windows.cc \
src/core/lib/profiling/basic_timers.cc \
src/core/lib/profiling/stap_timers.cc \
@@ -3115,7 +3130,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 \
@@ -3146,6 +3160,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 \
@@ -3195,10 +3210,10 @@ LIBGRPC_SRC = \
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_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 \
@@ -3221,12 +3236,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 \
@@ -3457,7 +3474,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 \
@@ -3488,6 +3504,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 \
@@ -3534,12 +3551,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 \
@@ -3561,10 +3580,10 @@ LIBGRPC_CRONET_SRC = \
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_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 \
@@ -3784,7 +3803,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 \
@@ -3815,6 +3833,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 \
@@ -3830,12 +3849,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 \
@@ -4064,7 +4085,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 \
@@ -4095,6 +4115,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 \
@@ -4110,12 +4131,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 \
@@ -4311,7 +4334,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 \
@@ -4342,6 +4364,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 \
@@ -4390,12 +4413,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 \
@@ -5111,7 +5136,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 \
@@ -5142,6 +5166,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 \
@@ -5162,12 +5187,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 \
@@ -9403,6 +9430,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 \
@@ -9502,6 +9544,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 \
@@ -11020,7 +11077,7 @@ endif
GPR_THD_TEST_SRC = \
- test/core/gpr/thd_test.cc \
+ test/core/gprpp/thd_test.cc \
GPR_THD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_THD_TEST_SRC))))
ifeq ($(NO_SECURE),true)
@@ -11040,7 +11097,7 @@ $(BINDIR)/$(CONFIG)/gpr_thd_test: $(GPR_THD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgp
endif
-$(OBJDIR)/$(CONFIG)/test/core/gpr/thd_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gprpp/thd_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_gpr_thd_test: $(GPR_THD_TEST_OBJS:.o=.dep)
@@ -13306,38 +13363,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 \
@@ -17910,6 +17935,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 \
@@ -17953,6 +18064,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 \
@@ -17996,6 +18150,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 \
@@ -22221,10 +22418,10 @@ 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_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/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl
index 9053d9d109..a441c3ff3d 100644
--- a/bazel/grpc_deps.bzl
+++ b/bazel/grpc_deps.bzl
@@ -120,12 +120,12 @@ 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?
diff --git a/build.yaml b/build.yaml
index b20eba9974..e2d194041a 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:
@@ -59,9 +59,6 @@ filegroups:
- 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_posix.cc
- - src/core/lib/gpr/thd_windows.cc
- src/core/lib/gpr/time.cc
- src/core/lib/gpr/time_posix.cc
- src/core/lib/gpr/time_precise.cc
@@ -71,6 +68,8 @@ filegroups:
- src/core/lib/gpr/tmpfile_posix.cc
- src/core/lib/gpr/tmpfile_windows.cc
- src/core/lib/gpr/wrap_memcpy.cc
+ - src/core/lib/gprpp/thd_posix.cc
+ - src/core/lib/gprpp/thd_windows.cc
- src/core/lib/profiling/basic_timers.cc
- src/core/lib/profiling/stap_timers.cc
uses:
@@ -104,7 +103,6 @@ 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.h
- src/core/lib/gpr/time_precise.h
- src/core/lib/gpr/tls.h
- src/core/lib/gpr/tls_gcc.h
@@ -118,6 +116,7 @@ filegroups:
- src/core/lib/gprpp/atomic_with_std.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/memory.h
+ - src/core/lib/gprpp/thd.h
- src/core/lib/profiling/timers.h
uses:
- gpr_codegen
@@ -250,7 +249,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
@@ -281,6 +279,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
@@ -404,6 +403,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
@@ -428,6 +428,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
@@ -447,6 +448,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
@@ -454,6 +456,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
@@ -469,12 +472,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
@@ -650,9 +655,9 @@ filegroups:
- 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_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:
@@ -673,10 +678,10 @@ filegroups:
- 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_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
@@ -2324,7 +2329,7 @@ targets:
build: test
language: c
src:
- - test/core/gpr/thd_test.cc
+ - test/core/gprpp/thd_test.cc
deps:
- gpr_test_util
- gpr
@@ -3147,17 +3152,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
@@ -4827,6 +4821,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
@@ -4843,6 +4861,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++
@@ -4855,6 +4882,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/config.m4 b/config.m4
index d95e6dbe3d..1a055845eb 100644
--- a/config.m4
+++ b/config.m4
@@ -65,9 +65,6 @@ if test "$PHP_GRPC" != "no"; then
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_posix.cc \
- src/core/lib/gpr/thd_windows.cc \
src/core/lib/gpr/time.cc \
src/core/lib/gpr/time_posix.cc \
src/core/lib/gpr/time_precise.cc \
@@ -77,6 +74,8 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/gpr/tmpfile_posix.cc \
src/core/lib/gpr/tmpfile_windows.cc \
src/core/lib/gpr/wrap_memcpy.cc \
+ src/core/lib/gprpp/thd_posix.cc \
+ src/core/lib/gprpp/thd_windows.cc \
src/core/lib/profiling/basic_timers.cc \
src/core/lib/profiling/stap_timers.cc \
src/core/lib/surface/init.cc \
@@ -180,7 +179,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 \
@@ -211,6 +209,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,10 +259,10 @@ if test "$PHP_GRPC" != "no"; then
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_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 \
@@ -286,12 +285,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 \
@@ -627,6 +628,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/compression)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/debug)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/gpr)
+ PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/gprpp)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/http)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/iomgr)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/json)
diff --git a/config.w32 b/config.w32
index 06b0c60b81..5e41295cbf 100644
--- a/config.w32
+++ b/config.w32
@@ -42,9 +42,6 @@ if (PHP_GRPC != "no") {
"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_posix.cc " +
- "src\\core\\lib\\gpr\\thd_windows.cc " +
"src\\core\\lib\\gpr\\time.cc " +
"src\\core\\lib\\gpr\\time_posix.cc " +
"src\\core\\lib\\gpr\\time_precise.cc " +
@@ -54,6 +51,8 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\gpr\\tmpfile_posix.cc " +
"src\\core\\lib\\gpr\\tmpfile_windows.cc " +
"src\\core\\lib\\gpr\\wrap_memcpy.cc " +
+ "src\\core\\lib\\gprpp\\thd_posix.cc " +
+ "src\\core\\lib\\gprpp\\thd_windows.cc " +
"src\\core\\lib\\profiling\\basic_timers.cc " +
"src\\core\\lib\\profiling\\stap_timers.cc " +
"src\\core\\lib\\surface\\init.cc " +
@@ -157,7 +156,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 " +
@@ -188,6 +186,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,10 +236,10 @@ if (PHP_GRPC != "no") {
"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_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 " +
@@ -263,12 +262,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 " +
@@ -639,6 +640,7 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\compression");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\debug");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\gpr");
+ FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\gprpp");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\http");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\iomgr");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\json");
diff --git a/doc/PROTOCOL-HTTP2.md b/doc/PROTOCOL-HTTP2.md
index 107a8e8824..bdd00ca363 100644
--- a/doc/PROTOCOL-HTTP2.md
+++ b/doc/PROTOCOL-HTTP2.md
@@ -191,7 +191,7 @@ grpc-java-android/0.9.1 (gingerbread/1.2.4; nexus5; tmobile)
Unless explicitly defined to be, gRPC Calls are not assumed to be idempotent. Specifically:
* Calls that cannot be proven to have started will not be retried.
-* There is no mechanisim for duplicate suppression as it is not necessary.
+* There is no mechanism for duplicate suppression as it is not necessary.
* Calls that are marked as idempotent may be sent multiple times.
diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md
index 19875c36a0..47ae7c5462 100644
--- a/doc/g_stands_for.md
+++ b/doc/g_stands_for.md
@@ -14,3 +14,4 @@ future), and the corresponding version numbers that used them:
- 1.8 'g' stands for 'generous'
- 1.9 'g' stands for 'glossy'
- 1.10 'g' stands for 'glamorous'
+- 1.11 'g' stands for 'gorgeous'
diff --git a/examples/android/helloworld/.gitignore b/examples/android/helloworld/.gitignore
new file mode 100644
index 0000000000..39fb081a42
--- /dev/null
+++ b/examples/android/helloworld/.gitignore
@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/examples/android/helloworld/README.md b/examples/android/helloworld/README.md
new file mode 100644
index 0000000000..ebb16d136b
--- /dev/null
+++ b/examples/android/helloworld/README.md
@@ -0,0 +1,24 @@
+gRPC on Android
+==============
+
+Note: Building the protobuf dependency for Android requires
+https://github.com/google/protobuf/pull/3878. This fix will be in the next
+protobuf release, but until then must be manually patched in to
+`third_party/protobuf` to build gRPC for Android.
+
+PREREQUISITES
+-------------
+
+- Android SDK
+- Android NDK
+- `protoc` and `grpc_cpp_plugin` binaries on the host system
+
+INSTALL
+-------
+
+The example application can be built via Android Studio or on the command line
+using `gradle`:
+
+ ```sh
+ $ ./gradlew installDebug
+ ```
diff --git a/examples/android/helloworld/app/.gitignore b/examples/android/helloworld/app/.gitignore
new file mode 100644
index 0000000000..796b96d1c4
--- /dev/null
+++ b/examples/android/helloworld/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/examples/android/helloworld/app/CMakeLists.txt b/examples/android/helloworld/app/CMakeLists.txt
new file mode 100644
index 0000000000..6ee18daaab
--- /dev/null
+++ b/examples/android/helloworld/app/CMakeLists.txt
@@ -0,0 +1,123 @@
+cmake_minimum_required(VERSION 3.4.1)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+
+set(helloworld_PROTOBUF_PROTOC_EXECUTABLE "/usr/local/bin/protoc" CACHE STRING "Protoc binary on host")
+set(helloworld_GRPC_CPP_PLUGIN_EXECUTABLE "/usr/local/bin/grpc_cpp_plugin" CACHE STRING "gRPC CPP plugin binary on host")
+
+set(GRPC_SRC_DIR ../../../../)
+
+set(GRPC_BUILD_DIR ../grpc/outputs/${ANDROID_ABI})
+file(MAKE_DIRECTORY ${GRPC_BUILD_DIR})
+
+add_subdirectory(${GRPC_SRC_DIR} ${GRPC_BUILD_DIR})
+
+include_directories(${GRPC_SRC_DIR}/include)
+
+add_library(libgrpc STATIC IMPORTED)
+set_target_properties(libgrpc PROPERTIES IMPORTED_LOCATION
+ ${GRPC_BUILD_DIR}/libgrpc.a)
+
+add_library(libgrpc++ STATIC IMPORTED)
+set_target_properties(libgrpc++ PROPERTIES IMPORTED_LOCATION
+ ${GRPC_BUILD_DIR}/libgrpc++.a)
+
+add_library(libgpr STATIC IMPORTED)
+set_target_properties(libgpr PROPERTIES IMPORTED_LOCATION
+ ${GRPC_BUILD_DIR}/libgpr.a)
+
+add_library(libcares STATIC IMPORTED)
+set_target_properties(libcares PROPERTIES IMPORTED_LOCATION
+ ${GRPC_BUILD_DIR}/third_party/cares/cares/lib/libcares.a)
+
+add_library(libzlib STATIC IMPORTED)
+set_target_properties(libzlib PROPERTIES IMPORTED_LOCATION
+ ${GRPC_BUILD_DIR}/third_party/zlib/libz.a)
+
+add_library(libcrypto STATIC IMPORTED)
+set_target_properties(libcrypto PROPERTIES IMPORTED_LOCATION
+ ${GRPC_BUILD_DIR}/third_party/boringssl/crypto/libcrypto.a)
+
+add_library(libssl STATIC IMPORTED)
+set_target_properties(libssl PROPERTIES IMPORTED_LOCATION
+ ${GRPC_BUILD_DIR}/third_party/boringssl/ssl/libssl.a)
+
+set(GRPC_PROTO_GENS_DIR ${CMAKE_BINARY_DIR}/gens)
+file(MAKE_DIRECTORY ${GRPC_PROTO_GENS_DIR})
+include_directories(${GRPC_PROTO_GENS_DIR})
+
+function(android_protobuf_grpc_generate_cpp SRC_FILES HDR_FILES INCLUDE_ROOT)
+ if(NOT ARGN)
+ message(SEND_ERROR "Error: android_protobuf_grpc_generate_cpp() called without any proto files")
+ return()
+ endif()
+
+ set(${SRC_FILES})
+ set(${HDR_FILES})
+ set(PROTOBUF_INCLUDE_PATH -I ${INCLUDE_ROOT})
+ foreach(FIL ${ARGN})
+ get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+ get_filename_component(FIL_WE ${FIL} NAME_WE)
+ file(RELATIVE_PATH REL_FIL ${CMAKE_CURRENT_SOURCE_DIR}/${INCLUDE_ROOT} ${ABS_FIL})
+ get_filename_component(REL_DIR ${REL_FIL} DIRECTORY)
+ set(RELFIL_WE "${REL_DIR}/${FIL_WE}")
+
+ list(APPEND ${SRC_FILES} "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc")
+ list(APPEND ${HDR_FILES} "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h")
+ list(APPEND ${SRC_FILES} "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc")
+ list(APPEND ${HDR_FILES} "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h")
+
+ add_custom_command(
+ OUTPUT "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.cc"
+ "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.grpc.pb.h"
+ "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.cc"
+ "${GRPC_PROTO_GENS_DIR}/${RELFIL_WE}.pb.h"
+ COMMAND ${helloworld_PROTOBUF_PROTOC_EXECUTABLE}
+ ARGS --grpc_out=${GRPC_PROTO_GENS_DIR}
+ --cpp_out=${GRPC_PROTO_GENS_DIR}
+ --plugin=protoc-gen-grpc=${helloworld_GRPC_CPP_PLUGIN_EXECUTABLE}
+ ${PROTOBUF_INCLUDE_PATH}
+ ${REL_FIL}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ DEPENDS ${helloworld_PROTOBUF_PROTOC_EXECUTABLE} ${helloworld_GRPC_CPP_PLUGIN_EXECUTABLE} ${ABS_FIL} )
+ endforeach()
+
+ set_source_files_properties(${${SRC_FILES}} ${${HDR_FILES}} PROPERTIES GENERATED TRUE)
+ set(${SRC_FILES} ${${SRC_FILES}} PARENT_SCOPE)
+ set(${HDR_FILES} ${${HDR_FILES}} PARENT_SCOPE)
+endfunction()
+
+set(PROTO_BASE_DIR ${GRPC_SRC_DIR}/examples/protos)
+
+android_protobuf_grpc_generate_cpp(
+ HELLOWORLD_PROTO_SRCS HELLOWORLD_PROTO_HDRS ${PROTO_BASE_DIR} ${PROTO_BASE_DIR}/helloworld.proto)
+
+add_library(helloworld_proto_lib
+ SHARED ${HELLOWORLD_PROTO_HDRS} ${HELLOWORLD_PROTO_SRCS})
+
+target_link_libraries(helloworld_proto_lib
+ libprotobuf
+ libgrpc++
+ android
+ log)
+
+find_library(log-lib
+ log)
+
+add_library(grpc-helloworld
+ SHARED src/main/cpp/grpc-helloworld.cc)
+
+target_include_directories(grpc-helloworld
+ PRIVATE ${HELLOWORLD_PROTO_HEADERS})
+
+target_link_libraries(grpc-helloworld
+ libgrpc++
+ libgrpc
+ libzlib
+ libcares
+ libssl
+ libcrypto
+ helloworld_proto_lib
+ libgpr
+ android
+ ${log-lib})
diff --git a/examples/android/helloworld/app/build.gradle b/examples/android/helloworld/app/build.gradle
new file mode 100644
index 0000000000..c6ab7308ae
--- /dev/null
+++ b/examples/android/helloworld/app/build.gradle
@@ -0,0 +1,53 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 26
+ defaultConfig {
+ applicationId "io.grpc.android.cpp.helloworldexample"
+ minSdkVersion 14
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ externalNativeBuild {
+ cmake {
+ cppFlags "-std=c++14 -frtti -fexceptions"
+ arguments '-DANDROID_STL=c++_static'
+ arguments '-DRUN_HAVE_POSIX_REGEX=0'
+ arguments '-DRUN_HAVE_STD_REGEX=0'
+ arguments '-DRUN_HAVE_STEADY_CLOCK=0'
+ arguments '-Dprotobuf_BUILD_PROTOC_BINARIES=off'
+ arguments '-DgRPC_BUILD_CODEGEN=off'
+ // Set this to the path to the protoc binary on the host system (codegen is not
+ // cross-compiled to Android)
+ arguments '-Dhelloworld_PROTOBUF_PROTOC_EXECUTABLE=/usr/local/bin/protoc'
+ // Set this to the path to the gRPC C++ protoc plugin binary on the host system
+ // (codegen is not cross-compiled to Android)
+ arguments '-Dhelloworld_GRPC_CPP_PLUGIN_EXECUTABLE=/usr/local/bin/grpc_cpp_plugin'
+ }
+ }
+ ndk.abiFilters 'x86'
+ }
+ buildTypes {
+ debug {
+ minifyEnabled false
+ }
+ release {
+ minifyEnabled true
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+ externalNativeBuild {
+ cmake {
+ path "CMakeLists.txt"
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation 'com.android.support:appcompat-v7:26.1.0'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.1'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
+}
diff --git a/examples/android/helloworld/app/proguard-rules.pro b/examples/android/helloworld/app/proguard-rules.pro
new file mode 100644
index 0000000000..f1b424510d
--- /dev/null
+++ b/examples/android/helloworld/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/examples/android/helloworld/app/src/main/AndroidManifest.xml b/examples/android/helloworld/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..8109da9e96
--- /dev/null
+++ b/examples/android/helloworld/app/src/main/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="io.grpc.helloworldexample.cpp" >
+
+ <uses-permission android:name="android.permission.INTERNET" />
+
+ <application
+ android:allowBackup="false"
+ android:icon="@mipmap/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/Base.V7.Theme.AppCompat.Light" >
+ <activity
+ android:name=".HelloworldActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/examples/android/helloworld/app/src/main/cpp/grpc-helloworld.cc b/examples/android/helloworld/app/src/main/cpp/grpc-helloworld.cc
new file mode 100644
index 0000000000..7a31b783c4
--- /dev/null
+++ b/examples/android/helloworld/app/src/main/cpp/grpc-helloworld.cc
@@ -0,0 +1,142 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <atomic>
+
+#include <grpc++/grpc++.h>
+#include <jni.h>
+
+#include "helloworld.grpc.pb.h"
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::Status;
+using helloworld::Greeter;
+using helloworld::HelloReply;
+using helloworld::HelloRequest;
+
+std::atomic<bool> stop_server(false);
+
+// Logic and data behind the server's behavior.
+class GreeterServiceImpl final : public Greeter::Service {
+ Status SayHello(ServerContext* context, const HelloRequest* request,
+ HelloReply* reply) override {
+ std::string prefix("Hello ");
+ reply->set_message(prefix + request->name());
+ return Status::OK;
+ }
+};
+
+void StartServer(JNIEnv* env, jobject obj, jmethodID is_cancelled_mid,
+ int port) {
+ const int host_port_buf_size = 1024;
+ char host_port[host_port_buf_size];
+ snprintf(host_port, host_port_buf_size, "0.0.0.0:%d", port);
+
+ GreeterServiceImpl service;
+ ServerBuilder builder;
+ // Listen on the given address without any authentication mechanism.
+ builder.AddListeningPort(host_port, grpc::InsecureServerCredentials());
+ // Register "service" as the instance through which we'll communicate with
+ // clients. In this case it corresponds to an *synchronous* service.
+ builder.RegisterService(&service);
+ // Finally assemble the server.
+ std::unique_ptr<Server> server(builder.BuildAndStart());
+ while (!stop_server.load()) {
+ // Check with the Java code to see if the user has requested the server stop or the app is no
+ // longer in the foreground.
+ jboolean is_cancelled = env->CallBooleanMethod(obj, is_cancelled_mid);
+ if (is_cancelled == JNI_TRUE) {
+ stop_server = true;
+ }
+ }
+}
+
+class GreeterClient {
+ public:
+ GreeterClient(std::shared_ptr<Channel> channel)
+ : stub_(Greeter::NewStub(channel)) {}
+
+ // Assembles the client's payload, sends it and presents the response back
+ // from the server.
+ std::string SayHello(const std::string& user) {
+ // Data we are sending to the server.
+ HelloRequest request;
+ request.set_name(user);
+
+ // Container for the data we expect from the server.
+ HelloReply reply;
+
+ // Context for the client. It could be used to convey extra information to
+ // the server and/or tweak certain RPC behaviors.
+ ClientContext context;
+ // The actual RPC.
+ Status status = stub_->SayHello(&context, request, &reply);
+
+ if (status.ok()) {
+ return reply.message();
+ } else {
+ return status.error_message();
+ }
+ }
+
+ private:
+ std::unique_ptr<Greeter::Stub> stub_;
+};
+
+// Send an RPC and return the response. Invoked from Java code.
+extern "C" JNIEXPORT jstring JNICALL
+Java_io_grpc_helloworldexample_cpp_HelloworldActivity_sayHello(
+ JNIEnv* env, jobject obj_unused, jstring host_raw, jint port_raw,
+ jstring message_raw) {
+ const char* host_chars = env->GetStringUTFChars(host_raw, (jboolean*)0);
+ std::string host(host_chars, env->GetStringUTFLength(host_raw));
+
+ int port = static_cast<int>(port_raw);
+
+ const char* message_chars = env->GetStringUTFChars(message_raw, (jboolean*)0);
+ std::string message(message_chars, env->GetStringUTFLength(message_raw));
+
+ const int host_port_buf_size = 1024;
+ char host_port[host_port_buf_size];
+ snprintf(host_port, host_port_buf_size, "%s:%d", host.c_str(), port);
+
+ GreeterClient greeter(
+ grpc::CreateChannel(host_port, grpc::InsecureChannelCredentials()));
+ std::string reply = greeter.SayHello(message);
+
+ return env->NewStringUTF(reply.c_str());
+}
+
+// Start the server. Invoked from Java code.
+extern "C" JNIEXPORT void JNICALL
+Java_io_grpc_helloworldexample_cpp_HelloworldActivity_startServer(
+ JNIEnv* env, jobject obj_this, jint port_raw) {
+ int port = static_cast<int>(port_raw);
+
+ jclass cls = env->GetObjectClass(obj_this);
+ jmethodID is_cancelled_mid =
+ env->GetMethodID(cls, "isRunServerTaskCancelled", "()Z");
+
+ stop_server = false;
+
+ StartServer(env, obj_this, is_cancelled_mid, port);
+}
diff --git a/examples/android/helloworld/app/src/main/java/io/grpc/helloworldexample/cpp/HelloworldActivity.java b/examples/android/helloworld/app/src/main/java/io/grpc/helloworldexample/cpp/HelloworldActivity.java
new file mode 100644
index 0000000000..ae5c88b208
--- /dev/null
+++ b/examples/android/helloworld/app/src/main/java/io/grpc/helloworldexample/cpp/HelloworldActivity.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2018, gRPC Authors All rights reserved.
+ *
+ * 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.
+ */
+
+package io.grpc.helloworldexample.cpp;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.text.TextUtils;
+import android.text.method.ScrollingMovementMethod;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+import java.lang.ref.WeakReference;
+
+public class HelloworldActivity extends AppCompatActivity {
+
+ static {
+ System.loadLibrary("grpc-helloworld");
+ }
+
+ private Button sendButton;
+ private Button serverButton;
+ private EditText hostEdit;
+ private EditText portEdit;
+ private EditText messageEdit;
+ private EditText serverPortEdit;
+ private TextView resultText;
+ private GrpcTask grpcTask;
+ private RunServerTask runServerTask;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_helloworld);
+ sendButton = (Button) findViewById(R.id.send_button);
+ serverButton = (Button) findViewById(R.id.server_button);
+ hostEdit = (EditText) findViewById(R.id.host_edit_text);
+ portEdit = (EditText) findViewById(R.id.port_edit_text);
+ messageEdit = (EditText) findViewById(R.id.message_edit_text);
+ serverPortEdit = (EditText) findViewById(R.id.server_port_edit_text);
+ resultText = (TextView) findViewById(R.id.grpc_response_text);
+ resultText.setMovementMethod(new ScrollingMovementMethod());
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ if (runServerTask != null) {
+ runServerTask.cancel(true);
+ runServerTask = null;
+ serverButton.setText("Start gRPC Server");
+ }
+ if (grpcTask != null) {
+ grpcTask.cancel(true);
+ grpcTask = null;
+ }
+ }
+
+ public void sendMessage(View view) {
+ ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))
+ .hideSoftInputFromWindow(hostEdit.getWindowToken(), 0);
+ sendButton.setEnabled(false);
+ resultText.setText("");
+ grpcTask = new GrpcTask(this);
+ grpcTask.executeOnExecutor(
+ AsyncTask.THREAD_POOL_EXECUTOR,
+ hostEdit.getText().toString(),
+ messageEdit.getText().toString(),
+ portEdit.getText().toString());
+ }
+
+ public void startOrStopServer(View view) {
+ if (runServerTask != null) {
+ runServerTask.cancel(true);
+ runServerTask = null;
+ serverButton.setText("Start gRPC Server");
+ Toast.makeText(this, "Server stopped", Toast.LENGTH_SHORT).show();
+ } else {
+ runServerTask = new RunServerTask(this);
+ String portStr = serverPortEdit.getText().toString();
+ int port = TextUtils.isEmpty(portStr) ? 50051 : Integer.valueOf(portStr);
+ runServerTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, port);
+ serverButton.setText("Stop gRPC Server");
+ Toast.makeText(this, "Server started on port " + port, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private static class RunServerTask extends AsyncTask<Integer, Void, Void> {
+ private final WeakReference<HelloworldActivity> activityReference;
+
+ private RunServerTask(HelloworldActivity activity) {
+ this.activityReference = new WeakReference<HelloworldActivity>(activity);
+ }
+
+ @Override
+ protected Void doInBackground(Integer... params) {
+ int port = params[0];
+ HelloworldActivity activity = activityReference.get();
+ if (activity != null) {
+ activity.startServer(port);
+ }
+ return null;
+ }
+ }
+
+ private static class GrpcTask extends AsyncTask<String, Void, String> {
+ private final WeakReference<HelloworldActivity> activityReference;
+
+ private GrpcTask(HelloworldActivity activity) {
+ this.activityReference = new WeakReference<HelloworldActivity>(activity);
+ }
+
+ @Override
+ protected String doInBackground(String... params) {
+ String host = params[0];
+ String message = params[1];
+ String portStr = params[2];
+ int port = TextUtils.isEmpty(portStr) ? 50051 : Integer.valueOf(portStr);
+ return sayHello(host, port, message);
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ HelloworldActivity activity = activityReference.get();
+ if (activity == null || isCancelled()) {
+ return;
+ }
+ TextView resultText = (TextView) activity.findViewById(R.id.grpc_response_text);
+ Button sendButton = (Button) activity.findViewById(R.id.send_button);
+ resultText.setText(result);
+ sendButton.setEnabled(true);
+ }
+ }
+
+ /**
+ * Invoked by native code to stop server when RunServerTask has been canceled, either by user
+ * request or upon app moving to background.
+ */
+ public boolean isRunServerTaskCancelled() {
+ if (runServerTask != null) {
+ return runServerTask.isCancelled();
+ }
+ return false;
+ }
+
+ public static native String sayHello(String host, int port, String message);
+
+ public native void startServer(int port);
+}
diff --git a/examples/android/helloworld/app/src/main/res/layout/activity_helloworld.xml b/examples/android/helloworld/app/src/main/res/layout/activity_helloworld.xml
new file mode 100644
index 0000000000..52804697a3
--- /dev/null
+++ b/examples/android/helloworld/app/src/main/res/layout/activity_helloworld.xml
@@ -0,0 +1,86 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".HelloworldActivity"
+ android:orientation="vertical" >
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="12dp"
+ android:paddingBottom="12dp"
+ android:textSize="16sp"
+ android:text="gRPC Client Configuration"
+ android:textStyle="bold" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+ <EditText
+ android:id="@+id/host_edit_text"
+ android:layout_weight="2"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:hint="Enter Host" />
+ <EditText
+ android:id="@+id/port_edit_text"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:inputType="numberDecimal"
+ android:hint="Enter Port" />
+ </LinearLayout>
+
+
+ <EditText
+ android:id="@+id/message_edit_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="Enter message to send" />
+
+ <Button
+ android:id="@+id/send_button"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:onClick="sendMessage"
+ android:text="Send gRPC Request" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="12dp"
+ android:paddingBottom="12dp"
+ android:textSize="16sp"
+ android:text="Response:" />
+
+ <TextView
+ android:id="@+id/grpc_response_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scrollbars = "vertical"
+ android:textSize="16sp" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="12dp"
+ android:paddingBottom="12dp"
+ android:textSize="16sp"
+ android:text="gRPC Server Configuration"
+ android:textStyle="bold" />
+
+ <EditText
+ android:id="@+id/server_port_edit_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hint="Server port" />
+
+ <Button
+ android:id="@+id/server_button"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:onClick="startOrStopServer"
+ android:text="Start gRPC Server" />
+
+</LinearLayout>
diff --git a/examples/android/helloworld/app/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/android/helloworld/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000000..cde69bccce
--- /dev/null
+++ b/examples/android/helloworld/app/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/examples/android/helloworld/app/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/android/helloworld/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000000..c133a0cbd3
--- /dev/null
+++ b/examples/android/helloworld/app/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/examples/android/helloworld/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/android/helloworld/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000..bfa42f0e7b
--- /dev/null
+++ b/examples/android/helloworld/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/examples/android/helloworld/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/android/helloworld/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..324e72cdd7
--- /dev/null
+++ b/examples/android/helloworld/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/examples/android/helloworld/app/src/main/res/values/strings.xml b/examples/android/helloworld/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000000..7e916e348c
--- /dev/null
+++ b/examples/android/helloworld/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+<resources>
+ <string name="app_name">GrpcHelloworldCppExample</string>
+</resources>
diff --git a/examples/android/helloworld/build.gradle b/examples/android/helloworld/build.gradle
new file mode 100644
index 0000000000..bd5f337f01
--- /dev/null
+++ b/examples/android/helloworld/build.gradle
@@ -0,0 +1,24 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.0.1'
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/examples/android/helloworld/gradle.properties b/examples/android/helloworld/gradle.properties
new file mode 100644
index 0000000000..aac7c9b461
--- /dev/null
+++ b/examples/android/helloworld/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/examples/android/helloworld/gradle/wrapper/gradle-wrapper.jar b/examples/android/helloworld/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000000..13372aef5e
--- /dev/null
+++ b/examples/android/helloworld/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/examples/android/helloworld/gradle/wrapper/gradle-wrapper.properties b/examples/android/helloworld/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000000..4c81831f53
--- /dev/null
+++ b/examples/android/helloworld/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Jan 25 11:45:30 PST 2018
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
diff --git a/examples/android/helloworld/gradlew b/examples/android/helloworld/gradlew
new file mode 100755
index 0000000000..9d82f78915
--- /dev/null
+++ b/examples/android/helloworld/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/examples/android/helloworld/gradlew.bat b/examples/android/helloworld/gradlew.bat
new file mode 100644
index 0000000000..8a0b282aa6
--- /dev/null
+++ b/examples/android/helloworld/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/examples/android/helloworld/settings.gradle b/examples/android/helloworld/settings.gradle
new file mode 100644
index 0000000000..e7b4def49c
--- /dev/null
+++ b/examples/android/helloworld/settings.gradle
@@ -0,0 +1 @@
+include ':app'
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 64029fb1f7..821c16da45 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,55 +69,12 @@ 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/grpcpp/alarm.h',
+ ss.source_files = 'include/grpcpp/alarm.h',
'include/grpcpp/channel.h',
'include/grpcpp/client_context.h',
'include/grpcpp/completion_queue.h',
@@ -156,36 +119,6 @@ Pod::Spec.new do |s|
'include/grpcpp/support/stub_options.h',
'include/grpcpp/support/sync_stream.h',
'include/grpcpp/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',
'include/grpcpp/impl/codegen/async_stream.h',
'include/grpcpp/impl/codegen/async_unary_call.h',
'include/grpcpp/impl/codegen/byte_buffer.h',
@@ -224,8 +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',
- 'include/grpcpp/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',
@@ -288,7 +220,6 @@ 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.h',
'src/core/lib/gpr/time_precise.h',
'src/core/lib/gpr/tls.h',
'src/core/lib/gpr/tls_gcc.h',
@@ -302,6 +233,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/atomic_with_std.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/memory.h',
+ 'src/core/lib/gprpp/thd.h',
'src/core/lib/profiling/timers.h',
'src/core/ext/transport/chttp2/transport/bin_decoder.h',
'src/core/ext/transport/chttp2/transport/bin_encoder.h',
@@ -341,9 +273,9 @@ Pod::Spec.new do |s|
'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_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',
@@ -364,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',
@@ -371,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',
@@ -475,6 +409,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',
@@ -499,6 +434,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',
@@ -519,8 +455,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',
- 'include/grpcpp/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',
@@ -540,7 +475,6 @@ 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.h',
'src/core/lib/gpr/time_precise.h',
'src/core/lib/gpr/tls.h',
'src/core/lib/gpr/tls_gcc.h',
@@ -554,6 +488,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/atomic_with_std.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/memory.h',
+ 'src/core/lib/gprpp/thd.h',
'src/core/lib/profiling/timers.h',
'src/core/lib/avl/avl.h',
'src/core/lib/backoff/backoff.h',
@@ -653,6 +588,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',
@@ -677,6 +613,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',
@@ -684,113 +621,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/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.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 45a9815edd..6c6c76991c 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'
@@ -192,7 +192,6 @@ 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.h',
'src/core/lib/gpr/time_precise.h',
'src/core/lib/gpr/tls.h',
'src/core/lib/gpr/tls_gcc.h',
@@ -206,6 +205,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/atomic_with_std.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/memory.h',
+ 'src/core/lib/gprpp/thd.h',
'src/core/lib/profiling/timers.h',
'src/core/lib/gpr/alloc.cc',
'src/core/lib/gpr/arena.cc',
@@ -233,9 +233,6 @@ Pod::Spec.new do |s|
'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_posix.cc',
- 'src/core/lib/gpr/thd_windows.cc',
'src/core/lib/gpr/time.cc',
'src/core/lib/gpr/time_posix.cc',
'src/core/lib/gpr/time_precise.cc',
@@ -245,6 +242,8 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/tmpfile_posix.cc',
'src/core/lib/gpr/tmpfile_windows.cc',
'src/core/lib/gpr/wrap_memcpy.cc',
+ 'src/core/lib/gprpp/thd_posix.cc',
+ 'src/core/lib/gprpp/thd_windows.cc',
'src/core/lib/profiling/basic_timers.cc',
'src/core/lib/profiling/stap_timers.cc',
'src/core/ext/transport/chttp2/transport/bin_decoder.h',
@@ -285,9 +284,9 @@ Pod::Spec.new do |s|
'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_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 +307,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 +315,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',
@@ -419,6 +420,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',
@@ -443,6 +445,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',
@@ -563,7 +566,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',
@@ -594,6 +596,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',
@@ -643,10 +646,10 @@ Pod::Spec.new do |s|
'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_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',
@@ -669,12 +672,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',
@@ -720,7 +725,6 @@ 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.h',
'src/core/lib/gpr/time_precise.h',
'src/core/lib/gpr/tls.h',
'src/core/lib/gpr/tls_gcc.h',
@@ -734,6 +738,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/atomic_with_std.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/memory.h',
+ 'src/core/lib/gprpp/thd.h',
'src/core/lib/profiling/timers.h',
'src/core/ext/transport/chttp2/transport/bin_decoder.h',
'src/core/ext/transport/chttp2/transport/bin_encoder.h',
@@ -773,9 +778,9 @@ Pod::Spec.new do |s|
'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_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',
@@ -796,6 +801,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',
@@ -803,6 +809,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',
@@ -907,6 +914,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',
@@ -931,6 +939,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',
@@ -1070,6 +1079,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.gemspec b/grpc.gemspec
index 670eee1f25..fbe70aa795 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -83,7 +83,6 @@ 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.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 )
@@ -97,6 +96,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gprpp/atomic_with_std.h )
s.files += %w( src/core/lib/gprpp/manual_constructor.h )
s.files += %w( src/core/lib/gprpp/memory.h )
+ s.files += %w( src/core/lib/gprpp/thd.h )
s.files += %w( src/core/lib/profiling/timers.h )
s.files += %w( src/core/lib/gpr/alloc.cc )
s.files += %w( src/core/lib/gpr/arena.cc )
@@ -124,9 +124,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/sync.cc )
s.files += %w( src/core/lib/gpr/sync_posix.cc )
s.files += %w( src/core/lib/gpr/sync_windows.cc )
- s.files += %w( src/core/lib/gpr/thd.cc )
- s.files += %w( src/core/lib/gpr/thd_posix.cc )
- s.files += %w( src/core/lib/gpr/thd_windows.cc )
s.files += %w( src/core/lib/gpr/time.cc )
s.files += %w( src/core/lib/gpr/time_posix.cc )
s.files += %w( src/core/lib/gpr/time_precise.cc )
@@ -136,6 +133,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/tmpfile_posix.cc )
s.files += %w( src/core/lib/gpr/tmpfile_windows.cc )
s.files += %w( src/core/lib/gpr/wrap_memcpy.cc )
+ s.files += %w( src/core/lib/gprpp/thd_posix.cc )
+ s.files += %w( src/core/lib/gprpp/thd_windows.cc )
s.files += %w( src/core/lib/profiling/basic_timers.cc )
s.files += %w( src/core/lib/profiling/stap_timers.cc )
s.files += %w( include/grpc/impl/codegen/byte_buffer.h )
@@ -211,9 +210,9 @@ Gem::Specification.new do |s|
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_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 +233,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 +241,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 )
@@ -345,6 +346,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 )
@@ -369,6 +371,7 @@ 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 )
@@ -493,7 +496,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 )
@@ -524,6 +526,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 )
@@ -573,10 +576,10 @@ Gem::Specification.new do |s|
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_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 )
@@ -599,12 +602,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 )
@@ -652,20 +657,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 c9390d306e..cd3deddb0e 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -187,9 +187,6 @@
'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_posix.cc',
- 'src/core/lib/gpr/thd_windows.cc',
'src/core/lib/gpr/time.cc',
'src/core/lib/gpr/time_posix.cc',
'src/core/lib/gpr/time_precise.cc',
@@ -199,6 +196,8 @@
'src/core/lib/gpr/tmpfile_posix.cc',
'src/core/lib/gpr/tmpfile_windows.cc',
'src/core/lib/gpr/wrap_memcpy.cc',
+ 'src/core/lib/gprpp/thd_posix.cc',
+ 'src/core/lib/gprpp/thd_windows.cc',
'src/core/lib/profiling/basic_timers.cc',
'src/core/lib/profiling/stap_timers.cc',
],
@@ -321,7 +320,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',
@@ -352,6 +350,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,10 +400,10 @@
'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_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',
@@ -427,12 +426,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',
@@ -618,7 +619,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',
@@ -649,6 +649,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',
@@ -664,12 +665,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',
@@ -833,7 +836,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',
@@ -864,6 +866,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',
@@ -879,12 +882,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',
@@ -1027,7 +1032,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',
@@ -1058,6 +1062,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',
@@ -1106,12 +1111,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',
@@ -2482,6 +2489,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',
@@ -2555,6 +2577,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/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 aec78be31b..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>
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 08776337cc..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>
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 3e897b0b27..dcce2e7f9a 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -314,6 +314,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
@@ -551,6 +562,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/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/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/package.xml b/package.xml
index 788161a4a1..db03230eba 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>
@@ -90,7 +90,6 @@
<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.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" />
@@ -104,6 +103,7 @@
<file baseinstalldir="/" name="src/core/lib/gprpp/atomic_with_std.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/manual_constructor.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/memory.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/thd.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/alloc.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/arena.cc" role="src" />
@@ -131,9 +131,6 @@
<file baseinstalldir="/" name="src/core/lib/gpr/sync.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/sync_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/sync_windows.cc" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr/thd.cc" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr/thd_posix.cc" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr/thd_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/time.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/time_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/time_precise.cc" role="src" />
@@ -143,6 +140,8 @@
<file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/wrap_memcpy.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/thd_posix.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/thd_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/basic_timers.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/stap_timers.cc" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer.h" role="src" />
@@ -218,9 +217,9 @@
<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_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 +240,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 +248,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" />
@@ -352,6 +353,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" />
@@ -376,6 +378,7 @@
<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" />
@@ -500,7 +503,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" />
@@ -531,6 +533,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" />
@@ -580,10 +583,10 @@
<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_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" />
@@ -606,12 +609,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" />
@@ -659,20 +664,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/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/compiler/php_generator.cc b/src/compiler/php_generator.cc
index d9705e8077..ca084cccbd 100644
--- a/src/compiler/php_generator.cc
+++ b/src/compiler/php_generator.cc
@@ -18,10 +18,12 @@
#include <map>
+#include <google/protobuf/compiler/php/php_generator.h>
#include "src/compiler/config.h"
#include "src/compiler/generator_helpers.h"
#include "src/compiler/php_generator_helpers.h"
+using google::protobuf::compiler::php::GeneratedClassName;
using grpc::protobuf::Descriptor;
using grpc::protobuf::FileDescriptor;
using grpc::protobuf::MethodDescriptor;
@@ -55,8 +57,10 @@ grpc::string MessageIdentifierName(const grpc::string& name,
const FileDescriptor* file) {
std::vector<grpc::string> tokens = grpc_generator::tokenize(name, ".");
std::ostringstream oss;
- oss << PackageName(file) << "\\"
- << grpc_generator::CapitalizeFirstLetter(tokens[tokens.size() - 1]);
+ if (PackageName(file) != "") {
+ oss << PackageName(file) << "\\";
+ }
+ oss << grpc_generator::CapitalizeFirstLetter(tokens[tokens.size() - 1]);
return oss.str();
}
@@ -67,9 +71,9 @@ void PrintMethod(const MethodDescriptor* method, Printer* out) {
vars["service_name"] = method->service()->full_name();
vars["name"] = method->name();
vars["input_type_id"] =
- MessageIdentifierName(input_type->full_name(), input_type->file());
- vars["output_type_id"] =
- MessageIdentifierName(output_type->full_name(), output_type->file());
+ MessageIdentifierName(GeneratedClassName(input_type), input_type->file());
+ vars["output_type_id"] = MessageIdentifierName(
+ GeneratedClassName(output_type), output_type->file());
out->Print("/**\n");
out->Print(GetPHPComments(method, " *").c_str());
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 9a8f25b630..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,144 +34,65 @@
#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;
@@ -179,7 +101,7 @@ typedef struct client_channel_channel_data {
/** 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;
@@ -306,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;
@@ -388,7 +309,7 @@ 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;
@@ -396,7 +317,7 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
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.
@@ -431,7 +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";
-
// 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
@@ -469,39 +389,39 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
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);
service_config_json =
gpr_strdup(grpc_channel_arg_get_string(channel_arg));
if (service_config_json != nullptr) {
- grpc_service_config* service_config =
- grpc_service_config_create(service_config_json);
+ 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);
- 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;
- 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;
@@ -514,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().
@@ -534,16 +454,13 @@ 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) {
@@ -722,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");
@@ -794,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);
@@ -809,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.
@@ -841,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;
+
+ // Set when we get a cancel_stream op.
+ grpc_error* cancel_error;
grpc_core::LoadBalancingPolicy::PickState pick;
- grpc_closure lb_pick_closure;
- grpc_closure lb_pick_cancel_closure;
+ 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
@@ -1001,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);
@@ -1011,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
@@ -1088,6 +2579,45 @@ static void pick_callback_done_locked(void* arg, grpc_error* error) {
GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback");
}
+// 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) {
@@ -1097,33 +2627,46 @@ static bool pick_callback_start_locked(grpc_call_element* elem) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: starting pick on lb_policy=%p",
chand, calld, chand->lb_policy.get());
}
- apply_service_config_to_call_locked(elem);
+ // Only get service config data on the first attempt.
+ if (calld->num_attempts_completed == 0) {
+ 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 = chand->lb_policy->PickLocked(&calld->pick);
if (pick_done) {
@@ -1137,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)));
}
@@ -1186,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 =
@@ -1224,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
@@ -1277,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)) {
@@ -1305,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) {
@@ -1333,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
@@ -1380,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) {
@@ -1428,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;
}
@@ -1441,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);
@@ -1452,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();
}
@@ -1652,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/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 248a6347d5..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>
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 59f4cdafb3..fa63dd75b5 100644
--- a/src/core/ext/filters/client_channel/lb_policy.cc
+++ b/src/core/ext/filters/client_channel/lb_policy.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/lb_policy.h"
#include "src/core/lib/iomgr/combiner.h"
diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h
index 6de652747e..c3e43e5ef6 100644
--- a/src/core/ext/filters/client_channel/lb_policy.h
+++ b/src/core/ext/filters/client_channel/lb_policy.h
@@ -19,6 +19,8 @@
#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"
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 11163a56dc..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
@@ -58,6 +58,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 <inttypes.h>
@@ -918,34 +920,8 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked(
// helper code for creating balancer channel
//
-// Helper function to construct a target info entry.
-grpc_slice_hash_table_entry BalancerEntryCreate(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;
-}
-
-// Comparison function used for slice_hash_table vtable.
-int BalancerNameCmp(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. */
-grpc_channel_args* BuildBalancerChannelArgs(
- const grpc_lb_addresses* addresses,
- FakeResolverResponseGenerator* response_generator,
- const grpc_channel_args* args) {
+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;
@@ -955,9 +931,6 @@ grpc_channel_args* BuildBalancerChannelArgs(
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 =
- (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;
@@ -965,32 +938,71 @@ grpc_channel_args* BuildBalancerChannelArgs(
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] =
- BalancerEntryCreate(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, gpr_free, BalancerNameCmp);
- 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);
+ 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 result;
+ return new_args;
}
//
@@ -1292,8 +1304,9 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
if (lb_channel_ == nullptr) {
char* uri_str;
gpr_asprintf(&uri_str, "fake:///%s", server_name_);
- lb_channel_ = grpc_lb_policy_grpclb_create_lb_channel(
- uri_str, client_channel_factory(), lb_channel_args);
+ 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);
}
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 f1878a594e..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>
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 178e299b61..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>
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 f1580e8b91..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>
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 7a8f5f1029..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"
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 2018aabb91..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>
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 e0e7d8bf5c..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"
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 f495cdb3c2..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,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include <string.h>
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 14c21dfe63..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,6 +19,8 @@
#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"
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 fbe07c58f7..cae7cc35e3 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>
@@ -657,7 +659,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);
@@ -671,9 +672,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(
@@ -703,6 +705,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);
@@ -774,8 +783,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 aeb0c39df9..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>
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 0fb3935609..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;
}
}
}
@@ -251,15 +258,11 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem,
grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG);
const char* service_config_str = grpc_channel_arg_get_string(channel_arg);
if (service_config_str != nullptr) {
- grpc_service_config* service_config =
- grpc_service_config_create(service_config_str);
+ 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 f3cc16d8cc..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/security_connector/security_connector.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_hash_table.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
@@ -71,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 =
@@ -84,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 2fc3c4fa41..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);
}
}
@@ -1571,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);
}
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 e1d4843785..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"
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.h b/src/core/lib/channel/channel_args.h
index c59bd0c7e7..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"
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/cpu_posix.cc b/src/core/lib/gpr/cpu_posix.cc
index 7a77f7ab64..915fd4976c 100644
--- a/src/core/lib/gpr/cpu_posix.cc
+++ b/src/core/lib/gpr/cpu_posix.cc
@@ -37,7 +37,7 @@ static long ncpus = 0;
static pthread_key_t thread_id_key;
static void init_ncpus() {
- ncpus = sysconf(_SC_NPROCESSORS_ONLN);
+ ncpus = sysconf(_SC_NPROCESSORS_CONF);
if (ncpus < 1 || ncpus > INT32_MAX) {
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 d7718273a6..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>
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
deleted file mode 100644
index 11391418b1..0000000000
--- a/src/core/lib/gpr/thd.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-/* Platform-independent features for gpr threads. */
-
-#include "src/core/lib/gpr/thd.h"
-
-#include <string.h>
-
-enum { GPR_THD_JOINABLE = 1 };
-
-gpr_thd_options gpr_thd_options_default(void) {
- gpr_thd_options options;
- memset(&options, 0, sizeof(options));
- return options;
-}
-
-void gpr_thd_options_set_detached(gpr_thd_options* options) {
- options->flags &= ~GPR_THD_JOINABLE;
-}
-
-void gpr_thd_options_set_joinable(gpr_thd_options* options) {
- options->flags |= GPR_THD_JOINABLE;
-}
-
-int gpr_thd_options_is_detached(const gpr_thd_options* options) {
- if (!options) return 1;
- return (options->flags & GPR_THD_JOINABLE) == 0;
-}
-
-int gpr_thd_options_is_joinable(const gpr_thd_options* options) {
- if (!options) return 0;
- return (options->flags & GPR_THD_JOINABLE) == GPR_THD_JOINABLE;
-}
diff --git a/src/core/lib/gpr/thd.h b/src/core/lib/gpr/thd.h
deleted file mode 100644
index 58ce0d0088..0000000000
--- a/src/core/lib/gpr/thd.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *
- * 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_LIB_GPR_THD_H
-#define GRPC_CORE_LIB_GPR_THD_H
-/** Internal thread interface for GPR.
-
- Types
- gpr_thd_options options used when creating a thread
- */
-
-#include <grpc/support/port_platform.h>
-#include <grpc/support/thd_id.h>
-#include <grpc/support/time.h>
-
-/** Thread creation options. */
-typedef struct {
- int flags; /** Opaque field. Get and set with accessors below. */
-} gpr_thd_options;
-
-/** Create a new thread running (*thd_body)(arg) and place its thread identifier
- in *t, and return true. If there are insufficient resources, return false.
- thd_name is the name of the thread for identification purposes on platforms
- that support thread naming.
- If options==NULL, default options are used.
- The thread is immediately runnable, and exits when (*thd_body)() returns. */
-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. */
-gpr_thd_options gpr_thd_options_default(void);
-
-/** Set the thread to become detached on startup - this is the default. */
-void gpr_thd_options_set_detached(gpr_thd_options* options);
-
-/** Set the thread to become joinable - mutually exclusive with detached. */
-void gpr_thd_options_set_joinable(gpr_thd_options* options);
-
-/** Returns non-zero if the option detached is set. */
-int gpr_thd_options_is_detached(const gpr_thd_options* options);
-
-/** Returns non-zero if the option joinable is set. */
-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. */
-void gpr_thd_join(gpr_thd_id t);
-
-/* 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_H */
diff --git a/src/core/lib/gpr/thd_posix.cc b/src/core/lib/gpr/thd_posix.cc
deleted file mode 100644
index fcd174bfba..0000000000
--- a/src/core/lib/gpr/thd_posix.cc
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-/* Posix implementation for gpr threads. */
-
-#include <grpc/support/port_platform.h>
-
-#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_id.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "src/core/lib/gpr/fork.h"
-#include "src/core/lib/gpr/useful.h"
-
-static gpr_mu g_mu;
-static gpr_cv g_cv;
-static int g_thread_count;
-static int g_awaiting_threads;
-
-struct thd_arg {
- void (*body)(void* arg); /* body of a thread */
- void* arg; /* argument to a thread */
- const char* name; /* name of thread. Can be nullptr. */
-};
-
-static void inc_thd_count();
-static void dec_thd_count();
-
-/* Body of every thread started via gpr_thd_new. */
-static void* thread_body(void* v) {
- struct thd_arg a = *static_cast<struct thd_arg*>(v);
- free(v);
- if (a.name != nullptr) {
-#if GPR_APPLE_PTHREAD_NAME
- /* Apple supports 64 characters, and will truncate if it's longer. */
- pthread_setname_np(a.name);
-#elif GPR_LINUX_PTHREAD_NAME
- /* Linux supports 16 characters max, and will error if it's longer. */
- char buf[16];
- size_t buf_len = GPR_ARRAY_SIZE(buf) - 1;
- strncpy(buf, a.name, buf_len);
- buf[buf_len] = '\0';
- pthread_setname_np(pthread_self(), buf);
-#endif // GPR_APPLE_PTHREAD_NAME
- }
- (*a.body)(a.arg);
- dec_thd_count();
- return nullptr;
-}
-
-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 thread_started;
- pthread_attr_t attr;
- pthread_t p;
- /* don't use gpr_malloc as we may cause an infinite recursion with
- * the profiling code */
- struct thd_arg* a = static_cast<struct thd_arg*>(malloc(sizeof(*a)));
- GPR_ASSERT(a != nullptr);
- a->body = thd_body;
- a->arg = arg;
- a->name = thd_name;
- inc_thd_count();
-
- GPR_ASSERT(pthread_attr_init(&attr) == 0);
- if (gpr_thd_options_is_detached(options)) {
- GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) ==
- 0);
- } else {
- GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) ==
- 0);
- }
- thread_started = (pthread_create(&p, &attr, &thread_body, a) == 0);
- GPR_ASSERT(pthread_attr_destroy(&attr) == 0);
- if (!thread_started) {
- /* don't use gpr_free, as this was allocated using malloc (see above) */
- free(a);
- dec_thd_count();
- }
- *t = (gpr_thd_id)p;
- return thread_started;
-}
-
-gpr_thd_id gpr_thd_currentid(void) { return (gpr_thd_id)pthread_self(); }
-
-void gpr_thd_join(gpr_thd_id t) { pthread_join((pthread_t)t, nullptr); }
-
-/*****************************************
- * Only used when fork support is enabled
- */
-
-static void inc_thd_count() {
- if (grpc_fork_support_enabled()) {
- gpr_mu_lock(&g_mu);
- g_thread_count++;
- gpr_mu_unlock(&g_mu);
- }
-}
-
-static void dec_thd_count() {
- if (grpc_fork_support_enabled()) {
- gpr_mu_lock(&g_mu);
- g_thread_count--;
- if (g_awaiting_threads && g_thread_count == 0) {
- gpr_cv_signal(&g_cv);
- }
- gpr_mu_unlock(&g_mu);
- }
-}
-
-void gpr_thd_init() {
- gpr_mu_init(&g_mu);
- gpr_cv_init(&g_cv);
- g_thread_count = 0;
- g_awaiting_threads = 0;
-}
-
-int gpr_await_threads(gpr_timespec deadline) {
- gpr_mu_lock(&g_mu);
- g_awaiting_threads = 1;
- int res = 0;
- if (g_thread_count > 0) {
- res = gpr_cv_wait(&g_cv, &g_mu, deadline);
- }
- g_awaiting_threads = 0;
- gpr_mu_unlock(&g_mu);
- return res == 0;
-}
-
-#endif /* GPR_POSIX_SYNC */
diff --git a/src/core/lib/gpr/thd_windows.cc b/src/core/lib/gpr/thd_windows.cc
deleted file mode 100644
index b467bd2662..0000000000
--- a/src/core/lib/gpr/thd_windows.cc
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-/* Windows implementation for gpr threads. */
-
-#include <grpc/support/port_platform.h>
-
-#ifdef GPR_WINDOWS
-
-#include "src/core/lib/gpr/thd.h"
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/thd_id.h>
-#include <string.h>
-
-#if defined(_MSC_VER)
-#define thread_local __declspec(thread)
-#elif defined(__GNUC__)
-#define thread_local __thread
-#else
-#error "Unknown compiler - please file a bug report"
-#endif
-
-struct thd_info {
- void (*body)(void* arg); /* body of a thread */
- void* arg; /* argument to a thread */
- HANDLE join_event; /* if joinable, the join event */
- int joinable; /* true if not detached */
-};
-
-static thread_local struct thd_info* g_thd_info;
-
-/* Destroys a thread info */
-static void destroy_thread(struct thd_info* t) {
- if (t->joinable) CloseHandle(t->join_event);
- gpr_free(t);
-}
-
-void gpr_thd_init(void) {}
-
-/* Body of every thread started via gpr_thd_new. */
-static DWORD WINAPI thread_body(void* v) {
- g_thd_info = (struct thd_info*)v;
- g_thd_info->body(g_thd_info->arg);
- if (g_thd_info->joinable) {
- BOOL ret = SetEvent(g_thd_info->join_event);
- GPR_ASSERT(ret);
- } else {
- destroy_thread(g_thd_info);
- }
- return 0;
-}
-
-int gpr_thd_new(gpr_thd_id* t, const char* thd_name,
- void (*thd_body)(void* arg), void* arg,
- const gpr_thd_options* options) {
- HANDLE handle;
- struct thd_info* info = (struct thd_info*)gpr_malloc(sizeof(*info));
- info->body = thd_body;
- info->arg = arg;
- *t = 0;
- if (gpr_thd_options_is_joinable(options)) {
- info->joinable = 1;
- info->join_event = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (info->join_event == NULL) {
- gpr_free(info);
- return 0;
- }
- } else {
- info->joinable = 0;
- }
- handle = CreateThread(NULL, 64 * 1024, thread_body, info, 0, NULL);
- if (handle == NULL) {
- destroy_thread(info);
- } else {
- *t = (gpr_thd_id)info;
- CloseHandle(handle);
- }
- return handle != NULL;
-}
-
-gpr_thd_id gpr_thd_currentid(void) { return (gpr_thd_id)g_thd_info; }
-
-void gpr_thd_join(gpr_thd_id t) {
- struct thd_info* info = (struct thd_info*)t;
- DWORD ret = WaitForSingleObject(info->join_event, INFINITE);
- GPR_ASSERT(ret == WAIT_OBJECT_0);
- destroy_thread(info);
-}
-
-#endif /* GPR_WINDOWS */
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 f7cd6424af..ba2f546675 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>
@@ -28,12 +30,12 @@
namespace grpc_core {
// The alignment of memory returned by gpr_malloc().
-constexpr size_t kAllignmentForDefaultAllocationInBytes = 8;
+constexpr size_t kAlignmentForDefaultAllocationInBytes = 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 = alignof(T) > kAllignmentForDefaultAllocationInBytes
+ void* p = alignof(T) > kAlignmentForDefaultAllocationInBytes
? gpr_malloc_aligned(sizeof(T), alignof(T))
: gpr_malloc(sizeof(T));
return new (p) T(std::forward<Args>(args)...);
@@ -43,7 +45,7 @@ inline T* New(Args&&... args) {
template <typename T>
inline void Delete(T* p) {
p->~T();
- if (alignof(T) > kAllignmentForDefaultAllocationInBytes) {
+ if (alignof(T) > kAlignmentForDefaultAllocationInBytes) {
gpr_free_aligned(p);
} else {
gpr_free(p);
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/gprpp/thd.h b/src/core/lib/gprpp/thd.h
new file mode 100644
index 0000000000..05c7ded45f
--- /dev/null
+++ b/src/core/lib/gprpp/thd.h
@@ -0,0 +1,135 @@
+/*
+ *
+ * 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_LIB_GPRPP_THD_H
+#define GRPC_CORE_LIB_GPRPP_THD_H
+
+/** Internal thread interface. */
+
+#include <grpc/support/port_platform.h>
+
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd_id.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/gprpp/abstract.h"
+#include "src/core/lib/gprpp/memory.h"
+
+namespace grpc_core {
+namespace internal {
+
+/// Base class for platform-specific thread-state
+class ThreadInternalsInterface {
+ public:
+ virtual ~ThreadInternalsInterface() {}
+ virtual void Start() GRPC_ABSTRACT;
+ virtual void Join() GRPC_ABSTRACT;
+ GRPC_ABSTRACT_BASE_CLASS
+};
+
+} // namespace internal
+
+class Thread {
+ public:
+ /// Default constructor only to allow use in structs that lack constructors
+ /// Does not produce a validly-constructed thread; must later
+ /// use placement new to construct a real thread. Does not init mu_ and cv_
+ Thread() : state_(FAKE), impl_(nullptr) {}
+
+ /// Normal constructor to create a thread with name \a thd_name,
+ /// which will execute a thread based on function \a thd_body
+ /// with argument \a arg once it is started.
+ /// The optional \a success argument indicates whether the thread
+ /// is successfully created.
+ Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg,
+ bool* success = nullptr);
+
+ /// Move constructor for thread. After this is called, the other thread
+ /// no longer represents a living thread object
+ Thread(Thread&& other) : state_(other.state_), impl_(other.impl_) {
+ other.state_ = MOVED;
+ other.impl_ = nullptr;
+ }
+
+ /// Move assignment operator for thread. After this is called, the other
+ /// thread no longer represents a living thread object. Not allowed if this
+ /// thread actually exists
+ Thread& operator=(Thread&& other) {
+ if (this != &other) {
+ // TODO(vjpai): if we can be sure that all Thread's are actually
+ // constructed, then we should assert GPR_ASSERT(impl_ == nullptr) here.
+ // However, as long as threads come in structures that are
+ // allocated via gpr_malloc, this will not be the case, so we cannot
+ // assert it for the time being.
+ state_ = other.state_;
+ impl_ = other.impl_;
+ other.state_ = MOVED;
+ other.impl_ = nullptr;
+ }
+ return *this;
+ }
+
+ /// The destructor is strictly optional; either the thread never came to life
+ /// and the constructor itself killed it or it has already been joined and
+ /// the Join function kills it. The destructor shouldn't have to do anything.
+ ~Thread() { GPR_ASSERT(impl_ == nullptr); }
+
+ void Start() {
+ if (impl_ != nullptr) {
+ GPR_ASSERT(state_ == ALIVE);
+ state_ = STARTED;
+ impl_->Start();
+ } else {
+ GPR_ASSERT(state_ == FAILED);
+ }
+ };
+
+ void Join() {
+ if (impl_ != nullptr) {
+ impl_->Join();
+ grpc_core::Delete(impl_);
+ state_ = DONE;
+ impl_ = nullptr;
+ } else {
+ GPR_ASSERT(state_ == FAILED);
+ }
+ };
+
+ static void Init();
+ static bool AwaitAll(gpr_timespec deadline);
+
+ private:
+ Thread(const Thread&) = delete;
+ Thread& operator=(const Thread&) = delete;
+
+ /// The thread states are as follows:
+ /// FAKE -- just a dummy placeholder Thread created by the default constructor
+ /// ALIVE -- an actual thread of control exists associated with this thread
+ /// STARTED -- the thread of control has been started
+ /// DONE -- the thread of control has completed and been joined
+ /// FAILED -- the thread of control never came alive
+ /// MOVED -- contents were moved out and we're no longer tracking them
+ enum ThreadState { FAKE, ALIVE, STARTED, DONE, FAILED, MOVED };
+ ThreadState state_;
+ internal::ThreadInternalsInterface* impl_;
+};
+
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_GPRPP_THD_H */
diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc
new file mode 100644
index 0000000000..2f6c2edcae
--- /dev/null
+++ b/src/core/lib/gprpp/thd_posix.cc
@@ -0,0 +1,209 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/* Posix implementation for gpr threads. */
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_POSIX_SYNC
+
+#include "src/core/lib/gprpp/thd.h"
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd_id.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "src/core/lib/gpr/fork.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/memory.h"
+
+namespace grpc_core {
+namespace {
+gpr_mu g_mu;
+gpr_cv g_cv;
+int g_thread_count;
+int g_awaiting_threads;
+
+class ThreadInternalsPosix;
+struct thd_arg {
+ ThreadInternalsPosix* thread;
+ void (*body)(void* arg); /* body of a thread */
+ void* arg; /* argument to a thread */
+ const char* name; /* name of thread. Can be nullptr. */
+};
+
+class ThreadInternalsPosix
+ : public grpc_core::internal::ThreadInternalsInterface {
+ public:
+ ThreadInternalsPosix(const char* thd_name, void (*thd_body)(void* arg),
+ void* arg, bool* success)
+ : started_(false) {
+ gpr_mu_init(&mu_);
+ gpr_cv_init(&ready_);
+ pthread_attr_t attr;
+ /* don't use gpr_malloc as we may cause an infinite recursion with
+ * the profiling code */
+ thd_arg* info = static_cast<thd_arg*>(malloc(sizeof(*info)));
+ GPR_ASSERT(info != nullptr);
+ info->thread = this;
+ info->body = thd_body;
+ info->arg = arg;
+ info->name = thd_name;
+ inc_thd_count();
+
+ GPR_ASSERT(pthread_attr_init(&attr) == 0);
+ GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) ==
+ 0);
+
+ *success =
+ (pthread_create(&pthread_id_, &attr,
+ [](void* v) -> void* {
+ thd_arg arg = *static_cast<thd_arg*>(v);
+ free(v);
+ if (arg.name != nullptr) {
+#if GPR_APPLE_PTHREAD_NAME
+ /* Apple supports 64 characters, and will
+ * truncate if it's longer. */
+ pthread_setname_np(arg.name);
+#elif GPR_LINUX_PTHREAD_NAME
+ /* Linux supports 16 characters max, and will
+ * error if it's longer. */
+ char buf[16];
+ size_t buf_len = GPR_ARRAY_SIZE(buf) - 1;
+ strncpy(buf, arg.name, buf_len);
+ buf[buf_len] = '\0';
+ pthread_setname_np(pthread_self(), buf);
+#endif // GPR_APPLE_PTHREAD_NAME
+ }
+
+ gpr_mu_lock(&arg.thread->mu_);
+ while (!arg.thread->started_) {
+ gpr_cv_wait(&arg.thread->ready_, &arg.thread->mu_,
+ gpr_inf_future(GPR_CLOCK_MONOTONIC));
+ }
+ gpr_mu_unlock(&arg.thread->mu_);
+
+ (*arg.body)(arg.arg);
+ dec_thd_count();
+ return nullptr;
+ },
+ info) == 0);
+
+ GPR_ASSERT(pthread_attr_destroy(&attr) == 0);
+
+ if (!success) {
+ /* don't use gpr_free, as this was allocated using malloc (see above) */
+ free(info);
+ dec_thd_count();
+ }
+ };
+
+ ~ThreadInternalsPosix() override {
+ gpr_mu_destroy(&mu_);
+ gpr_cv_destroy(&ready_);
+ }
+
+ void Start() override {
+ gpr_mu_lock(&mu_);
+ started_ = true;
+ gpr_cv_signal(&ready_);
+ gpr_mu_unlock(&mu_);
+ }
+
+ void Join() override { pthread_join(pthread_id_, nullptr); }
+
+ private:
+ /*****************************************
+ * Only used when fork support is enabled
+ */
+
+ static void inc_thd_count() {
+ if (grpc_fork_support_enabled()) {
+ gpr_mu_lock(&g_mu);
+ g_thread_count++;
+ gpr_mu_unlock(&g_mu);
+ }
+ }
+
+ static void dec_thd_count() {
+ if (grpc_fork_support_enabled()) {
+ gpr_mu_lock(&g_mu);
+ g_thread_count--;
+ if (g_awaiting_threads && g_thread_count == 0) {
+ gpr_cv_signal(&g_cv);
+ }
+ gpr_mu_unlock(&g_mu);
+ }
+ }
+
+ gpr_mu mu_;
+ gpr_cv ready_;
+ bool started_;
+ pthread_t pthread_id_;
+};
+
+} // namespace
+
+Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg,
+ bool* success) {
+ bool outcome = false;
+ impl_ =
+ grpc_core::New<ThreadInternalsPosix>(thd_name, thd_body, arg, &outcome);
+ if (outcome) {
+ state_ = ALIVE;
+ } else {
+ state_ = FAILED;
+ grpc_core::Delete(impl_);
+ impl_ = nullptr;
+ }
+
+ if (success != nullptr) {
+ *success = outcome;
+ }
+}
+
+void Thread::Init() {
+ gpr_mu_init(&g_mu);
+ gpr_cv_init(&g_cv);
+ g_thread_count = 0;
+ g_awaiting_threads = 0;
+}
+
+bool Thread::AwaitAll(gpr_timespec deadline) {
+ gpr_mu_lock(&g_mu);
+ g_awaiting_threads = 1;
+ int res = 0;
+ while ((g_thread_count > 0) &&
+ (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0)) {
+ res = gpr_cv_wait(&g_cv, &g_mu, deadline);
+ }
+ g_awaiting_threads = 0;
+ gpr_mu_unlock(&g_mu);
+ return res == 0;
+}
+
+} // namespace grpc_core
+
+// The following is in the external namespace as it is exposed as C89 API
+gpr_thd_id gpr_thd_currentid(void) { return (gpr_thd_id)pthread_self(); }
+
+#endif /* GPR_POSIX_SYNC */
diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc
new file mode 100644
index 0000000000..59ea02f3d2
--- /dev/null
+++ b/src/core/lib/gprpp/thd_windows.cc
@@ -0,0 +1,162 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/* Windows implementation for gpr threads. */
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_WINDOWS
+
+#include "src/core/lib/gprpp/thd.h"
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/thd_id.h>
+#include <string.h>
+
+#include "src/core/lib/gprpp/memory.h"
+
+#if defined(_MSC_VER)
+#define thread_local __declspec(thread)
+#define WIN_LAMBDA
+#elif defined(__GNUC__)
+#define thread_local __thread
+#define WIN_LAMBDA WINAPI
+#else
+#error "Unknown compiler - please file a bug report"
+#endif
+
+namespace {
+class ThreadInternalsWindows;
+struct thd_info {
+ ThreadInternalsWindows* thread;
+ void (*body)(void* arg); /* body of a thread */
+ void* arg; /* argument to a thread */
+ HANDLE join_event; /* the join event */
+};
+
+thread_local struct thd_info* g_thd_info;
+
+class ThreadInternalsWindows
+ : public grpc_core::internal::ThreadInternalsInterface {
+ public:
+ ThreadInternalsWindows(void (*thd_body)(void* arg), void* arg, bool* success)
+ : started_(false) {
+ gpr_mu_init(&mu_);
+ gpr_cv_init(&ready_);
+
+ HANDLE handle;
+ info_ = (struct thd_info*)gpr_malloc(sizeof(*info_));
+ info_->thread = this;
+ info_->body = thd_body;
+ info_->arg = arg;
+
+ info_->join_event = CreateEvent(nullptr, FALSE, FALSE, nullptr);
+ if (info_->join_event == nullptr) {
+ gpr_free(info_);
+ *success = false;
+ } else {
+ handle = CreateThread(
+ nullptr, 64 * 1024,
+ [](void* v) WIN_LAMBDA -> DWORD {
+ g_thd_info = static_cast<thd_info*>(v);
+ gpr_mu_lock(&g_thd_info->thread->mu_);
+ while (!g_thd_info->thread->started_) {
+ gpr_cv_wait(&g_thd_info->thread->ready_, &g_thd_info->thread->mu_,
+ gpr_inf_future(GPR_CLOCK_MONOTONIC));
+ }
+ gpr_mu_unlock(&g_thd_info->thread->mu_);
+ g_thd_info->body(g_thd_info->arg);
+ BOOL ret = SetEvent(g_thd_info->join_event);
+ GPR_ASSERT(ret);
+ return 0;
+ },
+ info_, 0, nullptr);
+ if (handle == nullptr) {
+ destroy_thread();
+ *success = false;
+ } else {
+ CloseHandle(handle);
+ *success = true;
+ }
+ }
+ }
+
+ ~ThreadInternalsWindows() override {
+ gpr_mu_destroy(&mu_);
+ gpr_cv_destroy(&ready_);
+ }
+
+ void Start() override {
+ gpr_mu_lock(&mu_);
+ started_ = true;
+ gpr_cv_signal(&ready_);
+ gpr_mu_unlock(&mu_);
+ }
+
+ void Join() override {
+ DWORD ret = WaitForSingleObject(info_->join_event, INFINITE);
+ GPR_ASSERT(ret == WAIT_OBJECT_0);
+ destroy_thread();
+ }
+
+ private:
+ void destroy_thread() {
+ CloseHandle(info_->join_event);
+ gpr_free(info_);
+ }
+
+ gpr_mu mu_;
+ gpr_cv ready_;
+ bool started_;
+ thd_info* info_;
+};
+
+} // namespace
+
+namespace grpc_core {
+
+void Thread::Init() {}
+
+bool Thread::AwaitAll(gpr_timespec deadline) {
+ // TODO: Consider adding this if needed
+ return false;
+}
+
+Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg,
+ bool* success) {
+ bool outcome = false;
+ impl_ = grpc_core::New<ThreadInternalsWindows>(thd_body, arg, &outcome);
+ if (outcome) {
+ state_ = ALIVE;
+ } else {
+ state_ = FAILED;
+ grpc_core::Delete(impl_);
+ impl_ = nullptr;
+ }
+
+ if (success != nullptr) {
+ *success = outcome;
+ }
+}
+
+} // namespace grpc_core
+
+gpr_thd_id gpr_thd_currentid(void) { return (gpr_thd_id)g_thd_info; }
+
+#endif /* GPR_WINDOWS */
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 bb7622c4cc..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>
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 e630ddf8e0..6120f9f44b 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
@@ -36,9 +38,9 @@
#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/gprpp/thd.h"
#include "src/core/lib/iomgr/block_annotate.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/wakeup_fd_cv.h"
@@ -253,8 +255,13 @@ typedef struct poll_result {
} poll_result;
typedef struct poll_args {
+ grpc_core::Thread poller_thd;
gpr_cv trigger;
int trigger_set;
+ bool harvestable;
+ gpr_cv harvest;
+ bool joinable;
+ gpr_cv join;
struct pollfd* fds;
nfds_t nfds;
poll_result* result;
@@ -264,15 +271,17 @@ typedef struct poll_args {
// This is a 2-tiered cache, we mantain a hash table
// of active poll calls, so we can wait on the result
-// of that call. We also maintain a freelist of inactive
-// poll threads.
+// of that call. We also maintain freelists of inactive
+// poll args and of dead poller threads.
typedef struct poll_hash_table {
poll_args* free_pollers;
poll_args** active_pollers;
+ poll_args* dead_pollers;
unsigned int size;
unsigned int count;
} poll_hash_table;
+// TODO(kpayson64): Eliminate use of global non-POD variables
poll_hash_table poll_cache;
grpc_cv_fd_table g_cvfds;
@@ -1299,6 +1308,7 @@ static void pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) {
static void run_poll(void* args);
static void cache_poller_locked(poll_args* args);
+static void cache_harvest_locked();
static void cache_insert_locked(poll_args* args) {
uint32_t key = gpr_murmur_hash3(args->fds, args->nfds * sizeof(struct pollfd),
@@ -1361,6 +1371,10 @@ static poll_args* get_poller_locked(struct pollfd* fds, nfds_t count) {
poll_args* pargs =
static_cast<poll_args*>(gpr_malloc(sizeof(struct poll_args)));
gpr_cv_init(&pargs->trigger);
+ gpr_cv_init(&pargs->harvest);
+ gpr_cv_init(&pargs->join);
+ pargs->harvestable = false;
+ pargs->joinable = false;
pargs->fds = fds;
pargs->nfds = count;
pargs->next = nullptr;
@@ -1368,11 +1382,9 @@ static poll_args* get_poller_locked(struct pollfd* fds, nfds_t count) {
pargs->trigger_set = 0;
init_result(pargs);
cache_poller_locked(pargs);
- gpr_thd_id t_id;
- gpr_thd_options opt = gpr_thd_options_default();
gpr_ref(&g_cvfds.pollcount);
- gpr_thd_options_set_detached(&opt);
- GPR_ASSERT(gpr_thd_new(&t_id, "grpc_poller", &run_poll, pargs, &opt));
+ pargs->poller_thd = grpc_core::Thread("grpc_poller", &run_poll, pargs);
+ pargs->poller_thd.Start();
return pargs;
}
@@ -1437,7 +1449,33 @@ static void cache_destroy_locked(poll_args* args) {
poll_cache.free_pollers = args->next;
}
- gpr_free(args);
+ // Now move this args to the dead poller list for later join
+ if (poll_cache.dead_pollers != nullptr) {
+ poll_cache.dead_pollers->prev = args;
+ }
+ args->prev = nullptr;
+ args->next = poll_cache.dead_pollers;
+ poll_cache.dead_pollers = args;
+}
+
+static void cache_harvest_locked() {
+ while (poll_cache.dead_pollers) {
+ poll_args* args = poll_cache.dead_pollers;
+ poll_cache.dead_pollers = poll_cache.dead_pollers->next;
+ // Keep the list consistent in case new dead pollers get added when we
+ // release the lock below to wait on joining
+ if (poll_cache.dead_pollers) {
+ poll_cache.dead_pollers->prev = nullptr;
+ }
+ args->harvestable = true;
+ gpr_cv_signal(&args->harvest);
+ while (!args->joinable) {
+ gpr_cv_wait(&args->join, &g_cvfds.mu,
+ gpr_inf_future(GPR_CLOCK_MONOTONIC));
+ }
+ args->poller_thd.Join();
+ gpr_free(args);
+ }
}
static void decref_poll_result(poll_result* res) {
@@ -1469,6 +1507,7 @@ static void run_poll(void* args) {
poll_result* result = pargs->result;
int retval = g_cvfds.poll(result->fds, result->nfds, CV_POLL_PERIOD_MS);
gpr_mu_lock(&g_cvfds.mu);
+ cache_harvest_locked();
if (retval != 0) {
result->completed = 1;
result->retval = retval;
@@ -1488,6 +1527,7 @@ static void run_poll(void* args) {
deadline = gpr_time_add(deadline, thread_grace);
pargs->trigger_set = 0;
gpr_cv_wait(&pargs->trigger, &g_cvfds.mu, deadline);
+ cache_harvest_locked();
if (!pargs->trigger_set) {
cache_destroy_locked(pargs);
break;
@@ -1496,10 +1536,15 @@ static void run_poll(void* args) {
gpr_mu_unlock(&g_cvfds.mu);
}
- // We still have the lock here
if (gpr_unref(&g_cvfds.pollcount)) {
gpr_cv_signal(&g_cvfds.shutdown_cv);
}
+ while (!pargs->harvestable) {
+ gpr_cv_wait(&pargs->harvest, &g_cvfds.mu,
+ gpr_inf_future(GPR_CLOCK_MONOTONIC));
+ }
+ pargs->joinable = true;
+ gpr_cv_signal(&pargs->join);
gpr_mu_unlock(&g_cvfds.mu);
}
@@ -1512,6 +1557,7 @@ static int cvfd_poll(struct pollfd* fds, nfds_t nfds, int timeout) {
nfds_t nsockfds = 0;
poll_result* result = nullptr;
gpr_mu_lock(&g_cvfds.mu);
+ cache_harvest_locked();
pollcv = static_cast<grpc_cv_node*>(gpr_malloc(sizeof(grpc_cv_node)));
pollcv->next = nullptr;
gpr_cv pollcv_cv;
@@ -1575,12 +1621,14 @@ static int cvfd_poll(struct pollfd* fds, nfds_t nfds, int timeout) {
pargs->trigger_set = 1;
gpr_cv_signal(&pargs->trigger);
gpr_cv_wait(&pollcv_cv, &g_cvfds.mu, deadline);
+ cache_harvest_locked();
res = result->retval;
errno = result->err;
result->watchcount--;
remove_cvn(&result->watchers, pollcv);
} else if (!skip_poll) {
gpr_cv_wait(&pollcv_cv, &g_cvfds.mu, deadline);
+ cache_harvest_locked();
}
idx = 0;
@@ -1637,6 +1685,7 @@ static void global_cv_fd_table_init() {
for (unsigned int i = 0; i < poll_cache.size; i++) {
poll_cache.active_pollers[i] = nullptr;
}
+ poll_cache.dead_pollers = nullptr;
gpr_mu_unlock(&g_cvfds.mu);
}
@@ -1655,6 +1704,7 @@ static void global_cv_fd_table_shutdown() {
grpc_poll_function = g_cvfds.poll;
gpr_free(g_cvfds.cvfds);
+ cache_harvest_locked();
gpr_free(poll_cache.active_pollers);
gpr_mu_unlock(&g_cvfds.mu);
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 1a2284f474..2f544b20ab 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 "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/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 d2a050919e..b017db53f8 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>
@@ -27,9 +29,9 @@
#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/gprpp/thd.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#define MAX_DEPTH 2
@@ -41,7 +43,7 @@ typedef struct {
size_t depth;
bool shutdown;
bool queued_long_job;
- gpr_thd_id id;
+ grpc_core::Thread thd;
} thread_state;
static thread_state* g_thread_state;
@@ -99,13 +101,13 @@ void grpc_executor_set_threading(bool threading) {
for (size_t i = 0; i < g_max_threads; i++) {
gpr_mu_init(&g_thread_state[i].mu);
gpr_cv_init(&g_thread_state[i].cv);
+ g_thread_state[i].thd = grpc_core::Thread();
g_thread_state[i].elems = GRPC_CLOSURE_LIST_INIT;
}
- gpr_thd_options opt = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&opt);
- gpr_thd_new(&g_thread_state[0].id, "grpc_executor", executor_thread,
- &g_thread_state[0], &opt);
+ g_thread_state[0].thd =
+ grpc_core::Thread("grpc_executor", executor_thread, &g_thread_state[0]);
+ g_thread_state[0].thd.Start();
} else {
if (cur_threads == 0) return;
for (size_t i = 0; i < g_max_threads; i++) {
@@ -119,7 +121,7 @@ void grpc_executor_set_threading(bool threading) {
gpr_spinlock_lock(&g_adding_thread_lock);
gpr_spinlock_unlock(&g_adding_thread_lock);
for (gpr_atm i = 0; i < g_cur_threads; i++) {
- gpr_thd_join(g_thread_state[i].id);
+ g_thread_state[i].thd.Join();
}
gpr_atm_no_barrier_store(&g_cur_threads, 0);
for (size_t i = 0; i < g_max_threads; i++) {
@@ -262,10 +264,10 @@ static void executor_push(grpc_closure* closure, grpc_error* error,
if (cur_thread_count < g_max_threads) {
gpr_atm_no_barrier_store(&g_cur_threads, cur_thread_count + 1);
- gpr_thd_options opt = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&opt);
- gpr_thd_new(&g_thread_state[cur_thread_count].id, "gpr_executor",
- executor_thread, &g_thread_state[cur_thread_count], &opt);
+ g_thread_state[cur_thread_count].thd =
+ grpc_core::Thread("grpc_executor", executor_thread,
+ &g_thread_state[cur_thread_count]);
+ g_thread_state[cur_thread_count].thd.Start();
}
gpr_spinlock_unlock(&g_adding_thread_lock);
}
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 c9a65c5702..f8645ab157 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
@@ -27,7 +29,7 @@
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/fork.h"
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/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"
@@ -51,7 +53,7 @@ void grpc_prefork() {
grpc_timer_manager_set_threading(false);
grpc_executor_set_threading(false);
grpc_core::ExecCtx::Get()->Flush();
- if (!gpr_await_threads(
+ if (!grpc_core::Thread::AwaitAll(
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_seconds(3, GPR_TIMESPAN)))) {
gpr_log(GPR_ERROR, "gRPC thread still active! Cannot fork!");
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 4716872ce4..ce77231036 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
@@ -28,7 +30,7 @@
#include <grpc/support/log_windows.h>
#include "src/core/lib/debug/stats.h"
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/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 70a80e1998..3c2b83a549 100644
--- a/src/core/lib/iomgr/iomgr.cc
+++ b/src/core/lib/iomgr/iomgr.cc
@@ -31,8 +31,8 @@
#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/gprpp/thd.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr_internal.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 c11bc28ad7..c11c37ca20 100644
--- a/src/core/lib/iomgr/iomgr_uv.cc
+++ b/src/core/lib/iomgr/iomgr_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/iomgr_uv.h b/src/core/lib/iomgr/iomgr_uv.h
index a382f0a5ae..4d62f00ad6 100644
--- a/src/core/lib/iomgr/iomgr_uv.h
+++ b/src/core/lib/iomgr/iomgr_uv.h
@@ -19,6 +19,8 @@
#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_id.h>
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 c46674c1dd..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"
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 240a24dee1..c1b83ddc14 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 "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/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 3dc1d871a1..2f68dbe214 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
@@ -33,8 +35,8 @@
#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/gprpp/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/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 8f4fd04402..7a62c88720 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
@@ -35,7 +37,7 @@
#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/gprpp/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 94e7953fde..94f288af27 100644
--- a/src/core/lib/iomgr/timer_manager.cc
+++ b/src/core/lib/iomgr/timer_manager.cc
@@ -16,22 +16,22 @@
*
*/
-#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 <inttypes.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
#include "src/core/lib/debug/trace.h"
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/timer.h"
+#include "src/core/lib/iomgr/timer_manager.h"
-typedef struct completed_thread {
- gpr_thd_id t;
- struct completed_thread* next;
-} completed_thread;
+struct completed_thread {
+ grpc_core::Thread thd;
+ completed_thread* next;
+};
extern grpc_core::TraceFlag grpc_timer_check_trace;
@@ -67,7 +67,7 @@ static void gc_completed_threads(void) {
g_completed_threads = nullptr;
gpr_mu_unlock(&g_mu);
while (to_gc != nullptr) {
- gpr_thd_join(to_gc->t);
+ to_gc->thd.Join();
completed_thread* next = to_gc->next;
gpr_free(to_gc);
to_gc = next;
@@ -84,18 +84,10 @@ static void start_timer_thread_and_unlock(void) {
if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, "Spawn timer thread");
}
- gpr_thd_options opt = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&opt);
completed_thread* ct =
static_cast<completed_thread*>(gpr_malloc(sizeof(*ct)));
- // The call to gpr_thd_new() has to be under the same lock used by
- // gc_completed_threads(), particularly due to ct->t, which is written here
- // (internally by gpr_thd_new) and read there. Otherwise it's possible for ct
- // to leak through g_completed_threads and be freed in gc_completed_threads()
- // before "&ct->t" is written to, causing a use-after-free.
- gpr_mu_lock(&g_mu);
- gpr_thd_new(&ct->t, "grpc_global_timer", timer_thread, ct, &opt);
- gpr_mu_unlock(&g_mu);
+ ct->thd = grpc_core::Thread("grpc_global_timer", timer_thread, ct);
+ ct->thd.Start();
}
void grpc_timer_manager_tick() {
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 41d35cb1fd..74faa6379e 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
@@ -30,8 +32,8 @@
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
-#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/thd.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 adf35b9088..2141db4c5b 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 bbd43025eb..3a62ef9cfb 100644
--- a/src/core/lib/json/json.h
+++ b/src/core/lib/json/json.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_JSON_JSON_H
#define GRPC_CORE_LIB_JSON_JSON_H
+#include <grpc/support/port_platform.h>
+
#include <stdlib.h>
#include "src/core/lib/json/json_common.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 ca6705a6b3..43384fd0ca 100644
--- a/src/core/lib/profiling/basic_timers.cc
+++ b/src/core/lib/profiling/basic_timers.cc
@@ -30,7 +30,7 @@
#include <string.h>
#include "src/core/lib/gpr/env.h"
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/thd.h"
typedef enum { BEGIN = '{', END = '}', MARK = '.' } marker_type;
@@ -68,7 +68,7 @@ static pthread_cond_t g_cv;
static gpr_timer_log_list g_in_progress_logs;
static gpr_timer_log_list g_done_logs;
static int g_shutdown;
-static gpr_thd_id g_writing_thread;
+static grpc_core::Thread* g_writing_thread;
static __thread int g_thread_id;
static int g_next_thread_id;
static int g_writing_enabled = 1;
@@ -182,7 +182,8 @@ static void finish_writing(void) {
g_shutdown = 1;
pthread_cond_signal(&g_cv);
pthread_mutex_unlock(&g_mu);
- gpr_thd_join(g_writing_thread);
+ g_writing_thread->Join();
+ grpc_core::Delete(g_writing_thread);
gpr_log(GPR_INFO, "flushing logs");
@@ -201,10 +202,8 @@ void gpr_timers_set_log_filename(const char* filename) {
}
static void init_output() {
- gpr_thd_options options = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&options);
- GPR_ASSERT(gpr_thd_new(&g_writing_thread, "timer_output_thread",
- writing_thread, NULL, &options));
+ g_writing_thread = grpc_core::New<grpc_core::Thread>("timer_output_thread",
+ writing_thread, nullptr);
atexit(finish_writing);
}
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 50beca897e..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>
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 fa0f89c583..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,
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/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc
index eb88045711..3cc151bec7 100644
--- a/src/core/lib/security/security_connector/security_connector.cc
+++ b/src/core/lib/security/security_connector/security_connector.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/security_connector/security_connector.h"
#include <stdbool.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/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h
index 0c972a7125..130c8ecd3e 100644
--- a/src/core/lib/security/security_connector/security_connector.h
+++ b/src/core/lib/security/security_connector/security_connector.h
@@ -19,6 +19,8 @@
#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>
#include <grpc/grpc_security.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 506f5a0666..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>
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 f109a51996..ecf59ec5c5 100644
--- a/src/core/lib/security/transport/security_handshaker.h
+++ b/src/core/lib/security/transport/security_handshaker.h
@@ -19,6 +19,8 @@
#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/security_connector/security_connector.h"
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 d536027c08..03353d6beb 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 26d8fceb2f..288313951e 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 7bc24a5049..ac9f9e6066 100644
--- a/src/core/lib/surface/init.cc
+++ b/src/core/lib/surface/init.cc
@@ -32,7 +32,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.h"
+#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/call_combiner.h"
#include "src/core/lib/iomgr/combiner.h"
@@ -123,7 +123,7 @@ void grpc_init(void) {
gpr_mu_lock(&g_init_mu);
if (++g_initializations == 1) {
gpr_time_init();
- gpr_thd_init();
+ grpc_core::Thread::Init();
grpc_stats_init();
grpc_slice_intern_init();
grpc_mdctx_global_init();
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 b96598c393..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>
diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h
index fc12e5686d..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"
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/security/transport/lb_targets_info.h b/src/core/lib/transport/status_metadata.h
index 7543d3c012..aed9c7ac20 100644
--- a/src/core/lib/security/transport/lb_targets_info.h
+++ b/src/core/lib/transport/status_metadata.h
@@ -16,17 +16,15 @@
*
*/
-#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H
-#define GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H
+#ifndef GRPC_CORE_LIB_TRANSPORT_STATUS_METADATA_H
+#define GRPC_CORE_LIB_TRANSPORT_STATUS_METADATA_H
-#include "src/core/lib/slice/slice_hash_table.h"
+#include <grpc/support/port_platform.h>
-/** Return a channel argument containing \a targets_info. */
-grpc_arg grpc_lb_targets_info_create_channel_arg(
- grpc_slice_hash_table* targets_info);
+#include <grpc/status.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);
+#include "src/core/lib/transport/metadata.h"
-#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_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..2fd408103b 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>
@@ -54,7 +56,7 @@ void grpc_tsi_alts_shutdown() {
grpc_tsi_alts_wait_for_cq_drain();
grpc_completion_queue_destroy(g_alts_resource.cq);
grpc_channel_destroy(g_alts_resource.channel);
- gpr_thd_join(g_alts_resource.thread_id);
+ g_alts_resource.thread.Join();
}
gpr_cv_destroy(&g_alts_resource.cv);
gpr_mu_destroy(&g_alts_resource.mu);
diff --git a/src/core/tsi/alts_transport_security.h b/src/core/tsi/alts_transport_security.h
index 37febd1e28..d6b8e11137 100644
--- a/src/core/tsi/alts_transport_security.h
+++ b/src/core/tsi/alts_transport_security.h
@@ -19,13 +19,15 @@
#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 "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/thd.h"
typedef struct alts_shared_resource {
- gpr_thd_id thread_id;
+ grpc_core::Thread thread;
grpc_channel* channel;
grpc_completion_queue* cq;
gpr_mu mu;
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 29fd59a0e9..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>
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 cba5984f4b..867f31f025 100644
--- a/src/cpp/client/channel_cc.cc
+++ b/src/cpp/client/channel_cc.cc
@@ -42,7 +42,7 @@
#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/gprpp/thd.h"
#include "src/core/lib/profiling/timers.h"
namespace grpc {
diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc
index 4ca6afd43f..fb1723c816 100644
--- a/src/cpp/common/version_cc.cc
+++ b/src/cpp/common/version_cc.cc
@@ -22,5 +22,5 @@
#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/server/dynamic_thread_pool.cc b/src/cpp/server/dynamic_thread_pool.cc
index 81c78fe739..fe887486d1 100644
--- a/src/cpp/server/dynamic_thread_pool.cc
+++ b/src/cpp/server/dynamic_thread_pool.cc
@@ -19,20 +19,24 @@
#include "src/cpp/server/dynamic_thread_pool.h"
#include <mutex>
-#include <thread>
#include <grpc/support/log.h>
+#include "src/core/lib/gprpp/thd.h"
+
namespace grpc {
DynamicThreadPool::DynamicThread::DynamicThread(DynamicThreadPool* pool)
: pool_(pool),
- thd_(new std::thread(&DynamicThreadPool::DynamicThread::ThreadFunc,
- this)) {}
-DynamicThreadPool::DynamicThread::~DynamicThread() {
- thd_->join();
- thd_.reset();
+ thd_("dynamic thread pool thread",
+ [](void* th) {
+ reinterpret_cast<DynamicThreadPool::DynamicThread*>(th)
+ ->ThreadFunc();
+ },
+ this) {
+ thd_.Start();
}
+DynamicThreadPool::DynamicThread::~DynamicThread() { thd_.Join(); }
void DynamicThreadPool::DynamicThread::ThreadFunc() {
pool_->ThreadFunc();
diff --git a/src/cpp/server/dynamic_thread_pool.h b/src/cpp/server/dynamic_thread_pool.h
index 880a03d0f0..5df8cf2b04 100644
--- a/src/cpp/server/dynamic_thread_pool.h
+++ b/src/cpp/server/dynamic_thread_pool.h
@@ -24,10 +24,10 @@
#include <memory>
#include <mutex>
#include <queue>
-#include <thread>
#include <grpcpp/support/config.h>
+#include "src/core/lib/gprpp/thd.h"
#include "src/cpp/server/thread_pool_interface.h"
namespace grpc {
@@ -47,7 +47,7 @@ class DynamicThreadPool final : public ThreadPoolInterface {
private:
DynamicThreadPool* pool_;
- std::unique_ptr<std::thread> thd_;
+ grpc_core::Thread thd_;
void ThreadFunc();
};
std::mutex mu_;
diff --git a/src/cpp/thread_manager/thread_manager.cc b/src/cpp/thread_manager/thread_manager.cc
index 23264f1b5b..21cc9bbb31 100644
--- a/src/cpp/thread_manager/thread_manager.cc
+++ b/src/cpp/thread_manager/thread_manager.cc
@@ -20,18 +20,24 @@
#include <climits>
#include <mutex>
-#include <thread>
#include <grpc/support/log.h>
+#include "src/core/lib/gprpp/thd.h"
+
namespace grpc {
ThreadManager::WorkerThread::WorkerThread(ThreadManager* thd_mgr)
: thd_mgr_(thd_mgr) {
// Make thread creation exclusive with respect to its join happening in
// ~WorkerThread().
- std::lock_guard<std::mutex> lock(wt_mu_);
- thd_ = std::thread(&ThreadManager::WorkerThread::Run, this);
+ thd_ = grpc_core::Thread(
+ "sync server thread",
+ [](void* th) {
+ reinterpret_cast<ThreadManager::WorkerThread*>(th)->Run();
+ },
+ this);
+ thd_.Start();
}
void ThreadManager::WorkerThread::Run() {
@@ -41,8 +47,7 @@ void ThreadManager::WorkerThread::Run() {
ThreadManager::WorkerThread::~WorkerThread() {
// Don't join until the thread is fully constructed.
- std::lock_guard<std::mutex> lock(wt_mu_);
- thd_.join();
+ thd_.Join();
}
ThreadManager::ThreadManager(int min_pollers, int max_pollers)
diff --git a/src/cpp/thread_manager/thread_manager.h b/src/cpp/thread_manager/thread_manager.h
index 1113031695..5a40f2de47 100644
--- a/src/cpp/thread_manager/thread_manager.h
+++ b/src/cpp/thread_manager/thread_manager.h
@@ -23,10 +23,11 @@
#include <list>
#include <memory>
#include <mutex>
-#include <thread>
#include <grpcpp/support/config.h>
+#include "src/core/lib/gprpp/thd.h"
+
namespace grpc {
class ThreadManager {
@@ -84,8 +85,8 @@ class ThreadManager {
virtual void Wait();
private:
- // Helper wrapper class around std::thread. This takes a ThreadManager object
- // and starts a new std::thread to calls the Run() function.
+ // Helper wrapper class around grpc_core::Thread. Takes a ThreadManager object
+ // and starts a new grpc_core::Thread to calls the Run() function.
//
// The Run() function calls ThreadManager::MainWorkLoop() function and once
// that completes, it marks the WorkerThread completed by calling
@@ -101,8 +102,7 @@ class ThreadManager {
void Run();
ThreadManager* const thd_mgr_;
- std::mutex wt_mu_;
- std::thread thd_;
+ grpc_core::Thread thd_;
};
// The main funtion in ThreadManager
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/experimental/README.md b/src/csharp/experimental/README.md
new file mode 100644
index 0000000000..f892a2ee95
--- /dev/null
+++ b/src/csharp/experimental/README.md
@@ -0,0 +1,16 @@
+This directory contains useful resources for getting gRPC C# to work on
+not-yet-supported platforms.
+
+# Unity & Xamarin
+gRPC C# currently doesn't support Unity or Xamarin, but some proof-of-concept
+work has been done. Some of the resources are shared in this directory to
+ease community work on Unity & Xamarin support.
+
+## Crosscompiling `grpc_csharp_ext` for Android
+
+* Install [Android NDK](https://developer.android.com/ndk/index.html)
+* Run `./build_native_ext_for_android.sh` to crosscompile using cmake.
+
+## Crosscompiling `grpc_csharp_ext` for iOS
+
+TBD
diff --git a/src/csharp/experimental/build_native_ext_for_android.sh b/src/csharp/experimental/build_native_ext_for_android.sh
new file mode 100755
index 0000000000..3063d78efa
--- /dev/null
+++ b/src/csharp/experimental/build_native_ext_for_android.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+# 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.
+
+# Helper script to crosscompile grpc_csharp_ext native extension for Android.
+
+cd "$(dirname "$0")/../../../cmake"
+
+mkdir -p build
+cd build
+
+# set to the location where Android SDK is installed
+ANDROID_NDK_PATH="$HOME/android-ndk-r16b"
+
+cmake ../.. \
+ -DCMAKE_SYSTEM_NAME=Android \
+ -DCMAKE_SYSTEM_VERSION=15 \
+ -DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a \
+ -DCMAKE_ANDROID_NDK="${ANDROID_NDK_PATH}" \
+ -DCMAKE_ANDROID_STL_TYPE=c++_static \
+ -DRUN_HAVE_POSIX_REGEX=0 \
+ -DRUN_HAVE_STD_REGEX=0 \
+ -DRUN_HAVE_STEADY_CLOCK=0 \
+ -DCMAKE_BUILD_TYPE=Release
+
+make grpc_csharp_ext
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 87646f7895..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]];
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/_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 479ed3aad8..75156793f1 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -41,9 +41,6 @@ CORE_SOURCE_FILES = [
'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_posix.cc',
- 'src/core/lib/gpr/thd_windows.cc',
'src/core/lib/gpr/time.cc',
'src/core/lib/gpr/time_posix.cc',
'src/core/lib/gpr/time_precise.cc',
@@ -53,6 +50,8 @@ CORE_SOURCE_FILES = [
'src/core/lib/gpr/tmpfile_posix.cc',
'src/core/lib/gpr/tmpfile_windows.cc',
'src/core/lib/gpr/wrap_memcpy.cc',
+ 'src/core/lib/gprpp/thd_posix.cc',
+ 'src/core/lib/gprpp/thd_windows.cc',
'src/core/lib/profiling/basic_timers.cc',
'src/core/lib/profiling/stap_timers.cc',
'src/core/lib/surface/init.cc',
@@ -156,7 +155,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',
@@ -187,6 +185,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,10 +235,10 @@ CORE_SOURCE_FILES = [
'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_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',
@@ -262,12 +261,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/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/CMakeLists.txt.template b/templates/CMakeLists.txt.template
index c279bef51f..0f088436d1 100644
--- a/templates/CMakeLists.txt.template
+++ b/templates/CMakeLists.txt.template
@@ -84,6 +84,7 @@
# Options
option(gRPC_BUILD_TESTS "Build tests" OFF)
+ option(gRPC_BUILD_CODEGEN "Build codegen" ON)
set(gRPC_INSTALL_default ON)
if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
@@ -125,6 +126,8 @@
set(_gRPC_PLATFORM_LINUX ON)
elseif(<%text>${CMAKE_SYSTEM_NAME}</%text> MATCHES "Darwin")
set(_gRPC_PLATFORM_MAC ON)
+ elseif(<%text>${CMAKE_SYSTEM_NAME}</%text> MATCHES "Android")
+ set(_gRPC_PLATFORM_ANDROID ON)
else()
set(_gRPC_PLATFORM_POSIX ON)
endif()
@@ -168,6 +171,8 @@
if(_gRPC_PLATFORM_MAC)
set(_gRPC_ALLTARGETS_LIBRARIES <%text>${CMAKE_DL_LIBS}</%text> m pthread)
+ elseif(_gRPC_PLATFORM_ANDROID)
+ set(_gRPC_ALLTARGETS_LIBRARIES <%text>${CMAKE_DL_LIBS}</%text> m)
elseif(UNIX)
set(_gRPC_ALLTARGETS_LIBRARIES <%text>${CMAKE_DL_LIBS}</%text> rt m pthread)
endif()
@@ -304,6 +309,13 @@
${cc_binary(tgt)}
${get_platforms_condition_end(tgt.platforms)}\
endif (gRPC_BUILD_TESTS)
+ % elif tgt.build in ["protoc"]:
+ if (gRPC_BUILD_CODEGEN)
+ ${get_platforms_condition_begin(tgt.platforms)}\
+ ${cc_binary(tgt)}
+ ${cc_install(tgt)}
+ ${get_platforms_condition_end(tgt.platforms)}\
+ endif (gRPC_BUILD_CODEGEN)
% else:
${get_platforms_condition_begin(tgt.platforms)}\
${cc_binary(tgt)}
@@ -314,6 +326,9 @@
% endfor
<%def name="cc_library(lib)">
+ % if any(proto_re.match(src) for src in lib.src):
+ if (gRPC_BUILD_CODEGEN)
+ % endif
add_library(${lib.name}${' SHARED' if lib.get('dll', None) == 'only' else ''}
% for src in lib.src:
% if not proto_re.match(src):
@@ -376,6 +391,14 @@
% endfor
)
% endif
+ % if lib.name in ["gpr"]:
+ if (_gRPC_PLATFORM_ANDROID)
+ target_link_libraries(gpr
+ android
+ log
+ )
+ endif (_gRPC_PLATFORM_ANDROID)
+ % endif
% if len(lib.get('public_headers', [])) > 0:
foreach(_hdr
@@ -390,6 +413,9 @@
)
endforeach()
% endif
+ % if any(proto_re.match(src) for src in lib.src):
+ endif (gRPC_BUILD_CODEGEN)
+ % endif
</%def>
<%def name="cc_binary(tgt)">
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/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc
index 6055ccbf4b..c03ebcf409 100644
--- a/test/core/bad_client/bad_client.cc
+++ b/test/core/bad_client/bad_client.cc
@@ -29,7 +29,7 @@
#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/gprpp/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"
@@ -220,11 +220,12 @@ void grpc_run_bad_client_test(
/* Check a ground truth */
GPR_ASSERT(grpc_server_has_open_connections(a.server));
- gpr_thd_id id;
gpr_event_init(&a.done_thd);
a.validator = server_validator;
/* Start validator */
- gpr_thd_new(&id, "grpc_bad_client", thd_func, &a, nullptr);
+
+ grpc_core::Thread server_validator_thd("grpc_bad_client", thd_func, &a);
+ server_validator_thd.Start();
for (int i = 0; i < num_args; i++) {
grpc_run_client_side_validator(&args[i], i == (num_args - 1) ? flags : 0,
&sfd, client_cq);
@@ -234,6 +235,7 @@ void grpc_run_bad_client_test(
/* Shutdown. */
shutdown_client(&sfd.client);
+ server_validator_thd.Join();
shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
grpc_server_shutdown_and_notify(a.server, shutdown_cq, nullptr);
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/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc
index 03af8954e1..14caa3ea5d 100644
--- a/test/core/client_channel/resolvers/fake_resolver_test.cc
+++ b/test/core/client_channel/resolvers/fake_resolver_test.cc
@@ -234,6 +234,11 @@ static void test_fake_resolver() {
grpc_timeout_milliseconds_to_deadline(100)) ==
nullptr);
// Clean up.
+ // Note: Need to explicitly unref the resolver and flush the exec_ctx
+ // to make sure that the final resolver callback (with error set to
+ // "Resolver Shutdown") is invoked before on_res_arg goes out of scope.
+ resolver.reset();
+ grpc_core::ExecCtx::Get()->Flush();
GRPC_COMBINER_UNREF(combiner, "test_fake_resolver");
}
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/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc
index 1af168e1f9..3d133cfc18 100644
--- a/test/core/end2end/bad_server_response_test.cc
+++ b/test/core/end2end/bad_server_response_test.cc
@@ -31,7 +31,8 @@
#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/gprpp/memory.h"
+#include "src/core/lib/gprpp/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"
@@ -253,15 +254,17 @@ static void actually_poll_server(void* arg) {
gpr_free(pa);
}
-static void poll_server_until_read_done(test_tcp_server* server,
- gpr_event* signal_when_done) {
+static grpc_core::Thread* poll_server_until_read_done(
+ test_tcp_server* server, gpr_event* signal_when_done) {
gpr_atm_rel_store(&state.done_atm, 0);
state.write_done = 0;
- gpr_thd_id id;
poll_args* pa = static_cast<poll_args*>(gpr_malloc(sizeof(*pa)));
pa->server = server;
pa->signal_when_done = signal_when_done;
- gpr_thd_new(&id, "grpc_poll_server", actually_poll_server, pa, nullptr);
+ auto* th = grpc_core::New<grpc_core::Thread>("grpc_poll_server",
+ actually_poll_server, pa);
+ th->Start();
+ return th;
}
static void run_test(const char* response_payload,
@@ -281,9 +284,11 @@ static void run_test(const char* response_payload,
state.response_payload_length = response_payload_length;
/* poll server until sending out the response */
- poll_server_until_read_done(&test_server, &ev);
+ grpc_core::UniquePtr<grpc_core::Thread> thdptr(
+ poll_server_until_read_done(&test_server, &ev));
start_rpc(server_port, expected_status, expected_detail);
gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
+ thdptr->Join();
/* clean up */
grpc_endpoint_shutdown(state.tcp,
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_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 27b897ce5a..b3b4171a72 100644
--- a/test/core/end2end/fixtures/h2_census.cc
+++ b/test/core/end2end/fixtures/h2_census.cc
@@ -30,7 +30,6 @@
#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 b4ec78d710..565c96cf93 100644
--- a/test/core/end2end/fixtures/h2_compress.cc
+++ b/test/core/end2end/fixtures/h2_compress.cc
@@ -30,7 +30,6 @@
#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 e97d078d9c..ed173c1afb 100644
--- a/test/core/end2end/fixtures/h2_full+pipe.cc
+++ b/test/core/end2end/fixtures/h2_full+pipe.cc
@@ -34,7 +34,6 @@
#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 12aa69bb17..afb86ea899 100644
--- a/test/core/end2end/fixtures/h2_full+trace.cc
+++ b/test/core/end2end/fixtures/h2_full+trace.cc
@@ -35,7 +35,6 @@
#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 c6b358dcc5..bd9ddff5b5 100644
--- a/test/core/end2end/fixtures/h2_full+workarounds.cc
+++ b/test/core/end2end/fixtures/h2_full+workarounds.cc
@@ -31,7 +31,6 @@
#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 32e3e55128..ca61ec8eff 100644
--- a/test/core/end2end/fixtures/h2_full.cc
+++ b/test/core/end2end/fixtures/h2_full.cc
@@ -29,7 +29,6 @@
#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 b990d7a763..90d0627860 100644
--- a/test/core/end2end/fixtures/h2_http_proxy.cc
+++ b/test/core/end2end/fixtures/h2_http_proxy.cc
@@ -31,7 +31,6 @@
#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"
diff --git a/test/core/end2end/fixtures/h2_load_reporting.cc b/test/core/end2end/fixtures/h2_load_reporting.cc
index 6adc0c154e..ec9eedbd34 100644
--- a/test/core/end2end/fixtures/h2_load_reporting.cc
+++ b/test/core/end2end/fixtures/h2_load_reporting.cc
@@ -31,7 +31,6 @@
#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 93dde4f4a2..c97188fbb2 100644
--- a/test/core/end2end/fixtures/h2_proxy.cc
+++ b/test/core/end2end/fixtures/h2_proxy.cc
@@ -29,7 +29,6 @@
#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 +48,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 5dd5c2ad67..d539ddae8f 100644
--- a/test/core/end2end/fixtures/h2_sockpair+trace.cc
+++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc
@@ -36,7 +36,6 @@
#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 52a7b95c3a..75f64024cd 100644
--- a/test/core/end2end/fixtures/h2_sockpair.cc
+++ b/test/core/end2end/fixtures/h2_sockpair.cc
@@ -30,7 +30,6 @@
#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 0d3cb34724..929631917d 100644
--- a/test/core/end2end/fixtures/h2_sockpair_1byte.cc
+++ b/test/core/end2end/fixtures/h2_sockpair_1byte.cc
@@ -30,7 +30,6 @@
#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 a97b14f1d6..1b081f9ea3 100644
--- a/test/core/end2end/fixtures/h2_uds.cc
+++ b/test/core/end2end/fixtures/h2_uds.cc
@@ -33,7 +33,6 @@
#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 18e8310251..58353376f3 100644
--- a/test/core/end2end/fixtures/http_proxy_fixture.cc
+++ b/test/core/end2end/fixtures/http_proxy_fixture.cc
@@ -33,7 +33,7 @@
#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/gprpp/thd.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/combiner.h"
@@ -53,7 +53,7 @@
struct grpc_end2end_http_proxy {
char* proxy_name;
- gpr_thd_id thd;
+ grpc_core::Thread thd;
grpc_tcp_server* server;
grpc_channel_args* channel_args;
gpr_mu* mu;
@@ -550,10 +550,8 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create(
grpc_tcp_server_start(proxy->server, &proxy->pollset, 1, on_accept, proxy);
// Start proxy thread.
- gpr_thd_options opt = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&opt);
- GPR_ASSERT(
- gpr_thd_new(&proxy->thd, "grpc_http_proxy", thread_main, proxy, &opt));
+ proxy->thd = grpc_core::Thread("grpc_http_proxy", thread_main, proxy);
+ proxy->thd.Start();
return proxy;
}
@@ -566,7 +564,7 @@ static void destroy_pollset(void* arg, grpc_error* error) {
void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) {
gpr_unref(&proxy->users); // Signal proxy thread to shutdown.
grpc_core::ExecCtx exec_ctx;
- gpr_thd_join(proxy->thd);
+ proxy->thd.Join();
grpc_tcp_server_shutdown_listeners(proxy->server);
grpc_tcp_server_unref(proxy->server);
gpr_free(proxy->proxy_name);
diff --git a/test/core/end2end/fixtures/inproc.cc b/test/core/end2end/fixtures/inproc.cc
index 4ddcc78495..d47de42540 100644
--- a/test/core/end2end/fixtures/inproc.cc
+++ b/test/core/end2end/fixtures/inproc.cc
@@ -29,7 +29,6 @@
#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 bc3b0ca35c..042c858b4c 100644
--- a/test/core/end2end/fixtures/proxy.cc
+++ b/test/core/end2end/fixtures/proxy.cc
@@ -25,12 +25,12 @@
#include <grpc/support/sync.h>
#include "src/core/lib/gpr/host_port.h"
-#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/thd.h"
#include "test/core/util/port.h"
struct grpc_end2end_proxy {
- gpr_thd_id thd;
+ grpc_core::Thread thd;
char* proxy_port;
char* server_port;
grpc_completion_queue* cq;
@@ -76,7 +76,6 @@ static void request_call(grpc_end2end_proxy* proxy);
grpc_end2end_proxy* grpc_end2end_proxy_create(const grpc_end2end_proxy_def* def,
grpc_channel_args* client_args,
grpc_channel_args* server_args) {
- gpr_thd_options opt = gpr_thd_options_default();
int proxy_port = grpc_pick_unused_port_or_die();
int server_port = grpc_pick_unused_port_or_die();
@@ -98,9 +97,8 @@ grpc_end2end_proxy* grpc_end2end_proxy_create(const grpc_end2end_proxy_def* def,
grpc_server_start(proxy->server);
grpc_call_details_init(&proxy->new_call_details);
- gpr_thd_options_set_joinable(&opt);
- GPR_ASSERT(
- gpr_thd_new(&proxy->thd, "grpc_end2end_proxy", thread_main, proxy, &opt));
+ proxy->thd = grpc_core::Thread("grpc_end2end_proxy", thread_main, proxy);
+ proxy->thd.Start();
request_call(proxy);
@@ -123,7 +121,7 @@ static void shutdown_complete(void* arg, int success) {
void grpc_end2end_proxy_destroy(grpc_end2end_proxy* proxy) {
grpc_server_shutdown_and_notify(proxy->server, proxy->cq,
new_closure(shutdown_complete, proxy));
- gpr_thd_join(proxy->thd);
+ proxy->thd.Join();
gpr_free(proxy->proxy_port);
gpr_free(proxy->server_port);
grpc_server_destroy(proxy->server);
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 bfd5d8525e..8e723fd609 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -24,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,
@@ -35,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,
)
@@ -47,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']),
@@ -55,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,
@@ -83,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,
)
@@ -118,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(),
@@ -134,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(),
@@ -142,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(),
@@ -183,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
diff --git a/test/core/end2end/tests/bad_ping.cc b/test/core/end2end/tests/bad_ping.cc
index 9fff3bfb7d..f305ea5703 100644
--- a/test/core/end2end/tests/bad_ping.cc
+++ b/test/core/end2end/tests/bad_ping.cc
@@ -25,7 +25,6 @@
#include <grpc/support/sync.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 a517ffa686..caa4265aa2 100644
--- a/test/core/end2end/tests/connectivity.cc
+++ b/test/core/end2end/tests/connectivity.cc
@@ -22,7 +22,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/thd.h"
#include "test/core/end2end/cq_verifier.h"
static void* tag(intptr_t t) { return (void*)t; }
@@ -50,8 +50,6 @@ static void test_connectivity(grpc_end2end_test_config config) {
grpc_connectivity_state state;
cq_verifier* cqv = cq_verifier_create(f.cq);
child_events ce;
- gpr_thd_options thdopt = gpr_thd_options_default();
- gpr_thd_id thdid;
grpc_channel_args client_args;
grpc_arg arg_array[1];
@@ -67,9 +65,8 @@ static void test_connectivity(grpc_end2end_test_config config) {
ce.channel = f.client;
ce.cq = f.cq;
gpr_event_init(&ce.started);
- gpr_thd_options_set_joinable(&thdopt);
- GPR_ASSERT(
- gpr_thd_new(&thdid, "grpc_connectivity", child_thread, &ce, &thdopt));
+ grpc_core::Thread thd("grpc_connectivity", child_thread, &ce);
+ thd.Start();
gpr_event_wait(&ce.started, gpr_inf_future(GPR_CLOCK_MONOTONIC));
@@ -86,7 +83,7 @@ static void test_connectivity(grpc_end2end_test_config config) {
f.client, GRPC_CHANNEL_IDLE, gpr_now(GPR_CLOCK_MONOTONIC), f.cq, tag(1));
/* eventually the child thread completion should trigger */
- gpr_thd_join(thdid);
+ thd.Join();
/* check that we're still in idle, and start connecting */
GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 1) ==
diff --git a/test/core/end2end/tests/ping.cc b/test/core/end2end/tests/ping.cc
index 8fce295f90..f523cbb0c7 100644
--- a/test/core/end2end/tests/ping.cc
+++ b/test/core/end2end/tests/ping.cc
@@ -22,7 +22,6 @@
#include <grpc/support/sync.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..5308ea0934 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++",
@@ -119,16 +129,6 @@ grpc_cc_test(
)
grpc_cc_test(
- name = "thd_test",
- srcs = ["thd_test.cc"],
- language = "C++",
- deps = [
- "//:gpr",
- "//test/core/util:gpr_test_util",
- ],
-)
-
-grpc_cc_test(
name = "time_test",
srcs = ["time_test.cc"],
language = "C++",
diff --git a/test/core/gpr/arena_test.cc b/test/core/gpr/arena_test.cc
index 9eaf57b631..111414ea3e 100644
--- a/test/core/gpr/arena_test.cc
+++ b/test/core/gpr/arena_test.cc
@@ -18,16 +18,17 @@
#include "src/core/lib/gpr/arena.h"
+#include <inttypes.h>
+#include <string.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.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 "src/core/lib/gprpp/thd.h"
#include "test/core/util/test_config.h"
static void test_noop(void) { gpr_arena_destroy(gpr_arena_create(1)); }
@@ -97,19 +98,18 @@ static void concurrent_test(void) {
gpr_event_init(&args.ev_start);
args.arena = gpr_arena_create(1024);
- gpr_thd_id thds[CONCURRENT_TEST_THREADS];
+ grpc_core::Thread thds[CONCURRENT_TEST_THREADS];
for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) {
- gpr_thd_options opt = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&opt);
- gpr_thd_new(&thds[i], "grpc_concurrent_test", concurrent_test_body, &args,
- &opt);
+ thds[i] =
+ grpc_core::Thread("grpc_concurrent_test", concurrent_test_body, &args);
+ thds[i].Start();
}
gpr_event_set(&args.ev_start, (void*)1);
- for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) {
- gpr_thd_join(thds[i]);
+ for (auto& th : thds) {
+ th.Join();
}
gpr_arena_destroy(args.arena);
diff --git a/test/core/gpr/cpu_test.cc b/test/core/gpr/cpu_test.cc
index 9f2c3f1923..1052d40b42 100644
--- a/test/core/gpr/cpu_test.cc
+++ b/test/core/gpr/cpu_test.cc
@@ -21,15 +21,17 @@
gpr_cpu_current_cpu()
*/
-#include <grpc/support/alloc.h>
#include <grpc/support/cpu.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
-#include <stdio.h>
-#include <string.h>
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/thd.h"
#include "test/core/util/test_config.h"
/* Test structure is essentially:
@@ -101,7 +103,6 @@ static void cpu_test(void) {
uint32_t i;
int cores_seen = 0;
struct cpu_test ct;
- gpr_thd_id thd;
ct.ncores = gpr_cpu_num_cores();
GPR_ASSERT(ct.ncores > 0);
ct.nthreads = static_cast<int>(ct.ncores) * 3;
@@ -110,15 +111,24 @@ static void cpu_test(void) {
gpr_mu_init(&ct.mu);
gpr_cv_init(&ct.done_cv);
ct.is_done = 0;
- for (i = 0; i < ct.ncores * 3; i++) {
- GPR_ASSERT(
- gpr_thd_new(&thd, "grpc_cpu_test", &worker_thread, &ct, nullptr));
+
+ uint32_t nthreads = ct.ncores * 3;
+ grpc_core::Thread* thd =
+ static_cast<grpc_core::Thread*>(gpr_malloc(sizeof(*thd) * nthreads));
+
+ for (i = 0; i < nthreads; i++) {
+ thd[i] = grpc_core::Thread("grpc_cpu_test", &worker_thread, &ct);
+ thd[i].Start();
}
gpr_mu_lock(&ct.mu);
while (!ct.is_done) {
gpr_cv_wait(&ct.done_cv, &ct.mu, gpr_inf_future(GPR_CLOCK_MONOTONIC));
}
gpr_mu_unlock(&ct.mu);
+ for (i = 0; i < nthreads; i++) {
+ thd[i].Join();
+ }
+ gpr_free(thd);
fprintf(stderr, "Saw cores [");
fflush(stderr);
for (i = 0; i < ct.ncores; i++) {
diff --git a/test/core/gpr/mpscq_test.cc b/test/core/gpr/mpscq_test.cc
index 96813466c9..8c0873941f 100644
--- a/test/core/gpr/mpscq_test.cc
+++ b/test/core/gpr/mpscq_test.cc
@@ -24,8 +24,8 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/thd.h"
#include "test/core/util/test_config.h"
typedef struct test_node {
@@ -76,18 +76,16 @@ static void test_mt(void) {
gpr_log(GPR_DEBUG, "test_mt");
gpr_event start;
gpr_event_init(&start);
- gpr_thd_id thds[100];
+ grpc_core::Thread thds[100];
thd_args ta[GPR_ARRAY_SIZE(thds)];
gpr_mpscq q;
gpr_mpscq_init(&q);
for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
- gpr_thd_options options = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&options);
ta[i].ctr = 0;
ta[i].q = &q;
ta[i].start = &start;
- GPR_ASSERT(
- gpr_thd_new(&thds[i], "grpc_mt_test", test_thread, &ta[i], &options));
+ thds[i] = grpc_core::Thread("grpc_mt_test", test_thread, &ta[i]);
+ thds[i].Start();
}
size_t num_done = 0;
size_t spins = 0;
@@ -104,8 +102,8 @@ static void test_mt(void) {
gpr_free(tn);
}
gpr_log(GPR_DEBUG, "spins: %" PRIdPTR, spins);
- for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
- gpr_thd_join(thds[i]);
+ for (auto& th : thds) {
+ th.Join();
}
gpr_mpscq_destroy(&q);
}
@@ -147,19 +145,17 @@ static void test_mt_multipop(void) {
gpr_log(GPR_DEBUG, "test_mt_multipop");
gpr_event start;
gpr_event_init(&start);
- gpr_thd_id thds[100];
- gpr_thd_id pull_thds[100];
+ grpc_core::Thread thds[50];
+ grpc_core::Thread pull_thds[50];
thd_args ta[GPR_ARRAY_SIZE(thds)];
gpr_mpscq q;
gpr_mpscq_init(&q);
for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
- gpr_thd_options options = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&options);
ta[i].ctr = 0;
ta[i].q = &q;
ta[i].start = &start;
- GPR_ASSERT(gpr_thd_new(&thds[i], "grpc_multipop_test", test_thread, &ta[i],
- &options));
+ thds[i] = grpc_core::Thread("grpc_multipop_test", test_thread, &ta[i]);
+ thds[i].Start();
}
pull_args pa;
pa.ta = ta;
@@ -170,18 +166,16 @@ static void test_mt_multipop(void) {
pa.start = &start;
gpr_mu_init(&pa.mu);
for (size_t i = 0; i < GPR_ARRAY_SIZE(pull_thds); i++) {
- gpr_thd_options options = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&options);
- GPR_ASSERT(gpr_thd_new(&pull_thds[i], "grpc_multipop_pull", pull_thread,
- &pa, &options));
+ pull_thds[i] = grpc_core::Thread("grpc_multipop_pull", pull_thread, &pa);
+ pull_thds[i].Start();
}
gpr_event_set(&start, (void*)1);
- for (size_t i = 0; i < GPR_ARRAY_SIZE(pull_thds); i++) {
- gpr_thd_join(pull_thds[i]);
+ for (auto& pth : pull_thds) {
+ pth.Join();
}
gpr_log(GPR_DEBUG, "spins: %" PRIdPTR, pa.spins);
- for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
- gpr_thd_join(thds[i]);
+ for (auto& th : thds) {
+ th.Join();
}
gpr_mpscq_destroy(&q);
}
diff --git a/test/core/gpr/spinlock_test.cc b/test/core/gpr/spinlock_test.cc
index 9f182bc154..0ee72edb15 100644
--- a/test/core/gpr/spinlock_test.cc
+++ b/test/core/gpr/spinlock_test.cc
@@ -16,24 +16,26 @@
*
*/
-/* Test of gpr synchronization support. */
+/* Test of gpr spin-lock support. */
#include "src/core/lib/gpr/spinlock.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/thd.h"
#include "test/core/util/test_config.h"
/* ------------------------------------------------- */
/* Tests for gpr_spinlock. */
struct test {
int thread_count; /* number of threads */
- gpr_thd_id* threads;
+ grpc_core::Thread* threads;
int64_t iterations; /* number of iterations per thread */
int64_t counter;
@@ -46,7 +48,7 @@ struct test {
static struct test* test_new(int threads, int64_t iterations, int incr_step) {
struct test* m = static_cast<struct test*>(gpr_malloc(sizeof(*m)));
m->thread_count = threads;
- m->threads = static_cast<gpr_thd_id*>(
+ m->threads = static_cast<grpc_core::Thread*>(
gpr_malloc(sizeof(*m->threads) * static_cast<size_t>(threads)));
m->iterations = iterations;
m->counter = 0;
@@ -66,10 +68,8 @@ static void test_destroy(struct test* m) {
static void test_create_threads(struct test* m, void (*body)(void* arg)) {
int i;
for (i = 0; i != m->thread_count; i++) {
- gpr_thd_options opt = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&opt);
- GPR_ASSERT(
- gpr_thd_new(&m->threads[i], "grpc_create_threads", body, m, &opt));
+ m->threads[i] = grpc_core::Thread("grpc_create_threads", body, m);
+ m->threads[i].Start();
}
}
@@ -77,7 +77,7 @@ static void test_create_threads(struct test* m, void (*body)(void* arg)) {
static void test_wait(struct test* m) {
int i;
for (i = 0; i != m->thread_count; i++) {
- gpr_thd_join(m->threads[i]);
+ m->threads[i].Join();
}
}
diff --git a/test/core/gpr/sync_test.cc b/test/core/gpr/sync_test.cc
index bafd91020b..24b4562819 100644
--- a/test/core/gpr/sync_test.cc
+++ b/test/core/gpr/sync_test.cc
@@ -18,14 +18,16 @@
/* Test of gpr synchronization support. */
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/time.h>
+
#include <stdio.h>
#include <stdlib.h>
-#include "src/core/lib/gpr/thd.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/gprpp/thd.h"
#include "test/core/util/test_config.h"
/* ==================Example use of interface===================
@@ -133,7 +135,8 @@ int queue_remove(queue* q, int* head, gpr_timespec abs_deadline) {
/* ------------------------------------------------- */
/* Tests for gpr_mu and gpr_cv, and the queue example. */
struct test {
- int threads; /* number of threads */
+ int nthreads; /* number of threads */
+ grpc_core::Thread* threads;
int64_t iterations; /* number of iterations per thread */
int64_t counter;
@@ -157,13 +160,15 @@ struct test {
};
/* Return pointer to a new struct test. */
-static struct test* test_new(int threads, int64_t iterations, int incr_step) {
+static struct test* test_new(int nthreads, int64_t iterations, int incr_step) {
struct test* m = static_cast<struct test*>(gpr_malloc(sizeof(*m)));
- m->threads = threads;
+ m->nthreads = nthreads;
+ m->threads = static_cast<grpc_core::Thread*>(
+ gpr_malloc(sizeof(*m->threads) * nthreads));
m->iterations = iterations;
m->counter = 0;
m->thread_count = 0;
- m->done = threads;
+ m->done = nthreads;
m->incr_step = incr_step;
gpr_mu_init(&m->mu);
gpr_cv_init(&m->cv);
@@ -171,7 +176,7 @@ static struct test* test_new(int threads, int64_t iterations, int incr_step) {
queue_init(&m->q);
gpr_stats_init(&m->stats_counter, 0);
gpr_ref_init(&m->refcount, 0);
- gpr_ref_init(&m->thread_refcount, threads);
+ gpr_ref_init(&m->thread_refcount, nthreads);
gpr_event_init(&m->event);
return m;
}
@@ -182,15 +187,16 @@ static void test_destroy(struct test* m) {
gpr_cv_destroy(&m->cv);
gpr_cv_destroy(&m->done_cv);
queue_destroy(&m->q);
+ gpr_free(m->threads);
gpr_free(m);
}
-/* Create m->threads threads, each running (*body)(m) */
+/* Create m->nthreads threads, each running (*body)(m) */
static void test_create_threads(struct test* m, void (*body)(void* arg)) {
- gpr_thd_id id;
int i;
- for (i = 0; i != m->threads; i++) {
- GPR_ASSERT(gpr_thd_new(&id, "grpc_create_threads", body, m, nullptr));
+ for (i = 0; i != m->nthreads; i++) {
+ m->threads[i] = grpc_core::Thread("grpc_create_threads", body, m);
+ m->threads[i].Start();
}
}
@@ -201,9 +207,12 @@ static void test_wait(struct test* m) {
gpr_cv_wait(&m->done_cv, &m->mu, gpr_inf_future(GPR_CLOCK_MONOTONIC));
}
gpr_mu_unlock(&m->mu);
+ for (int i = 0; i != m->nthreads; i++) {
+ m->threads[i].Join();
+ }
}
-/* Get an integer thread id in the raneg 0..threads-1 */
+/* Get an integer thread id in the raneg 0..nthreads-1 */
static int thread_id(struct test* m) {
int id;
gpr_mu_lock(&m->mu);
@@ -245,16 +254,20 @@ static void test(const char* name, void (*body)(void* m),
fprintf(stderr, " %ld", static_cast<long>(iterations));
fflush(stderr);
m = test_new(10, iterations, incr_step);
+ grpc_core::Thread extra_thd;
if (extra != nullptr) {
- gpr_thd_id id;
- GPR_ASSERT(gpr_thd_new(&id, name, extra, m, nullptr));
+ extra_thd = grpc_core::Thread(name, extra, m);
+ extra_thd.Start();
m->done++; /* one more thread to wait for */
}
test_create_threads(m, body);
test_wait(m);
- if (m->counter != m->threads * m->iterations * m->incr_step) {
+ if (extra != nullptr) {
+ extra_thd.Join();
+ }
+ if (m->counter != m->nthreads * m->iterations * m->incr_step) {
fprintf(stderr, "counter %ld threads %d iterations %ld\n",
- static_cast<long>(m->counter), m->threads,
+ static_cast<long>(m->counter), m->nthreads,
static_cast<long>(m->iterations));
fflush(stderr);
GPR_ASSERT(0);
@@ -296,7 +309,7 @@ static void inctry(void* v /*=m*/) {
mark_thread_done(m);
}
-/* Increment counter only when (m->counter%m->threads)==m->thread_id; then mark
+/* Increment counter only when (m->counter%m->nthreads)==m->thread_id; then mark
thread as done. */
static void inc_by_turns(void* v /*=m*/) {
struct test* m = static_cast<struct test*>(v);
@@ -304,7 +317,7 @@ static void inc_by_turns(void* v /*=m*/) {
int id = thread_id(m);
for (i = 0; i != m->iterations; i++) {
gpr_mu_lock(&m->mu);
- while ((m->counter % m->threads) != id) {
+ while ((m->counter % m->nthreads) != id) {
gpr_cv_wait(&m->cv, &m->mu, gpr_inf_future(GPR_CLOCK_MONOTONIC));
}
m->counter++;
@@ -369,12 +382,12 @@ static void many_producers(void* v /*=m*/) {
mark_thread_done(m);
}
-/* Consume elements from m->q until m->threads*m->iterations are seen,
+/* Consume elements from m->q until m->nthreads*m->iterations are seen,
wait an extra second to confirm that no more elements are arriving,
then mark thread as done. */
static void consumer(void* v /*=m*/) {
struct test* m = static_cast<struct test*>(v);
- int64_t n = m->iterations * m->threads;
+ int64_t n = m->iterations * m->nthreads;
int64_t i;
int value;
for (i = 0; i != n; i++) {
@@ -424,11 +437,11 @@ static void refinc(void* v /*=m*/) {
}
/* Wait until m->event is set to (void *)1, then decrement m->refcount by 1
- (m->threads * m->iterations * m->incr_step) times, and ensure that the last
+ (m->nthreads * m->iterations * m->incr_step) times, and ensure that the last
decrement caused the counter to reach zero, then mark thread as done. */
static void refcheck(void* v /*=m*/) {
struct test* m = static_cast<struct test*>(v);
- int64_t n = m->iterations * m->threads * m->incr_step;
+ int64_t n = m->iterations * m->nthreads * m->incr_step;
int64_t i;
GPR_ASSERT(gpr_event_wait(&m->event, gpr_inf_future(GPR_CLOCK_REALTIME)) ==
(void*)1);
diff --git a/test/core/gpr/time_test.cc b/test/core/gpr/time_test.cc
index e6bcc1247d..c80aac649d 100644
--- a/test/core/gpr/time_test.cc
+++ b/test/core/gpr/time_test.cc
@@ -26,7 +26,6 @@
#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 1e4534dc5a..0502fc7ef4 100644
--- a/test/core/gpr/tls_test.cc
+++ b/test/core/gpr/tls_test.cc
@@ -18,13 +18,15 @@
/* Test of gpr thread local storage support. */
-#include <grpc/support/log.h>
-#include <grpc/support/sync.h>
+#include "src/core/lib/gpr/tls.h"
+
#include <stdio.h>
#include <stdlib.h>
-#include "src/core/lib/gpr/thd.h"
-#include "src/core/lib/gpr/tls.h"
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+
+#include "src/core/lib/gprpp/thd.h"
#include "test/core/util/test_config.h"
#define NUM_THREADS 100
@@ -46,21 +48,18 @@ static void thd_body(void* arg) {
/* ------------------------------------------------- */
int main(int argc, char* argv[]) {
- gpr_thd_options opt = gpr_thd_options_default();
- int i;
- gpr_thd_id threads[NUM_THREADS];
+ grpc_core::Thread threads[NUM_THREADS];
grpc_test_init(argc, argv);
gpr_tls_init(&test_var);
- gpr_thd_options_set_joinable(&opt);
-
- for (i = 0; i < NUM_THREADS; i++) {
- gpr_thd_new(&threads[i], "grpc_tls_test", thd_body, nullptr, &opt);
+ for (auto& th : threads) {
+ th = grpc_core::Thread("grpc_tls_test", thd_body, nullptr);
+ th.Start();
}
- for (i = 0; i < NUM_THREADS; i++) {
- gpr_thd_join(threads[i]);
+ for (auto& th : threads) {
+ th.Join();
}
gpr_tls_destroy(&test_var);
diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD
index 1c11e0bdb5..a8a5739552 100644
--- a/test/core/gprpp/BUILD
+++ b/test/core/gprpp/BUILD
@@ -24,7 +24,6 @@ grpc_cc_test(
language = "C++",
deps = [
"//:gpr",
- "//:gpr++_base",
"//test/core/util:gpr_test_util",
],
)
@@ -37,7 +36,7 @@ grpc_cc_test(
],
language = "C++",
deps = [
- "//:gpr++_base",
+ "//:gpr_base",
"//test/core/util:gpr_test_util",
],
)
@@ -58,39 +57,49 @@ grpc_cc_test(
grpc_cc_test(
name = "orphanable_test",
srcs = ["orphanable_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
language = "C++",
deps = [
"//:orphanable",
"//test/core/util:gpr_test_util",
],
- external_deps = [
- "gtest",
- ],
)
grpc_cc_test(
name = "ref_counted_test",
srcs = ["ref_counted_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
language = "C++",
deps = [
"//:ref_counted",
"//test/core/util:gpr_test_util",
],
- external_deps = [
- "gtest",
- ],
)
grpc_cc_test(
name = "ref_counted_ptr_test",
srcs = ["ref_counted_ptr_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
language = "C++",
deps = [
"//:ref_counted",
"//:ref_counted_ptr",
"//test/core/util:gpr_test_util",
],
- external_deps = [
- "gtest",
+)
+
+grpc_cc_test(
+ name = "thd_test",
+ srcs = ["thd_test.cc"],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//test/core/util:gpr_test_util",
],
)
diff --git a/test/core/gprpp/manual_constructor_test.cc b/test/core/gprpp/manual_constructor_test.cc
index 74777fe11c..af162ae8e8 100644
--- a/test/core/gprpp/manual_constructor_test.cc
+++ b/test/core/gprpp/manual_constructor_test.cc
@@ -26,7 +26,6 @@
#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/gpr/thd_test.cc b/test/core/gprpp/thd_test.cc
index 18bbaae6c9..82dd681049 100644
--- a/test/core/gpr/thd_test.cc
+++ b/test/core/gprpp/thd_test.cc
@@ -18,17 +18,18 @@
/* Test of gpr thread support. */
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/thd.h"
+
+#include <stdio.h>
+#include <stdlib.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
-#include <stdio.h>
-#include <stdlib.h>
#include "test/core/util/test_config.h"
-#define NUM_THREADS 300
+#define NUM_THREADS 100
struct test {
gpr_mu mu;
@@ -38,7 +39,7 @@ struct test {
};
/* A Thread body. Decrement t->n, and if is becomes zero, set t->done. */
-static void thd_body(void* v) {
+static void thd_body1(void* v) {
struct test* t = static_cast<struct test*>(v);
gpr_mu_lock(&t->mu);
t->n--;
@@ -49,48 +50,42 @@ static void thd_body(void* v) {
gpr_mu_unlock(&t->mu);
}
-static void thd_body_joinable(void* v) {}
-
-/* Test thread options work as expected */
-static void test_options(void) {
- gpr_thd_options options = gpr_thd_options_default();
- GPR_ASSERT(!gpr_thd_options_is_joinable(&options));
- GPR_ASSERT(gpr_thd_options_is_detached(&options));
- gpr_thd_options_set_joinable(&options);
- GPR_ASSERT(gpr_thd_options_is_joinable(&options));
- GPR_ASSERT(!gpr_thd_options_is_detached(&options));
- gpr_thd_options_set_detached(&options);
- GPR_ASSERT(!gpr_thd_options_is_joinable(&options));
- GPR_ASSERT(gpr_thd_options_is_detached(&options));
-}
-
-/* Test that we can create a number of threads and wait for them. */
-static void test(void) {
- int i;
- gpr_thd_id thd;
- gpr_thd_id thds[NUM_THREADS];
+/* Test that we can create a number of threads, wait for them, and join them. */
+static void test1(void) {
+ grpc_core::Thread thds[NUM_THREADS];
struct test t;
- gpr_thd_options options = gpr_thd_options_default();
gpr_mu_init(&t.mu);
gpr_cv_init(&t.done_cv);
t.n = NUM_THREADS;
t.is_done = 0;
- for (i = 0; i < NUM_THREADS; i++) {
- GPR_ASSERT(gpr_thd_new(&thd, "grpc_thread_test", &thd_body, &t, nullptr));
+ for (auto& th : thds) {
+ th = grpc_core::Thread("grpc_thread_body1_test", &thd_body1, &t);
+ th.Start();
}
gpr_mu_lock(&t.mu);
while (!t.is_done) {
gpr_cv_wait(&t.done_cv, &t.mu, gpr_inf_future(GPR_CLOCK_REALTIME));
}
gpr_mu_unlock(&t.mu);
+ for (auto& th : thds) {
+ th.Join();
+ }
GPR_ASSERT(t.n == 0);
- gpr_thd_options_set_joinable(&options);
- for (i = 0; i < NUM_THREADS; i++) {
- GPR_ASSERT(gpr_thd_new(&thds[i], "grpc_joinable_thread_test",
- &thd_body_joinable, nullptr, &options));
+}
+
+static void thd_body2(void* v) {}
+
+/* Test that we can create a number of threads and join them. */
+static void test2(void) {
+ grpc_core::Thread thds[NUM_THREADS];
+ for (auto& th : thds) {
+ bool ok;
+ th = grpc_core::Thread("grpc_thread_body2_test", &thd_body2, nullptr, &ok);
+ GPR_ASSERT(ok);
+ th.Start();
}
- for (i = 0; i < NUM_THREADS; i++) {
- gpr_thd_join(thds[i]);
+ for (auto& th : thds) {
+ th.Join();
}
}
@@ -98,7 +93,7 @@ static void test(void) {
int main(int argc, char* argv[]) {
grpc_test_init(argc, argv);
- test_options();
- test();
+ test1();
+ test2();
return 0;
}
diff --git a/test/core/handshake/client_ssl.cc b/test/core/handshake/client_ssl.cc
index fe2ab251e3..8ac763ac4b 100644
--- a/test/core/handshake/client_ssl.cc
+++ b/test/core/handshake/client_ssl.cc
@@ -35,7 +35,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/load_file.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@@ -230,12 +230,11 @@ static bool client_ssl_test(char* server_alpn_preferred) {
GPR_ASSERT(server_socket > 0 && port > 0);
// Launch the TLS server thread.
- gpr_thd_options thdopt = gpr_thd_options_default();
- gpr_thd_id thdid;
- gpr_thd_options_set_joinable(&thdopt);
server_args args = {server_socket, server_alpn_preferred};
- GPR_ASSERT(gpr_thd_new(&thdid, "grpc_client_ssl_test", server_thread, &args,
- &thdopt));
+ bool ok;
+ grpc_core::Thread thd("grpc_client_ssl_test", server_thread, &args, &ok);
+ GPR_ASSERT(ok);
+ thd.Start();
// Load key pair and establish client SSL credentials.
grpc_ssl_pem_key_cert_pair pem_key_cert_pair;
@@ -303,7 +302,7 @@ static bool client_ssl_test(char* server_alpn_preferred) {
grpc_slice_unref(key_slice);
grpc_slice_unref(ca_slice);
- gpr_thd_join(thdid);
+ thd.Join();
grpc_shutdown();
diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc
index 80000ca8d3..9788320e0d 100644
--- a/test/core/handshake/readahead_handshaker_server_ssl.cc
+++ b/test/core/handshake/readahead_handshaker_server_ssl.cc
@@ -30,7 +30,6 @@
#include <grpc/support/string_util.h>
#include <grpc/support/sync.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 f0465c8e3e..8fa5f7fb35 100644
--- a/test/core/handshake/server_ssl.cc
+++ b/test/core/handshake/server_ssl.cc
@@ -30,7 +30,6 @@
#include <grpc/support/string_util.h>
#include <grpc/support/sync.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 d202a7cfd6..41b2829d8b 100644
--- a/test/core/handshake/server_ssl_common.cc
+++ b/test/core/handshake/server_ssl_common.cc
@@ -32,7 +32,7 @@
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/load_file.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@@ -138,11 +138,10 @@ bool server_ssl_test(const char* alpn_list[], unsigned int alpn_list_len,
gpr_event_init(&client_handshake_complete);
// Launch the gRPC server thread.
- gpr_thd_options thdopt = gpr_thd_options_default();
- gpr_thd_id thdid;
- gpr_thd_options_set_joinable(&thdopt);
- GPR_ASSERT(
- gpr_thd_new(&thdid, "grpc_ssl_test", server_thread, &port, &thdopt));
+ bool ok;
+ grpc_core::Thread thd("grpc_ssl_test", server_thread, &port, &ok);
+ GPR_ASSERT(ok);
+ thd.Start();
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
@@ -235,7 +234,7 @@ bool server_ssl_test(const char* alpn_list[], unsigned int alpn_list_len,
EVP_cleanup();
close(sock);
- gpr_thd_join(thdid);
+ thd.Join();
grpc_shutdown();
diff --git a/test/core/handshake/server_ssl_common.h b/test/core/handshake/server_ssl_common.h
index f726a1cd3a..32bc6f9897 100644
--- a/test/core/handshake/server_ssl_common.h
+++ b/test/core/handshake/server_ssl_common.h
@@ -26,7 +26,6 @@
#include <grpc/support/string_util.h>
#include <grpc/support/sync.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 8426b3d233..cf2c7db846 100644
--- a/test/core/iomgr/combiner_test.cc
+++ b/test/core/iomgr/combiner_test.cc
@@ -22,8 +22,8 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/thd.h"
#include "test/core/util/test_config.h"
static void test_no_op(void) {
@@ -97,21 +97,19 @@ static void test_execute_many(void) {
gpr_log(GPR_DEBUG, "test_execute_many");
grpc_combiner* lock = grpc_combiner_create();
- gpr_thd_id thds[100];
+ grpc_core::Thread thds[100];
thd_args ta[GPR_ARRAY_SIZE(thds)];
for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
- gpr_thd_options options = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&options);
ta[i].ctr = 0;
ta[i].lock = lock;
gpr_event_init(&ta[i].done);
- GPR_ASSERT(gpr_thd_new(&thds[i], "grpc_execute_many", execute_many_loop,
- &ta[i], &options));
+ thds[i] = grpc_core::Thread("grpc_execute_many", execute_many_loop, &ta[i]);
+ thds[i].Start();
}
for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
GPR_ASSERT(gpr_event_wait(&ta[i].done,
gpr_inf_future(GPR_CLOCK_REALTIME)) != nullptr);
- gpr_thd_join(thds[i]);
+ thds[i].Join();
}
grpc_core::ExecCtx exec_ctx;
GRPC_COMBINER_UNREF(lock, "test_execute_many");
diff --git a/test/core/iomgr/error_test.cc b/test/core/iomgr/error_test.cc
index f6292b72a9..a1628a1f71 100644
--- a/test/core/iomgr/error_test.cc
+++ b/test/core/iomgr/error_test.cc
@@ -24,7 +24,6 @@
#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 02d11271ec..c3ba6d7c14 100644
--- a/test/core/iomgr/ev_epollsig_linux_test.cc
+++ b/test/core/iomgr/ev_epollsig_linux_test.cc
@@ -30,8 +30,8 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "test/core/util/test_config.h"
@@ -259,11 +259,10 @@ static void test_threading(void) {
shared.pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
grpc_pollset_init(shared.pollset, &shared.mu);
- gpr_thd_id thds[10];
- for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
- gpr_thd_options opt = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&opt);
- gpr_thd_new(&thds[i], "test_thread", test_threading_loop, &shared, &opt);
+ grpc_core::Thread thds[10];
+ for (auto& th : thds) {
+ th = grpc_core::Thread("test_thread", test_threading_loop, &shared);
+ th.Start();
}
grpc_wakeup_fd fd;
GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_fd_init", grpc_wakeup_fd_init(&fd)));
@@ -280,8 +279,8 @@ static void test_threading(void) {
}
GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_first",
grpc_wakeup_fd_wakeup(shared.wakeup_fd)));
- for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
- gpr_thd_join(thds[i]);
+ for (auto& th : thds) {
+ th.Join();
}
fd.read_fd = 0;
grpc_wakeup_fd_destroy(&fd);
diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc
index 341579f178..79b2b50e70 100644
--- a/test/core/iomgr/resolve_address_posix_test.cc
+++ b/test/core/iomgr/resolve_address_posix_test.cc
@@ -27,8 +27,8 @@
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
-#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "test/core/util/test_config.h"
@@ -38,6 +38,7 @@ static gpr_timespec test_deadline(void) {
}
typedef struct args_struct {
+ grpc_core::Thread thd;
gpr_event ev;
grpc_resolved_addresses* addrs;
gpr_atm done_atm;
@@ -59,6 +60,9 @@ void args_init(args_struct* args) {
void args_finish(args_struct* args) {
GPR_ASSERT(gpr_event_wait(&args->ev, test_deadline()));
+ args->thd.Join();
+ // Don't need to explicitly destruct args->thd since
+ // args is actually going to be destructed, not just freed
grpc_resolved_addresses_destroy(args->addrs);
grpc_pollset_set_del_pollset(args->pollset_set, args->pollset);
grpc_pollset_set_destroy(args->pollset_set);
@@ -101,8 +105,8 @@ static void actually_poll(void* argsp) {
static void poll_pollset_until_request_done(args_struct* args) {
gpr_atm_rel_store(&args->done_atm, 0);
- gpr_thd_id id;
- gpr_thd_new(&id, "grpc_poll_pollset", actually_poll, args, nullptr);
+ args->thd = grpc_core::Thread("grpc_poll_pollset", actually_poll, args);
+ args->thd.Start();
}
static void must_succeed(void* argsp, grpc_error* err) {
diff --git a/test/core/iomgr/wakeup_fd_cv_test.cc b/test/core/iomgr/wakeup_fd_cv_test.cc
index 68dcb50aa6..9bd7c6e47e 100644
--- a/test/core/iomgr/wakeup_fd_cv_test.cc
+++ b/test/core/iomgr/wakeup_fd_cv_test.cc
@@ -26,7 +26,7 @@
#include <grpc/support/time.h>
#include "src/core/lib/gpr/env.h"
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/iomgr_posix.h"
@@ -103,8 +103,6 @@ void test_poll_cv_trigger(void) {
grpc_wakeup_fd cvfd1, cvfd2, cvfd3;
struct pollfd pfds[6];
poll_args pargs;
- gpr_thd_id t_id;
- gpr_thd_options opt;
GPR_ASSERT(grpc_wakeup_fd_init(&cvfd1) == GRPC_ERROR_NONE);
GPR_ASSERT(grpc_wakeup_fd_init(&cvfd2) == GRPC_ERROR_NONE);
@@ -135,79 +133,91 @@ void test_poll_cv_trigger(void) {
pargs.timeout = 1000;
pargs.result = -2;
- opt = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&opt);
- gpr_thd_new(&t_id, "grpc_background_poll", &background_poll, &pargs, &opt);
-
- // Wakeup wakeup_fd not listening for events
- GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd1) == GRPC_ERROR_NONE);
- gpr_thd_join(t_id);
- GPR_ASSERT(pargs.result == 0);
- GPR_ASSERT(pfds[0].revents == 0);
- GPR_ASSERT(pfds[1].revents == 0);
- GPR_ASSERT(pfds[2].revents == 0);
- GPR_ASSERT(pfds[3].revents == 0);
- GPR_ASSERT(pfds[4].revents == 0);
- GPR_ASSERT(pfds[5].revents == 0);
-
- // Pollin on socket fd
- pargs.timeout = -1;
- pargs.result = -2;
- gpr_thd_new(&t_id, "grpc_background_poll", &background_poll, &pargs, &opt);
- trigger_socket_event();
- gpr_thd_join(t_id);
- GPR_ASSERT(pargs.result == 1);
- GPR_ASSERT(pfds[0].revents == 0);
- GPR_ASSERT(pfds[1].revents == 0);
- GPR_ASSERT(pfds[2].revents == POLLIN);
- GPR_ASSERT(pfds[3].revents == 0);
- GPR_ASSERT(pfds[4].revents == 0);
- GPR_ASSERT(pfds[5].revents == 0);
-
- // Pollin on wakeup fd
- reset_socket_event();
- pargs.result = -2;
- gpr_thd_new(&t_id, "grpc_background_poll", &background_poll, &pargs, &opt);
- GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd2) == GRPC_ERROR_NONE);
- gpr_thd_join(t_id);
-
- GPR_ASSERT(pargs.result == 1);
- GPR_ASSERT(pfds[0].revents == 0);
- GPR_ASSERT(pfds[1].revents == POLLIN);
- GPR_ASSERT(pfds[2].revents == 0);
- GPR_ASSERT(pfds[3].revents == 0);
- GPR_ASSERT(pfds[4].revents == 0);
- GPR_ASSERT(pfds[5].revents == 0);
-
- // Pollin on wakeupfd before poll()
- pargs.result = -2;
- gpr_thd_new(&t_id, "grpc_background_poll", &background_poll, &pargs, &opt);
- gpr_thd_join(t_id);
-
- GPR_ASSERT(pargs.result == 1);
- GPR_ASSERT(pfds[0].revents == 0);
- GPR_ASSERT(pfds[1].revents == POLLIN);
- GPR_ASSERT(pfds[2].revents == 0);
- GPR_ASSERT(pfds[3].revents == 0);
- GPR_ASSERT(pfds[4].revents == 0);
- GPR_ASSERT(pfds[5].revents == 0);
-
- // No Events
- pargs.result = -2;
- pargs.timeout = 1000;
- reset_socket_event();
- GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd1) == GRPC_ERROR_NONE);
- GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd2) == GRPC_ERROR_NONE);
- gpr_thd_new(&t_id, "grpc_background_poll", &background_poll, &pargs, &opt);
- gpr_thd_join(t_id);
-
- GPR_ASSERT(pargs.result == 0);
- GPR_ASSERT(pfds[0].revents == 0);
- GPR_ASSERT(pfds[1].revents == 0);
- GPR_ASSERT(pfds[2].revents == 0);
- GPR_ASSERT(pfds[3].revents == 0);
- GPR_ASSERT(pfds[4].revents == 0);
- GPR_ASSERT(pfds[5].revents == 0);
+ {
+ grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs);
+ thd.Start();
+ // Wakeup wakeup_fd not listening for events
+ GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd1) == GRPC_ERROR_NONE);
+ thd.Join();
+ GPR_ASSERT(pargs.result == 0);
+ GPR_ASSERT(pfds[0].revents == 0);
+ GPR_ASSERT(pfds[1].revents == 0);
+ GPR_ASSERT(pfds[2].revents == 0);
+ GPR_ASSERT(pfds[3].revents == 0);
+ GPR_ASSERT(pfds[4].revents == 0);
+ GPR_ASSERT(pfds[5].revents == 0);
+ }
+
+ {
+ // Pollin on socket fd
+ pargs.timeout = -1;
+ pargs.result = -2;
+ grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs);
+ thd.Start();
+ trigger_socket_event();
+ thd.Join();
+ GPR_ASSERT(pargs.result == 1);
+ GPR_ASSERT(pfds[0].revents == 0);
+ GPR_ASSERT(pfds[1].revents == 0);
+ GPR_ASSERT(pfds[2].revents == POLLIN);
+ GPR_ASSERT(pfds[3].revents == 0);
+ GPR_ASSERT(pfds[4].revents == 0);
+ GPR_ASSERT(pfds[5].revents == 0);
+ }
+
+ {
+ // Pollin on wakeup fd
+ reset_socket_event();
+ pargs.result = -2;
+ grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs);
+ thd.Start();
+ GPR_ASSERT(grpc_wakeup_fd_wakeup(&cvfd2) == GRPC_ERROR_NONE);
+ thd.Join();
+
+ GPR_ASSERT(pargs.result == 1);
+ GPR_ASSERT(pfds[0].revents == 0);
+ GPR_ASSERT(pfds[1].revents == POLLIN);
+ GPR_ASSERT(pfds[2].revents == 0);
+ GPR_ASSERT(pfds[3].revents == 0);
+ GPR_ASSERT(pfds[4].revents == 0);
+ GPR_ASSERT(pfds[5].revents == 0);
+ }
+
+ {
+ // Pollin on wakeupfd before poll()
+ pargs.result = -2;
+ grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs);
+ thd.Start();
+ thd.Join();
+
+ GPR_ASSERT(pargs.result == 1);
+ GPR_ASSERT(pfds[0].revents == 0);
+ GPR_ASSERT(pfds[1].revents == POLLIN);
+ GPR_ASSERT(pfds[2].revents == 0);
+ GPR_ASSERT(pfds[3].revents == 0);
+ GPR_ASSERT(pfds[4].revents == 0);
+ GPR_ASSERT(pfds[5].revents == 0);
+ }
+
+ {
+ // No Events
+ pargs.result = -2;
+ pargs.timeout = 1000;
+ reset_socket_event();
+ GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd1) == GRPC_ERROR_NONE);
+ GPR_ASSERT(grpc_wakeup_fd_consume_wakeup(&cvfd2) == GRPC_ERROR_NONE);
+ grpc_core::Thread thd("grpc_background_poll", &background_poll, &pargs);
+ thd.Start();
+ thd.Join();
+
+ GPR_ASSERT(pargs.result == 0);
+ GPR_ASSERT(pfds[0].revents == 0);
+ GPR_ASSERT(pfds[1].revents == 0);
+ GPR_ASSERT(pfds[2].revents == 0);
+ GPR_ASSERT(pfds[3].revents == 0);
+ GPR_ASSERT(pfds[4].revents == 0);
+ GPR_ASSERT(pfds[5].revents == 0);
+ }
}
int main(int argc, char** argv) {
diff --git a/test/core/network_benchmarks/low_level_ping_pong.cc b/test/core/network_benchmarks/low_level_ping_pong.cc
index 33716b9d4a..a983b1876d 100644
--- a/test/core/network_benchmarks/low_level_ping_pong.cc
+++ b/test/core/network_benchmarks/low_level_ping_pong.cc
@@ -38,8 +38,8 @@
#include <grpc/support/log.h>
#include <grpc/support/time.h>
-#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/socket_utils_posix.h"
#include "test/core/util/cmdline.h"
@@ -575,7 +575,6 @@ int create_socket(const char* socket_type, fd_pair* client_fds,
static int run_benchmark(const char* socket_type, thread_args* client_args,
thread_args* server_args) {
- gpr_thd_id tid;
int rv = 0;
rv = create_socket(socket_type, &client_args->fds, &server_args->fds);
@@ -586,8 +585,11 @@ static int run_benchmark(const char* socket_type, thread_args* client_args,
gpr_log(GPR_INFO, "Starting test %s %s %zu", client_args->strategy_name,
socket_type, client_args->msg_size);
- gpr_thd_new(&tid, "server_thread", server_thread_wrap, server_args, nullptr);
+ grpc_core::Thread server("server_thread", server_thread_wrap, server_args);
+ server.Start();
client_thread(client_args);
+ server.Join();
+
return 0;
}
diff --git a/test/core/security/BUILD b/test/core/security/BUILD
index 6eaf0a19ce..9776e6d5fd 100644
--- a/test/core/security/BUILD
+++ b/test/core/security/BUILD
@@ -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/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 ff48075365..a2a648e2ad 100644
--- a/test/core/statistics/rpc_stats_test.cc
+++ b/test/core/statistics/rpc_stats_test.cc
@@ -27,7 +27,6 @@
#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 861ed5d1a8..cff05caec1 100644
--- a/test/core/surface/byte_buffer_reader_test.cc
+++ b/test/core/surface/byte_buffer_reader_test.cc
@@ -26,7 +26,7 @@
#include <grpc/support/time.h>
#include "src/core/lib/compression/message_compress.h"
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/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 81319f4df4..9c8d8d8395 100644
--- a/test/core/surface/completion_queue_threading_test.cc
+++ b/test/core/surface/completion_queue_threading_test.cc
@@ -22,8 +22,8 @@
#include <grpc/support/log.h>
#include <grpc/support/time.h>
-#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "test/core/util/test_config.h"
@@ -78,16 +78,14 @@ static void test_too_many_plucks(void) {
grpc_completion_queue* cc;
void* tags[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS];
grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)];
- gpr_thd_id thread_ids[GPR_ARRAY_SIZE(tags)];
+ grpc_core::Thread threads[GPR_ARRAY_SIZE(tags)];
struct thread_state thread_states[GPR_ARRAY_SIZE(tags)];
- gpr_thd_options thread_options = gpr_thd_options_default();
grpc_core::ExecCtx exec_ctx;
unsigned i, j;
LOG_TEST("test_too_many_plucks");
cc = grpc_completion_queue_create_for_pluck(nullptr);
- gpr_thd_options_set_joinable(&thread_options);
for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
tags[i] = create_test_tag();
@@ -96,8 +94,9 @@ static void test_too_many_plucks(void) {
}
thread_states[i].cc = cc;
thread_states[i].tag = tags[i];
- gpr_thd_new(thread_ids + i, "grpc_pluck_test", pluck_one, thread_states + i,
- &thread_options);
+ threads[i] =
+ grpc_core::Thread("grpc_pluck_test", pluck_one, thread_states + i);
+ threads[i].Start();
}
/* wait until all other threads are plucking */
@@ -113,8 +112,8 @@ static void test_too_many_plucks(void) {
nullptr, &completions[i]);
}
- for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
- gpr_thd_join(thread_ids[i]);
+ for (auto& th : threads) {
+ th.Join();
}
shutdown_and_destroy(cc);
@@ -220,8 +219,9 @@ static void test_threading(size_t producers, size_t consumers) {
"test_threading", producers, consumers);
/* start all threads: they will wait for phase1 */
+ grpc_core::Thread* threads = reinterpret_cast<grpc_core::Thread*>(
+ gpr_malloc(sizeof(*threads) * (producers + consumers)));
for (i = 0; i < producers + consumers; i++) {
- gpr_thd_id id;
gpr_event_init(&options[i].on_started);
gpr_event_init(&options[i].on_phase1_done);
gpr_event_init(&options[i].on_finished);
@@ -230,10 +230,13 @@ static void test_threading(size_t producers, size_t consumers) {
options[i].events_triggered = 0;
options[i].cc = cc;
options[i].id = optid++;
- GPR_ASSERT(gpr_thd_new(&id,
- i < producers ? "grpc_producer" : "grpc_consumer",
- i < producers ? producer_thread : consumer_thread,
- options + i, nullptr));
+
+ bool ok;
+ threads[i] = grpc_core::Thread(
+ i < producers ? "grpc_producer" : "grpc_consumer",
+ i < producers ? producer_thread : consumer_thread, options + i, &ok);
+ GPR_ASSERT(ok);
+ threads[i].Start();
gpr_event_wait(&options[i].on_started, ten_seconds_time());
}
@@ -266,6 +269,11 @@ static void test_threading(size_t producers, size_t consumers) {
/* destroy the completion channel */
grpc_completion_queue_destroy(cc);
+ for (i = 0; i < producers + consumers; i++) {
+ threads[i].Join();
+ }
+ gpr_free(threads);
+
/* verify that everything was produced and consumed */
for (i = 0; i < producers + consumers; i++) {
if (i < producers) {
diff --git a/test/core/surface/concurrent_connectivity_test.cc b/test/core/surface/concurrent_connectivity_test.cc
index 95af4abd48..c1298b6636 100644
--- a/test/core/surface/concurrent_connectivity_test.cc
+++ b/test/core/surface/concurrent_connectivity_test.cc
@@ -30,7 +30,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/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"
@@ -172,73 +172,77 @@ int run_concurrent_connectivity_test() {
grpc_init();
- gpr_thd_id threads[NUM_THREADS];
- gpr_thd_id server;
-
- char* localhost = gpr_strdup("localhost:54321");
- gpr_thd_options options = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&options);
-
/* First round, no server */
- gpr_log(GPR_DEBUG, "Wave 1");
- for (size_t i = 0; i < NUM_THREADS; ++i) {
- gpr_thd_new(&threads[i], "grpc_wave_1", create_loop_destroy, localhost,
- &options);
- }
- for (size_t i = 0; i < NUM_THREADS; ++i) {
- gpr_thd_join(threads[i]);
+ {
+ gpr_log(GPR_DEBUG, "Wave 1");
+ char* localhost = gpr_strdup("localhost:54321");
+ grpc_core::Thread threads[NUM_THREADS];
+ for (auto& th : threads) {
+ th = grpc_core::Thread("grpc_wave_1", create_loop_destroy, localhost);
+ th.Start();
+ }
+ for (auto& th : threads) {
+ th.Join();
+ }
+ gpr_free(localhost);
}
- gpr_free(localhost);
- /* Second round, actual grpc server */
- gpr_log(GPR_DEBUG, "Wave 2");
- int port = grpc_pick_unused_port_or_die();
- gpr_asprintf(&args.addr, "localhost:%d", port);
- args.server = grpc_server_create(nullptr, nullptr);
- grpc_server_add_insecure_http2_port(args.server, args.addr);
- args.cq = grpc_completion_queue_create_for_next(nullptr);
- grpc_server_register_completion_queue(args.server, args.cq, nullptr);
- grpc_server_start(args.server);
- gpr_thd_new(&server, "grpc_wave_2_server", server_thread, &args, &options);
-
- for (size_t i = 0; i < NUM_THREADS; ++i) {
- gpr_thd_new(&threads[i], "grpc_wave_2", create_loop_destroy, args.addr,
- &options);
- }
- for (size_t i = 0; i < NUM_THREADS; ++i) {
- gpr_thd_join(threads[i]);
- }
- grpc_server_shutdown_and_notify(args.server, args.cq, tag(0xd1e));
-
- gpr_thd_join(server);
- grpc_server_destroy(args.server);
- grpc_completion_queue_destroy(args.cq);
- gpr_free(args.addr);
-
- /* Third round, bogus tcp server */
- gpr_log(GPR_DEBUG, "Wave 3");
- args.pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
- grpc_pollset_init(args.pollset, &args.mu);
- gpr_event_init(&args.ready);
- gpr_thd_new(&server, "grpc_wave_3_server", bad_server_thread, &args,
- &options);
- gpr_event_wait(&args.ready, gpr_inf_future(GPR_CLOCK_MONOTONIC));
-
- for (size_t i = 0; i < NUM_THREADS; ++i) {
- gpr_thd_new(&threads[i], "grpc_wave_3", create_loop_destroy, args.addr,
- &options);
- }
- for (size_t i = 0; i < NUM_THREADS; ++i) {
- gpr_thd_join(threads[i]);
+ {
+ /* Second round, actual grpc server */
+ gpr_log(GPR_DEBUG, "Wave 2");
+ int port = grpc_pick_unused_port_or_die();
+ gpr_asprintf(&args.addr, "localhost:%d", port);
+ args.server = grpc_server_create(nullptr, nullptr);
+ grpc_server_add_insecure_http2_port(args.server, args.addr);
+ args.cq = grpc_completion_queue_create_for_next(nullptr);
+ grpc_server_register_completion_queue(args.server, args.cq, nullptr);
+ grpc_server_start(args.server);
+ grpc_core::Thread server2("grpc_wave_2_server", server_thread, &args);
+ server2.Start();
+
+ grpc_core::Thread threads[NUM_THREADS];
+ for (auto& th : threads) {
+ th = grpc_core::Thread("grpc_wave_2", create_loop_destroy, args.addr);
+ th.Start();
+ }
+ for (auto& th : threads) {
+ th.Join();
+ }
+ grpc_server_shutdown_and_notify(args.server, args.cq, tag(0xd1e));
+
+ server2.Join();
+ grpc_server_destroy(args.server);
+ grpc_completion_queue_destroy(args.cq);
+ gpr_free(args.addr);
}
- gpr_atm_rel_store(&args.stop, 1);
- gpr_thd_join(server);
{
- grpc_core::ExecCtx exec_ctx;
- grpc_pollset_shutdown(
- args.pollset, GRPC_CLOSURE_CREATE(done_pollset_shutdown, args.pollset,
- grpc_schedule_on_exec_ctx));
+ /* Third round, bogus tcp server */
+ gpr_log(GPR_DEBUG, "Wave 3");
+ args.pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
+ grpc_pollset_init(args.pollset, &args.mu);
+ gpr_event_init(&args.ready);
+ grpc_core::Thread server3("grpc_wave_3_server", bad_server_thread, &args);
+ server3.Start();
+ gpr_event_wait(&args.ready, gpr_inf_future(GPR_CLOCK_MONOTONIC));
+
+ grpc_core::Thread threads[NUM_THREADS];
+ for (auto& th : threads) {
+ th = grpc_core::Thread("grpc_wave_3", create_loop_destroy, args.addr);
+ th.Start();
+ }
+ for (auto& th : threads) {
+ th.Join();
+ }
+
+ gpr_atm_rel_store(&args.stop, 1);
+ server3.Join();
+ {
+ grpc_core::ExecCtx exec_ctx;
+ grpc_pollset_shutdown(
+ args.pollset, GRPC_CLOSURE_CREATE(done_pollset_shutdown, args.pollset,
+ grpc_schedule_on_exec_ctx));
+ }
}
grpc_shutdown();
@@ -278,18 +282,17 @@ void watches_with_short_timeouts(void* addr) {
int run_concurrent_watches_with_short_timeouts_test() {
grpc_init();
- gpr_thd_id threads[NUM_THREADS];
+ grpc_core::Thread threads[NUM_THREADS];
char* localhost = gpr_strdup("localhost:54321");
- gpr_thd_options options = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&options);
- for (size_t i = 0; i < NUM_THREADS; ++i) {
- gpr_thd_new(&threads[i], "grpc_short_watches", watches_with_short_timeouts,
- localhost, &options);
+ for (auto& th : threads) {
+ th = grpc_core::Thread("grpc_short_watches", watches_with_short_timeouts,
+ localhost);
+ th.Start();
}
- for (size_t i = 0; i < NUM_THREADS; ++i) {
- gpr_thd_join(threads[i]);
+ for (auto& th : threads) {
+ th.Join();
}
gpr_free(localhost);
diff --git a/test/core/surface/num_external_connectivity_watchers_test.cc b/test/core/surface/num_external_connectivity_watchers_test.cc
index 49d28ad1c7..467deeeaec 100644
--- a/test/core/surface/num_external_connectivity_watchers_test.cc
+++ b/test/core/surface/num_external_connectivity_watchers_test.cc
@@ -23,7 +23,7 @@
#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/gprpp/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/sequential_connectivity_test.cc b/test/core/surface/sequential_connectivity_test.cc
index 428d17ff1b..9aba4c499e 100644
--- a/test/core/surface/sequential_connectivity_test.cc
+++ b/test/core/surface/sequential_connectivity_test.cc
@@ -23,7 +23,7 @@
#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/gprpp/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"
@@ -67,10 +67,8 @@ static void run_test(const test_fixture* fixture) {
grpc_server_start(server);
server_thread_args sta = {server, server_cq};
- gpr_thd_id server_thread;
- gpr_thd_options thdopt = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&thdopt);
- gpr_thd_new(&server_thread, "grpc_server", server_thread_func, &sta, &thdopt);
+ grpc_core::Thread server_thread("grpc_server", server_thread_func, &sta);
+ server_thread.Start();
grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
grpc_channel* channels[NUM_CONNECTIONS];
@@ -95,7 +93,7 @@ static void run_test(const test_fixture* fixture) {
}
grpc_server_shutdown_and_notify(server, server_cq, nullptr);
- gpr_thd_join(server_thread);
+ server_thread.Join();
grpc_completion_queue_shutdown(server_cq);
grpc_completion_queue_shutdown(cq);
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/transport_security_test_lib.cc b/test/core/tsi/transport_security_test_lib.cc
index 7af6431c66..8ea83f7088 100644
--- a/test/core/tsi/transport_security_test_lib.cc
+++ b/test/core/tsi/transport_security_test_lib.cc
@@ -24,7 +24,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.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/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc
index 1d2dcae94b..ee6958dfcf 100644
--- a/test/cpp/client/client_channel_stress_test.cc
+++ b/test/cpp/client/client_channel_stress_test.cc
@@ -35,8 +35,8 @@
#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/gprpp/thd.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "test/core/util/port.h"
diff --git a/test/cpp/cocoapods/generic/generic.mm b/test/cpp/cocoapods/generic/generic.mm
index 5ca34f195c..26f09b0af0 100644
--- a/test/cpp/cocoapods/generic/generic.mm
+++ b/test/cpp/cocoapods/generic/generic.mm
@@ -32,7 +32,7 @@
#include <grpc/grpc.h>
#include <grpc/support/time.h>
-#include "src/core/lib/gpr/thd.h"
+#include "src/core/lib/gprpp/thd.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
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/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index df706a2237..d3620584a9 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -33,7 +33,6 @@
#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 c28ffea79c..6bde6641b7 100644
--- a/test/cpp/end2end/client_crash_test.cc
+++ b/test/cpp/end2end/client_crash_test.cc
@@ -26,7 +26,6 @@
#include <grpc/support/log.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 16600d12b0..96a855c30e 100644
--- a/test/cpp/end2end/client_lb_end2end_test.cc
+++ b/test/cpp/end2end/client_lb_end2end_test.cc
@@ -38,7 +38,6 @@
#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 38fdde990f..1e2cdb8b62 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -35,7 +35,6 @@
#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 ae6c6c7d11..20804bc19e 100644
--- a/test/cpp/end2end/filter_end2end_test.cc
+++ b/test/cpp/end2end/filter_end2end_test.cc
@@ -33,7 +33,6 @@
#include <grpc/grpc.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 86a41fc585..42b15a06e9 100644
--- a/test/cpp/end2end/generic_end2end_test.cc
+++ b/test/cpp/end2end/generic_end2end_test.cc
@@ -31,7 +31,6 @@
#include <grpc/grpc.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 96bd93682e..33f485be93 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -34,9 +34,12 @@
#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 +61,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
@@ -307,9 +312,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());
@@ -378,15 +381,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_);
}
@@ -447,7 +457,7 @@ class GrpclbEnd2endTest : public ::testing::Test {
void WaitForBackend(size_t backend_idx) {
do {
- SendRpc();
+ (void)SendRpc();
} while (backends_[backend_idx]->request_count() == 0);
ResetBackendCounters();
}
@@ -523,10 +533,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_);
@@ -564,8 +574,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();
@@ -598,6 +609,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 {
@@ -633,11 +645,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
@@ -647,20 +700,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());
@@ -890,7 +938,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 ==========");
@@ -952,7 +1003,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 ==========");
diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc
index fe530432ea..e3976a4838 100644
--- a/test/cpp/end2end/mock_test.cc
+++ b/test/cpp/end2end/mock_test.cc
@@ -29,7 +29,6 @@
#include <grpc/support/log.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 574d357bef..108dcd29e7 100644
--- a/test/cpp/end2end/server_crash_test.cc
+++ b/test/cpp/end2end/server_crash_test.cc
@@ -26,7 +26,6 @@
#include <grpc/support/log.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 38f9b6755c..a0349fdc4c 100644
--- a/test/cpp/end2end/server_early_return_test.cc
+++ b/test/cpp/end2end/server_early_return_test.cc
@@ -29,7 +29,6 @@
#include <grpc/support/log.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 2c8928151a..4dc1d1f1d9 100644
--- a/test/cpp/end2end/streaming_throughput_test.cc
+++ b/test/cpp/end2end/streaming_throughput_test.cc
@@ -33,7 +33,6 @@
#include <grpc/support/log.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 0842d8e64a..828beefea3 100644
--- a/test/cpp/end2end/thread_stress_test.cc
+++ b/test/cpp/end2end/thread_stress_test.cc
@@ -28,7 +28,6 @@
#include <grpc/grpc.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/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/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_copyright.py b/tools/distrib/check_copyright.py
index 55cec938c9..6e1a303fb0 100755
--- a/tools/distrib/check_copyright.py
+++ b/tools/distrib/check_copyright.py
@@ -86,6 +86,9 @@ _EXEMPT = frozenset((
'tools/grpcz/census.proto',
# status.proto copied from googleapis
'src/proto/grpc/status/status.proto',
+
+ # Gradle wrapper used to build for Android
+ 'examples/android/helloworld/gradlew.bat',
))
RE_YEAR = r'Copyright (?P<first_year>[0-9]+\-)?(?P<last_year>[0-9]+) gRPC authors.'
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/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 94c23fb488..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
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index eba2705429..ff5abc679d 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
@@ -1030,7 +1030,6 @@ 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.h \
src/core/lib/gpr/time_precise.h \
src/core/lib/gpr/tls.h \
src/core/lib/gpr/tls_gcc.h \
@@ -1049,6 +1048,7 @@ src/core/lib/gprpp/memory.h \
src/core/lib/gprpp/orphanable.h \
src/core/lib/gprpp/ref_counted.h \
src/core/lib/gprpp/ref_counted_ptr.h \
+src/core/lib/gprpp/thd.h \
src/core/lib/http/format_request.h \
src/core/lib/http/httpcli.h \
src/core/lib/http/parser.h \
@@ -1125,6 +1125,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 \
@@ -1149,6 +1150,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.internal b/tools/doxygen/Doxyfile.core.internal
index e99c9c06b4..57f9147f44 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -901,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 \
@@ -927,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 \
@@ -1093,10 +1097,6 @@ src/core/lib/gpr/string_windows.h \
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.h \
-src/core/lib/gpr/thd_posix.cc \
-src/core/lib/gpr/thd_windows.cc \
src/core/lib/gpr/time.cc \
src/core/lib/gpr/time_posix.cc \
src/core/lib/gpr/time_precise.cc \
@@ -1125,6 +1125,9 @@ src/core/lib/gprpp/memory.h \
src/core/lib/gprpp/orphanable.h \
src/core/lib/gprpp/ref_counted.h \
src/core/lib/gprpp/ref_counted_ptr.h \
+src/core/lib/gprpp/thd.h \
+src/core/lib/gprpp/thd_posix.cc \
+src/core/lib/gprpp/thd_windows.cc \
src/core/lib/http/format_request.cc \
src/core/lib/http/format_request.h \
src/core/lib/http/httpcli.cc \
@@ -1309,13 +1312,13 @@ 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_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 \
@@ -1326,12 +1329,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 \
@@ -1388,6 +1391,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/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..16586a2d0d
--- /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=@com_github_bazelbuild_bazeltoolchains//configs/debian8_clang/0.3.0/bazel_0.10.0:toolchain \
+ --crosstool_top=@com_github_bazelbuild_bazeltoolchains//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 8ae3582e55..906f690d98 100644
--- a/tools/interop_matrix/client_matrix.py
+++ b/tools/interop_matrix/client_matrix.py
@@ -112,6 +112,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.9.2': None
},
+ {
+ 'v1.10.0': None
+ },
],
'java': [
{
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 93d247944e..6b8b26f41b 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -764,7 +764,7 @@
"language": "c",
"name": "gpr_thd_test",
"src": [
- "test/core/gpr/thd_test.cc"
+ "test/core/gprpp/thd_test.cc"
],
"third_party": false,
"type": "target"
@@ -1964,23 +1964,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"
@@ -4175,6 +4158,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"
],
@@ -4190,6 +4207,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",
@@ -4208,6 +4239,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",
@@ -7099,20 +7144,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",
@@ -8051,6 +8156,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",
@@ -8133,6 +8253,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",
@@ -8223,9 +8358,6 @@
"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_posix.cc",
- "src/core/lib/gpr/thd_windows.cc",
"src/core/lib/gpr/time.cc",
"src/core/lib/gpr/time_posix.cc",
"src/core/lib/gpr/time_precise.cc",
@@ -8235,6 +8367,8 @@
"src/core/lib/gpr/tmpfile_posix.cc",
"src/core/lib/gpr/tmpfile_windows.cc",
"src/core/lib/gpr/wrap_memcpy.cc",
+ "src/core/lib/gprpp/thd_posix.cc",
+ "src/core/lib/gprpp/thd_windows.cc",
"src/core/lib/profiling/basic_timers.cc",
"src/core/lib/profiling/stap_timers.cc"
],
@@ -8272,7 +8406,6 @@
"src/core/lib/gpr/spinlock.h",
"src/core/lib/gpr/string.h",
"src/core/lib/gpr/string_windows.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",
@@ -8286,6 +8419,7 @@
"src/core/lib/gprpp/atomic_with_std.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/memory.h",
+ "src/core/lib/gprpp/thd.h",
"src/core/lib/profiling/timers.h"
],
"is_filegroup": true,
@@ -8318,7 +8452,6 @@
"src/core/lib/gpr/spinlock.h",
"src/core/lib/gpr/string.h",
"src/core/lib/gpr/string_windows.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",
@@ -8332,6 +8465,7 @@
"src/core/lib/gprpp/atomic_with_std.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/memory.h",
+ "src/core/lib/gprpp/thd.h",
"src/core/lib/profiling/timers.h"
],
"third_party": false,
@@ -8517,7 +8651,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",
@@ -8548,6 +8681,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"
@@ -8672,6 +8806,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",
@@ -8696,6 +8831,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"
@@ -8814,6 +8950,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",
@@ -8838,6 +8975,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"
@@ -8861,6 +8999,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",
@@ -8868,6 +9007,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"
@@ -8896,6 +9036,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",
@@ -8909,6 +9051,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",
@@ -9248,9 +9392,9 @@
"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_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"
],
@@ -9290,13 +9434,13 @@
"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_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",
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 2d62fc6326..6ce7ec28c4 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -2274,30 +2274,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",
@@ -4465,6 +4441,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"
],
@@ -4495,6 +4519,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",
@@ -4512,6 +4560,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,
@@ -7296,6 +7368,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": [
@@ -8634,6 +9051,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": [
@@ -9951,6 +10713,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": [
@@ -12493,6 +13585,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": [
@@ -13674,6 +15111,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": [
@@ -14929,6 +16651,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": [
@@ -16290,6 +18357,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": [
@@ -17715,6 +20127,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": [
@@ -19091,6 +21863,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": [
@@ -20492,6 +23609,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": [
@@ -26770,6 +30247,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": [
@@ -29256,6 +33078,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": [
@@ -31537,6 +35704,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": [
@@ -32852,6 +37364,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": [
@@ -35363,6 +40220,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": [
@@ -36525,6 +41727,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": [
@@ -37757,6 +43244,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": [
@@ -39095,6 +44927,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": [
@@ -40496,6 +46673,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": [
@@ -41849,6 +48386,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": [
@@ -47964,6 +54846,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": [
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_deprecated_grpc++.py b/tools/run_tests/sanity/check_deprecated_grpc++.py
index e0779ba0e5..4ec49fae39 100755
--- a/tools/run_tests/sanity/check_deprecated_grpc++.py
+++ b/tools/run_tests/sanity/check_deprecated_grpc++.py
@@ -170,4 +170,22 @@ for path_file in expected_files:
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/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
index 0c1ad9d44d..a15473db0f 100644
--- a/tools/run_tests/sanity/sanity_tests.yaml
+++ b/tools/run_tests/sanity/sanity_tests.yaml
@@ -11,6 +11,7 @@
- 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