From c73c4f7ae22c8f68a93b1bf062d92e37aef79431 Mon Sep 17 00:00:00 2001 From: Adam Czachorowski Date: Thu, 14 Dec 2017 16:21:00 +0100 Subject: [PATCH 001/546] Fix the ownership comment on grpc_lb_addresses_set_address() function. It does not take ownership of balancer_name since commit 53af23cfbf3b1fd4579ec084dbcb7b89a7ae2e96 --- src/core/ext/filters/client_channel/lb_policy_factory.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) 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 9da231b657b..db917cba586 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -70,16 +70,14 @@ grpc_lb_addresses* grpc_lb_addresses_create( grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses); /** Sets the value of the address at index \a index of \a addresses. - * \a address is a socket address of length \a address_len. - * Takes ownership of \a balancer_name. */ + * \a address is a socket address of length \a address_len. */ void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index, const void* address, size_t address_len, bool is_balancer, const char* balancer_name, void* user_data); /** Sets the value of the address at index \a index of \a addresses from \a uri. - * Returns true upon success, false otherwise. Takes ownership of \a - * balancer_name. */ + * Returns true upon success, false otherwise. */ bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses, size_t index, const grpc_uri* uri, bool is_balancer, From 215b6555c17b32fbf607aa0045db96d54949ce91 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 24 Apr 2018 15:58:11 -0700 Subject: [PATCH 002/546] Add Node perf tests for both implementations --- .../performance/build_performance.sh | 2 + .../performance/build_performance_node.sh | 26 +++++ .../run_tests/performance/run_worker_node.sh | 30 ++++++ .../run_tests/performance/scenario_config.py | 97 +++++++++++++++++++ 4 files changed, 155 insertions(+) create mode 100644 tools/run_tests/performance/build_performance_node.sh create mode 100644 tools/run_tests/performance/run_worker_node.sh diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh index 22e0ca9fa07..55762c6a237 100755 --- a/tools/run_tests/performance/build_performance.sh +++ b/tools/run_tests/performance/build_performance.sh @@ -58,5 +58,7 @@ do *) python tools/run_tests/run_tests.py -l "$language" -c "$CONFIG" --build_only -j 8 ;; + "node") + tools/run_tests/performance/build_performance_node.sh esac done diff --git a/tools/run_tests/performance/build_performance_node.sh b/tools/run_tests/performance/build_performance_node.sh new file mode 100644 index 00000000000..1e3f5df2305 --- /dev/null +++ b/tools/run_tests/performance/build_performance_node.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# 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. + +set +ex + +nvm install 9 + +set -ex + +cd "$(dirname "$0")/../../../../grpc-node" + +npm install + +./node_modules/.bin/gulp setup diff --git a/tools/run_tests/performance/run_worker_node.sh b/tools/run_tests/performance/run_worker_node.sh new file mode 100644 index 00000000000..0278beac237 --- /dev/null +++ b/tools/run_tests/performance/run_worker_node.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# 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. + +nvm use 9 + +set -ex + +fixture=$1 + +shift + +# Enter repo root +cd "$(dirname "$0")/../../.." + +# Enter the grpc-node repo root (expected to be next to grpc repo root) +cd ../grpc-node + +node -r test/fixtures/$fixture.js tools/run_tests/performance/worker.js $@ diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py index f05753154e9..b683f2d01d5 100644 --- a/tools/run_tests/performance/scenario_config.py +++ b/tools/run_tests/performance/scenario_config.py @@ -1150,6 +1150,101 @@ class GoLanguage: def __str__(self): return 'go' +class NodeLanguage: + + def __init__(self, node_purejs=False): + pass + self.node_purejs = node_purejs + self.safename = str(self) + + def worker_cmdline(self): + fixture = 'native_js' if self.node_purejs else 'native_native' + return ['tools/run_tests/performance/run_worker_node.sh', fixture] + + def worker_port_offset(self): + if self.node_purejs: + return 1100 + return 1000 + + def scenarios(self): + node_implementation = 'node_purejs' if self.node_purejs else 'node' + for secure in [True, False]: + secstr = 'secure' if secure else 'insecure' + smoketest_categories = ([SMOKETEST] if secure else []) + [SCALABLE] + + yield _ping_pong_scenario( + '%s_to_node_generic_async_streaming_ping_pong_%s' % + (secstr, node_implementation), + rpc_type='STREAMING', + client_type='ASYNC_CLIENT', + server_type='ASYNC_GENERIC_SERVER', + server_language='node', + use_generic_payload=True, + async_server_threads=1, + secure=secure, + categories=smoketest_categories) + + yield _ping_pong_scenario( + '%s_to_node_protobuf_async_streaming_ping_pong_%s' % + (secstr, node_implementation), + rpc_type='STREAMING', + client_type='ASYNC_CLIENT', + server_type='ASYNC_SERVER', + server_language='node', + async_server_threads=1, + secure=secure) + + yield _ping_pong_scenario( + '%s_to_node_protobuf_async_unary_ping_pong_%s' % + (secstr, node_implementation), + rpc_type='UNARY', + client_type='ASYNC_CLIENT', + server_type='ASYNC_SERVER', + server_language='node', + async_server_threads=1, + secure=secure, + categories=smoketest_categories) + + yield _ping_pong_scenario( + '%s_to_node_protobuf_async_unary_qps_unconstrained_%s' % + (secstr, node_implementation), + rpc_type='UNARY', + client_type='ASYNC_CLIENT', + server_type='ASYNC_SERVER', + server_language='node', + unconstrained_client='async', + secure=secure, + categories=smoketest_categories + [SCALABLE]) + + yield _ping_pong_scenario( + '%s_to_node_protobuf_async_streaming_qps_unconstrained_%s' % + (secstr, node_implementation), + rpc_type='STREAMING', + client_type='ASYNC_CLIENT', + server_type='ASYNC_SERVER', + server_language='node', + unconstrained_client='async', + secure=secure, + categories=[SCALABLE]) + + yield _ping_pong_scenario( + '%s_to_node_generic_async_streaming_qps_unconstrained_%s' % + (secstr, node_implementation), + rpc_type='STREAMING', + client_type='ASYNC_CLIENT', + server_type='ASYNC_GENERIC_SERVER', + server_language='node', + unconstrained_client='async', + use_generic_payload=True, + secure=secure, + categories=[SCALABLE]) + + # TODO(murgatroid99): add scenarios node vs C++ + + def __str__(self): + if self.node_purejs: + return 'node_purejs' + return 'node' LANGUAGES = { 'c++': CXXLanguage(), @@ -1160,4 +1255,6 @@ LANGUAGES = { 'java': JavaLanguage(), 'python': PythonLanguage(), 'go': GoLanguage(), + 'node': NodeLanguage(), + 'node_purejs': NodeLanguage(node_purejs=True) } From 5f3aa5ca0b97d05cc0b81efb149af1f2a5b8d741 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 24 Apr 2018 16:58:58 -0700 Subject: [PATCH 003/546] Fix sanity --- tools/run_tests/performance/run_worker_node.sh | 2 +- tools/run_tests/performance/scenario_config.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/performance/run_worker_node.sh b/tools/run_tests/performance/run_worker_node.sh index 0278beac237..2511522c711 100644 --- a/tools/run_tests/performance/run_worker_node.sh +++ b/tools/run_tests/performance/run_worker_node.sh @@ -27,4 +27,4 @@ cd "$(dirname "$0")/../../.." # Enter the grpc-node repo root (expected to be next to grpc repo root) cd ../grpc-node -node -r test/fixtures/$fixture.js tools/run_tests/performance/worker.js $@ +node -r "test/fixtures/$fixture.js" tools/run_tests/performance/worker.js "$@" diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py index b683f2d01d5..dde299ae36b 100644 --- a/tools/run_tests/performance/scenario_config.py +++ b/tools/run_tests/performance/scenario_config.py @@ -1150,6 +1150,7 @@ class GoLanguage: def __str__(self): return 'go' + class NodeLanguage: def __init__(self, node_purejs=False): @@ -1163,7 +1164,7 @@ class NodeLanguage: def worker_port_offset(self): if self.node_purejs: - return 1100 + return 1100 return 1000 def scenarios(self): @@ -1246,6 +1247,7 @@ class NodeLanguage: return 'node_purejs' return 'node' + LANGUAGES = { 'c++': CXXLanguage(), 'csharp': CSharpLanguage(), From fbf3bd460b12313802b2d4a752f544dbcf241c18 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 26 Apr 2018 14:23:49 -0700 Subject: [PATCH 004/546] Fix some issues with Node benchmark scripts --- tools/run_tests/performance/build_performance.sh | 5 +++-- .../performance/build_performance_node.sh | 2 ++ tools/run_tests/performance/run_worker_node.sh | 4 +++- tools/run_tests/performance/scenario_config.py | 15 ++++++++------- 4 files changed, 16 insertions(+), 10 deletions(-) mode change 100644 => 100755 tools/run_tests/performance/build_performance_node.sh mode change 100644 => 100755 tools/run_tests/performance/run_worker_node.sh diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh index 55762c6a237..35d9e905986 100755 --- a/tools/run_tests/performance/build_performance.sh +++ b/tools/run_tests/performance/build_performance.sh @@ -55,10 +55,11 @@ do "csharp") python tools/run_tests/run_tests.py -l "$language" -c "$CONFIG" --build_only -j 8 --compiler coreclr ;; + "node"|"node_purejs") + tools/run_tests/performance/build_performance_node.sh + ;; *) python tools/run_tests/run_tests.py -l "$language" -c "$CONFIG" --build_only -j 8 ;; - "node") - tools/run_tests/performance/build_performance_node.sh esac done diff --git a/tools/run_tests/performance/build_performance_node.sh b/tools/run_tests/performance/build_performance_node.sh old mode 100644 new mode 100755 index 1e3f5df2305..74adde91f34 --- a/tools/run_tests/performance/build_performance_node.sh +++ b/tools/run_tests/performance/build_performance_node.sh @@ -15,6 +15,8 @@ set +ex +. "$HOME/.nvm/nvm.sh" + nvm install 9 set -ex diff --git a/tools/run_tests/performance/run_worker_node.sh b/tools/run_tests/performance/run_worker_node.sh old mode 100644 new mode 100755 index 2511522c711..a9bbdccbc1c --- a/tools/run_tests/performance/run_worker_node.sh +++ b/tools/run_tests/performance/run_worker_node.sh @@ -13,6 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +. "$HOME/.nvm/nvm.sh" + nvm use 9 set -ex @@ -27,4 +29,4 @@ cd "$(dirname "$0")/../../.." # Enter the grpc-node repo root (expected to be next to grpc repo root) cd ../grpc-node -node -r "test/fixtures/$fixture.js" tools/run_tests/performance/worker.js "$@" +node -r "./test/fixtures/$fixture" test/performance/worker.js "$@" diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py index dde299ae36b..bd65b829459 100644 --- a/tools/run_tests/performance/scenario_config.py +++ b/tools/run_tests/performance/scenario_config.py @@ -1160,7 +1160,8 @@ class NodeLanguage: def worker_cmdline(self): fixture = 'native_js' if self.node_purejs else 'native_native' - return ['tools/run_tests/performance/run_worker_node.sh', fixture] + return ['tools/run_tests/performance/run_worker_node.sh', fixture, + '--benchmark_impl=grpc'] def worker_port_offset(self): if self.node_purejs: @@ -1175,7 +1176,7 @@ class NodeLanguage: yield _ping_pong_scenario( '%s_to_node_generic_async_streaming_ping_pong_%s' % - (secstr, node_implementation), + (node_implementation, secstr), rpc_type='STREAMING', client_type='ASYNC_CLIENT', server_type='ASYNC_GENERIC_SERVER', @@ -1187,7 +1188,7 @@ class NodeLanguage: yield _ping_pong_scenario( '%s_to_node_protobuf_async_streaming_ping_pong_%s' % - (secstr, node_implementation), + (node_implementation, secstr), rpc_type='STREAMING', client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER', @@ -1197,7 +1198,7 @@ class NodeLanguage: yield _ping_pong_scenario( '%s_to_node_protobuf_async_unary_ping_pong_%s' % - (secstr, node_implementation), + (node_implementation, secstr), rpc_type='UNARY', client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER', @@ -1208,7 +1209,7 @@ class NodeLanguage: yield _ping_pong_scenario( '%s_to_node_protobuf_async_unary_qps_unconstrained_%s' % - (secstr, node_implementation), + (node_implementation, secstr), rpc_type='UNARY', client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER', @@ -1219,7 +1220,7 @@ class NodeLanguage: yield _ping_pong_scenario( '%s_to_node_protobuf_async_streaming_qps_unconstrained_%s' % - (secstr, node_implementation), + (node_implementation, secstr), rpc_type='STREAMING', client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER', @@ -1230,7 +1231,7 @@ class NodeLanguage: yield _ping_pong_scenario( '%s_to_node_generic_async_streaming_qps_unconstrained_%s' % - (secstr, node_implementation), + (node_implementation, secstr), rpc_type='STREAMING', client_type='ASYNC_CLIENT', server_type='ASYNC_GENERIC_SERVER', From cc8b0c0ab4592bddd3e6d2c715a5f9f0f4b2aa3f Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 26 Apr 2018 14:46:06 -0700 Subject: [PATCH 005/546] Add node to performace test runner script --- tools/internal_ci/linux/grpc_full_performance_master.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/linux/grpc_full_performance_master.sh b/tools/internal_ci/linux/grpc_full_performance_master.sh index 4eddc187314..24ee71edd1b 100755 --- a/tools/internal_ci/linux/grpc_full_performance_master.sh +++ b/tools/internal_ci/linux/grpc_full_performance_master.sh @@ -21,7 +21,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_perf_multilang_rc # run 8core client vs 8core server tools/run_tests/run_performance_tests.py \ - -l c++ csharp ruby java python go php7 php7_protobuf_c \ + -l c++ csharp ruby java python go php7 php7_protobuf_c node node_purejs \ --netperf \ --category scalable \ --remote_worker_host grpc-kokoro-performance-server-8core grpc-kokoro-performance-client-8core grpc-kokoro-performance-client2-8core \ From c44cda2c3d98485a7709270cddb94d6645fbead0 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 26 Apr 2018 15:08:54 -0700 Subject: [PATCH 006/546] Reformat script code --- tools/run_tests/performance/scenario_config.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py index bd65b829459..2e78bd07fb2 100644 --- a/tools/run_tests/performance/scenario_config.py +++ b/tools/run_tests/performance/scenario_config.py @@ -1160,8 +1160,10 @@ class NodeLanguage: def worker_cmdline(self): fixture = 'native_js' if self.node_purejs else 'native_native' - return ['tools/run_tests/performance/run_worker_node.sh', fixture, - '--benchmark_impl=grpc'] + return [ + 'tools/run_tests/performance/run_worker_node.sh', fixture, + '--benchmark_impl=grpc' + ] def worker_port_offset(self): if self.node_purejs: From 07c7eda3e3bfbb2c2d33f8083515d218752506a7 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 30 Apr 2018 14:20:28 -0700 Subject: [PATCH 007/546] Add node repo to repo archive --- tools/run_tests/run_performance_tests.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py index 9a9f74e9e5a..e77bdbaa486 100755 --- a/tools/run_tests/run_performance_tests.py +++ b/tools/run_tests/run_performance_tests.py @@ -194,6 +194,8 @@ def archive_repo(languages): cmdline.append('../grpc-java') if 'go' in languages: cmdline.append('../grpc-go') + if 'node' in languages or 'node_purejs' in languages: + cmdline.append('../grpc-node') archive_job = jobset.JobSpec( cmdline=cmdline, shortname='archive_repo', timeout_seconds=3 * 60) From f2177c735f12980fa20aeb57876e87f9e8539f28 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 1 May 2018 11:03:22 -0700 Subject: [PATCH 008/546] Increase build timeouts to account for Node build --- tools/run_tests/run_performance_tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py index e77bdbaa486..cfe7bfc6182 100755 --- a/tools/run_tests/run_performance_tests.py +++ b/tools/run_tests/run_performance_tests.py @@ -249,9 +249,9 @@ def build_on_remote_hosts(hosts, languages=scenario_config.LANGUAGES.keys(), build_local=False): """Builds performance worker on remote hosts (and maybe also locally).""" - build_timeout = 15 * 60 + build_timeout = 30 * 60 # Kokoro VMs (which are local only) do not have caching, so they need more time to build - local_build_timeout = 30 * 60 + local_build_timeout = 45 * 60 build_jobs = [] for host in hosts: user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, host) From 520b2a0786494ff530b7a91d616c255a33e940a8 Mon Sep 17 00:00:00 2001 From: ganmacs Date: Wed, 16 May 2018 00:26:11 +0900 Subject: [PATCH 009/546] Fix a error message To match the name with the code in #parse_args method. --- src/ruby/pb/test/client.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb index 1b9d7cbbe61..7ac12c39a51 100755 --- a/src/ruby/pb/test/client.rb +++ b/src/ruby/pb/test/client.rb @@ -95,7 +95,7 @@ end # creates a test stub that accesses host:port securely. def create_stub(opts) - address = "#{opts.host}:#{opts.port}" + address = "#{opts.server_host}:#{opts.server_port}" # Provide channel args that request compression by default # for compression interop tests @@ -703,8 +703,8 @@ class NamedTests end # Args is used to hold the command line info. -Args = Struct.new(:default_service_account, :host, :host_override, - :oauth_scope, :port, :secure, :test_case, +Args = Struct.new(:default_service_account, :server_host, :host_override, + :oauth_scope, :server_port, :secure, :test_case, :use_test_ca) # validates the command line options, returning them as a Hash. @@ -715,7 +715,7 @@ def parse_args opts.on('--oauth_scope scope', 'Scope for OAuth tokens') { |v| args['oauth_scope'] = v } opts.on('--server_host SERVER_HOST', 'server hostname') do |v| - args['host'] = v + args['server_host'] = v end opts.on('--default_service_account email_address', 'email address of the default service account') do |v| @@ -725,7 +725,9 @@ def parse_args 'override host via a HTTP header') do |v| args['host_override'] = v end - opts.on('--server_port SERVER_PORT', 'server port') { |v| args['port'] = v } + opts.on('--server_port SERVER_PORT', 'server port') do |v| + args['server_port'] = v + end # instance_methods(false) gives only the methods defined in that class test_cases = NamedTests.instance_methods(false).map(&:to_s) test_case_list = test_cases.join(',') @@ -744,7 +746,7 @@ def parse_args end def _check_args(args) - %w(host port test_case).each do |a| + %w(server_host server_port test_case).each do |a| if args[a].nil? fail(OptionParser::MissingArgument, "please specify --#{a}") end From 87daf00f437b2bc9fb3c2ab662e7f7105e3dfccb Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Fri, 8 Jun 2018 13:50:32 -0700 Subject: [PATCH 010/546] Simplify call error/status aggregation --- .../message_size/message_size_filter.cc | 38 +- src/core/lib/surface/call.cc | 341 +++++------------- 2 files changed, 135 insertions(+), 244 deletions(-) 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 c7fc3f2e627..3cd569b5da4 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -99,10 +99,15 @@ struct call_data { // recv_message_ready up-call on transport_stream_op, and remember to // call our next_recv_message_ready member after handling it. grpc_closure recv_message_ready; + grpc_closure recv_trailing_metadata; + // The error caused by a message that is too large, or GRPC_ERROR_NONE + grpc_error* error; // Used by recv_message_ready. grpc_core::OrphanablePtr* recv_message; // Original recv_message_ready callback, invoked after our own. grpc_closure* next_recv_message_ready; + // Original recv_trailing_metadata callback, invoked after our own. + grpc_closure* next_recv_trailing_metadata; }; struct channel_data { @@ -130,6 +135,8 @@ static void recv_message_ready(void* user_data, grpc_error* error) { grpc_error* new_error = grpc_error_set_int( GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED); + GRPC_ERROR_UNREF(calld->error); + calld->error = GRPC_ERROR_REF(new_error); if (error == GRPC_ERROR_NONE) { error = new_error; } else { @@ -144,6 +151,23 @@ static void recv_message_ready(void* user_data, grpc_error* error) { GRPC_CLOSURE_RUN(calld->next_recv_message_ready, error); } +// Callback invoked on completion of recv_trailing_metadata +// Notifies the recv_trailing_metadata batch of any message size failures +static void recv_trailing_metadata(void* user_data, grpc_error* error) { + grpc_call_element* elem = (grpc_call_element*)user_data; + call_data* calld = (call_data*)elem->call_data; + if (error == GRPC_ERROR_NONE) { + error = calld->error; + } else if (calld->error == GRPC_ERROR_NONE) { + error = GRPC_ERROR_REF(error); + } else if (calld->error != error) { + error = grpc_error_add_child(GRPC_ERROR_REF(error), calld->error); + } + calld->error = GRPC_ERROR_NONE; + // Invoke the next callback. + GRPC_CLOSURE_RUN(calld->next_recv_trailing_metadata, error); +} + // Start transport stream op. static void start_transport_stream_op_batch( grpc_call_element* elem, grpc_transport_stream_op_batch* op) { @@ -172,6 +196,11 @@ static void start_transport_stream_op_batch( calld->recv_message = op->payload->recv_message.recv_message; op->payload->recv_message.recv_message_ready = &calld->recv_message_ready; } + // Inject callback for receiving trailing metadata. + if (op->recv_trailing_metadata) { + calld->next_recv_trailing_metadata = op->on_complete; + op->on_complete = &calld->recv_trailing_metadata; + } // Chain to the next filter. grpc_call_next_op(elem, op); } @@ -183,8 +212,12 @@ static grpc_error* init_call_elem(grpc_call_element* elem, call_data* calld = static_cast(elem->call_data); calld->call_combiner = args->call_combiner; calld->next_recv_message_ready = nullptr; + calld->next_recv_trailing_metadata = nullptr; + calld->error = GRPC_ERROR_NONE; GRPC_CLOSURE_INIT(&calld->recv_message_ready, recv_message_ready, elem, grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata, recv_trailing_metadata, + elem, grpc_schedule_on_exec_ctx); // Get max sizes from channel data, then merge in per-method config values. // Note: Per-method config is only available on the client, so we // apply the max request size to the send limit and the max response @@ -213,7 +246,10 @@ static grpc_error* init_call_elem(grpc_call_element* elem, // Destructor for call_data. static void destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, - grpc_closure* ignored) {} + grpc_closure* ignored) { + call_data* calld = (call_data*)elem->call_data; + GRPC_ERROR_UNREF(calld->error); +} static int default_size(const grpc_channel_args* args, int without_minimal_stack) { diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 1cf8ea94e75..e012244b0f4 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -70,46 +70,6 @@ // Used to create arena for the first call. #define ESTIMATED_MDELEM_COUNT 16 -/* Status data for a request can come from several sources; this - enumerates them all, and acts as a priority sorting for which - status to return to the application - earlier entries override - later ones */ -typedef enum { - /* Status came from the application layer overriding whatever - the wire says */ - STATUS_FROM_API_OVERRIDE = 0, - /* Status came from 'the wire' - or somewhere below the surface - layer */ - STATUS_FROM_WIRE, - /* Status was created by some internal channel stack operation: must come via - add_batch_error */ - STATUS_FROM_CORE, - /* Status was created by some surface error */ - STATUS_FROM_SURFACE, - /* Status came from the server sending status */ - STATUS_FROM_SERVER_STATUS, - STATUS_SOURCE_COUNT -} status_source; - -typedef struct { - bool is_set; - grpc_error* error; -} received_status; - -static gpr_atm pack_received_status(received_status r) { - return r.is_set ? (1 | (gpr_atm)r.error) : 0; -} - -static received_status unpack_received_status(gpr_atm atm) { - if ((atm & 1) == 0) { - return {false, GRPC_ERROR_NONE}; - } else { - return {true, (grpc_error*)(atm & ~static_cast(1))}; - } -} - -#define MAX_ERRORS_PER_BATCH 4 - typedef struct batch_control { grpc_call* call; /* Share memory for cq_completion and notify_tag as they are never needed @@ -134,10 +94,7 @@ typedef struct batch_control { grpc_closure start_batch; grpc_closure finish_batch; gpr_refcount steps_to_complete; - - grpc_error* errors[MAX_ERRORS_PER_BATCH]; - gpr_atm num_errors; - + grpc_error* batch_error; grpc_transport_stream_op_batch op; } batch_control; @@ -200,9 +157,6 @@ struct grpc_call { // A char* indicating the peer name. gpr_atm peer_string; - /* Packed received call statuses from various sources */ - gpr_atm status[STATUS_SOURCE_COUNT]; - /* Call data useful used for reporting. Only valid after the call has * completed */ grpc_call_final_info final_info; @@ -234,6 +188,7 @@ struct grpc_call { grpc_closure receiving_stream_ready; grpc_closure receiving_initial_metadata_ready; uint32_t test_only_last_message_flags; + bool cancelled; grpc_closure release_call; @@ -247,6 +202,7 @@ struct grpc_call { int* cancelled; } server; } final_op; + grpc_error* status_error; /* recv_state can contain one of the following values: RECV_NONE : : no initial metadata and messages received @@ -279,23 +235,15 @@ grpc_core::TraceFlag grpc_compression_trace(false, "compression"); static void execute_batch(grpc_call* call, grpc_transport_stream_op_batch* op, grpc_closure* start_batch_closure); -static void cancel_with_status(grpc_call* c, status_source source, - grpc_status_code status, + +static void cancel_with_status(grpc_call* c, grpc_status_code status, const char* description); -static void cancel_with_error(grpc_call* c, status_source source, - grpc_error* error); +static void cancel_with_error(grpc_call* c, grpc_error* error); static void destroy_call(void* call_stack, grpc_error* error); static void receiving_slice_ready(void* bctlp, grpc_error* error); -static void get_final_status( - grpc_call* call, void (*set_value)(grpc_status_code code, void* user_data), - void* set_value_user_data, grpc_slice* details, const char** error_string); -static void set_status_value_directly(grpc_status_code status, void* dest); -static void set_status_from_error(grpc_call* call, status_source source, - grpc_error* error); +static void set_final_status(grpc_call* call, grpc_error* error); static void process_data_after_md(batch_control* bctl); static void post_batch_completion(batch_control* bctl); -static void add_batch_error(batch_control* bctl, grpc_error* error, - bool has_cancelled); static void add_init_error(grpc_error** composite, grpc_error* new_err) { if (new_err == GRPC_ERROR_NONE) return; @@ -456,10 +404,10 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, gpr_mu_unlock(&pc->child_list_mu); } if (error != GRPC_ERROR_NONE) { - cancel_with_error(call, STATUS_FROM_SURFACE, GRPC_ERROR_REF(error)); + cancel_with_error(call, GRPC_ERROR_REF(error)); } if (immediately_cancel) { - cancel_with_error(call, STATUS_FROM_API_OVERRIDE, GRPC_ERROR_CANCELLED); + cancel_with_error(call, GRPC_ERROR_CANCELLED); } if (args->cq != nullptr) { GPR_ASSERT(args->pollset_set_alternative == nullptr && @@ -520,7 +468,6 @@ static void release_call(void* call, grpc_error* error) { GRPC_CHANNEL_INTERNAL_UNREF(channel, "call"); } -static void set_status_value_directly(grpc_status_code status, void* dest); static void destroy_call(void* call, grpc_error* error) { GPR_TIMER_SCOPE("destroy_call", 0); size_t i; @@ -547,16 +494,14 @@ static void destroy_call(void* call, grpc_error* error) { GRPC_CQ_INTERNAL_UNREF(c->cq, "bind"); } - get_final_status(c, set_status_value_directly, &c->final_info.final_status, - nullptr, c->final_info.error_string); + grpc_slice slice = grpc_empty_slice(); + grpc_error_get_status(c->status_error, c->send_deadline, + &c->final_info.final_status, &slice, nullptr, + c->final_info.error_string); + GRPC_ERROR_UNREF(c->status_error); c->final_info.stats.latency = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time); - for (i = 0; i < STATUS_SOURCE_COUNT; i++) { - GRPC_ERROR_UNREF( - unpack_received_status(gpr_atm_acq_load(&c->status[i])).error); - } - grpc_call_stack_destroy(CALL_STACK_FROM_CALL(c), &c->final_info, GRPC_CLOSURE_INIT(&c->release_call, release_call, c, grpc_schedule_on_exec_ctx)); @@ -594,7 +539,7 @@ void grpc_call_unref(grpc_call* c) { bool cancel = gpr_atm_acq_load(&c->any_ops_sent_atm) != 0 && gpr_atm_acq_load(&c->received_final_op_atm) == 0; if (cancel) { - cancel_with_error(c, STATUS_FROM_API_OVERRIDE, GRPC_ERROR_CANCELLED); + cancel_with_error(c, GRPC_ERROR_CANCELLED); } else { // Unset the call combiner cancellation closure. This has the // effect of scheduling the previously set cancellation closure, if @@ -609,8 +554,7 @@ grpc_call_error grpc_call_cancel(grpc_call* call, void* reserved) { GRPC_API_TRACE("grpc_call_cancel(call=%p, reserved=%p)", 2, (call, reserved)); GPR_ASSERT(!reserved); grpc_core::ExecCtx exec_ctx; - cancel_with_error(call, STATUS_FROM_API_OVERRIDE, GRPC_ERROR_CANCELLED); - + cancel_with_error(call, GRPC_ERROR_CANCELLED); return GRPC_CALL_OK; } @@ -664,8 +608,7 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call* c, "c=%p, status=%d, description=%s, reserved=%p)", 4, (c, (int)status, description, reserved)); GPR_ASSERT(reserved == nullptr); - cancel_with_status(c, STATUS_FROM_API_OVERRIDE, status, description); - + cancel_with_status(c, status, description); return GRPC_CALL_OK; } @@ -685,15 +628,18 @@ static void done_termination(void* arg, grpc_error* error) { gpr_free(state); } -static void cancel_with_error(grpc_call* c, status_source source, - grpc_error* error) { +static void cancel_with_error(grpc_call* c, grpc_error* error) { + if (c->cancelled) { + GRPC_ERROR_UNREF(error); + return; + } + c->cancelled = true; GRPC_CALL_INTERNAL_REF(c, "termination"); // Inform the call combiner of the cancellation, so that it can cancel // any in-flight asynchronous actions that may be holding the call // combiner. This ensures that the cancel_stream batch can be sent // down the filter stack in a timely manner. grpc_call_combiner_cancel(&c->call_combiner, GRPC_ERROR_REF(error)); - set_status_from_error(c, source, GRPC_ERROR_REF(error)); cancel_state* state = static_cast(gpr_malloc(sizeof(*state))); state->call = c; GRPC_CLOSURE_INIT(&state->finish_batch, done_termination, state, @@ -716,90 +662,28 @@ static grpc_error* error_from_status(grpc_status_code status, GRPC_ERROR_INT_GRPC_STATUS, status); } -static void cancel_with_status(grpc_call* c, status_source source, - grpc_status_code status, +static void cancel_with_status(grpc_call* c, grpc_status_code status, const char* description) { - cancel_with_error(c, source, error_from_status(status, description)); + cancel_with_error(c, error_from_status(status, description)); } -/******************************************************************************* - * FINAL STATUS CODE MANIPULATION - */ - -static bool get_final_status_from( - grpc_call* call, grpc_error* error, bool allow_ok_status, - void (*set_value)(grpc_status_code code, void* user_data), - void* set_value_user_data, grpc_slice* details, const char** error_string) { - grpc_status_code code; - grpc_slice slice = grpc_empty_slice(); - grpc_error_get_status(error, call->send_deadline, &code, &slice, nullptr, - error_string); - if (code == GRPC_STATUS_OK && !allow_ok_status) { - return false; - } - - set_value(code, set_value_user_data); - if (details != nullptr) { - *details = grpc_slice_ref_internal(slice); - } - return true; -} - -static void get_final_status( - grpc_call* call, void (*set_value)(grpc_status_code code, void* user_data), - void* set_value_user_data, grpc_slice* details, const char** error_string) { - int i; - received_status status[STATUS_SOURCE_COUNT]; - for (i = 0; i < STATUS_SOURCE_COUNT; i++) { - status[i] = unpack_received_status(gpr_atm_acq_load(&call->status[i])); - } +static void set_final_status(grpc_call* call, grpc_error* error) { if (grpc_call_error_trace.enabled()) { - gpr_log(GPR_INFO, "get_final_status %s", call->is_client ? "CLI" : "SVR"); - for (i = 0; i < STATUS_SOURCE_COUNT; i++) { - if (status[i].is_set) { - gpr_log(GPR_INFO, " %d: %s", i, grpc_error_string(status[i].error)); - } - } + gpr_log(GPR_DEBUG, "set_final_status %s", call->is_client ? "CLI" : "SVR"); + gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); } - /* first search through ignoring "OK" statuses: if something went wrong, - * ensure we report it */ - for (int allow_ok_status = 0; allow_ok_status < 2; allow_ok_status++) { - /* search for the best status we can present: ideally the error we use has a - clearly defined grpc-status, and we'll prefer that. */ - for (i = 0; i < STATUS_SOURCE_COUNT; i++) { - if (status[i].is_set && - grpc_error_has_clear_grpc_status(status[i].error)) { - if (get_final_status_from(call, status[i].error, allow_ok_status != 0, - set_value, set_value_user_data, details, - error_string)) { - return; - } - } - } - /* If no clearly defined status exists, search for 'anything' */ - for (i = 0; i < STATUS_SOURCE_COUNT; i++) { - if (status[i].is_set) { - if (get_final_status_from(call, status[i].error, allow_ok_status != 0, - set_value, set_value_user_data, details, - error_string)) { - return; - } - } - } - } - /* If nothing exists, set some default */ if (call->is_client) { - set_value(GRPC_STATUS_UNKNOWN, set_value_user_data); + const char** error_string = call->final_op.client.error_string; + grpc_status_code code; + grpc_slice slice = grpc_empty_slice(); + grpc_error_get_status(error, call->send_deadline, &code, &slice, nullptr, + error_string); + *call->final_op.client.status = code; + *call->final_op.client.status_details = grpc_slice_ref_internal(slice); + call->status_error = error; } else { - set_value(GRPC_STATUS_OK, set_value_user_data); - } -} - -static void set_status_from_error(grpc_call* call, status_source source, - grpc_error* error) { - if (!gpr_atm_rel_cas(&call->status[source], - pack_received_status({false, GRPC_ERROR_NONE}), - pack_received_status({true, error}))) { + *call->final_op.server.cancelled = + error != GRPC_ERROR_NONE || call->status_error != GRPC_ERROR_NONE; GRPC_ERROR_UNREF(error); } } @@ -1018,6 +902,7 @@ static grpc_stream_compression_algorithm decode_stream_compression( static void publish_app_metadata(grpc_call* call, grpc_metadata_batch* b, int is_trailing) { if (b->list.count == 0) return; + if (!call->is_client && is_trailing) return; if (is_trailing && call->buffered_metadata[1] == nullptr) return; GPR_TIMER_SCOPE("publish_app_metadata", 0); grpc_metadata_array* dest; @@ -1071,9 +956,12 @@ static void recv_initial_filter(grpc_call* call, grpc_metadata_batch* b) { publish_app_metadata(call, b, false); } -static void recv_trailing_filter(void* args, grpc_metadata_batch* b) { +static void recv_trailing_filter(void* args, grpc_metadata_batch* b, + grpc_error* batch_error) { grpc_call* call = static_cast(args); - if (b->idx.named.grpc_status != nullptr) { + if (batch_error != GRPC_ERROR_NONE) { + set_final_status(call, GRPC_ERROR_REF(batch_error)); + } else if (b->idx.named.grpc_status != nullptr) { grpc_status_code status_code = grpc_get_status_code_from_metadata(b->idx.named.grpc_status->md); grpc_error* error = @@ -1092,10 +980,16 @@ static void recv_trailing_filter(void* args, grpc_metadata_batch* b) { error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, grpc_empty_slice()); } - set_status_from_error(call, STATUS_FROM_WIRE, error); + set_final_status(call, GRPC_ERROR_REF(error)); grpc_metadata_batch_remove(b, b->idx.named.grpc_status); + GRPC_ERROR_UNREF(error); + } else { + // TODO(kpayson) batch completed successfully w/no error + no status, should + // we assert instead? + set_final_status(call, GRPC_ERROR_NONE); } publish_app_metadata(call, b, true); + GRPC_ERROR_UNREF(batch_error); } grpc_call_stack* grpc_call_get_call_stack(grpc_call* call) { @@ -1106,14 +1000,6 @@ grpc_call_stack* grpc_call_get_call_stack(grpc_call* call) { * BATCH API IMPLEMENTATION */ -static void set_status_value_directly(grpc_status_code status, void* dest) { - *static_cast(dest) = status; -} - -static void set_cancelled_value(grpc_status_code status, void* dest) { - *static_cast(dest) = (status != GRPC_STATUS_OK); -} - static bool are_write_flags_valid(uint32_t flags) { /* check that only bits in GRPC_WRITE_(INTERNAL?)_USED_MASK are set */ const uint32_t allowed_write_positions = @@ -1181,31 +1067,15 @@ static void finish_batch_completion(void* user_data, GRPC_CALL_INTERNAL_UNREF(call, "completion"); } -static grpc_error* consolidate_batch_errors(batch_control* bctl) { - size_t n = static_cast(gpr_atm_acq_load(&bctl->num_errors)); - if (n == 0) { - return GRPC_ERROR_NONE; - } else if (n == 1) { - /* Skip creating a composite error in the case that only one error was - logged */ - grpc_error* e = bctl->errors[0]; - bctl->errors[0] = nullptr; - return e; - } else { - grpc_error* error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Call batch failed", bctl->errors, n); - for (size_t i = 0; i < n; i++) { - GRPC_ERROR_UNREF(bctl->errors[i]); - bctl->errors[i] = nullptr; - } - return error; - } +static void reset_batch_errors(batch_control* bctl) { + GRPC_ERROR_UNREF(bctl->batch_error); + bctl->batch_error = GRPC_ERROR_NONE; } static void post_batch_completion(batch_control* bctl) { grpc_call* next_child_call; grpc_call* call = bctl->call; - grpc_error* error = consolidate_batch_errors(bctl); + grpc_error* error = GRPC_ERROR_REF(bctl->batch_error); if (bctl->op.send_initial_metadata) { grpc_metadata_batch_destroy( @@ -1223,7 +1093,7 @@ static void post_batch_completion(batch_control* bctl) { if (bctl->op.recv_trailing_metadata) { grpc_metadata_batch* md = &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; - recv_trailing_filter(call, md); + recv_trailing_filter(call, md, GRPC_ERROR_REF(bctl->batch_error)); /* propagate cancellation to any interested children */ gpr_atm_rel_store(&call->received_final_op_atm, 1); @@ -1237,8 +1107,7 @@ static void post_batch_completion(batch_control* bctl) { next_child_call = child->child->sibling_next; if (child->cancellation_is_inherited) { GRPC_CALL_INTERNAL_REF(child, "propagate_cancel"); - cancel_with_error(child, STATUS_FROM_API_OVERRIDE, - GRPC_ERROR_CANCELLED); + cancel_with_error(child, GRPC_ERROR_CANCELLED); GRPC_CALL_INTERNAL_UNREF(child, "propagate_cancel"); } child = next_child_call; @@ -1247,16 +1116,6 @@ static void post_batch_completion(batch_control* bctl) { gpr_mu_unlock(&pc->child_list_mu); } - if (call->is_client) { - get_final_status(call, set_status_value_directly, - call->final_op.client.status, - call->final_op.client.status_details, - call->final_op.client.error_string); - } else { - get_final_status(call, set_cancelled_value, - call->final_op.server.cancelled, nullptr, nullptr); - } - GRPC_ERROR_UNREF(error); error = GRPC_ERROR_NONE; } @@ -1265,9 +1124,10 @@ static void post_batch_completion(batch_control* bctl) { grpc_byte_buffer_destroy(*call->receiving_buffer); *call->receiving_buffer = nullptr; } + reset_batch_errors(bctl); if (bctl->completion_data.notify_tag.is_closure) { - /* unrefs bctl->error */ + /* unrefs error */ bctl->call = nullptr; /* This closure may be meant to be run within some combiner. Since we aren't * running in any combiner here, we need to use GRPC_CLOSURE_SCHED instead @@ -1277,7 +1137,7 @@ static void post_batch_completion(batch_control* bctl) { error); GRPC_CALL_INTERNAL_UNREF(call, "completion"); } else { - /* unrefs bctl->error */ + /* unrefs error */ grpc_cq_end_op(bctl->call->cq, bctl->completion_data.notify_tag.tag, error, finish_batch_completion, bctl, &bctl->completion_data.cq_completion); @@ -1386,8 +1246,10 @@ static void receiving_stream_ready(void* bctlp, grpc_error* error) { grpc_call* call = bctl->call; if (error != GRPC_ERROR_NONE) { call->receiving_stream.reset(); - add_batch_error(bctl, GRPC_ERROR_REF(error), true); - cancel_with_error(call, STATUS_FROM_SURFACE, GRPC_ERROR_REF(error)); + if (bctl->batch_error == GRPC_ERROR_NONE) { + bctl->batch_error = GRPC_ERROR_REF(error); + } + cancel_with_error(call, GRPC_ERROR_REF(error)); } /* If recv_state is RECV_NONE, we will save the batch_control * object with rel_cas, and will not use it after the cas. Its corresponding @@ -1423,8 +1285,7 @@ static void validate_filtered_metadata(batch_control* bctl) { call->incoming_stream_compression_algorithm, call->incoming_message_compression_algorithm); gpr_log(GPR_ERROR, "%s", error_msg); - cancel_with_status(call, STATUS_FROM_SURFACE, GRPC_STATUS_INTERNAL, - error_msg); + cancel_with_status(call, GRPC_STATUS_INTERNAL, error_msg); gpr_free(error_msg); } else if ( grpc_compression_algorithm_from_message_stream_compression_algorithm( @@ -1436,8 +1297,7 @@ static void validate_filtered_metadata(batch_control* bctl) { "compression (%d).", call->incoming_stream_compression_algorithm, call->incoming_message_compression_algorithm); - cancel_with_status(call, STATUS_FROM_SURFACE, GRPC_STATUS_INTERNAL, - error_msg); + cancel_with_status(call, GRPC_STATUS_INTERNAL, error_msg); gpr_free(error_msg); } else { char* error_msg = nullptr; @@ -1447,8 +1307,7 @@ static void validate_filtered_metadata(batch_control* bctl) { gpr_asprintf(&error_msg, "Invalid compression algorithm value '%d'.", compression_algorithm); gpr_log(GPR_ERROR, "%s", error_msg); - cancel_with_status(call, STATUS_FROM_SURFACE, GRPC_STATUS_UNIMPLEMENTED, - error_msg); + cancel_with_status(call, GRPC_STATUS_UNIMPLEMENTED, error_msg); } else if (grpc_compression_options_is_algorithm_enabled( &compression_options, compression_algorithm) == 0) { /* check if algorithm is supported by current channel config */ @@ -1457,8 +1316,7 @@ static void validate_filtered_metadata(batch_control* bctl) { gpr_asprintf(&error_msg, "Compression algorithm '%s' is disabled.", algo_name); gpr_log(GPR_ERROR, "%s", error_msg); - cancel_with_status(call, STATUS_FROM_SURFACE, GRPC_STATUS_UNIMPLEMENTED, - error_msg); + cancel_with_status(call, GRPC_STATUS_UNIMPLEMENTED, error_msg); } gpr_free(error_msg); @@ -1476,23 +1334,12 @@ static void validate_filtered_metadata(batch_control* bctl) { } } -static void add_batch_error(batch_control* bctl, grpc_error* error, - bool has_cancelled) { - if (error == GRPC_ERROR_NONE) return; - int idx = static_cast(gpr_atm_full_fetch_add(&bctl->num_errors, 1)); - if (idx == 0 && !has_cancelled) { - cancel_with_error(bctl->call, STATUS_FROM_CORE, GRPC_ERROR_REF(error)); - } - bctl->errors[idx] = error; -} - static void receiving_initial_metadata_ready(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; GRPC_CALL_COMBINER_STOP(&call->call_combiner, "recv_initial_metadata_ready"); - add_batch_error(bctl, GRPC_ERROR_REF(error), false); if (error == GRPC_ERROR_NONE) { grpc_metadata_batch* md = &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */]; @@ -1505,6 +1352,11 @@ static void receiving_initial_metadata_ready(void* bctlp, grpc_error* error) { if (md->deadline != GRPC_MILLIS_INF_FUTURE && !call->is_client) { call->send_deadline = md->deadline; } + } else { + if (bctl->batch_error == GRPC_ERROR_NONE) { + bctl->batch_error = GRPC_ERROR_REF(error); + } + cancel_with_error(call, GRPC_ERROR_REF(error)); } grpc_closure* saved_rsr_closure = nullptr; @@ -1542,7 +1394,12 @@ static void finish_batch(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; GRPC_CALL_COMBINER_STOP(&call->call_combiner, "on_complete"); - add_batch_error(bctl, GRPC_ERROR_REF(error), false); + if (bctl->batch_error == GRPC_ERROR_NONE) { + bctl->batch_error = GRPC_ERROR_REF(error); + } + if (error != GRPC_ERROR_NONE) { + cancel_with_error(call, GRPC_ERROR_REF(error)); + } finish_batch_step(bctl); } @@ -1740,28 +1597,26 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, call->send_extra_metadata_count = 1; call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem( call->channel, op->data.send_status_from_server.status); - { - grpc_error* override_error = GRPC_ERROR_NONE; - if (op->data.send_status_from_server.status != GRPC_STATUS_OK) { - override_error = - error_from_status(op->data.send_status_from_server.status, - "Returned non-ok status"); - } - if (op->data.send_status_from_server.status_details != nullptr) { - call->send_extra_metadata[1].md = grpc_mdelem_from_slices( - GRPC_MDSTR_GRPC_MESSAGE, - grpc_slice_ref_internal( - *op->data.send_status_from_server.status_details)); - call->send_extra_metadata_count++; - char* msg = grpc_slice_to_c_string( - GRPC_MDVALUE(call->send_extra_metadata[1].md)); - override_error = - grpc_error_set_str(override_error, GRPC_ERROR_STR_GRPC_MESSAGE, - grpc_slice_from_copied_string(msg)); - gpr_free(msg); - } - set_status_from_error(call, STATUS_FROM_API_OVERRIDE, override_error); + if (op->data.send_status_from_server.status_details != nullptr) { + call->send_extra_metadata[1].md = grpc_mdelem_from_slices( + GRPC_MDSTR_GRPC_MESSAGE, + grpc_slice_ref_internal( + *op->data.send_status_from_server.status_details)); + call->send_extra_metadata_count++; + char* msg = grpc_slice_to_c_string( + GRPC_MDVALUE(call->send_extra_metadata[1].md)); + gpr_free(msg); } + grpc_error* status_error = + op->data.send_status_from_server.status == GRPC_STATUS_OK + ? GRPC_ERROR_NONE + : grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Server returned error"), + GRPC_ERROR_INT_GRPC_STATUS, + static_cast( + op->data.send_status_from_server.status)); + call->status_error = status_error; if (!prepare_application_metadata( call, static_cast( From 9324ac67287936619199c03755c54af8da6a3486 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 19 Jun 2018 14:24:37 -0700 Subject: [PATCH 011/546] Regenerate build files --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6371521f6a5..ab7ae5b4003 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7511,6 +7511,7 @@ target_include_directories(handshake_verify_peer_options PRIVATE ${_gRPC_CARES_INCLUDE_DIR} PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) target_link_libraries(handshake_verify_peer_options From e670c3754c56f3d2cd1612df95953508e299a5a1 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Tue, 19 Jun 2018 23:16:42 -0700 Subject: [PATCH 012/546] Minor bug in timer code during shutdown --- src/core/lib/iomgr/timer_generic.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/timer_generic.cc b/src/core/lib/iomgr/timer_generic.cc index 4294162af7c..70417d69b63 100644 --- a/src/core/lib/iomgr/timer_generic.cc +++ b/src/core/lib/iomgr/timer_generic.cc @@ -291,7 +291,7 @@ static void timer_list_init() { static void timer_list_shutdown() { size_t i; run_some_expired_timers( - GPR_ATM_MAX, nullptr, + GRPC_MILLIS_INF_FUTURE, nullptr, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Timer list shutdown")); for (i = 0; i < g_num_shards; i++) { timer_shard* shard = &g_shards[i]; @@ -714,7 +714,7 @@ static grpc_timer_check_result timer_check(grpc_millis* next) { #if GPR_ARCH_64 gpr_log(GPR_INFO, "TIMER CHECK BEGIN: now=%" PRId64 " next=%s tls_min=%" PRId64 - " glob_min=%" PRIdPTR, + " glob_min=%" PRId64, now, next_str, min_timer, gpr_atm_no_barrier_load((gpr_atm*)(&g_shared_mutables.min_timer))); #else From dd0995d0159169d23f92eaf1df228033c337866c Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Thu, 21 Jun 2018 17:22:09 -0700 Subject: [PATCH 013/546] Changes --- .../filters/http/client/http_client_filter.cc | 14 ++++++- .../filters/http/server/http_server_filter.cc | 30 +++++++++++++++ .../message_size/message_size_filter.cc | 38 ++++++++++--------- src/core/lib/surface/call.cc | 16 ++++++++ 4 files changed, 79 insertions(+), 19 deletions(-) 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 1678051beb1..eadb9db1be8 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -51,6 +51,7 @@ struct call_data { grpc_linked_mdelem user_agent; // State for handling recv_initial_metadata ops. grpc_metadata_batch* recv_initial_metadata; + grpc_error* recv_initial_metadata_error; grpc_closure* original_recv_initial_metadata_ready; grpc_closure recv_initial_metadata_ready; // State for handling recv_trailing_metadata ops. @@ -147,6 +148,7 @@ static void recv_initial_metadata_ready(void* user_data, grpc_error* error) { call_data* calld = static_cast(elem->call_data); if (error == GRPC_ERROR_NONE) { error = client_filter_incoming_metadata(elem, calld->recv_initial_metadata); + calld->recv_initial_metadata_error = GRPC_ERROR_REF(error); } else { GRPC_ERROR_REF(error); } @@ -162,6 +164,13 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { } else { GRPC_ERROR_REF(error); } + if (calld->recv_initial_metadata_error != GRPC_ERROR_NONE) { + if (error == GRPC_ERROR_NONE) { + error = GRPC_ERROR_REF(calld->recv_initial_metadata_error); + } else { + error = grpc_error_add_child(error, calld->recv_initial_metadata_error); + } + } GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, error); } @@ -434,7 +443,10 @@ static grpc_error* init_call_elem(grpc_call_element* elem, /* Destructor for call_data */ static void destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, - grpc_closure* ignored) {} + grpc_closure* ignored) { + call_data* calld = static_cast(elem->call_data); + GRPC_ERROR_UNREF(calld->recv_initial_metadata_error); +} static grpc_mdelem scheme_from_args(const grpc_channel_args* args) { unsigned i; 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 3919447f264..48eeb9212c6 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -50,6 +50,7 @@ struct call_data { // State for intercepting recv_initial_metadata. grpc_closure recv_initial_metadata_ready; + grpc_error* recv_initial_metadata_ready_error; grpc_closure* original_recv_initial_metadata_ready; grpc_metadata_batch* recv_initial_metadata; uint32_t* recv_initial_metadata_flags; @@ -60,6 +61,9 @@ struct call_data { grpc_closure recv_message_ready; grpc_core::OrphanablePtr* recv_message; bool seen_recv_message_ready; + + grpc_closure recv_trailing_metadata_ready; + grpc_closure* original_recv_trailing_metadata_ready; }; } // namespace @@ -267,6 +271,7 @@ static void hs_recv_initial_metadata_ready(void* user_data, grpc_error* err) { calld->seen_recv_initial_metadata_ready = true; if (err == GRPC_ERROR_NONE) { err = hs_filter_incoming_metadata(elem, calld->recv_initial_metadata); + calld->recv_initial_metadata_ready_error = GRPC_ERROR_REF(err); if (calld->seen_recv_message_ready) { // We've already seen the recv_message callback, but we previously // deferred it, so we need to return it here. @@ -313,6 +318,22 @@ static void hs_recv_message_ready(void* user_data, grpc_error* err) { } } +static void hs_recv_trailing_metadata_ready(void* user_data, grpc_error* err) { + grpc_call_element* elem = static_cast(user_data); + call_data* calld = static_cast(elem->call_data); + if (calld->recv_initial_metadata_ready_error != GRPC_ERROR_NONE) { + if (err == GRPC_ERROR_NONE) { + err = GRPC_ERROR_REF(calld->recv_initial_metadata_ready_error); + } else { + err = grpc_error_add_child(err, calld->recv_initial_metadata_ready_error); + } + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); + } else { + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, + GRPC_ERROR_REF(err)); + } +} + static grpc_error* hs_mutate_op(grpc_call_element* elem, grpc_transport_stream_op_batch* op) { /* grab pointers to our data from the call element */ @@ -357,6 +378,11 @@ static grpc_error* hs_mutate_op(grpc_call_element* elem, op->payload->recv_message.recv_message_ready = &calld->recv_message_ready; } + if (op->recv_trailing_metadata) { + calld->original_recv_trailing_metadata_ready = + op->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + } + if (op->send_trailing_metadata) { grpc_error* error = hs_filter_outgoing_metadata( elem, op->payload->send_trailing_metadata.send_trailing_metadata); @@ -389,6 +415,9 @@ static grpc_error* hs_init_call_elem(grpc_call_element* elem, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&calld->recv_message_ready, hs_recv_message_ready, elem, grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, + hs_recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); return GRPC_ERROR_NONE; } @@ -397,6 +426,7 @@ static void hs_destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, grpc_closure* ignored) { call_data* calld = static_cast(elem->call_data); + GRPC_ERROR_UNREF(calld->recv_initial_metadata_ready_error); if (calld->have_read_stream) { calld->read_stream->Orphan(); } 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 a859476dab0..f3081df38db 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -99,7 +99,7 @@ struct call_data { // recv_message_ready up-call on transport_stream_op, and remember to // call our next_recv_message_ready member after handling it. grpc_closure recv_message_ready; - grpc_closure recv_trailing_metadata; + grpc_closure recv_trailing_metadata_ready; // The error caused by a message that is too large, or GRPC_ERROR_NONE grpc_error* error; // Used by recv_message_ready. @@ -107,7 +107,7 @@ struct call_data { // Original recv_message_ready callback, invoked after our own. grpc_closure* next_recv_message_ready; // Original recv_trailing_metadata callback, invoked after our own. - grpc_closure* next_recv_trailing_metadata; + grpc_closure* next_recv_trailing_metadata_ready; }; struct channel_data { @@ -136,13 +136,13 @@ static void recv_message_ready(void* user_data, grpc_error* error) { GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED); GRPC_ERROR_UNREF(calld->error); - calld->error = GRPC_ERROR_REF(new_error); if (error == GRPC_ERROR_NONE) { error = new_error; } else { error = grpc_error_add_child(error, new_error); GRPC_ERROR_UNREF(new_error); } + calld->error = GRPC_ERROR_REF(error); gpr_free(message_string); } else { GRPC_ERROR_REF(error); @@ -153,19 +153,20 @@ static void recv_message_ready(void* user_data, grpc_error* error) { // Callback invoked on completion of recv_trailing_metadata // Notifies the recv_trailing_metadata batch of any message size failures -static void recv_trailing_metadata(void* user_data, grpc_error* error) { - grpc_call_element* elem = (grpc_call_element*)user_data; - call_data* calld = (call_data*)elem->call_data; - if (error == GRPC_ERROR_NONE) { - error = calld->error; - } else if (calld->error == GRPC_ERROR_NONE) { +static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { + grpc_call_element* elem = static_cast(user_data); + call_data* calld = static_cast(elem->call_data); + if (calld->error != GRPC_ERROR_NONE) { + if (error == GRPC_ERROR_NONE) { + error = GRPC_ERROR_REF(calld->error); + } else { + error = grpc_error_add_child(error, calld->error); + } + } else { error = GRPC_ERROR_REF(error); - } else if (calld->error != error) { - error = grpc_error_add_child(GRPC_ERROR_REF(error), calld->error); } - calld->error = GRPC_ERROR_NONE; // Invoke the next callback. - GRPC_CLOSURE_RUN(calld->next_recv_trailing_metadata, error); + GRPC_CLOSURE_RUN(calld->next_recv_trailing_metadata_ready, error); } // Start transport stream op. @@ -198,10 +199,10 @@ static void start_transport_stream_op_batch( } // Inject callback for receiving trailing metadata. if (op->recv_trailing_metadata) { - calld->next_recv_trailing_metadata = + calld->next_recv_trailing_metadata_ready = op->payload->recv_trailing_metadata.recv_trailing_metadata_ready; op->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &calld->recv_trailing_metadata; + &calld->recv_trailing_metadata_ready; } // Chain to the next filter. grpc_call_next_op(elem, op); @@ -214,12 +215,13 @@ static grpc_error* init_call_elem(grpc_call_element* elem, call_data* calld = static_cast(elem->call_data); calld->call_combiner = args->call_combiner; calld->next_recv_message_ready = nullptr; - calld->next_recv_trailing_metadata = nullptr; + calld->next_recv_trailing_metadata_ready = nullptr; calld->error = GRPC_ERROR_NONE; GRPC_CLOSURE_INIT(&calld->recv_message_ready, recv_message_ready, elem, grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata, recv_trailing_metadata, - elem, grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, + recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); // Get max sizes from channel data, then merge in per-method config values. // Note: Per-method config is only available on the client, so we // apply the max request size to the send limit and the max response diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index eae01106355..38a00b8b67e 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -689,6 +689,8 @@ static void set_final_status(grpc_call* call, grpc_error* error) { gpr_log(GPR_DEBUG, "set_final_status %s", call->is_client ? "CLI" : "SVR"); gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); } + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(call->channel); if (call->is_client) { const char** error_string = call->final_op.client.error_string; grpc_status_code code; @@ -698,9 +700,23 @@ static void set_final_status(grpc_call* call, grpc_error* error) { *call->final_op.client.status = code; *call->final_op.client.status_details = grpc_slice_ref_internal(slice); call->status_error = error; + if (channelz_channel != nullptr) { + if (*call->final_op.client.status != GRPC_STATUS_OK) { + channelz_channel->RecordCallFailed(); + } else { + channelz_channel->RecordCallSucceeded(); + } + } } else { *call->final_op.server.cancelled = error != GRPC_ERROR_NONE || call->status_error != GRPC_ERROR_NONE; + if (channelz_channel != nullptr) { + if (*call->final_op.server.cancelled) { + channelz_channel->RecordCallFailed(); + } else { + channelz_channel->RecordCallSucceeded(); + } + } GRPC_ERROR_UNREF(error); } } From 96c0a266a0a5f83a2bdd9678dbd05620f6380a91 Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Fri, 22 Jun 2018 13:00:07 -0700 Subject: [PATCH 014/546] Changes --- src/core/ext/filters/http/client/http_client_filter.cc | 2 +- src/core/ext/filters/http/server/http_server_filter.cc | 9 +++++---- src/core/ext/filters/message_size/message_size_filter.cc | 5 +++-- 3 files changed, 9 insertions(+), 7 deletions(-) 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 eadb9db1be8..04ac4ac947c 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -167,7 +167,7 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { if (calld->recv_initial_metadata_error != GRPC_ERROR_NONE) { if (error == GRPC_ERROR_NONE) { error = GRPC_ERROR_REF(calld->recv_initial_metadata_error); - } else { + } else if (error != calld->recv_initial_metadata_error) { error = grpc_error_add_child(error, calld->recv_initial_metadata_error); } } 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 48eeb9212c6..01e5aa445eb 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -324,14 +324,15 @@ static void hs_recv_trailing_metadata_ready(void* user_data, grpc_error* err) { if (calld->recv_initial_metadata_ready_error != GRPC_ERROR_NONE) { if (err == GRPC_ERROR_NONE) { err = GRPC_ERROR_REF(calld->recv_initial_metadata_ready_error); - } else { + } else if (err != calld->recv_initial_metadata_ready_error) { err = grpc_error_add_child(err, calld->recv_initial_metadata_ready_error); + } else { + err = GRPC_ERROR_REF(err); } - GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); } else { - GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, - GRPC_ERROR_REF(err)); + err = GRPC_ERROR_REF(err); } + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); } static grpc_error* hs_mutate_op(grpc_call_element* elem, 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 f3081df38db..deb5ae70ecc 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -140,7 +140,6 @@ static void recv_message_ready(void* user_data, grpc_error* error) { error = new_error; } else { error = grpc_error_add_child(error, new_error); - GRPC_ERROR_UNREF(new_error); } calld->error = GRPC_ERROR_REF(error); gpr_free(message_string); @@ -159,8 +158,10 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { if (calld->error != GRPC_ERROR_NONE) { if (error == GRPC_ERROR_NONE) { error = GRPC_ERROR_REF(calld->error); + } else if (error != calld->error) { + error = grpc_error_add_child(error, GRPC_ERROR_REF(calld->error)); } else { - error = grpc_error_add_child(error, calld->error); + error = GRPC_ERROR_REF(error); } } else { error = GRPC_ERROR_REF(error); From e2a9e6cf721866c17110244f9da6c37f30f1faef Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Fri, 22 Jun 2018 13:25:43 -0700 Subject: [PATCH 015/546] Changes --- src/core/lib/surface/call.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 38a00b8b67e..b97c2ec760a 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -1015,10 +1015,15 @@ static void recv_trailing_filter(void* args, grpc_metadata_batch* b, set_final_status(call, GRPC_ERROR_REF(error)); grpc_metadata_batch_remove(b, b->idx.named.grpc_status); GRPC_ERROR_UNREF(error); - } else { - // TODO(kpayson) batch completed successfully w/no error + no status, should - // we assert instead? + } else if (!call->is_client) { set_final_status(call, GRPC_ERROR_NONE); + } else { + gpr_log(GPR_DEBUG, + "Received trailing metadata with no error and no status"); + set_final_status( + call, grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("No status received"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNKNOWN)); } publish_app_metadata(call, b, true); GRPC_ERROR_UNREF(batch_error); From 2069bf520f5428a5523d3fbd34eb44d63802332e Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Mon, 25 Jun 2018 10:37:51 -0700 Subject: [PATCH 016/546] Fix tsan failure --- src/core/lib/surface/call.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index b97c2ec760a..2b451e46a19 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -189,7 +189,7 @@ struct grpc_call { grpc_closure receiving_initial_metadata_ready; grpc_closure receiving_trailing_metadata_ready; uint32_t test_only_last_message_flags; - bool cancelled; + gpr_atm cancelled; grpc_closure release_call; @@ -304,6 +304,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, gpr_arena_alloc(arena, ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + channel_stack->call_stack_size)); gpr_ref_init(&call->ext_ref, 1); + gpr_atm_no_barrier_store(&call->cancelled, 0); call->arena = arena; grpc_call_combiner_init(&call->call_combiner); *out_call = call; @@ -646,11 +647,10 @@ static void done_termination(void* arg, grpc_error* error) { } static void cancel_with_error(grpc_call* c, grpc_error* error) { - if (c->cancelled) { + if (!gpr_atm_rel_cas(&c->cancelled, 0, 1)) { GRPC_ERROR_UNREF(error); return; } - c->cancelled = true; GRPC_CALL_INTERNAL_REF(c, "termination"); // Inform the call combiner of the cancellation, so that it can cancel // any in-flight asynchronous actions that may be holding the call From a9e27ae2c4138d2bd8f9c49d999ac3adb5baabea Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Tue, 26 Jun 2018 14:51:04 -0700 Subject: [PATCH 017/546] Roll back filter changes --- .../filters/http/client/http_client_filter.cc | 14 +----- .../filters/http/server/http_server_filter.cc | 31 ------------- .../message_size/message_size_filter.cc | 45 +------------------ 3 files changed, 3 insertions(+), 87 deletions(-) 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 04ac4ac947c..1678051beb1 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -51,7 +51,6 @@ struct call_data { grpc_linked_mdelem user_agent; // State for handling recv_initial_metadata ops. grpc_metadata_batch* recv_initial_metadata; - grpc_error* recv_initial_metadata_error; grpc_closure* original_recv_initial_metadata_ready; grpc_closure recv_initial_metadata_ready; // State for handling recv_trailing_metadata ops. @@ -148,7 +147,6 @@ static void recv_initial_metadata_ready(void* user_data, grpc_error* error) { call_data* calld = static_cast(elem->call_data); if (error == GRPC_ERROR_NONE) { error = client_filter_incoming_metadata(elem, calld->recv_initial_metadata); - calld->recv_initial_metadata_error = GRPC_ERROR_REF(error); } else { GRPC_ERROR_REF(error); } @@ -164,13 +162,6 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { } else { GRPC_ERROR_REF(error); } - if (calld->recv_initial_metadata_error != GRPC_ERROR_NONE) { - if (error == GRPC_ERROR_NONE) { - error = GRPC_ERROR_REF(calld->recv_initial_metadata_error); - } else if (error != calld->recv_initial_metadata_error) { - error = grpc_error_add_child(error, calld->recv_initial_metadata_error); - } - } GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, error); } @@ -443,10 +434,7 @@ static grpc_error* init_call_elem(grpc_call_element* elem, /* Destructor for call_data */ static void destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, - grpc_closure* ignored) { - call_data* calld = static_cast(elem->call_data); - GRPC_ERROR_UNREF(calld->recv_initial_metadata_error); -} + grpc_closure* ignored) {} static grpc_mdelem scheme_from_args(const grpc_channel_args* args) { unsigned i; 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 01e5aa445eb..3919447f264 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -50,7 +50,6 @@ struct call_data { // State for intercepting recv_initial_metadata. grpc_closure recv_initial_metadata_ready; - grpc_error* recv_initial_metadata_ready_error; grpc_closure* original_recv_initial_metadata_ready; grpc_metadata_batch* recv_initial_metadata; uint32_t* recv_initial_metadata_flags; @@ -61,9 +60,6 @@ struct call_data { grpc_closure recv_message_ready; grpc_core::OrphanablePtr* recv_message; bool seen_recv_message_ready; - - grpc_closure recv_trailing_metadata_ready; - grpc_closure* original_recv_trailing_metadata_ready; }; } // namespace @@ -271,7 +267,6 @@ static void hs_recv_initial_metadata_ready(void* user_data, grpc_error* err) { calld->seen_recv_initial_metadata_ready = true; if (err == GRPC_ERROR_NONE) { err = hs_filter_incoming_metadata(elem, calld->recv_initial_metadata); - calld->recv_initial_metadata_ready_error = GRPC_ERROR_REF(err); if (calld->seen_recv_message_ready) { // We've already seen the recv_message callback, but we previously // deferred it, so we need to return it here. @@ -318,23 +313,6 @@ static void hs_recv_message_ready(void* user_data, grpc_error* err) { } } -static void hs_recv_trailing_metadata_ready(void* user_data, grpc_error* err) { - grpc_call_element* elem = static_cast(user_data); - call_data* calld = static_cast(elem->call_data); - if (calld->recv_initial_metadata_ready_error != GRPC_ERROR_NONE) { - if (err == GRPC_ERROR_NONE) { - err = GRPC_ERROR_REF(calld->recv_initial_metadata_ready_error); - } else if (err != calld->recv_initial_metadata_ready_error) { - err = grpc_error_add_child(err, calld->recv_initial_metadata_ready_error); - } else { - err = GRPC_ERROR_REF(err); - } - } else { - err = GRPC_ERROR_REF(err); - } - GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); -} - static grpc_error* hs_mutate_op(grpc_call_element* elem, grpc_transport_stream_op_batch* op) { /* grab pointers to our data from the call element */ @@ -379,11 +357,6 @@ static grpc_error* hs_mutate_op(grpc_call_element* elem, op->payload->recv_message.recv_message_ready = &calld->recv_message_ready; } - if (op->recv_trailing_metadata) { - calld->original_recv_trailing_metadata_ready = - op->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - } - if (op->send_trailing_metadata) { grpc_error* error = hs_filter_outgoing_metadata( elem, op->payload->send_trailing_metadata.send_trailing_metadata); @@ -416,9 +389,6 @@ static grpc_error* hs_init_call_elem(grpc_call_element* elem, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&calld->recv_message_ready, hs_recv_message_ready, elem, grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, - hs_recv_trailing_metadata_ready, elem, - grpc_schedule_on_exec_ctx); return GRPC_ERROR_NONE; } @@ -427,7 +397,6 @@ static void hs_destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, grpc_closure* ignored) { call_data* calld = static_cast(elem->call_data); - GRPC_ERROR_UNREF(calld->recv_initial_metadata_ready_error); if (calld->have_read_stream) { calld->read_stream->Orphan(); } 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 deb5ae70ecc..c7fc3f2e627 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -99,15 +99,10 @@ struct call_data { // recv_message_ready up-call on transport_stream_op, and remember to // call our next_recv_message_ready member after handling it. grpc_closure recv_message_ready; - grpc_closure recv_trailing_metadata_ready; - // The error caused by a message that is too large, or GRPC_ERROR_NONE - grpc_error* error; // Used by recv_message_ready. grpc_core::OrphanablePtr* recv_message; // Original recv_message_ready callback, invoked after our own. grpc_closure* next_recv_message_ready; - // Original recv_trailing_metadata callback, invoked after our own. - grpc_closure* next_recv_trailing_metadata_ready; }; struct channel_data { @@ -135,13 +130,12 @@ static void recv_message_ready(void* user_data, grpc_error* error) { grpc_error* new_error = grpc_error_set_int( GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED); - GRPC_ERROR_UNREF(calld->error); if (error == GRPC_ERROR_NONE) { error = new_error; } else { error = grpc_error_add_child(error, new_error); + GRPC_ERROR_UNREF(new_error); } - calld->error = GRPC_ERROR_REF(error); gpr_free(message_string); } else { GRPC_ERROR_REF(error); @@ -150,26 +144,6 @@ static void recv_message_ready(void* user_data, grpc_error* error) { GRPC_CLOSURE_RUN(calld->next_recv_message_ready, error); } -// Callback invoked on completion of recv_trailing_metadata -// Notifies the recv_trailing_metadata batch of any message size failures -static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { - grpc_call_element* elem = static_cast(user_data); - call_data* calld = static_cast(elem->call_data); - if (calld->error != GRPC_ERROR_NONE) { - if (error == GRPC_ERROR_NONE) { - error = GRPC_ERROR_REF(calld->error); - } else if (error != calld->error) { - error = grpc_error_add_child(error, GRPC_ERROR_REF(calld->error)); - } else { - error = GRPC_ERROR_REF(error); - } - } else { - error = GRPC_ERROR_REF(error); - } - // Invoke the next callback. - GRPC_CLOSURE_RUN(calld->next_recv_trailing_metadata_ready, error); -} - // Start transport stream op. static void start_transport_stream_op_batch( grpc_call_element* elem, grpc_transport_stream_op_batch* op) { @@ -198,13 +172,6 @@ static void start_transport_stream_op_batch( calld->recv_message = op->payload->recv_message.recv_message; op->payload->recv_message.recv_message_ready = &calld->recv_message_ready; } - // Inject callback for receiving trailing metadata. - if (op->recv_trailing_metadata) { - calld->next_recv_trailing_metadata_ready = - op->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - op->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &calld->recv_trailing_metadata_ready; - } // Chain to the next filter. grpc_call_next_op(elem, op); } @@ -216,13 +183,8 @@ static grpc_error* init_call_elem(grpc_call_element* elem, call_data* calld = static_cast(elem->call_data); calld->call_combiner = args->call_combiner; calld->next_recv_message_ready = nullptr; - calld->next_recv_trailing_metadata_ready = nullptr; - calld->error = GRPC_ERROR_NONE; GRPC_CLOSURE_INIT(&calld->recv_message_ready, recv_message_ready, elem, grpc_schedule_on_exec_ctx); - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, - recv_trailing_metadata_ready, elem, - grpc_schedule_on_exec_ctx); // Get max sizes from channel data, then merge in per-method config values. // Note: Per-method config is only available on the client, so we // apply the max request size to the send limit and the max response @@ -251,10 +213,7 @@ static grpc_error* init_call_elem(grpc_call_element* elem, // Destructor for call_data. static void destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, - grpc_closure* ignored) { - call_data* calld = (call_data*)elem->call_data; - GRPC_ERROR_UNREF(calld->error); -} + grpc_closure* ignored) {} static int default_size(const grpc_channel_args* args, int without_minimal_stack) { From b51f6aba269c76519d8d1e24b99908c5f712a5e7 Mon Sep 17 00:00:00 2001 From: Carter Sande Date: Fri, 22 Jun 2018 14:31:29 +0000 Subject: [PATCH 018/546] Add Solaris and AIX autodetection --- include/grpc/impl/codegen/port_platform.h | 39 +++++++++++++++++++++++ src/core/lib/iomgr/port.h | 12 +++++++ 2 files changed, 51 insertions(+) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 01ce5f03e96..7f9d9fd82bc 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -282,6 +282,45 @@ #else /* _LP64 */ #define GPR_ARCH_32 1 #endif /* _LP64 */ +#elif defined(__sun) +#define GPR_PLATFORM_STRING "solaris" +#define GPR_SOLARIS 1 +#define GPR_CPU_POSIX 1 +#define GPR_GCC_ATOMIC 1 +#define GPR_GCC_TLS 1 +#define GPR_POSIX_LOG 1 +#define GPR_POSIX_ENV 1 +#define GPR_POSIX_TMPFILE 1 +#define GPR_POSIX_STRING 1 +#define GPR_POSIX_SUBPROCESS 1 +#define GPR_POSIX_SYNC 1 +#define GPR_POSIX_TIME 1 +#ifdef _LP64 +#define GPR_ARCH_64 1 +#else /* _LP64 */ +#define GPR_ARCH_32 1 +#endif /* _LP64 */ +#elif defined(_AIX) +#define GPR_PLATFORM_STRING "aix" +#ifndef _ALL_SOURCE +#define _ALL_SOURCE +#endif +#define GPR_AIX 1 +#define GPR_CPU_POSIX 1 +#define GPR_GCC_ATOMIC 1 +#define GPR_GCC_TLS 1 +#define GPR_POSIX_LOG 1 +#define GPR_POSIX_ENV 1 +#define GPR_POSIX_TMPFILE 1 +#define GPR_POSIX_STRING 1 +#define GPR_POSIX_SUBPROCESS 1 +#define GPR_POSIX_SYNC 1 +#define GPR_POSIX_TIME 1 +#ifdef _LP64 +#define GPR_ARCH_64 1 +#else /* _LP64 */ +#define GPR_ARCH_32 1 +#endif /* _LP64 */ #elif defined(__native_client__) #define GPR_PLATFORM_STRING "nacl" #ifndef _BSD_SOURCE diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 80d8e63cdd0..36b497ae292 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -139,6 +139,18 @@ #define GRPC_POSIX_SOCKET 1 #define GRPC_POSIX_SOCKETUTILS 1 #define GRPC_POSIX_WAKEUP_FD 1 +#elif defined(GPR_SOLARIS) +#define GRPC_HAVE_UNIX_SOCKET 1 +#define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1 +#define GRPC_POSIX_SOCKET 1 +#define GRPC_POSIX_SOCKETUTILS 1 +#define GRPC_POSIX_WAKEUP_FD 1 +#elif defined(GPR_AIX) +#define GRPC_HAVE_UNIX_SOCKET 1 +#define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1 +#define GRPC_POSIX_SOCKET 1 +#define GRPC_POSIX_SOCKETUTILS 1 +#define GRPC_POSIX_WAKEUP_FD 1 #elif defined(GPR_NACL) #define GRPC_HAVE_ARPA_NAMESER 1 #define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1 From cf54ce355a2034fc45ff9baef27a8f710acb369f Mon Sep 17 00:00:00 2001 From: Carter Sande Date: Fri, 22 Jun 2018 15:25:48 +0000 Subject: [PATCH 019/546] ev_posix.cc: Fix poll function on AIX --- src/core/lib/iomgr/ev_posix.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 1139b3273ab..85ffd5147c7 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -59,7 +59,14 @@ grpc_core::DebugOnlyTraceFlag grpc_polling_api_trace(false, "polling_api"); /** Default poll() function - a pointer so that it can be overridden by some * tests */ +#ifndef GPR_AIX grpc_poll_function_type grpc_poll_function = poll; +#else +int aix_poll(struct pollfd fds[], nfds_t nfds, int timeout) { + return poll(fds, nfds, timeout); +} +grpc_poll_function_type grpc_poll_function = aix_poll; +#endif grpc_wakeup_fd grpc_global_wakeup_fd; From d5736045d35bcf2823f97cd740b7953514b76215 Mon Sep 17 00:00:00 2001 From: Carter Sande Date: Tue, 3 Jul 2018 21:34:34 +0000 Subject: [PATCH 020/546] port_platform.h: Make Solaris detection macro more precise --- include/grpc/impl/codegen/port_platform.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 7f9d9fd82bc..bb8cba9d550 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -282,7 +282,7 @@ #else /* _LP64 */ #define GPR_ARCH_32 1 #endif /* _LP64 */ -#elif defined(__sun) +#elif defined(__sun) && defined(__SVR4) #define GPR_PLATFORM_STRING "solaris" #define GPR_SOLARIS 1 #define GPR_CPU_POSIX 1 From a0a061034351a6cd616ee2d01fae99604216b9ba Mon Sep 17 00:00:00 2001 From: Carter Sande Date: Thu, 5 Jul 2018 18:55:14 +0000 Subject: [PATCH 021/546] port_platform.h: GPR_GETPID_IN_UNISTD_H on Solaris/AIX --- include/grpc/impl/codegen/port_platform.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index bb8cba9d550..e850d41c5cb 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -295,6 +295,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 #else /* _LP64 */ @@ -316,6 +317,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 #else /* _LP64 */ From 299c2c5e115b6a1204d67f3a4ae8de66c5386fe6 Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Mon, 9 Jul 2018 12:10:02 -0700 Subject: [PATCH 022/546] Include cancellation error --- src/core/lib/surface/call.cc | 62 ++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 6f136cd2a96..6f0905a9dac 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -190,7 +190,7 @@ struct grpc_call { grpc_closure receiving_initial_metadata_ready; grpc_closure receiving_trailing_metadata_ready; uint32_t test_only_last_message_flags; - gpr_atm cancelled; + gpr_atm cancel_error; grpc_closure release_call; @@ -301,7 +301,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, gpr_arena_alloc(arena, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + channel_stack->call_stack_size)); gpr_ref_init(&call->ext_ref, 1); - gpr_atm_no_barrier_store(&call->cancelled, 0); + gpr_atm_no_barrier_store(&call->cancel_error, GRPC_ERROR_NONE); call->arena = arena; grpc_call_combiner_init(&call->call_combiner); *out_call = call; @@ -509,10 +509,33 @@ static void destroy_call(void* call, grpc_error* error) { GRPC_CQ_INTERNAL_UNREF(c->cq, "bind"); } + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(c->channel); + if (c->is_client) { + if (channelz_channel != nullptr) { + if (*c->final_op.client.status != GRPC_STATUS_OK) { + channelz_channel->RecordCallFailed(); + } else { + channelz_channel->RecordCallSucceeded(); + } + } + } else { + if (channelz_channel != nullptr) { + if (*c->final_op.server.cancelled || c->status_error != GRPC_ERROR_NONE) { + channelz_channel->RecordCallFailed(); + } else { + channelz_channel->RecordCallSucceeded(); + } + } + } + grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(c->status_error, c->send_deadline, &c->final_info.final_status, &slice, nullptr, c->final_info.error_string); + grpc_error* cancel_error = + (grpc_error*)gpr_atm_no_barrier_load(&c->cancel_error); + GRPC_ERROR_UNREF(cancel_error); GRPC_ERROR_UNREF(c->status_error); c->final_info.stats.latency = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time); @@ -644,10 +667,12 @@ static void done_termination(void* arg, grpc_error* error) { } static void cancel_with_error(grpc_call* c, grpc_error* error) { - if (!gpr_atm_rel_cas(&c->cancelled, 0, 1)) { + if (!gpr_atm_rel_cas(&c->cancel_error, (gpr_atm)GRPC_ERROR_NONE, + (gpr_atm)error)) { GRPC_ERROR_UNREF(error); return; } + GRPC_ERROR_REF(error); GRPC_CALL_INTERNAL_REF(c, "termination"); // Inform the call combiner of the cancellation, so that it can cancel // any in-flight asynchronous actions that may be holding the call @@ -681,14 +706,26 @@ static void cancel_with_status(grpc_call* c, grpc_status_code status, cancel_with_error(c, error_from_status(status, description)); } +// The final status of a call is determined when the +// recv_trailing_metadata_ready callback is invoked. The status is determined +// based on the following (in order). +// 1. The first cancellation error that has occured prior to the callback. +// 2. The error passed to the recv_trailing_metadata_ready callback. +// 3. The status from the metadata on the call (grpc-status). static void set_final_status(grpc_call* call, grpc_error* error) { if (grpc_call_error_trace.enabled()) { gpr_log(GPR_DEBUG, "set_final_status %s", call->is_client ? "CLI" : "SVR"); gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); } - grpc_core::channelz::ChannelNode* channelz_channel = - grpc_channel_get_channelz_node(call->channel); + grpc_error* cancel_error = + (grpc_error*)gpr_atm_no_barrier_load(&call->cancel_error); + if (cancel_error != GRPC_ERROR_NONE && error == GRPC_ERROR_NONE) { + error = GRPC_ERROR_REF(cancel_error); + } else if (cancel_error != GRPC_ERROR_NONE && cancel_error != error) { + error = grpc_error_add_child(GRPC_ERROR_REF(cancel_error), error); + } if (call->is_client) { + call->status_error = error; const char** error_string = call->final_op.client.error_string; grpc_status_code code; grpc_slice slice = grpc_empty_slice(); @@ -696,24 +733,9 @@ static void set_final_status(grpc_call* call, grpc_error* error) { error_string); *call->final_op.client.status = code; *call->final_op.client.status_details = grpc_slice_ref_internal(slice); - call->status_error = error; - if (channelz_channel != nullptr) { - if (*call->final_op.client.status != GRPC_STATUS_OK) { - channelz_channel->RecordCallFailed(); - } else { - channelz_channel->RecordCallSucceeded(); - } - } } else { *call->final_op.server.cancelled = error != GRPC_ERROR_NONE || call->status_error != GRPC_ERROR_NONE; - if (channelz_channel != nullptr) { - if (*call->final_op.server.cancelled) { - channelz_channel->RecordCallFailed(); - } else { - channelz_channel->RecordCallSucceeded(); - } - } GRPC_ERROR_UNREF(error); } } From 1b6e8514a9e915fb3a74e81a9724ca8043d9e81f Mon Sep 17 00:00:00 2001 From: easy Date: Wed, 11 Jul 2018 14:55:46 +1000 Subject: [PATCH 023/546] Move GetSpanFromServerContext() to public header. --- include/grpcpp/opencensus.h | 7 +++++++ src/cpp/ext/filters/census/grpc_plugin.h | 4 ---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/opencensus.h b/include/grpcpp/opencensus.h index 7e5d1dfeb41..29b221f7674 100644 --- a/include/grpcpp/opencensus.h +++ b/include/grpcpp/opencensus.h @@ -19,6 +19,8 @@ #ifndef GRPCPP_OPENCENSUS_H #define GRPCPP_OPENCENSUS_H +#include "opencensus/trace/span.h" + namespace grpc { // These symbols in this file will not be included in the binary unless // grpc_opencensus_plugin build target was added as a dependency. At the moment @@ -36,6 +38,11 @@ void RegisterOpenCensusPlugin(); // ViewDescriptors below. void RegisterOpenCensusViewsForExport(); +class ServerContext; + +// Returns the tracing Span for the current RPC. +::opencensus::trace::Span GetSpanFromServerContext(ServerContext* context); + } // namespace grpc #endif // GRPCPP_OPENCENSUS_H diff --git a/src/cpp/ext/filters/census/grpc_plugin.h b/src/cpp/ext/filters/census/grpc_plugin.h index 7ff2e7a8b8c..9e319cb994e 100644 --- a/src/cpp/ext/filters/census/grpc_plugin.h +++ b/src/cpp/ext/filters/census/grpc_plugin.h @@ -24,15 +24,11 @@ #include "absl/strings/string_view.h" #include "include/grpcpp/opencensus.h" #include "opencensus/stats/stats.h" -#include "opencensus/trace/span.h" namespace grpc { class ServerContext; -// Returns the tracing Span for the current RPC. -::opencensus::trace::Span GetSpanFromServerContext(ServerContext* context); - // The tag keys set when recording RPC stats. ::opencensus::stats::TagKey ClientMethodTagKey(); ::opencensus::stats::TagKey ClientStatusTagKey(); From a3d93f324b93329de79124d570dbddb47a6862e0 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 11 Jul 2018 19:34:24 -0700 Subject: [PATCH 024/546] fix format --- src/core/lib/iomgr/timer_generic.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/timer_generic.cc b/src/core/lib/iomgr/timer_generic.cc index 70417d69b63..008d37119a9 100644 --- a/src/core/lib/iomgr/timer_generic.cc +++ b/src/core/lib/iomgr/timer_generic.cc @@ -716,7 +716,8 @@ static grpc_timer_check_result timer_check(grpc_millis* next) { "TIMER CHECK BEGIN: now=%" PRId64 " next=%s tls_min=%" PRId64 " glob_min=%" PRId64, now, next_str, min_timer, - gpr_atm_no_barrier_load((gpr_atm*)(&g_shared_mutables.min_timer))); + static_cast(gpr_atm_no_barrier_load( + (gpr_atm*)(&g_shared_mutables.min_timer)))); #else gpr_log(GPR_INFO, "TIMER CHECK BEGIN: now=%" PRId64 " next=%s min=%" PRId64, now, next_str, min_timer); From a135059ce7d2db3180045810f66dd69a8fc88284 Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Fri, 13 Jul 2018 13:24:31 -0700 Subject: [PATCH 025/546] Make error strings consistent --- src/core/lib/iomgr/error.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index 90ed34da11f..93a5c20abb9 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -399,14 +399,14 @@ static grpc_error* copy_error_and_unref(grpc_error* in) { out = GRPC_ERROR_CREATE_FROM_STATIC_STRING("unknown"); if (in == GRPC_ERROR_NONE) { internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION, - grpc_slice_from_static_string("no error")); + grpc_slice_from_static_string("No Error")); internal_set_int(&out, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK); } else if (in == GRPC_ERROR_OOM) { internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION, - grpc_slice_from_static_string("oom")); + grpc_slice_from_static_string("Out of memory")); } else if (in == GRPC_ERROR_CANCELLED) { internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION, - grpc_slice_from_static_string("cancelled")); + grpc_slice_from_static_string("Cancelled")); internal_set_int(&out, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED); } } else if (gpr_ref_is_unique(&in->atomics.refs)) { From 5defb7354b620a67ef42cb2ad73bab7bdd512fa6 Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Fri, 13 Jul 2018 13:49:23 -0700 Subject: [PATCH 026/546] compile error fix --- src/core/lib/surface/call.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 6f0905a9dac..88156ed3bcd 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -301,7 +301,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, gpr_arena_alloc(arena, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + channel_stack->call_stack_size)); gpr_ref_init(&call->ext_ref, 1); - gpr_atm_no_barrier_store(&call->cancel_error, GRPC_ERROR_NONE); + gpr_atm_no_barrier_store(&call->cancel_error, (gpr_atm)GRPC_ERROR_NONE); call->arena = arena; grpc_call_combiner_init(&call->call_combiner); *out_call = call; From f0397933b007e2614ba38fc98f0ee6391a2eea9d Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 31 May 2018 19:39:52 -0700 Subject: [PATCH 027/546] Fathom TCP level changes. TracedBuffer for keeping track of all buffers to be traced. Adding tests for Fathom and TracedBuffer. A lot more. Please read PR description. --- BUILD | 4 + CMakeLists.txt | 46 +++ Makefile | 48 +++ build.yaml | 18 ++ config.m4 | 2 + config.w32 | 2 + gRPC-C++.podspec | 4 + gRPC-Core.podspec | 6 + grpc.gemspec | 4 + grpc.gyp | 8 + package.xml | 4 + .../client_channel/http_connect_handshaker.cc | 2 +- .../client/insecure/channel_create_posix.cc | 2 +- .../server/insecure/server_chttp2_posix.cc | 2 +- .../chttp2/transport/chttp2_transport.cc | 3 +- src/core/lib/http/httpcli.cc | 2 +- src/core/lib/iomgr/buffer_list.cc | 143 +++++++++ src/core/lib/iomgr/buffer_list.h | 81 +++++ src/core/lib/iomgr/endpoint.cc | 4 +- src/core/lib/iomgr/endpoint.h | 6 +- src/core/lib/iomgr/endpoint_cfstream.cc | 2 +- src/core/lib/iomgr/endpoint_pair_posix.cc | 4 +- src/core/lib/iomgr/ev_epoll1_linux.cc | 18 +- src/core/lib/iomgr/ev_epollex_linux.cc | 18 +- src/core/lib/iomgr/ev_epollsig_linux.cc | 18 +- src/core/lib/iomgr/ev_posix.cc | 4 +- src/core/lib/iomgr/internal_errqueue.cc | 40 +++ src/core/lib/iomgr/internal_errqueue.h | 76 +++++ src/core/lib/iomgr/port.h | 1 + src/core/lib/iomgr/tcp_client_posix.cc | 2 +- src/core/lib/iomgr/tcp_custom.cc | 2 +- src/core/lib/iomgr/tcp_posix.cc | 287 +++++++++++++++++- src/core/lib/iomgr/tcp_posix.h | 8 + src/core/lib/iomgr/tcp_server_posix.cc | 4 +- .../iomgr/tcp_server_utils_posix_common.cc | 2 +- src/core/lib/iomgr/tcp_windows.cc | 2 +- src/core/lib/iomgr/udp_server.cc | 2 +- .../lib/security/transport/secure_endpoint.cc | 4 +- .../security/transport/security_handshaker.cc | 2 +- src/python/grpcio/grpc_core_dependencies.py | 2 + test/core/bad_client/bad_client.cc | 2 +- test/core/end2end/bad_server_response_test.cc | 2 +- .../end2end/fixtures/http_proxy_fixture.cc | 10 +- test/core/iomgr/BUILD | 13 + test/core/iomgr/buffer_list_test.cc | 111 +++++++ test/core/iomgr/endpoint_tests.cc | 7 +- test/core/iomgr/tcp_posix_test.cc | 126 +++++++- test/core/util/mock_endpoint.cc | 2 +- test/core/util/passthru_endpoint.cc | 2 +- test/core/util/trickle_endpoint.cc | 5 +- .../microbenchmarks/bm_chttp2_transport.cc | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 + tools/doxygen/Doxyfile.core.internal | 4 + .../generated/sources_and_headers.json | 23 ++ tools/run_tests/generated/tests.json | 20 ++ 55 files changed, 1142 insertions(+), 78 deletions(-) create mode 100644 src/core/lib/iomgr/buffer_list.cc create mode 100644 src/core/lib/iomgr/buffer_list.h create mode 100644 src/core/lib/iomgr/internal_errqueue.cc create mode 100644 src/core/lib/iomgr/internal_errqueue.h create mode 100644 test/core/iomgr/buffer_list_test.cc diff --git a/BUILD b/BUILD index 8523bbb660f..c8ee2df3a51 100644 --- a/BUILD +++ b/BUILD @@ -695,6 +695,7 @@ grpc_cc_library( "src/core/lib/http/format_request.cc", "src/core/lib/http/httpcli.cc", "src/core/lib/http/parser.cc", + "src/core/lib/iomgr/buffer_list.cc", "src/core/lib/iomgr/call_combiner.cc", "src/core/lib/iomgr/combiner.cc", "src/core/lib/iomgr/endpoint.cc", @@ -715,6 +716,7 @@ grpc_cc_library( "src/core/lib/iomgr/gethostname_fallback.cc", "src/core/lib/iomgr/gethostname_host_name_max.cc", "src/core/lib/iomgr/gethostname_sysconf.cc", + "src/core/lib/iomgr/internal_errqueue.cc", "src/core/lib/iomgr/iocp_windows.cc", "src/core/lib/iomgr/iomgr.cc", "src/core/lib/iomgr/iomgr_custom.cc", @@ -844,6 +846,7 @@ grpc_cc_library( "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", + "src/core/lib/iomgr/buffer_list.h", "src/core/lib/iomgr/block_annotate.h", "src/core/lib/iomgr/call_combiner.h", "src/core/lib/iomgr/closure.h", @@ -861,6 +864,7 @@ grpc_cc_library( "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/gevent_util.h", + "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", "src/core/lib/iomgr/iomgr_custom.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 7222894af62..8570b2c35c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -228,6 +228,9 @@ add_dependencies(buildtests_c avl_test) add_dependencies(buildtests_c bad_server_response_test) add_dependencies(buildtests_c bin_decoder_test) add_dependencies(buildtests_c bin_encoder_test) +if(_gRPC_PLATFORM_LINUX) +add_dependencies(buildtests_c buffer_list_test) +endif() add_dependencies(buildtests_c channel_create_test) add_dependencies(buildtests_c chttp2_hpack_encoder_test) add_dependencies(buildtests_c chttp2_stream_map_test) @@ -963,6 +966,7 @@ add_library(grpc src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -983,6 +987,7 @@ add_library(grpc src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -1364,6 +1369,7 @@ add_library(grpc_cronet src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -1384,6 +1390,7 @@ add_library(grpc_cronet src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -1754,6 +1761,7 @@ add_library(grpc_test_util src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -1774,6 +1782,7 @@ add_library(grpc_test_util src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -2062,6 +2071,7 @@ add_library(grpc_test_util_unsecure src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -2082,6 +2092,7 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -2349,6 +2360,7 @@ add_library(grpc_unsecure src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -2369,6 +2381,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -3186,6 +3199,7 @@ add_library(grpc++_cronet src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -3206,6 +3220,7 @@ add_library(grpc++_cronet src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -5761,6 +5776,37 @@ target_link_libraries(bin_encoder_test grpc ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX) + +add_executable(buffer_list_test + test/core/iomgr/buffer_list_test.cc +) + + +target_include_directories(buffer_list_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 ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(buffer_list_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr_test_util + gpr +) + +endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 47c9dc7ccdf..4edc029d384 100644 --- a/Makefile +++ b/Makefile @@ -969,6 +969,7 @@ avl_test: $(BINDIR)/$(CONFIG)/avl_test bad_server_response_test: $(BINDIR)/$(CONFIG)/bad_server_response_test bin_decoder_test: $(BINDIR)/$(CONFIG)/bin_decoder_test bin_encoder_test: $(BINDIR)/$(CONFIG)/bin_encoder_test +buffer_list_test: $(BINDIR)/$(CONFIG)/buffer_list_test channel_create_test: $(BINDIR)/$(CONFIG)/channel_create_test check_epollexclusive: $(BINDIR)/$(CONFIG)/check_epollexclusive chttp2_hpack_encoder_test: $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test @@ -1419,6 +1420,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/bad_server_response_test \ $(BINDIR)/$(CONFIG)/bin_decoder_test \ $(BINDIR)/$(CONFIG)/bin_encoder_test \ + $(BINDIR)/$(CONFIG)/buffer_list_test \ $(BINDIR)/$(CONFIG)/channel_create_test \ $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test \ $(BINDIR)/$(CONFIG)/chttp2_stream_map_test \ @@ -1929,6 +1931,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/bin_decoder_test || ( echo test bin_decoder_test failed ; exit 1 ) $(E) "[RUN] Testing bin_encoder_test" $(Q) $(BINDIR)/$(CONFIG)/bin_encoder_test || ( echo test bin_encoder_test failed ; exit 1 ) + $(E) "[RUN] Testing buffer_list_test" + $(Q) $(BINDIR)/$(CONFIG)/buffer_list_test || ( echo test buffer_list_test failed ; exit 1 ) $(E) "[RUN] Testing channel_create_test" $(Q) $(BINDIR)/$(CONFIG)/channel_create_test || ( echo test channel_create_test failed ; exit 1 ) $(E) "[RUN] Testing chttp2_hpack_encoder_test" @@ -3409,6 +3413,7 @@ LIBGRPC_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -3429,6 +3434,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -3809,6 +3815,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -3829,6 +3836,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -4197,6 +4205,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -4217,6 +4226,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -4496,6 +4506,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -4516,6 +4527,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -4761,6 +4773,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -4781,6 +4794,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -5586,6 +5600,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -5606,6 +5621,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -10565,6 +10581,38 @@ endif endif +BUFFER_LIST_TEST_SRC = \ + test/core/iomgr/buffer_list_test.cc \ + +BUFFER_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BUFFER_LIST_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/buffer_list_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/buffer_list_test: $(BUFFER_LIST_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) $(BUFFER_LIST_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)/buffer_list_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/buffer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_buffer_list_test: $(BUFFER_LIST_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BUFFER_LIST_TEST_OBJS:.o=.dep) +endif +endif + + CHANNEL_CREATE_TEST_SRC = \ test/core/surface/channel_create_test.cc \ diff --git a/build.yaml b/build.yaml index 3067ca9161d..711edb08665 100644 --- a/build.yaml +++ b/build.yaml @@ -254,6 +254,7 @@ filegroups: - src/core/lib/http/format_request.cc - src/core/lib/http/httpcli.cc - src/core/lib/http/parser.cc + - src/core/lib/iomgr/buffer_list.cc - src/core/lib/iomgr/call_combiner.cc - src/core/lib/iomgr/combiner.cc - src/core/lib/iomgr/endpoint.cc @@ -274,6 +275,7 @@ filegroups: - src/core/lib/iomgr/gethostname_fallback.cc - src/core/lib/iomgr/gethostname_host_name_max.cc - src/core/lib/iomgr/gethostname_sysconf.cc + - src/core/lib/iomgr/internal_errqueue.cc - src/core/lib/iomgr/iocp_windows.cc - src/core/lib/iomgr/iomgr.cc - src/core/lib/iomgr/iomgr_custom.cc @@ -432,6 +434,7 @@ filegroups: - src/core/lib/http/httpcli.h - src/core/lib/http/parser.h - src/core/lib/iomgr/block_annotate.h + - src/core/lib/iomgr/buffer_list.h - src/core/lib/iomgr/call_combiner.h - src/core/lib/iomgr/closure.h - src/core/lib/iomgr/combiner.h @@ -447,6 +450,7 @@ filegroups: - src/core/lib/iomgr/exec_ctx.h - src/core/lib/iomgr/executor.h - src/core/lib/iomgr/gethostname.h + - src/core/lib/iomgr/internal_errqueue.h - src/core/lib/iomgr/iocp_windows.h - src/core/lib/iomgr/iomgr.h - src/core/lib/iomgr/iomgr_custom.h @@ -2107,6 +2111,20 @@ targets: - grpc_test_util - grpc uses_polling: false +- name: buffer_list_test + build: test + language: c + src: + - test/core/iomgr/buffer_list_test.cc + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr + exclude_iomgrs: + - uv + platforms: + - linux - name: channel_create_test build: test language: c diff --git a/config.m4 b/config.m4 index c277ccafc8c..f75baee8a56 100644 --- a/config.m4 +++ b/config.m4 @@ -108,6 +108,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -128,6 +129,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ diff --git a/config.w32 b/config.w32 index 2857781dd57..9783ce39115 100644 --- a/config.w32 +++ b/config.w32 @@ -83,6 +83,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\http\\format_request.cc " + "src\\core\\lib\\http\\httpcli.cc " + "src\\core\\lib\\http\\parser.cc " + + "src\\core\\lib\\iomgr\\buffer_list.cc " + "src\\core\\lib\\iomgr\\call_combiner.cc " + "src\\core\\lib\\iomgr\\combiner.cc " + "src\\core\\lib\\iomgr\\endpoint.cc " + @@ -103,6 +104,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\gethostname_fallback.cc " + "src\\core\\lib\\iomgr\\gethostname_host_name_max.cc " + "src\\core\\lib\\iomgr\\gethostname_sysconf.cc " + + "src\\core\\lib\\iomgr\\internal_errqueue.cc " + "src\\core\\lib\\iomgr\\iocp_windows.cc " + "src\\core\\lib\\iomgr\\iomgr.cc " + "src\\core\\lib\\iomgr\\iomgr_custom.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 57d58cc4400..04b29e57303 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -378,6 +378,7 @@ Pod::Spec.new do |s| 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', 'src/core/lib/iomgr/block_annotate.h', + 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', @@ -393,6 +394,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', 'src/core/lib/iomgr/iomgr_custom.h', @@ -565,6 +567,7 @@ Pod::Spec.new do |s| 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', 'src/core/lib/iomgr/block_annotate.h', + 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', @@ -580,6 +583,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', 'src/core/lib/iomgr/iomgr_custom.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 997617c5307..9ff1b2bcbe8 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -389,6 +389,7 @@ Pod::Spec.new do |s| 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', 'src/core/lib/iomgr/block_annotate.h', + 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', @@ -404,6 +405,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', 'src/core/lib/iomgr/iomgr_custom.h', @@ -533,6 +535,7 @@ Pod::Spec.new do |s| 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -553,6 +556,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', @@ -979,6 +983,7 @@ Pod::Spec.new do |s| 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', 'src/core/lib/iomgr/block_annotate.h', + 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', @@ -994,6 +999,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', 'src/core/lib/iomgr/iomgr_custom.h', diff --git a/grpc.gemspec b/grpc.gemspec index b69d5a7c6fc..5b26cd86429 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -326,6 +326,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/http/httpcli.h ) s.files += %w( src/core/lib/http/parser.h ) s.files += %w( src/core/lib/iomgr/block_annotate.h ) + s.files += %w( src/core/lib/iomgr/buffer_list.h ) s.files += %w( src/core/lib/iomgr/call_combiner.h ) s.files += %w( src/core/lib/iomgr/closure.h ) s.files += %w( src/core/lib/iomgr/combiner.h ) @@ -341,6 +342,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/exec_ctx.h ) s.files += %w( src/core/lib/iomgr/executor.h ) s.files += %w( src/core/lib/iomgr/gethostname.h ) + s.files += %w( src/core/lib/iomgr/internal_errqueue.h ) s.files += %w( src/core/lib/iomgr/iocp_windows.h ) s.files += %w( src/core/lib/iomgr/iomgr.h ) s.files += %w( src/core/lib/iomgr/iomgr_custom.h ) @@ -470,6 +472,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/http/format_request.cc ) s.files += %w( src/core/lib/http/httpcli.cc ) s.files += %w( src/core/lib/http/parser.cc ) + s.files += %w( src/core/lib/iomgr/buffer_list.cc ) s.files += %w( src/core/lib/iomgr/call_combiner.cc ) s.files += %w( src/core/lib/iomgr/combiner.cc ) s.files += %w( src/core/lib/iomgr/endpoint.cc ) @@ -490,6 +493,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/gethostname_fallback.cc ) s.files += %w( src/core/lib/iomgr/gethostname_host_name_max.cc ) s.files += %w( src/core/lib/iomgr/gethostname_sysconf.cc ) + s.files += %w( src/core/lib/iomgr/internal_errqueue.cc ) s.files += %w( src/core/lib/iomgr/iocp_windows.cc ) s.files += %w( src/core/lib/iomgr/iomgr.cc ) s.files += %w( src/core/lib/iomgr/iomgr_custom.cc ) diff --git a/grpc.gyp b/grpc.gyp index 0db6afe4682..be2325b951c 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -300,6 +300,7 @@ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -320,6 +321,7 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', @@ -655,6 +657,7 @@ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -675,6 +678,7 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', @@ -888,6 +892,7 @@ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -908,6 +913,7 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', @@ -1099,6 +1105,7 @@ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -1119,6 +1126,7 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', diff --git a/package.xml b/package.xml index a9dc2dc79ac..a3ce1d10d20 100644 --- a/package.xml +++ b/package.xml @@ -331,6 +331,7 @@ + @@ -346,6 +347,7 @@ + @@ -475,6 +477,7 @@ + @@ -495,6 +498,7 @@ + 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 4e8b8b71dbd..7ce8da8c00e 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -320,7 +320,7 @@ static void http_connect_handshaker_do_handshake( // Take a new ref to be held by the write callback. gpr_ref(&handshaker->refcount); grpc_endpoint_write(args->endpoint, &handshaker->write_buffer, - &handshaker->request_done_closure); + &handshaker->request_done_closure, nullptr); gpr_mu_unlock(&handshaker->mu); } 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 dfed824cd5b..5bdcb387c9b 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 @@ -50,7 +50,7 @@ grpc_channel* grpc_insecure_channel_create_from_fd( GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0); grpc_endpoint* client = grpc_tcp_client_create_from_fd( - grpc_fd_create(fd, "client", false), args, "fd-client"); + grpc_fd_create(fd, "client", true), args, "fd-client"); grpc_transport* transport = grpc_create_chttp2_transport(final_args, client, true); 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 a0228785eeb..e4bd91d07ba 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 @@ -44,7 +44,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server, gpr_asprintf(&name, "fd:%d", fd); grpc_endpoint* server_endpoint = - grpc_tcp_create(grpc_fd_create(fd, name, false), + grpc_tcp_create(grpc_fd_create(fd, name, true), grpc_server_get_channel_args(server), name); gpr_free(name); diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index bc6fa0d0eb0..73323546991 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1007,7 +1007,8 @@ static void write_action(void* gt, grpc_error* error) { grpc_endpoint_write( t->ep, &t->outbuf, GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t, - grpc_combiner_scheduler(t->combiner))); + grpc_combiner_scheduler(t->combiner)), + nullptr); } static void write_action_end_locked(void* tp, grpc_error* error) { diff --git a/src/core/lib/http/httpcli.cc b/src/core/lib/http/httpcli.cc index 12060074c53..3bd7a2ce590 100644 --- a/src/core/lib/http/httpcli.cc +++ b/src/core/lib/http/httpcli.cc @@ -163,7 +163,7 @@ static void done_write(void* arg, grpc_error* error) { static void start_write(internal_request* req) { grpc_slice_ref_internal(req->request_text); grpc_slice_buffer_add(&req->outgoing, req->request_text); - grpc_endpoint_write(req->ep, &req->outgoing, &req->done_write); + grpc_endpoint_write(req->ep, &req->outgoing, &req->done_write, nullptr); } static void on_handshake_done(void* arg, grpc_endpoint* ep) { diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc new file mode 100644 index 00000000000..4f0b522cca5 --- /dev/null +++ b/src/core/lib/iomgr/buffer_list.cc @@ -0,0 +1,143 @@ +/* + * + * 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 + +#include "src/core/lib/iomgr/buffer_list.h" +#include "src/core/lib/iomgr/port.h" + +#include + +#ifdef GRPC_LINUX_ERRQUEUE +#include + +#include "src/core/lib/gprpp/memory.h" + +namespace grpc_core { +void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, + void* arg) { + gpr_log(GPR_INFO, "Adding new entry %u", seq_no); + GPR_DEBUG_ASSERT(head != nullptr); + TracedBuffer* new_elem = New(seq_no, arg); + /* Store the current time as the sendmsg time. */ + new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME); + if (*head == nullptr) { + *head = new_elem; + gpr_log(GPR_INFO, "returning"); + return; + } + /* Append at the end. */ + TracedBuffer* ptr = *head; + while (ptr->next_ != nullptr) { + ptr = ptr->next_; + } + ptr->next_ = new_elem; + gpr_log(GPR_INFO, "returning"); +} + +namespace { +void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) { + gts->tv_sec = ts->tv_sec; + gts->tv_nsec = static_cast(ts->tv_nsec); + gts->clock_type = GPR_CLOCK_REALTIME; +} + +void (*timestamps_callback)(void*, grpc_core::Timestamps*, + grpc_error* shutdown_err); +} /* namespace */ + +void TracedBuffer::ProcessTimestamp(TracedBuffer** head, + struct sock_extended_err* serr, + struct scm_timestamping* tss) { + gpr_log(GPR_INFO, "Got timestamp %d", serr->ee_data); + GPR_DEBUG_ASSERT(head != nullptr); + TracedBuffer* elem = *head; + TracedBuffer* next = nullptr; + while (elem != nullptr) { + gpr_log(GPR_INFO, "looping"); + /* The byte number refers to the sequence number of the last byte which this + * timestamp relates to. For scheduled and send, we are interested in the + * timestamp for the first byte, whereas for ack, we are interested in the + * last */ + if (serr->ee_data >= elem->seq_no_) { + switch (serr->ee_info) { + case SCM_TSTAMP_SCHED: + gpr_log(GPR_INFO, "type sched\n"); + fill_gpr_from_timestamp(&(elem->ts_.scheduled_time), &(tss->ts[0])); + elem = elem->next_; + break; + case SCM_TSTAMP_SND: + gpr_log(GPR_INFO, "type send\n"); + fill_gpr_from_timestamp(&(elem->ts_.sent_time), &(tss->ts[0])); + elem = elem->next_; + break; + case SCM_TSTAMP_ACK: + gpr_log(GPR_INFO, "type ack\n"); + if (serr->ee_data >= elem->seq_no_) { + fill_gpr_from_timestamp(&(elem->ts_.acked_time), &(tss->ts[0])); + /* Got all timestamps. Do the callback and free this TracedBuffer. + * The thing below can be passed by value if we don't want the + * restriction on the lifetime. */ + timestamps_callback(elem->arg_, &(elem->ts_), GRPC_ERROR_NONE); + next = elem->next_; + Delete(elem); + *head = elem = next; + break; + default: + abort(); + } + } + } else { + break; + } + } +} + +void TracedBuffer::Shutdown(TracedBuffer** head, grpc_error* shutdown_err) { + GPR_DEBUG_ASSERT(head != nullptr); + TracedBuffer* elem = *head; + while (elem != nullptr) { + if (timestamps_callback) { + timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err); + } + auto* next = elem->next_; + Delete(elem); + elem = next; + } + *head = nullptr; + GRPC_ERROR_UNREF(shutdown_err); +} + +void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*, + grpc_error* error)) { + timestamps_callback = fn; +} +} /* namespace grpc_core */ + +#else /* GRPC_LINUX_ERRQUEUE */ + +namespace grpc_core { +void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*, + grpc_error* error)) { + gpr_log(GPR_DEBUG, "Timestamps callback is not enabled for this platform"); +} +} /* namespace grpc_core */ + +#endif /* GRPC_LINUX_ERRQUEUE */ diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h new file mode 100644 index 00000000000..d42f97ff97e --- /dev/null +++ b/src/core/lib/iomgr/buffer_list.h @@ -0,0 +1,81 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H +#define GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H + +#include + +#include "src/core/lib/iomgr/port.h" + +#include + +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/internal_errqueue.h" + +namespace grpc_core { +struct Timestamps { + gpr_timespec sendmsg_time; + gpr_timespec scheduled_time; + gpr_timespec sent_time; + gpr_timespec acked_time; +}; + +#ifdef GRPC_LINUX_ERRQUEUE +class TracedBuffer { + public: + /** Add a new entry in the TracedBuffer list pointed to by head */ + static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no, + void* arg); + + /** Processes a timestamp received */ + static void ProcessTimestamp(grpc_core::TracedBuffer** head, + struct sock_extended_err* serr, + struct scm_timestamping* tss); + + /** Calls the callback for each traced buffer in the list with timestamps that + * it has. */ + static void Shutdown(grpc_core::TracedBuffer** head, + grpc_error* shutdown_err); + + private: + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + + TracedBuffer(int seq_no, void* arg) + : seq_no_(seq_no), arg_(arg), next_(nullptr) { + gpr_log(GPR_INFO, "seq_no %d", seq_no_); + } + + uint32_t seq_no_; /* The sequence number for the last byte in the buffer */ + void* arg_; /* The arg to pass to timestamps_callback */ + grpc_core::Timestamps ts_; + grpc_core::TracedBuffer* next_; +}; +#else /* GRPC_LINUX_ERRQUEUE */ +class TracedBuffer {}; +#endif /* GRPC_LINUX_ERRQUEUE */ + +/** Sets the timestamp callback */ +void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*, + grpc_error* error)); + +}; // namespace grpc_core + +#endif /* GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H */ diff --git a/src/core/lib/iomgr/endpoint.cc b/src/core/lib/iomgr/endpoint.cc index 92e79301114..44fb47e19d9 100644 --- a/src/core/lib/iomgr/endpoint.cc +++ b/src/core/lib/iomgr/endpoint.cc @@ -28,8 +28,8 @@ void grpc_endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* slices, } void grpc_endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { - ep->vtable->write(ep, slices, cb); + grpc_closure* cb, void* arg) { + ep->vtable->write(ep, slices, cb, arg); } void grpc_endpoint_add_to_pollset(grpc_endpoint* ep, grpc_pollset* pollset) { diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h index 15db1649fa9..ea39ea632eb 100644 --- a/src/core/lib/iomgr/endpoint.h +++ b/src/core/lib/iomgr/endpoint.h @@ -33,10 +33,12 @@ typedef struct grpc_endpoint grpc_endpoint; typedef struct grpc_endpoint_vtable grpc_endpoint_vtable; +class Timestamps; struct grpc_endpoint_vtable { void (*read)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb); - void (*write)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb); + void (*write)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb, + void* arg); void (*add_to_pollset)(grpc_endpoint* ep, grpc_pollset* pollset); void (*add_to_pollset_set)(grpc_endpoint* ep, grpc_pollset_set* pollset); void (*delete_from_pollset_set)(grpc_endpoint* ep, grpc_pollset_set* pollset); @@ -72,7 +74,7 @@ int grpc_endpoint_get_fd(grpc_endpoint* ep); it is a valid slice buffer. */ void grpc_endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb); + grpc_closure* cb, void* arg); /* Causes any pending and future read/write callbacks to run immediately with success==0 */ diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc index c3bc0cc8fd9..70d674f7504 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.cc +++ b/src/core/lib/iomgr/endpoint_cfstream.cc @@ -268,7 +268,7 @@ static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices, } static void CFStreamWrite(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void *arg) { CFStreamEndpoint* ep_impl = reinterpret_cast(ep); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_DEBUG, "CFStream endpoint:%p write (%p, %p) length:%zu", diff --git a/src/core/lib/iomgr/endpoint_pair_posix.cc b/src/core/lib/iomgr/endpoint_pair_posix.cc index 5c5c246f998..3afbfd72543 100644 --- a/src/core/lib/iomgr/endpoint_pair_posix.cc +++ b/src/core/lib/iomgr/endpoint_pair_posix.cc @@ -59,11 +59,11 @@ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char* name, grpc_core::ExecCtx exec_ctx; gpr_asprintf(&final_name, "%s:client", name); - p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, false), args, + p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, true), args, "socketpair-server"); gpr_free(final_name); gpr_asprintf(&final_name, "%s:server", name); - p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, false), args, + p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, true), args, "socketpair-client"); gpr_free(final_name); diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index 86a0243d2ef..e8ee5c4ce94 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -386,15 +386,27 @@ static bool fd_is_shutdown(grpc_fd* fd) { } static void fd_notify_on_read(grpc_fd* fd, grpc_closure* closure) { - fd->read_closure->NotifyOn(closure); + if (closure != nullptr) { + fd->read_closure->NotifyOn(closure); + } else { + fd->read_closure->SetReady(); + } } static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) { - fd->write_closure->NotifyOn(closure); + if (closure != nullptr) { + fd->write_closure->NotifyOn(closure); + } else { + fd->write_closure->SetReady(); + } } static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) { - fd->error_closure->NotifyOn(closure); + if (closure != nullptr) { + fd->error_closure->NotifyOn(closure); + } else { + fd->error_closure->SetReady(); + } } static void fd_become_readable(grpc_fd* fd, grpc_pollset* notifier) { diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index 7b368410cf6..b17aa905738 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -539,15 +539,27 @@ static void fd_shutdown(grpc_fd* fd, grpc_error* why) { } static void fd_notify_on_read(grpc_fd* fd, grpc_closure* closure) { - fd->read_closure->NotifyOn(closure); + if (closure != nullptr) { + fd->read_closure->NotifyOn(closure); + } else { + fd->read_closure->SetReady(); + } } static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) { - fd->write_closure->NotifyOn(closure); + if (closure != nullptr) { + fd->write_closure->NotifyOn(closure); + } else { + fd->write_closure->SetReady(); + } } static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) { - fd->error_closure->NotifyOn(closure); + if (closure != nullptr) { + fd->error_closure->NotifyOn(closure); + } else { + fd->error_closure->SetReady(); + } } /******************************************************************************* diff --git a/src/core/lib/iomgr/ev_epollsig_linux.cc b/src/core/lib/iomgr/ev_epollsig_linux.cc index 2189801c187..7bdfa22b8e4 100644 --- a/src/core/lib/iomgr/ev_epollsig_linux.cc +++ b/src/core/lib/iomgr/ev_epollsig_linux.cc @@ -947,15 +947,27 @@ static void fd_shutdown(grpc_fd* fd, grpc_error* why) { } static void fd_notify_on_read(grpc_fd* fd, grpc_closure* closure) { - fd->read_closure->NotifyOn(closure); + if (closure != nullptr) { + fd->read_closure->NotifyOn(closure); + } else { + fd->read_closure->SetReady(); + } } static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) { - fd->write_closure->NotifyOn(closure); + if (closure != nullptr) { + fd->write_closure->NotifyOn(closure); + } else { + fd->write_closure->SetReady(); + } } static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) { - fd->error_closure->NotifyOn(closure); + if (closure != nullptr) { + fd->error_closure->NotifyOn(closure); + } else { + fd->error_closure->SetReady(); + } } /******************************************************************************* diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 1139b3273ab..6ca985cb221 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -200,8 +200,8 @@ bool grpc_event_engine_can_track_errors(void) { grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) { GRPC_POLLING_API_TRACE("fd_create(%d, %s, %d)", fd, name, track_err); GRPC_FD_TRACE("fd_create(%d, %s, %d)", fd, name, track_err); - GPR_DEBUG_ASSERT(!track_err || g_event_engine->can_track_err); - return g_event_engine->fd_create(fd, name, track_err); + return g_event_engine->fd_create(fd, name, + track_err && g_event_engine->can_track_err); } int grpc_fd_wrapped_fd(grpc_fd* fd) { diff --git a/src/core/lib/iomgr/internal_errqueue.cc b/src/core/lib/iomgr/internal_errqueue.cc new file mode 100644 index 00000000000..3f3da668406 --- /dev/null +++ b/src/core/lib/iomgr/internal_errqueue.cc @@ -0,0 +1,40 @@ +/* + * + * 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 + +#include "src/core/lib/iomgr/port.h" + +#include "src/core/lib/iomgr/internal_errqueue.h" + +#ifdef GRPC_POSIX_SOCKET_TCP + +#ifdef GPR_LINUX +#include +#endif /* GPR_LINUX */ + +bool kernel_supports_errqueue() { +#ifdef LINUX_VERSION_CODE +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) + return true; +#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) */ +#endif /* LINUX_VERSION_CODE */ + return false; +} + +#endif /* GRPC_POSIX_SOCKET_TCP */ diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h new file mode 100644 index 00000000000..92292e95e10 --- /dev/null +++ b/src/core/lib/iomgr/internal_errqueue.h @@ -0,0 +1,76 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H +#define GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H + +#include + +#include "src/core/lib/iomgr/port.h" + +#ifdef GRPC_POSIX_SOCKET_TCP + +#include +#include + +#ifdef GRPC_LINUX_ERRQUEUE +#include +#include +#include +#endif /* GRPC_LINUX_ERRQUEUE */ + +namespace grpc_core { +/* Redefining scm_timestamping in the same way that defines + * it, so that code compiles on systems that don't have it. */ +struct scm_timestamping { + struct timespec ts[3]; +}; + +/* Also redefine timestamp types */ +/* The timestamp type for when the driver passed skb to NIC, or HW. */ +constexpr int SCM_TSTAMP_SND = 0; +/* The timestamp type for when data entered the packet scheduler. */ +constexpr int SCM_TSTAMP_SCHED = 1; +/* The timestamp type for when data acknowledged by peer. */ +constexpr int SCM_TSTAMP_ACK = 2; + +/* Redefine required constants from */ +constexpr uint32_t SOF_TIMESTAMPING_TX_SOFTWARE = 1u << 1; +constexpr uint32_t SOF_TIMESTAMPING_SOFTWARE = 1u << 4; +constexpr uint32_t SOF_TIMESTAMPING_OPT_ID = 1u << 7; +constexpr uint32_t SOF_TIMESTAMPING_TX_SCHED = 1u << 8; +constexpr uint32_t SOF_TIMESTAMPING_TX_ACK = 1u << 9; +constexpr uint32_t SOF_TIMESTAMPING_OPT_TSONLY = 1u << 11; + +constexpr uint32_t kTimestampingSocketOptions = SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_OPT_ID | + SOF_TIMESTAMPING_OPT_TSONLY; + +constexpr uint32_t kTimestampingRecordingOptions = + SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_TX_ACK; + +/* Returns true if kernel is capable of supporting errqueue and timestamping. + * Currently allowing only linux kernels above 4.0.0 + */ +bool kernel_supports_errqueue(); +} // namespace grpc_core + +#endif /* GRPC_POSIX_SOCKET_TCP */ + +#endif /* GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H */ diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 80d8e63cdd0..a06e9f827b7 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -60,6 +60,7 @@ #define GRPC_HAVE_IP_PKTINFO 1 #define GRPC_HAVE_MSG_NOSIGNAL 1 #define GRPC_HAVE_UNIX_SOCKET 1 +#define GRPC_LINUX_ERRQUEUE 1 #define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1 #define GRPC_POSIX_FORK 1 #define GRPC_POSIX_HOST_NAME_MAX 1 diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc index 296ee74311a..9c989b7dfee 100644 --- a/src/core/lib/iomgr/tcp_client_posix.cc +++ b/src/core/lib/iomgr/tcp_client_posix.cc @@ -279,7 +279,7 @@ grpc_error* grpc_tcp_client_prepare_fd(const grpc_channel_args* channel_args, } addr_str = grpc_sockaddr_to_uri(mapped_addr); gpr_asprintf(&name, "tcp-client:%s", addr_str); - *fdobj = grpc_fd_create(fd, name, false); + *fdobj = grpc_fd_create(fd, name, true); gpr_free(name); gpr_free(addr_str); return GRPC_ERROR_NONE; diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc index 990e8d632b9..e02a1898f25 100644 --- a/src/core/lib/iomgr/tcp_custom.cc +++ b/src/core/lib/iomgr/tcp_custom.cc @@ -221,7 +221,7 @@ static void custom_write_callback(grpc_custom_socket* socket, } static void endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* write_slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 9df2e206b2e..97251e7bdcc 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -26,7 +26,9 @@ #include "src/core/lib/iomgr/tcp_posix.h" #include +#include #include +#include #include #include #include @@ -45,6 +47,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/buffer_list.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/profiling/timers.h" @@ -96,17 +99,26 @@ struct grpc_tcp { grpc_closure read_done_closure; grpc_closure write_done_closure; + grpc_closure error_closure; char* peer_string; grpc_resource_user* resource_user; grpc_resource_user_slice_allocator slice_allocator; + + grpc_core::TracedBuffer* head; + gpr_mu traced_buffer_lock; + void* outgoing_buffer_arg; + int bytes_counter; + bool socket_ts_enabled; + gpr_atm stop_error_notification; }; struct backup_poller { gpr_mu* pollset_mu; grpc_closure run_poller; }; + } // namespace #define BACKUP_POLLER_POLLSET(b) ((grpc_pollset*)((b) + 1)) @@ -301,6 +313,7 @@ static void tcp_free(grpc_tcp* tcp) { grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); gpr_free(tcp->peer_string); + gpr_mu_destroy(&tcp->traced_buffer_lock); gpr_free(tcp); } @@ -346,6 +359,11 @@ static void tcp_destroy(grpc_endpoint* ep) { grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = reinterpret_cast(ep); grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); + if (grpc_event_engine_can_track_errors()) { + // gpr_log(GPR_INFO, "stop errors"); + gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); + grpc_fd_notify_on_error(tcp->em_fd, nullptr); + } TCP_UNREF(tcp, "destroy"); } @@ -512,6 +530,215 @@ static void tcp_read(grpc_endpoint* ep, grpc_slice_buffer* incoming_buffer, } } +/** This is to be called if outgoing_buffer_arg is not null. On linux platforms, + * this will call sendmsg with socket options set to collect timestamps inside + * the kernel. On return, sent_length is set to the return value of the sendmsg + * call. Returns false if setting the socket options failed. This is not + * implemented for non-linux platforms currently, and crashes out. + */ +static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, + size_t sending_length, + ssize_t* sent_length, grpc_error** error); +static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error); + +#ifdef GRPC_LINUX_ERRQUEUE +static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, + size_t sending_length, + ssize_t* sent_length, + grpc_error** error) { + if (!tcp->socket_ts_enabled) { + // gpr_log(GPR_INFO, "setting options yo"); + uint32_t opt = grpc_core::kTimestampingSocketOptions; + if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, + static_cast(&opt), sizeof(opt)) != 0) { + *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "setsockopt"), tcp); + grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); + gpr_log(GPR_INFO, "failed to set"); + return false; + } + tcp->socket_ts_enabled = true; + } + union { + char cmsg_buf[CMSG_SPACE(sizeof(uint32_t))]; + struct cmsghdr align; + } u; + cmsghdr* cmsg = reinterpret_cast(u.cmsg_buf); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SO_TIMESTAMPING; + cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t)); + *reinterpret_cast(CMSG_DATA(cmsg)) = + grpc_core::kTimestampingRecordingOptions; + msg->msg_control = u.cmsg_buf; + msg->msg_controllen = CMSG_SPACE(sizeof(uint32_t)); + + ssize_t length; + do { + GRPC_STATS_INC_SYSCALL_WRITE(); + length = sendmsg(tcp->fd, msg, SENDMSG_FLAGS); + } while (length < 0 && errno == EINTR); + *sent_length = length; + /* Only save timestamps if all the bytes were taken by sendmsg. */ + if (sending_length == static_cast(length)) { + gpr_mu_lock(&tcp->traced_buffer_lock); + grpc_core::TracedBuffer::AddNewEntry( + &tcp->head, static_cast(tcp->bytes_counter + length), + tcp->outgoing_buffer_arg); + gpr_mu_unlock(&tcp->traced_buffer_lock); + tcp->outgoing_buffer_arg = nullptr; + } + return true; +} + +struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, + struct cmsghdr* cmsg) { + auto next_cmsg = CMSG_NXTHDR(msg, cmsg); + if (next_cmsg == nullptr) { + gpr_log(GPR_ERROR, "Received timestamp without extended error"); + return cmsg; + } + + if (!(next_cmsg->cmsg_level == SOL_IP || next_cmsg->cmsg_level == SOL_IPV6) || + !(next_cmsg->cmsg_type == IP_RECVERR || + next_cmsg->cmsg_type == IPV6_RECVERR)) { + gpr_log(GPR_ERROR, "Unexpected cmsg"); + return cmsg; + } + + auto tss = + reinterpret_cast(CMSG_DATA(cmsg)); + auto serr = reinterpret_cast(CMSG_DATA(next_cmsg)); + if (serr->ee_errno != ENOMSG || + serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) { + gpr_log(GPR_ERROR, "Unexpected cmsg"); + return cmsg; + } + /* The error handling can potentially be done on another thread so we need + * to protect the traced buffer list. A lock free list might be better. Using + * a simple mutex for now. */ + gpr_mu_lock(&tcp->traced_buffer_lock); + // gpr_log(GPR_INFO, "processing timestamp"); + grpc_core::TracedBuffer::ProcessTimestamp(&tcp->head, serr, tss); + gpr_mu_unlock(&tcp->traced_buffer_lock); + return next_cmsg; +} + +/** For linux platforms, reads the socket's error queue and processes error + * messages from the queue. Returns true if all the errors processed were + * timestamps. Returns false if the any of the errors were not timestamps. For + * non-linux platforms, error processing is not enabled currently, and hence + * crashes out. + */ +static bool process_errors(grpc_tcp* tcp) { + // gpr_log(GPR_INFO, "process errors"); + while (true) { + // gpr_log(GPR_INFO, "looping"); + struct iovec iov; + iov.iov_base = nullptr; + iov.iov_len = 0; + struct msghdr msg; + msg.msg_name = nullptr; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 0; + msg.msg_flags = 0; + + union { + char rbuf[1024 /*CMSG_SPACE(sizeof(scm_timestamping)) + + CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in))*/]; + struct cmsghdr align; + } aligned_buf; + memset(&aligned_buf, 0, sizeof(aligned_buf)); + + msg.msg_control = aligned_buf.rbuf; + msg.msg_controllen = sizeof(aligned_buf.rbuf); + + int r, saved_errno; + do { + // gpr_log(GPR_INFO, "error recvmsg"); + r = recvmsg(tcp->fd, &msg, MSG_ERRQUEUE); + saved_errno = errno; + } while (r < 0 && saved_errno == EINTR); + + if (r == -1 && saved_errno == EAGAIN) { + // gpr_log(GPR_INFO, "here"); + return true; /* No more errors to process */ + } + if (r == -1) { + // gpr_log(GPR_INFO, "%d", saved_errno); + return false; + } + if ((msg.msg_flags & MSG_CTRUNC) == 1) { + gpr_log(GPR_INFO, "Error message was truncated."); + } + + // gpr_log(GPR_INFO, "%d %lu", r, msg.msg_controllen); + if (msg.msg_controllen == 0) { + /* There was no control message read. Return now */ + return true; + } + for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg && cmsg->cmsg_len; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level != SOL_SOCKET || + cmsg->cmsg_type != SCM_TIMESTAMPING) { + /* Got a weird one, not a timestamp */ + gpr_log(GPR_INFO, "weird %d %d %d", r, cmsg->cmsg_level, + cmsg->cmsg_type); + continue; + } + process_timestamp(tcp, &msg, cmsg); + } + } +} + +static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { + // gpr_log(GPR_INFO, "grpc_tcp_handle_error"); + grpc_tcp* tcp = static_cast(arg); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p got_error: %s", tcp, grpc_error_string(error)); + } + + if (error != GRPC_ERROR_NONE || + static_cast(gpr_atm_acq_load(&tcp->stop_error_notification))) { + /* We aren't going to register to hear on error anymore, so it is safe to + * unref. */ + // gpr_log(GPR_INFO, "%p %d", error, + // static_cast(gpr_atm_acq_load(&tcp->stop_error_notification))); + // gpr_log(GPR_INFO, "unref"); + grpc_core::TracedBuffer::Shutdown(&tcp->head, GRPC_ERROR_REF(error)); + TCP_UNREF(tcp, "error"); + // gpr_log(GPR_INFO, "here"); + } else { + if (!process_errors(tcp)) { + // gpr_log(GPR_INFO, "no timestamps"); + /* This was not a timestamps error. This was an actual error. Set the + * read and write closures to be ready. + */ + grpc_fd_notify_on_read(tcp->em_fd, nullptr); + grpc_fd_notify_on_write(tcp->em_fd, nullptr); + } + GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, + grpc_schedule_on_exec_ctx); + grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); + // gpr_log(GPR_INFO, "udhar se"); + } +} + +#else /* GRPC_LINUX_ERRQUEUE */ +static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, + size_t sending_length, + ssize_t* sent_length, + grpc_error** error) { + gpr_log(GPR_ERROR, "Write with timestamps not supported for this platform"); + GPR_ASSERT(0); + return false; +} + +static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { + gpr_log(GPR_ERROR, "Error handling is not supported for this platform"); + GPR_ASSERT(0); +} +#endif /* GRPC_LINUX_ERRQUEUE */ + /* returns true if done, false if pending; if returning true, *error is set */ #define MAX_WRITE_IOVEC 1000 static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { @@ -552,19 +779,26 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = iov_size; - msg.msg_control = nullptr; - msg.msg_controllen = 0; msg.msg_flags = 0; - - GRPC_STATS_INC_TCP_WRITE_SIZE(sending_length); - GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(iov_size); - - GPR_TIMER_SCOPE("sendmsg", 1); - do { - /* TODO(klempner): Cork if this is a partial write */ - GRPC_STATS_INC_SYSCALL_WRITE(); - sent_length = sendmsg(tcp->fd, &msg, SENDMSG_FLAGS); - } while (sent_length < 0 && errno == EINTR); + if (tcp->outgoing_buffer_arg != nullptr) { + if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length, + error)) + return true; /* something went wrong with timestamps */ + } else { + msg.msg_control = nullptr; + msg.msg_controllen = 0; + + GRPC_STATS_INC_TCP_WRITE_SIZE(sending_length); + GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(iov_size); + + GPR_TIMER_SCOPE("sendmsg", 1); + do { + /* TODO(klempner): Cork if this is a partial write */ + GRPC_STATS_INC_SYSCALL_WRITE(); + sent_length = sendmsg(tcp->fd, &msg, SENDMSG_FLAGS); + } while (sent_length < 0 && errno == EINTR); + } + // gpr_log(GPR_INFO, "sent length %ld", sent_length); if (sent_length < 0) { if (errno == EAGAIN) { @@ -588,6 +822,7 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { } GPR_ASSERT(tcp->outgoing_byte_idx == 0); + tcp->bytes_counter += sent_length; trailing = sending_length - static_cast(sent_length); while (trailing > 0) { size_t slice_length; @@ -602,7 +837,6 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { trailing -= slice_length; } } - if (outgoing_slice_idx == tcp->outgoing_buffer->count) { *error = GRPC_ERROR_NONE; grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); @@ -635,14 +869,14 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "write: %s", str); } - + // gpr_log(GPR_INFO, "scheduling callback"); GRPC_CLOSURE_SCHED(cb, error); TCP_UNREF(tcp, "write"); } } static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { GPR_TIMER_SCOPE("tcp_write", 0); grpc_tcp* tcp = reinterpret_cast(ep); grpc_error* error = GRPC_ERROR_NONE; @@ -670,6 +904,8 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, } tcp->outgoing_buffer = buf; tcp->outgoing_byte_idx = 0; + tcp->outgoing_buffer_arg = arg; + if (arg) GPR_ASSERT(grpc_event_engine_can_track_errors()); if (!tcp_flush(tcp, &error)) { TCP_REF(tcp, "write"); @@ -677,16 +913,20 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "write: delayed"); } + // gpr_log(GPR_INFO, "notify"); notify_on_write(tcp); } else { if (grpc_tcp_trace.enabled()) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "write: %s", str); } + // gpr_log(GPR_INFO, "sched"); GRPC_CLOSURE_SCHED(cb, error); } } +namespace {} /* namespace */ + static void tcp_add_to_pollset(grpc_endpoint* ep, grpc_pollset* pollset) { grpc_tcp* tcp = reinterpret_cast(ep); grpc_pollset_add_fd(pollset, tcp->em_fd); @@ -787,6 +1027,8 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->bytes_read_this_round = 0; /* Will be set to false by the very first endpoint read function */ tcp->is_first_read = true; + tcp->bytes_counter = -1; + tcp->socket_ts_enabled = false; /* paired with unref in grpc_tcp_destroy */ gpr_ref_init(&tcp->refcount, 1); gpr_atm_no_barrier_store(&tcp->shutdown_count, 0); @@ -798,6 +1040,16 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, /* Tell network status tracker about new endpoint */ grpc_network_status_register_endpoint(&tcp->base); grpc_resource_quota_unref_internal(resource_quota); + gpr_mu_init(&tcp->traced_buffer_lock); + tcp->head = nullptr; + /* Start being notified on errors if event engine can track errors. */ + if (grpc_event_engine_can_track_errors()) { + TCP_REF(tcp, "error"); + gpr_atm_rel_store(&tcp->stop_error_notification, 0); + GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, + grpc_schedule_on_exec_ctx); + grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); + } return &tcp->base; } @@ -816,6 +1068,11 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, tcp->release_fd = fd; tcp->release_fd_cb = done; grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); + if (grpc_event_engine_can_track_errors()) { + // gpr_log(GPR_INFO, "stop errors"); + gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); + grpc_fd_notify_on_error(tcp->em_fd, nullptr); + } TCP_UNREF(tcp, "destroy"); } diff --git a/src/core/lib/iomgr/tcp_posix.h b/src/core/lib/iomgr/tcp_posix.h index af89bd24db1..322af627275 100644 --- a/src/core/lib/iomgr/tcp_posix.h +++ b/src/core/lib/iomgr/tcp_posix.h @@ -31,7 +31,10 @@ #include +#include "src/core/lib/iomgr/port.h" + #include "src/core/lib/debug/trace.h" +#include "src/core/lib/iomgr/buffer_list.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/ev_posix.h" @@ -54,4 +57,9 @@ int grpc_tcp_fd(grpc_endpoint* ep); void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, grpc_closure* done); +/** Sets the callback function to call when timestamps for a write are + * collected. */ +void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*)); + #endif /* GRPC_CORE_LIB_IOMGR_TCP_POSIX_H */ diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc index 8ddf684feac..824db07fbfd 100644 --- a/src/core/lib/iomgr/tcp_server_posix.cc +++ b/src/core/lib/iomgr/tcp_server_posix.cc @@ -226,7 +226,7 @@ static void on_read(void* arg, grpc_error* err) { gpr_log(GPR_INFO, "SERVER_CONNECT: incoming connection: %s", addr_str); } - grpc_fd* fdobj = grpc_fd_create(fd, name, false); + grpc_fd* fdobj = grpc_fd_create(fd, name, true); read_notifier_pollset = sp->server->pollsets[static_cast(gpr_atm_no_barrier_fetch_add( @@ -362,7 +362,7 @@ static grpc_error* clone_port(grpc_tcp_listener* listener, unsigned count) { listener->sibling = sp; sp->server = listener->server; sp->fd = fd; - sp->emfd = grpc_fd_create(fd, name, false); + sp->emfd = grpc_fd_create(fd, name, true); memcpy(&sp->addr, &listener->addr, sizeof(grpc_resolved_address)); sp->port = port; sp->port_index = listener->port_index; 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 b9f81455729..9595c028ce0 100644 --- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc @@ -105,7 +105,7 @@ static grpc_error* add_socket_to_server(grpc_tcp_server* s, int fd, s->tail = sp; sp->server = s; sp->fd = fd; - sp->emfd = grpc_fd_create(fd, name, false); + sp->emfd = grpc_fd_create(fd, name, true); memcpy(&sp->addr, addr, sizeof(grpc_resolved_address)); sp->port = port; sp->port_index = port_index; diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 5d316d477b7..fd146c94b43 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -296,7 +296,7 @@ static void on_write(void* tcpp, grpc_error* error) { /* Initiates a write. */ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { grpc_tcp* tcp = (grpc_tcp*)ep; grpc_winsocket* socket = tcp->socket; grpc_winsocket_callback_info* info = &socket->write_info; diff --git a/src/core/lib/iomgr/udp_server.cc b/src/core/lib/iomgr/udp_server.cc index bdb2d0e7644..3dd7cab855c 100644 --- a/src/core/lib/iomgr/udp_server.cc +++ b/src/core/lib/iomgr/udp_server.cc @@ -152,7 +152,7 @@ GrpcUdpListener::GrpcUdpListener(grpc_udp_server* server, int fd, grpc_sockaddr_to_string(&addr_str, addr, 1); gpr_asprintf(&name, "udp-server-listener:%s", addr_str); gpr_free(addr_str); - emfd_ = grpc_fd_create(fd, name, false); + emfd_ = grpc_fd_create(fd, name, true); memcpy(&addr_, addr, sizeof(grpc_resolved_address)); GPR_ASSERT(emfd_); gpr_free(name); diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc index 840b2e73bcf..f40f969bb7f 100644 --- a/src/core/lib/security/transport/secure_endpoint.cc +++ b/src/core/lib/security/transport/secure_endpoint.cc @@ -254,7 +254,7 @@ static void flush_write_staging_buffer(secure_endpoint* ep, uint8_t** cur, } static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { GPR_TIMER_SCOPE("secure_endpoint.endpoint_write", 0); unsigned i; @@ -342,7 +342,7 @@ static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, return; } - grpc_endpoint_write(ep->wrapped_ep, &ep->output_buffer, cb); + grpc_endpoint_write(ep->wrapped_ep, &ep->output_buffer, cb, arg); } static void endpoint_shutdown(grpc_endpoint* secure_ep, grpc_error* why) { diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index aff723ed044..d76d5826388 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -259,7 +259,7 @@ static grpc_error* on_handshake_next_done_locked( grpc_slice_buffer_reset_and_unref_internal(&h->outgoing); grpc_slice_buffer_add(&h->outgoing, to_send); grpc_endpoint_write(h->args->endpoint, &h->outgoing, - &h->on_handshake_data_sent_to_peer); + &h->on_handshake_data_sent_to_peer, nullptr); } else if (handshaker_result == nullptr) { // There is nothing to send, but need to read from peer. grpc_endpoint_read(h->args->endpoint, h->args->read_buffer, diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 49185cc6487..2a74d2a95c5 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -82,6 +82,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -102,6 +103,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc index c03ebcf4096..ade23133c55 100644 --- a/test/core/bad_client/bad_client.cc +++ b/test/core/bad_client/bad_client.cc @@ -115,7 +115,7 @@ void grpc_run_client_side_validator(grpc_bad_client_arg* arg, uint32_t flags, grpc_schedule_on_exec_ctx); /* Write data */ - grpc_endpoint_write(sfd->client, &outgoing, &done_write_closure); + grpc_endpoint_write(sfd->client, &outgoing, &done_write_closure, nullptr); grpc_core::ExecCtx::Get()->Flush(); /* Await completion, unless the request is large and write may not finish diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index 3d133cfc186..f7396a16845 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -104,7 +104,7 @@ static void handle_write() { grpc_slice_buffer_reset_and_unref(&state.outgoing_buffer); grpc_slice_buffer_add(&state.outgoing_buffer, slice); - grpc_endpoint_write(state.tcp, &state.outgoing_buffer, &on_write); + grpc_endpoint_write(state.tcp, &state.outgoing_buffer, &on_write, nullptr); } static void handle_read(void* arg, grpc_error* error) { diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index f02fa9d9983..ea9c000efb9 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -201,7 +201,7 @@ static void on_client_write_done(void* arg, grpc_error* error) { &conn->client_write_buffer); conn->client_is_writing = true; grpc_endpoint_write(conn->client_endpoint, &conn->client_write_buffer, - &conn->on_client_write_done); + &conn->on_client_write_done, nullptr); } else { // No more writes. Unref the connection. proxy_connection_unref(conn, "write_done"); @@ -226,7 +226,7 @@ static void on_server_write_done(void* arg, grpc_error* error) { &conn->server_write_buffer); conn->server_is_writing = true; grpc_endpoint_write(conn->server_endpoint, &conn->server_write_buffer, - &conn->on_server_write_done); + &conn->on_server_write_done, nullptr); } else { // No more writes. Unref the connection. proxy_connection_unref(conn, "server_write"); @@ -257,7 +257,7 @@ static void on_client_read_done(void* arg, grpc_error* error) { proxy_connection_ref(conn, "client_read"); conn->server_is_writing = true; grpc_endpoint_write(conn->server_endpoint, &conn->server_write_buffer, - &conn->on_server_write_done); + &conn->on_server_write_done, nullptr); } // Read more data. grpc_endpoint_read(conn->client_endpoint, &conn->client_read_buffer, @@ -288,7 +288,7 @@ static void on_server_read_done(void* arg, grpc_error* error) { proxy_connection_ref(conn, "server_read"); conn->client_is_writing = true; grpc_endpoint_write(conn->client_endpoint, &conn->client_write_buffer, - &conn->on_client_write_done); + &conn->on_client_write_done, nullptr); } // Read more data. grpc_endpoint_read(conn->server_endpoint, &conn->server_read_buffer, @@ -340,7 +340,7 @@ static void on_server_connect_done(void* arg, grpc_error* error) { grpc_slice_buffer_add(&conn->client_write_buffer, slice); conn->client_is_writing = true; grpc_endpoint_write(conn->client_endpoint, &conn->client_write_buffer, - &conn->on_write_response_done); + &conn->on_write_response_done, nullptr); } /** diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index fb0490a95f4..a3d2ba2fc06 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -233,6 +233,19 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "buffer_list_test", + srcs = ["buffer_list_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + + grpc_cc_test( name = "tcp_server_posix_test", srcs = ["tcp_server_posix_test.cc"], diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc new file mode 100644 index 00000000000..9ffb71c85ff --- /dev/null +++ b/test/core/iomgr/buffer_list_test.cc @@ -0,0 +1,111 @@ +/* + * + * 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 "src/core/lib/iomgr/port.h" + +#include "src/core/lib/iomgr/buffer_list.h" + +#include + +#include "test/core/util/test_config.h" + +#ifdef GRPC_LINUX_ERRQUEUE + +static void TestShutdownFlushesListVerifier(void* arg, + grpc_core::Timestamps* ts, + grpc_error* error) { + GPR_ASSERT(error == GRPC_ERROR_NONE); + GPR_ASSERT(arg != nullptr); + gpr_atm* done = reinterpret_cast(arg); + gpr_atm_rel_store(done, static_cast(1)); +} + +/** Tests that all TracedBuffer elements in the list are flushed out on + * shutdown. + * Also tests that arg is passed correctly. + */ +static void TestShutdownFlushesList() { + grpc_core::grpc_tcp_set_write_timestamps_callback( + TestShutdownFlushesListVerifier); + grpc_core::TracedBuffer* list = nullptr; +#define NUM_ELEM 5 + gpr_atm verifier_called[NUM_ELEM]; + for (auto i = 0; i < NUM_ELEM; i++) { + gpr_atm_rel_store(&verifier_called[i], static_cast(0)); + grpc_core::TracedBuffer::AddNewEntry( + &list, i, static_cast(&verifier_called[i])); + } + grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE); + GPR_ASSERT(list == nullptr); + for (auto i = 0; i < NUM_ELEM; i++) { + GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) == + static_cast(1)); + } +} + +static void TestVerifierCalledOnAckVerifier(void* arg, + grpc_core::Timestamps* ts, + grpc_error* error) { + GPR_ASSERT(error == GRPC_ERROR_NONE); + GPR_ASSERT(arg != nullptr); + GPR_ASSERT(ts->acked_time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->acked_time.tv_sec == 123); + GPR_ASSERT(ts->acked_time.tv_nsec == 456); + gpr_atm* done = reinterpret_cast(arg); + gpr_atm_rel_store(done, static_cast(1)); +} + +/** Tests that the timestamp verifier is called on an ACK timestamp. + */ +static void TestVerifierCalledOnAck() { + struct sock_extended_err serr; + serr.ee_data = 213; + serr.ee_info = grpc_core::SCM_TSTAMP_ACK; + struct grpc_core::scm_timestamping tss; + tss.ts[0].tv_sec = 123; + tss.ts[0].tv_nsec = 456; + grpc_core::grpc_tcp_set_write_timestamps_callback( + TestVerifierCalledOnAckVerifier); + grpc_core::TracedBuffer* list = nullptr; + gpr_atm verifier_called; + gpr_atm_rel_store(&verifier_called, static_cast(0)); + grpc_core::TracedBuffer::AddNewEntry(&list, 213, &verifier_called); + grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, &tss); + GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast(1)); + GPR_ASSERT(list == nullptr); + grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE); +} + +static void TestTcpBufferList() { + TestVerifierCalledOnAck(); + TestShutdownFlushesList(); +} + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + TestTcpBufferList(); + grpc_shutdown(); + return 0; +} + +#else /* GRPC_LINUX_ERRQUEUE */ + +int main(int argc, char** argv) { return 1; } + +#endif /* GRPC_LINUX_ERRQUEUE */ diff --git a/test/core/iomgr/endpoint_tests.cc b/test/core/iomgr/endpoint_tests.cc index 8db8ac5ed6f..a9e8ba86c5d 100644 --- a/test/core/iomgr/endpoint_tests.cc +++ b/test/core/iomgr/endpoint_tests.cc @@ -150,8 +150,8 @@ static void read_and_write_test_write_handler(void* data, grpc_error* error) { &state->current_write_data); grpc_slice_buffer_reset_and_unref(&state->outgoing); grpc_slice_buffer_addn(&state->outgoing, slices, nslices); - grpc_endpoint_write(state->write_ep, &state->outgoing, - &state->done_write); + grpc_endpoint_write(state->write_ep, &state->outgoing, &state->done_write, + nullptr); gpr_free(slices); return; } @@ -294,7 +294,8 @@ static void multiple_shutdown_test(grpc_endpoint_test_config config) { grpc_slice_buffer_add(&slice_buffer, grpc_slice_from_copied_string("a")); grpc_endpoint_write(f.client_ep, &slice_buffer, GRPC_CLOSURE_CREATE(inc_on_failure, &fail_count, - grpc_schedule_on_exec_ctx)); + grpc_schedule_on_exec_ctx), + nullptr); wait_for_fail_count(&fail_count, 3); grpc_endpoint_shutdown(f.client_ep, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown")); diff --git a/test/core/iomgr/tcp_posix_test.cc b/test/core/iomgr/tcp_posix_test.cc index 3e87831e440..648150a765d 100644 --- a/test/core/iomgr/tcp_posix_test.cc +++ b/test/core/iomgr/tcp_posix_test.cc @@ -36,6 +36,9 @@ #include #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/buffer_list.h" +#include "src/core/lib/iomgr/ev_posix.h" +#include "src/core/lib/iomgr/sockaddr_posix.h" #include "src/core/lib/slice/slice_internal.h" #include "test/core/iomgr/endpoint_tests.h" #include "test/core/util/test_config.h" @@ -68,6 +71,48 @@ static void create_sockets(int sv[2]) { GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0); } +static void create_inet_sockets(int sv[2]) { + gpr_log(GPR_INFO, "create sockets"); + /* Prepare listening socket */ + struct sockaddr_in addr; + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + int sock = socket(AF_INET, SOCK_STREAM, 0); + GPR_ASSERT(sock); + GPR_ASSERT(bind(sock, (sockaddr*)&addr, sizeof(sockaddr_in)) == 0); + listen(sock, 1); + + /* Prepare client socket and connect to server */ + socklen_t len = sizeof(sockaddr_in); + GPR_ASSERT(getsockname(sock, (sockaddr*)&addr, &len) == 0); + + gpr_log(GPR_INFO, "%d\n", addr.sin_port); + char* addra = inet_ntoa(addr.sin_addr); + gpr_log(GPR_INFO, "%s\n", addra); + + int client = socket(AF_INET, SOCK_STREAM, 0); + GPR_ASSERT(client); + int ret; + do { + ret = connect(client, (sockaddr*)&addr, sizeof(sockaddr_in)); + } while (ret == -1 && errno == EINTR); + + /* Accept client connection */ + len = sizeof(socklen_t); + int server; + do { + server = accept(sock, (sockaddr*)&addr, (socklen_t*)&len); + } while (server == -1 && errno == EINTR); + GPR_ASSERT(server != -1); + + sv[0] = server; + sv[1] = client; + int flags = fcntl(sv[0], F_GETFL, 0); + GPR_ASSERT(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK) == 0); + flags = fcntl(sv[1], F_GETFL, 0); + GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0); +} + static ssize_t fill_socket(int fd) { ssize_t write_bytes; ssize_t total_bytes = 0; @@ -289,6 +334,7 @@ static grpc_slice* allocate_blocks(size_t num_bytes, size_t slice_size, static void write_done(void* user_data /* write_socket_state */, grpc_error* error) { + GPR_ASSERT(error == GRPC_ERROR_NONE); struct write_socket_state* state = static_cast(user_data); gpr_log(GPR_INFO, "Write done callback called"); @@ -314,17 +360,22 @@ void drain_socket_blocking(int fd, size_t num_bytes, size_t read_size) { for (;;) { grpc_pollset_worker* worker = nullptr; + gpr_log(GPR_INFO, "in loop"); gpr_mu_lock(g_mu); + gpr_log(GPR_INFO, "in locked polling"); GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(g_pollset, &worker, grpc_timespec_to_millis_round_up( grpc_timeout_milliseconds_to_deadline(10))))); + gpr_log(GPR_INFO, "done locked polling"); gpr_mu_unlock(g_mu); do { + gpr_log(GPR_INFO, "doing a read"); bytes_read = read(fd, buf, bytes_left > read_size ? read_size : bytes_left); + gpr_log(GPR_INFO, "done with read"); } while (bytes_read < 0 && errno == EINTR); GPR_ASSERT(bytes_read >= 0); for (i = 0; i < bytes_read; ++i) { @@ -340,10 +391,24 @@ void drain_socket_blocking(int fd, size_t num_bytes, size_t read_size) { gpr_free(buf); } +/* Verifier for timestamps callback for write_test */ +void timestamps_verifier(void* arg, grpc_core::Timestamps* ts, + grpc_error* error) { + GPR_ASSERT(error == GRPC_ERROR_NONE); + GPR_ASSERT(arg != nullptr); + GPR_ASSERT(ts->sendmsg_time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->scheduled_time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->acked_time.clock_type == GPR_CLOCK_REALTIME); + gpr_atm* done_timestamps = (gpr_atm*)arg; + gpr_atm_rel_store(done_timestamps, static_cast(1)); +} + /* Write to a socket using the grpc_tcp API, then drain it directly. Note that if the write does not complete immediately we need to drain the - socket in parallel with the read. */ -static void write_test(size_t num_bytes, size_t slice_size) { + socket in parallel with the read. If collect_timestamps is true, it will + try to get timestamps for the write. */ +static void write_test(size_t num_bytes, size_t slice_size, + bool collect_timestamps) { int sv[2]; grpc_endpoint* ep; struct write_socket_state state; @@ -356,19 +421,27 @@ static void write_test(size_t num_bytes, size_t slice_size) { grpc_timespec_to_millis_round_up(grpc_timeout_seconds_to_deadline(20)); grpc_core::ExecCtx exec_ctx; + if (collect_timestamps && !grpc_event_engine_can_track_errors()) { + return; + } + gpr_log(GPR_INFO, "Start write test with %" PRIuPTR " bytes, slice size %" PRIuPTR, num_bytes, slice_size); - create_sockets(sv); + if (collect_timestamps) { + create_inet_sockets(sv); + } else { + create_sockets(sv); + } grpc_arg a[1]; a[0].key = const_cast(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER, a[0].value.integer = static_cast(slice_size); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; - ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test", false), &args, - "test"); + ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test", collect_timestamps), + &args, "test"); grpc_endpoint_add_to_pollset(ep, g_pollset); state.ep = ep; @@ -381,18 +454,28 @@ static void write_test(size_t num_bytes, size_t slice_size) { GRPC_CLOSURE_INIT(&write_done_closure, write_done, &state, grpc_schedule_on_exec_ctx); - grpc_endpoint_write(ep, &outgoing, &write_done_closure); + gpr_atm done_timestamps; + gpr_atm_rel_store(&done_timestamps, static_cast(0)); + grpc_endpoint_write(ep, &outgoing, &write_done_closure, + grpc_event_engine_can_track_errors() && collect_timestamps + ? (void*)&done_timestamps + : nullptr); + gpr_log(GPR_INFO, "about to drain"); drain_socket_blocking(sv[0], num_bytes, num_bytes); + gpr_log(GPR_INFO, "done drain"); + exec_ctx.Flush(); gpr_mu_lock(g_mu); for (;;) { grpc_pollset_worker* worker = nullptr; - if (state.write_done) { + if (state.write_done && + (!(grpc_event_engine_can_track_errors() && collect_timestamps) || + gpr_atm_acq_load(&done_timestamps) == static_cast(1))) { break; } GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(g_pollset, &worker, deadline))); gpr_mu_unlock(g_mu); - + exec_ctx.Flush(); gpr_mu_lock(g_mu); } gpr_mu_unlock(g_mu); @@ -488,6 +571,7 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) { } void run_tests(void) { + gpr_log(GPR_INFO, "run tests"); size_t i = 0; read_test(100, 8192); @@ -496,15 +580,25 @@ void run_tests(void) { read_test(10000, 1); large_read_test(8192); large_read_test(1); - - write_test(100, 8192); - write_test(100, 1); - write_test(100000, 8192); - write_test(100000, 1); - write_test(100000, 137); + gpr_log(GPR_INFO, "done read tests"); + + write_test(100, 8192, false); + write_test(100, 1, false); + write_test(100000, 8192, false); + write_test(100000, 1, false); + write_test(100000, 137, false); + gpr_log(GPR_INFO, "done normal write tests"); + + write_test(100, 8192, true); + write_test(100, 1, true); + write_test(100000, 8192, true); + write_test(100000, 1, true); + write_test(100, 137, true); + gpr_log(GPR_INFO, "done super write tests"); for (i = 1; i < 1000; i = GPR_MAX(i + 1, i * 5 / 4)) { - write_test(40320, i); + write_test(40320, i, false); + write_test(40320, i, true); } release_fd_test(100, 8192); @@ -549,6 +643,8 @@ int main(int argc, char** argv) { grpc_closure destroyed; grpc_test_init(argc, argv); grpc_init(); + gpr_log(GPR_INFO, "here"); + grpc_core::grpc_tcp_set_write_timestamps_callback(timestamps_verifier); { grpc_core::ExecCtx exec_ctx; g_pollset = static_cast(gpr_zalloc(grpc_pollset_size())); diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc index 1156cd5fc5c..ef6fd62b516 100644 --- a/test/core/util/mock_endpoint.cc +++ b/test/core/util/mock_endpoint.cc @@ -55,7 +55,7 @@ static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, } static void me_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { mock_endpoint* m = reinterpret_cast(ep); for (size_t i = 0; i < slices->count; i++) { m->on_write(slices->slices[i]); diff --git a/test/core/util/passthru_endpoint.cc b/test/core/util/passthru_endpoint.cc index 59582167478..3cc8ad6fe14 100644 --- a/test/core/util/passthru_endpoint.cc +++ b/test/core/util/passthru_endpoint.cc @@ -76,7 +76,7 @@ static half* other_half(half* h) { } static void me_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { half* m = other_half(reinterpret_cast(ep)); gpr_mu_lock(&m->parent->mu); grpc_error* error = GRPC_ERROR_NONE; diff --git a/test/core/util/trickle_endpoint.cc b/test/core/util/trickle_endpoint.cc index f2efb049b49..62ed72a6295 100644 --- a/test/core/util/trickle_endpoint.cc +++ b/test/core/util/trickle_endpoint.cc @@ -62,7 +62,7 @@ static void maybe_call_write_cb_locked(trickle_endpoint* te) { } static void te_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { trickle_endpoint* te = reinterpret_cast(ep); gpr_mu_lock(&te->mu); GPR_ASSERT(te->write_cb == nullptr); @@ -186,7 +186,8 @@ size_t grpc_trickle_endpoint_trickle(grpc_endpoint* ep) { te->last_write = now; grpc_endpoint_write( te->wrapped, &te->writing_buffer, - GRPC_CLOSURE_CREATE(te_finish_write, te, grpc_schedule_on_exec_ctx)); + GRPC_CLOSURE_CREATE(te_finish_write, te, grpc_schedule_on_exec_ctx), + nullptr); maybe_call_write_cb_locked(te); } } diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index 1e9bd273aaf..189923a841e 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -96,7 +96,7 @@ class DummyEndpoint : public grpc_endpoint { } static void write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { GRPC_CLOSURE_SCHED(cb, GRPC_ERROR_NONE); } diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index ba322a90a54..7f526b2e2d2 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1065,6 +1065,7 @@ src/core/lib/http/format_request.h \ src/core/lib/http/httpcli.h \ src/core/lib/http/parser.h \ src/core/lib/iomgr/block_annotate.h \ +src/core/lib/iomgr/buffer_list.h \ src/core/lib/iomgr/call_combiner.h \ src/core/lib/iomgr/closure.h \ src/core/lib/iomgr/combiner.h \ @@ -1080,6 +1081,7 @@ src/core/lib/iomgr/ev_posix.h \ src/core/lib/iomgr/exec_ctx.h \ src/core/lib/iomgr/executor.h \ src/core/lib/iomgr/gethostname.h \ +src/core/lib/iomgr/internal_errqueue.h \ src/core/lib/iomgr/iocp_windows.h \ src/core/lib/iomgr/iomgr.h \ src/core/lib/iomgr/iomgr_custom.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 576950934ec..9307302aef5 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1153,6 +1153,8 @@ src/core/lib/http/parser.cc \ src/core/lib/http/parser.h \ src/core/lib/iomgr/README.md \ src/core/lib/iomgr/block_annotate.h \ +src/core/lib/iomgr/buffer_list.cc \ +src/core/lib/iomgr/buffer_list.h \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/call_combiner.h \ src/core/lib/iomgr/closure.h \ @@ -1188,6 +1190,8 @@ src/core/lib/iomgr/gethostname.h \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ +src/core/lib/iomgr/internal_errqueue.cc \ +src/core/lib/iomgr/internal_errqueue.h \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iocp_windows.h \ src/core/lib/iomgr/iomgr.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 7953fa37723..ef6141dfb11 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -163,6 +163,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "buffer_list_test", + "src": [ + "test/core/iomgr/buffer_list_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -9385,6 +9402,7 @@ "src/core/lib/http/format_request.cc", "src/core/lib/http/httpcli.cc", "src/core/lib/http/parser.cc", + "src/core/lib/iomgr/buffer_list.cc", "src/core/lib/iomgr/call_combiner.cc", "src/core/lib/iomgr/combiner.cc", "src/core/lib/iomgr/endpoint.cc", @@ -9405,6 +9423,7 @@ "src/core/lib/iomgr/gethostname_fallback.cc", "src/core/lib/iomgr/gethostname_host_name_max.cc", "src/core/lib/iomgr/gethostname_sysconf.cc", + "src/core/lib/iomgr/internal_errqueue.cc", "src/core/lib/iomgr/iocp_windows.cc", "src/core/lib/iomgr/iomgr.cc", "src/core/lib/iomgr/iomgr_custom.cc", @@ -9564,6 +9583,7 @@ "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", "src/core/lib/iomgr/block_annotate.h", + "src/core/lib/iomgr/buffer_list.h", "src/core/lib/iomgr/call_combiner.h", "src/core/lib/iomgr/closure.h", "src/core/lib/iomgr/combiner.h", @@ -9579,6 +9599,7 @@ "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", + "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", "src/core/lib/iomgr/iomgr_custom.h", @@ -9714,6 +9735,7 @@ "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", "src/core/lib/iomgr/block_annotate.h", + "src/core/lib/iomgr/buffer_list.h", "src/core/lib/iomgr/call_combiner.h", "src/core/lib/iomgr/closure.h", "src/core/lib/iomgr/combiner.h", @@ -9729,6 +9751,7 @@ "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", + "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", "src/core/lib/iomgr/iomgr_custom.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 5c556a2f52f..3abca8efd84 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -195,6 +195,26 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "gtest": false, + "language": "c", + "name": "buffer_list_test", + "platforms": [ + "linux" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From 0d757a659fd24ecfed801614565d2408e2e302fc Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 16 Jul 2018 16:21:43 -0700 Subject: [PATCH 028/546] Adding docs and cleaning up --- src/core/lib/iomgr/buffer_list.cc | 11 +--- src/core/lib/iomgr/buffer_list.h | 35 +++++++---- src/core/lib/iomgr/endpoint.h | 2 + src/core/lib/iomgr/endpoint_cfstream.cc | 2 +- src/core/lib/iomgr/internal_errqueue.h | 6 ++ src/core/lib/iomgr/tcp_posix.cc | 79 +++++++++++++------------ src/core/lib/iomgr/tcp_posix.h | 5 -- test/core/iomgr/tcp_posix_test.cc | 19 ------ 8 files changed, 77 insertions(+), 82 deletions(-) diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index 4f0b522cca5..8d1645d0dec 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -31,14 +31,12 @@ namespace grpc_core { void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, void* arg) { - gpr_log(GPR_INFO, "Adding new entry %u", seq_no); GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* new_elem = New(seq_no, arg); /* Store the current time as the sendmsg time. */ new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME); if (*head == nullptr) { *head = new_elem; - gpr_log(GPR_INFO, "returning"); return; } /* Append at the end. */ @@ -47,16 +45,18 @@ void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, ptr = ptr->next_; } ptr->next_ = new_elem; - gpr_log(GPR_INFO, "returning"); } namespace { +/** Fills gpr_timespec gts based on values from timespec ts */ void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) { gts->tv_sec = ts->tv_sec; gts->tv_nsec = static_cast(ts->tv_nsec); gts->clock_type = GPR_CLOCK_REALTIME; } +/** The saved callback function that will be invoked when we get all the + * timestamps that we are going to get for a TracedBuffer. */ void (*timestamps_callback)(void*, grpc_core::Timestamps*, grpc_error* shutdown_err); } /* namespace */ @@ -64,12 +64,10 @@ void (*timestamps_callback)(void*, grpc_core::Timestamps*, void TracedBuffer::ProcessTimestamp(TracedBuffer** head, struct sock_extended_err* serr, struct scm_timestamping* tss) { - gpr_log(GPR_INFO, "Got timestamp %d", serr->ee_data); GPR_DEBUG_ASSERT(head != nullptr); TracedBuffer* elem = *head; TracedBuffer* next = nullptr; while (elem != nullptr) { - gpr_log(GPR_INFO, "looping"); /* The byte number refers to the sequence number of the last byte which this * timestamp relates to. For scheduled and send, we are interested in the * timestamp for the first byte, whereas for ack, we are interested in the @@ -77,17 +75,14 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head, if (serr->ee_data >= elem->seq_no_) { switch (serr->ee_info) { case SCM_TSTAMP_SCHED: - gpr_log(GPR_INFO, "type sched\n"); fill_gpr_from_timestamp(&(elem->ts_.scheduled_time), &(tss->ts[0])); elem = elem->next_; break; case SCM_TSTAMP_SND: - gpr_log(GPR_INFO, "type send\n"); fill_gpr_from_timestamp(&(elem->ts_.sent_time), &(tss->ts[0])); elem = elem->next_; break; case SCM_TSTAMP_ACK: - gpr_log(GPR_INFO, "type ack\n"); if (serr->ee_data >= elem->seq_no_) { fill_gpr_from_timestamp(&(elem->ts_.acked_time), &(tss->ts[0])); /* Got all timestamps. Do the callback and free this TracedBuffer. diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index d42f97ff97e..0f66dcc8727 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -37,20 +37,34 @@ struct Timestamps { gpr_timespec acked_time; }; +/** TracedBuffer is a class to keep track of timestamps for a specific buffer in + * the TCP layer. We are only tracking timestamps for Linux kernels and hence + * this class would only be used by Linux platforms. For all other platforms, + * TracedBuffer would be an empty class. + * + * The timestamps collected are according to grpc_core::Timestamps declared + * above. + * + * A TracedBuffer list is kept track of using the head element of the list. If + * the head element of the list is nullptr, then the list is empty. + */ #ifdef GRPC_LINUX_ERRQUEUE class TracedBuffer { public: - /** Add a new entry in the TracedBuffer list pointed to by head */ + /** Add a new entry in the TracedBuffer list pointed to by head. Also saves + * sendmsg_time with the current timestamp. */ static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no, void* arg); - /** Processes a timestamp received */ + /** Processes a received timestamp based on sock_extended_err and + * scm_timestamping structures. It will invoke the timestamps callback if the + * timestamp type is SCM_TSTAMP_ACK. */ static void ProcessTimestamp(grpc_core::TracedBuffer** head, struct sock_extended_err* serr, struct scm_timestamping* tss); - /** Calls the callback for each traced buffer in the list with timestamps that - * it has. */ + /** Cleans the list by calling the callback for each traced buffer in the list + * with timestamps that it has. */ static void Shutdown(grpc_core::TracedBuffer** head, grpc_error* shutdown_err); @@ -58,24 +72,23 @@ class TracedBuffer { GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW TracedBuffer(int seq_no, void* arg) - : seq_no_(seq_no), arg_(arg), next_(nullptr) { - gpr_log(GPR_INFO, "seq_no %d", seq_no_); - } + : seq_no_(seq_no), arg_(arg), next_(nullptr) {} uint32_t seq_no_; /* The sequence number for the last byte in the buffer */ void* arg_; /* The arg to pass to timestamps_callback */ - grpc_core::Timestamps ts_; - grpc_core::TracedBuffer* next_; + grpc_core::Timestamps ts_; /* The timestamps corresponding to this buffer */ + grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */ }; #else /* GRPC_LINUX_ERRQUEUE */ class TracedBuffer {}; #endif /* GRPC_LINUX_ERRQUEUE */ -/** Sets the timestamp callback */ +/** Sets the callback function to call when timestamps for a write are + * collected. The callback does not own a reference to error. */ void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, grpc_core::Timestamps*, grpc_error* error)); -}; // namespace grpc_core +}; /* namespace grpc_core */ #endif /* GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H */ diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h index ea39ea632eb..1f590a80cae 100644 --- a/src/core/lib/iomgr/endpoint.h +++ b/src/core/lib/iomgr/endpoint.h @@ -72,6 +72,8 @@ int grpc_endpoint_get_fd(grpc_endpoint* ep); \a slices may be mutated at will by the endpoint until cb is called. No guarantee is made to the content of slices after a write EXCEPT that it is a valid slice buffer. + \a arg is platform specific. It is currently only used by TCP on linux + platforms as an argument that would be forwarded to the timestamps callback. */ void grpc_endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb, void* arg); diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc index 70d674f7504..df2cf508c8f 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.cc +++ b/src/core/lib/iomgr/endpoint_cfstream.cc @@ -268,7 +268,7 @@ static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices, } static void CFStreamWrite(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, void *arg) { + grpc_closure* cb, void* arg) { CFStreamEndpoint* ep_impl = reinterpret_cast(ep); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_DEBUG, "CFStream endpoint:%p write (%p, %p) length:%zu", diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h index 92292e95e10..bbe3377b430 100644 --- a/src/core/lib/iomgr/internal_errqueue.h +++ b/src/core/lib/iomgr/internal_errqueue.h @@ -16,6 +16,12 @@ * */ +/* This file contains constants defined in and + * so as to allow collecting network timestamps in the + * kernel. This file allows tcp_posix.cc to compile on platforms that do not + * have and . + */ + #ifndef GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H #define GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 97251e7bdcc..4300a9f8829 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -106,12 +106,16 @@ struct grpc_tcp { grpc_resource_user* resource_user; grpc_resource_user_slice_allocator slice_allocator; - grpc_core::TracedBuffer* head; - gpr_mu traced_buffer_lock; - void* outgoing_buffer_arg; - int bytes_counter; - bool socket_ts_enabled; - gpr_atm stop_error_notification; + grpc_core::TracedBuffer* head; /* List of traced buffers */ + gpr_mu traced_buffer_lock; /* Lock for access to list of traced buffers */ + void* outgoing_buffer_arg; /* buffer arg provided on grpc_endpoint_write */ + int bytes_counter; /* Current TCP relative sequence number. Used for + timestamping traced buffers. */ + bool socket_ts_enabled; /* True if timestamping options are set on the socket + */ + gpr_atm + stop_error_notification; /* Set to 1 if we do not want to be notified on + errors anymore */ }; struct backup_poller { @@ -360,7 +364,6 @@ static void tcp_destroy(grpc_endpoint* ep) { grpc_tcp* tcp = reinterpret_cast(ep); grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { - // gpr_log(GPR_INFO, "stop errors"); gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); grpc_fd_notify_on_error(tcp->em_fd, nullptr); } @@ -539,6 +542,8 @@ static void tcp_read(grpc_endpoint* ep, grpc_slice_buffer* incoming_buffer, static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, size_t sending_length, ssize_t* sent_length, grpc_error** error); + +/** The callback function to be invoked when we get an error on the socket. */ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error); #ifdef GRPC_LINUX_ERRQUEUE @@ -547,13 +552,14 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, ssize_t* sent_length, grpc_error** error) { if (!tcp->socket_ts_enabled) { - // gpr_log(GPR_INFO, "setting options yo"); uint32_t opt = grpc_core::kTimestampingSocketOptions; if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, static_cast(&opt), sizeof(opt)) != 0) { *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "setsockopt"), tcp); grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); - gpr_log(GPR_INFO, "failed to set"); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_ERROR, "Failed to set timestamping options on the socket."); + } return false; } tcp->socket_ts_enabled = true; @@ -589,18 +595,29 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, return true; } +/** Reads \a cmsg to derive timestamps from the control messages. If a valid + * timestamp is found, the traced buffer list is updated with this timestamp. + * The caller of this function should be looping on the control messages found + * in \a msg. \a cmsg should point to the control message that the caller wants + * processed. + * On return, a pointer to a control message is returned. On the next iteration, + * CMSG_NXTHDR(msg, ret_val) should be passed as \a cmsg. */ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, struct cmsghdr* cmsg) { auto next_cmsg = CMSG_NXTHDR(msg, cmsg); if (next_cmsg == nullptr) { - gpr_log(GPR_ERROR, "Received timestamp without extended error"); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_ERROR, "Received timestamp without extended error"); + } return cmsg; } if (!(next_cmsg->cmsg_level == SOL_IP || next_cmsg->cmsg_level == SOL_IPV6) || !(next_cmsg->cmsg_type == IP_RECVERR || next_cmsg->cmsg_type == IPV6_RECVERR)) { - gpr_log(GPR_ERROR, "Unexpected cmsg"); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_ERROR, "Unexpected control message"); + } return cmsg; } @@ -609,14 +626,13 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, auto serr = reinterpret_cast(CMSG_DATA(next_cmsg)); if (serr->ee_errno != ENOMSG || serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) { - gpr_log(GPR_ERROR, "Unexpected cmsg"); + gpr_log(GPR_ERROR, "Unexpected control message"); return cmsg; } /* The error handling can potentially be done on another thread so we need * to protect the traced buffer list. A lock free list might be better. Using * a simple mutex for now. */ gpr_mu_lock(&tcp->traced_buffer_lock); - // gpr_log(GPR_INFO, "processing timestamp"); grpc_core::TracedBuffer::ProcessTimestamp(&tcp->head, serr, tss); gpr_mu_unlock(&tcp->traced_buffer_lock); return next_cmsg; @@ -624,14 +640,12 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, /** For linux platforms, reads the socket's error queue and processes error * messages from the queue. Returns true if all the errors processed were - * timestamps. Returns false if the any of the errors were not timestamps. For + * timestamps. Returns false if any of the errors were not timestamps. For * non-linux platforms, error processing is not enabled currently, and hence * crashes out. */ static bool process_errors(grpc_tcp* tcp) { - // gpr_log(GPR_INFO, "process errors"); while (true) { - // gpr_log(GPR_INFO, "looping"); struct iovec iov; iov.iov_base = nullptr; iov.iov_len = 0; @@ -654,24 +668,22 @@ static bool process_errors(grpc_tcp* tcp) { int r, saved_errno; do { - // gpr_log(GPR_INFO, "error recvmsg"); r = recvmsg(tcp->fd, &msg, MSG_ERRQUEUE); saved_errno = errno; } while (r < 0 && saved_errno == EINTR); if (r == -1 && saved_errno == EAGAIN) { - // gpr_log(GPR_INFO, "here"); return true; /* No more errors to process */ } if (r == -1) { - // gpr_log(GPR_INFO, "%d", saved_errno); return false; } - if ((msg.msg_flags & MSG_CTRUNC) == 1) { - gpr_log(GPR_INFO, "Error message was truncated."); + if (grpc_tcp_trace.enabled()) { + if ((msg.msg_flags & MSG_CTRUNC) == 1) { + gpr_log(GPR_INFO, "Error message was truncated."); + } } - // gpr_log(GPR_INFO, "%d %lu", r, msg.msg_controllen); if (msg.msg_controllen == 0) { /* There was no control message read. Return now */ return true; @@ -680,10 +692,12 @@ static bool process_errors(grpc_tcp* tcp) { cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_TIMESTAMPING) { - /* Got a weird one, not a timestamp */ - gpr_log(GPR_INFO, "weird %d %d %d", r, cmsg->cmsg_level, - cmsg->cmsg_type); - continue; + /* Got a weird control message, not a timestamp */ + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "weird control message cmsg_level:%d cmsg_type:%d", + cmsg->cmsg_level, cmsg->cmsg_type); + } + return false; } process_timestamp(tcp, &msg, cmsg); } @@ -691,7 +705,6 @@ static bool process_errors(grpc_tcp* tcp) { } static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { - // gpr_log(GPR_INFO, "grpc_tcp_handle_error"); grpc_tcp* tcp = static_cast(arg); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p got_error: %s", tcp, grpc_error_string(error)); @@ -701,15 +714,10 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { static_cast(gpr_atm_acq_load(&tcp->stop_error_notification))) { /* We aren't going to register to hear on error anymore, so it is safe to * unref. */ - // gpr_log(GPR_INFO, "%p %d", error, - // static_cast(gpr_atm_acq_load(&tcp->stop_error_notification))); - // gpr_log(GPR_INFO, "unref"); grpc_core::TracedBuffer::Shutdown(&tcp->head, GRPC_ERROR_REF(error)); TCP_UNREF(tcp, "error"); - // gpr_log(GPR_INFO, "here"); } else { if (!process_errors(tcp)) { - // gpr_log(GPR_INFO, "no timestamps"); /* This was not a timestamps error. This was an actual error. Set the * read and write closures to be ready. */ @@ -719,7 +727,6 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, grpc_schedule_on_exec_ctx); grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); - // gpr_log(GPR_INFO, "udhar se"); } } @@ -798,7 +805,6 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { sent_length = sendmsg(tcp->fd, &msg, SENDMSG_FLAGS); } while (sent_length < 0 && errno == EINTR); } - // gpr_log(GPR_INFO, "sent length %ld", sent_length); if (sent_length < 0) { if (errno == EAGAIN) { @@ -869,7 +875,6 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "write: %s", str); } - // gpr_log(GPR_INFO, "scheduling callback"); GRPC_CLOSURE_SCHED(cb, error); TCP_UNREF(tcp, "write"); } @@ -913,14 +918,12 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "write: delayed"); } - // gpr_log(GPR_INFO, "notify"); notify_on_write(tcp); } else { if (grpc_tcp_trace.enabled()) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "write: %s", str); } - // gpr_log(GPR_INFO, "sched"); GRPC_CLOSURE_SCHED(cb, error); } } @@ -1069,7 +1072,7 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, tcp->release_fd_cb = done; grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); if (grpc_event_engine_can_track_errors()) { - // gpr_log(GPR_INFO, "stop errors"); + /* Stop errors notification. */ gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); grpc_fd_notify_on_error(tcp->em_fd, nullptr); } diff --git a/src/core/lib/iomgr/tcp_posix.h b/src/core/lib/iomgr/tcp_posix.h index 322af627275..eff825cb925 100644 --- a/src/core/lib/iomgr/tcp_posix.h +++ b/src/core/lib/iomgr/tcp_posix.h @@ -57,9 +57,4 @@ int grpc_tcp_fd(grpc_endpoint* ep); void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, grpc_closure* done); -/** Sets the callback function to call when timestamps for a write are - * collected. */ -void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, - grpc_core::Timestamps*)); - #endif /* GRPC_CORE_LIB_IOMGR_TCP_POSIX_H */ diff --git a/test/core/iomgr/tcp_posix_test.cc b/test/core/iomgr/tcp_posix_test.cc index 648150a765d..6447cc234db 100644 --- a/test/core/iomgr/tcp_posix_test.cc +++ b/test/core/iomgr/tcp_posix_test.cc @@ -72,7 +72,6 @@ static void create_sockets(int sv[2]) { } static void create_inet_sockets(int sv[2]) { - gpr_log(GPR_INFO, "create sockets"); /* Prepare listening socket */ struct sockaddr_in addr; memset(&addr, 0, sizeof(struct sockaddr_in)); @@ -86,10 +85,6 @@ static void create_inet_sockets(int sv[2]) { socklen_t len = sizeof(sockaddr_in); GPR_ASSERT(getsockname(sock, (sockaddr*)&addr, &len) == 0); - gpr_log(GPR_INFO, "%d\n", addr.sin_port); - char* addra = inet_ntoa(addr.sin_addr); - gpr_log(GPR_INFO, "%s\n", addra); - int client = socket(AF_INET, SOCK_STREAM, 0); GPR_ASSERT(client); int ret; @@ -337,9 +332,7 @@ static void write_done(void* user_data /* write_socket_state */, GPR_ASSERT(error == GRPC_ERROR_NONE); struct write_socket_state* state = static_cast(user_data); - gpr_log(GPR_INFO, "Write done callback called"); gpr_mu_lock(g_mu); - gpr_log(GPR_INFO, "Signalling write done"); state->write_done = 1; GPR_ASSERT( GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr))); @@ -360,22 +353,17 @@ void drain_socket_blocking(int fd, size_t num_bytes, size_t read_size) { for (;;) { grpc_pollset_worker* worker = nullptr; - gpr_log(GPR_INFO, "in loop"); gpr_mu_lock(g_mu); - gpr_log(GPR_INFO, "in locked polling"); GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(g_pollset, &worker, grpc_timespec_to_millis_round_up( grpc_timeout_milliseconds_to_deadline(10))))); - gpr_log(GPR_INFO, "done locked polling"); gpr_mu_unlock(g_mu); do { - gpr_log(GPR_INFO, "doing a read"); bytes_read = read(fd, buf, bytes_left > read_size ? read_size : bytes_left); - gpr_log(GPR_INFO, "done with read"); } while (bytes_read < 0 && errno == EINTR); GPR_ASSERT(bytes_read >= 0); for (i = 0; i < bytes_read; ++i) { @@ -460,9 +448,7 @@ static void write_test(size_t num_bytes, size_t slice_size, grpc_event_engine_can_track_errors() && collect_timestamps ? (void*)&done_timestamps : nullptr); - gpr_log(GPR_INFO, "about to drain"); drain_socket_blocking(sv[0], num_bytes, num_bytes); - gpr_log(GPR_INFO, "done drain"); exec_ctx.Flush(); gpr_mu_lock(g_mu); for (;;) { @@ -571,7 +557,6 @@ static void release_fd_test(size_t num_bytes, size_t slice_size) { } void run_tests(void) { - gpr_log(GPR_INFO, "run tests"); size_t i = 0; read_test(100, 8192); @@ -580,21 +565,18 @@ void run_tests(void) { read_test(10000, 1); large_read_test(8192); large_read_test(1); - gpr_log(GPR_INFO, "done read tests"); write_test(100, 8192, false); write_test(100, 1, false); write_test(100000, 8192, false); write_test(100000, 1, false); write_test(100000, 137, false); - gpr_log(GPR_INFO, "done normal write tests"); write_test(100, 8192, true); write_test(100, 1, true); write_test(100000, 8192, true); write_test(100000, 1, true); write_test(100, 137, true); - gpr_log(GPR_INFO, "done super write tests"); for (i = 1; i < 1000; i = GPR_MAX(i + 1, i * 5 / 4)) { write_test(40320, i, false); @@ -643,7 +625,6 @@ int main(int argc, char** argv) { grpc_closure destroyed; grpc_test_init(argc, argv); grpc_init(); - gpr_log(GPR_INFO, "here"); grpc_core::grpc_tcp_set_write_timestamps_callback(timestamps_verifier); { grpc_core::ExecCtx exec_ctx; From f5ee0ffb66aba560a1a4d84fa1484fd88cd4d211 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 17 Jul 2018 07:11:22 -0700 Subject: [PATCH 029/546] Fix flow control tracing --- .../ext/transport/chttp2/transport/flow_control.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/flow_control.cc b/src/core/ext/transport/chttp2/transport/flow_control.cc index e89c363200e..5f3dd984611 100644 --- a/src/core/ext/transport/chttp2/transport/flow_control.cc +++ b/src/core/ext/transport/chttp2/transport/flow_control.cc @@ -55,7 +55,7 @@ static char* fmt_int64_diff_str(int64_t old_val, int64_t new_val) { static char* fmt_uint32_diff_str(uint32_t old_val, uint32_t new_val) { char* str; - if (new_val > 0 && old_val != new_val) { + if (old_val != new_val) { gpr_asprintf(&str, "%" PRIu32 " -> %" PRIu32 "", old_val, new_val); } else { gpr_asprintf(&str, "%" PRIu32 "", old_val); @@ -98,10 +98,12 @@ void FlowControlTrace::Finish() { if (sfc_ != nullptr) { srw_str = fmt_int64_diff_str(remote_window_delta_ + remote_window, sfc_->remote_window_delta() + remote_window); - slw_str = fmt_int64_diff_str(local_window_delta_ + acked_local_window, - local_window_delta_ + acked_local_window); - saw_str = fmt_int64_diff_str(announced_window_delta_ + acked_local_window, - announced_window_delta_ + acked_local_window); + slw_str = + fmt_int64_diff_str(local_window_delta_ + acked_local_window, + sfc_->local_window_delta() + acked_local_window); + saw_str = + fmt_int64_diff_str(announced_window_delta_ + acked_local_window, + sfc_->announced_window_delta() + acked_local_window); } else { srw_str = gpr_leftpad("", ' ', kTracePadding); slw_str = gpr_leftpad("", ' ', kTracePadding); From bbee13661c82c13e2f1b728c94f9535112f54d92 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 18 Jul 2018 18:31:09 -0700 Subject: [PATCH 030/546] Add channelz subchannel support --- include/grpc/grpc.h | 4 + .../client_channel/client_channel_channelz.cc | 29 ++++ .../client_channel/client_channel_channelz.h | 35 ++++- .../ext/filters/client_channel/subchannel.cc | 31 +++- .../ext/filters/client_channel/subchannel.h | 2 + src/core/lib/channel/channel_trace.cc | 30 ++-- src/core/lib/channel/channelz.cc | 142 +++++++++++------- src/core/lib/channel/channelz.h | 131 ++++++++++++---- src/core/lib/channel/channelz_registry.cc | 16 ++ src/core/lib/surface/channel.cc | 3 + test/core/channel/channelz_test.cc | 29 ++++ test/cpp/util/channel_trace_proto_helper.cc | 4 + test/cpp/util/channel_trace_proto_helper.h | 1 + 13 files changed, 354 insertions(+), 103 deletions(-) diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index f0eb2c0121b..942c83bcde3 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -477,6 +477,10 @@ GRPCAPI char* grpc_channelz_get_top_channels(intptr_t start_channel_id); is allocated and must be freed by the application. */ GRPCAPI char* grpc_channelz_get_channel(intptr_t channel_id); +/* Returns a single Subchannel, or else a NOT_FOUND code. The returned string + is allocated and must be freed by the application. */ +GRPCAPI char* grpc_channelz_get_subchannel(intptr_t subchannel_id); + #ifdef __cplusplus } #endif diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index d43e9ea67a5..5a0eec5d152 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -24,6 +24,8 @@ #include "src/core/lib/surface/channel.h" #include "src/core/lib/transport/connectivity_state.h" +#include + namespace grpc_core { namespace channelz { namespace { @@ -109,5 +111,32 @@ RefCountedPtr ClientChannelNode::MakeClientChannelNode( channel, channel_tracer_max_nodes, is_top_level_channel); } +ClientChannelSubchannelNode::ClientChannelSubchannelNode( + size_t channel_tracer_max_nodes, grpc_subchannel* subchannel) + : SubchannelNode(channel_tracer_max_nodes), subchannel_(subchannel) { + target_ = + UniquePtr(gpr_strdup(grpc_subchannel_get_target(subchannel_))); +} + +void ClientChannelSubchannelNode::PopulateTarget(grpc_json* json) { + GPR_ASSERT(target_.get() != nullptr); + grpc_json_create_child(nullptr, json, "target", target_.get(), + GRPC_JSON_STRING, false); +} + +void ClientChannelSubchannelNode::PopulateConnectivityState(grpc_json* json) { + grpc_connectivity_state state; + if (subchannel_ == nullptr) { + state = GRPC_CHANNEL_SHUTDOWN; + } else { + state = grpc_subchannel_check_connectivity(subchannel_, nullptr); + } + json = grpc_json_create_child(nullptr, json, "state", nullptr, + GRPC_JSON_OBJECT, false); + grpc_json_create_child(nullptr, json, "state", + grpc_connectivity_state_name(state), GRPC_JSON_STRING, + false); +} + } // namespace channelz } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 6f27b5c8b70..b1bd8db89e5 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -26,6 +26,8 @@ #include "src/core/lib/channel/channelz.h" #include "src/core/lib/gprpp/inlined_vector.h" +typedef struct grpc_subchannel grpc_subchannel; + namespace grpc_core { // TODO(ncteisen), this only contains the uuids of the children for now, @@ -55,16 +57,45 @@ class ClientChannelNode : public ChannelNode { static grpc_arg CreateChannelArg(); protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW ClientChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, bool is_top_level_channel); virtual ~ClientChannelNode() {} private: + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW grpc_channel_element* client_channel_; }; +// Subtype of SubchannelNode that overrides and provides client_channel +// specific functionality like querying for connectivity_state and +// subchannel target. +class ClientChannelSubchannelNode : public SubchannelNode { + public: + ClientChannelSubchannelNode(size_t channel_tracer_max_nodes, + grpc_subchannel* subchannel); + ~ClientChannelSubchannelNode() override {} + + // Override this functionality since subchannels have a notion of + // channel connectivity. + void PopulateConnectivityState(grpc_json* json) override; + + // Override this functionality since client_channels subchannels hold + // their own target. + void PopulateTarget(grpc_json* json) override; + + void MarkSubchannelDestroyed() { + GPR_ASSERT(subchannel_ != nullptr); + subchannel_ = nullptr; + } + + private: + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + grpc_subchannel* subchannel_; + UniquePtr target_; +}; + } // namespace channelz } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 93df2aff700..0c3313c5de9 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -135,7 +135,7 @@ struct grpc_subchannel { /** our alarm */ grpc_timer alarm; - grpc_core::RefCountedPtr + grpc_core::RefCountedPtr channelz_subchannel; }; @@ -181,7 +181,13 @@ static void connection_destroy(void* arg, grpc_error* error) { static void subchannel_destroy(void* arg, grpc_error* error) { grpc_subchannel* c = static_cast(arg); - c->channelz_subchannel.reset(); + if (c->channelz_subchannel != nullptr) { + c->channelz_subchannel->trace()->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("Subchannel destroyed")); + c->channelz_subchannel->MarkSubchannelDestroyed(); + c->channelz_subchannel.reset(); + } gpr_free((void*)c->filters); grpc_channel_args_destroy(c->args); grpc_connectivity_state_destroy(&c->state_tracker); @@ -381,9 +387,18 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, const grpc_arg* arg = grpc_channel_args_find(c->args, GRPC_ARG_ENABLE_CHANNELZ); bool channelz_enabled = grpc_channel_arg_get_bool(arg, false); + arg = grpc_channel_args_find(c->args, + GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); + const grpc_integer_options options = {0, 0, INT_MAX}; + size_t channel_tracer_max_nodes = + (size_t)grpc_channel_arg_get_integer(arg, options); if (channelz_enabled) { - c->channelz_subchannel = - grpc_core::MakeRefCounted(); + c->channelz_subchannel = grpc_core::MakeRefCounted< + grpc_core::channelz::ClientChannelSubchannelNode>( + channel_tracer_max_nodes, c); + c->channelz_subchannel->trace()->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("Subchannel created")); } return grpc_subchannel_index_register(key, c); @@ -757,6 +772,14 @@ void grpc_get_subchannel_address_arg(const grpc_channel_args* args, } } +const char* grpc_subchannel_get_target(grpc_subchannel* subchannel) { + const grpc_arg* addr_arg = + grpc_channel_args_find(subchannel->args, GRPC_ARG_SUBCHANNEL_ADDRESS); + const char* addr_str = grpc_channel_arg_get_string(addr_arg); + GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy. + return addr_str; +} + const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args) { const grpc_arg* addr_arg = grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS); diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 9e53f7d5423..dd3a2d96214 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -177,6 +177,8 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, void grpc_get_subchannel_address_arg(const grpc_channel_args* args, grpc_resolved_address* addr); +const char* grpc_subchannel_get_target(grpc_subchannel* subchannel); + /// Returns the URI string for the address to connect to. const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args); diff --git a/src/core/lib/channel/channel_trace.cc b/src/core/lib/channel/channel_trace.cc index b3443310ac6..dd6fdeed545 100644 --- a/src/core/lib/channel/channel_trace.cc +++ b/src/core/lib/channel/channel_trace.cc @@ -178,24 +178,26 @@ grpc_json* ChannelTrace::RenderJson() const { if (!max_list_size_) return nullptr; // tracing is disabled if max_events == 0 grpc_json* json = grpc_json_create(GRPC_JSON_OBJECT); - char* num_events_logged_str; - gpr_asprintf(&num_events_logged_str, "%" PRId64, num_events_logged_); grpc_json* json_iterator = nullptr; - json_iterator = - grpc_json_create_child(json_iterator, json, "numEventsLogged", - num_events_logged_str, GRPC_JSON_STRING, true); + if (num_events_logged_ > 0) { + json_iterator = grpc_json_add_number_string_child( + json, json_iterator, "numEventsLogged", num_events_logged_); + } json_iterator = grpc_json_create_child( json_iterator, json, "creationTimestamp", gpr_format_timespec(time_created_), GRPC_JSON_STRING, true); - grpc_json* events = grpc_json_create_child(json_iterator, json, "events", - nullptr, GRPC_JSON_ARRAY, false); - json_iterator = nullptr; - TraceEvent* it = head_trace_; - while (it != nullptr) { - json_iterator = grpc_json_create_child(json_iterator, events, nullptr, - nullptr, GRPC_JSON_OBJECT, false); - it->RenderTraceEvent(json_iterator); - it = it->next(); + // only add in the event list if it is non-empty. + if (num_events_logged_ > 0) { + grpc_json* events = grpc_json_create_child(json_iterator, json, "events", + nullptr, GRPC_JSON_ARRAY, false); + json_iterator = nullptr; + TraceEvent* it = head_trace_; + while (it != nullptr) { + json_iterator = grpc_json_create_child(json_iterator, events, nullptr, + nullptr, GRPC_JSON_OBJECT, false); + it->RenderTraceEvent(json_iterator); + it = it->next(); + } } return json; } diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 9d6002ed8a1..7fe086da3cf 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -41,69 +41,33 @@ namespace grpc_core { namespace channelz { -ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, - bool is_top_level_channel) - : channel_(channel), - target_(nullptr), - channel_uuid_(-1), - is_top_level_channel_(is_top_level_channel) { +CallCountingBase::CallCountingBase(size_t channel_tracer_max_nodes) { trace_.Init(channel_tracer_max_nodes); - target_ = UniquePtr(grpc_channel_get_target(channel_)); - channel_uuid_ = ChannelzRegistry::RegisterChannelNode(this); gpr_atm_no_barrier_store(&last_call_started_millis_, (gpr_atm)ExecCtx::Get()->Now()); } -ChannelNode::~ChannelNode() { - trace_.Destroy(); - ChannelzRegistry::UnregisterChannelNode(channel_uuid_); -} +CallCountingBase::~CallCountingBase() { trace_.Destroy(); } -void ChannelNode::RecordCallStarted() { +void CallCountingBase::RecordCallStarted() { gpr_atm_no_barrier_fetch_add(&calls_started_, (gpr_atm)1); gpr_atm_no_barrier_store(&last_call_started_millis_, (gpr_atm)ExecCtx::Get()->Now()); } -void ChannelNode::PopulateConnectivityState(grpc_json* json) {} - -void ChannelNode::PopulateChildRefs(grpc_json* json) {} - -grpc_json* ChannelNode::RenderJson() { - // We need to track these three json objects to build our object - grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); - grpc_json* json = top_level_json; - grpc_json* json_iterator = nullptr; - // create and fill the ref child - json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr, - GRPC_JSON_OBJECT, false); - json = json_iterator; - json_iterator = nullptr; - json_iterator = grpc_json_add_number_string_child(json, json_iterator, - "channelId", channel_uuid_); - // reset json iterators to top level object - json = top_level_json; - json_iterator = nullptr; - // create and fill the data child. - grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr, - GRPC_JSON_OBJECT, false); - json = data; - json_iterator = nullptr; - PopulateConnectivityState(json); - GPR_ASSERT(target_.get() != nullptr); - json_iterator = grpc_json_create_child( - json_iterator, json, "target", target_.get(), GRPC_JSON_STRING, false); +void CallCountingBase::PopulateTrace(grpc_json* json) { // fill in the channel trace if applicable - grpc_json* trace = trace_->RenderJson(); - if (trace != nullptr) { + grpc_json* trace_json = trace_->RenderJson(); + if (trace_json != nullptr) { // we manually link up and fill the child since it was created for us in // ChannelTrace::RenderJson - trace->key = "trace"; // this object is named trace in channelz.proto - json_iterator = grpc_json_link_child(json, trace, json_iterator); + trace_json->key = "trace"; // this object is named trace in channelz.proto + grpc_json_link_child(json, trace_json, nullptr); } - // reset the parent to be the data object. - json = data; - json_iterator = nullptr; +} + +void CallCountingBase::PopulateCallData(grpc_json* json) { + grpc_json* json_iterator = nullptr; if (calls_started_ != 0) { json_iterator = grpc_json_add_number_string_child( json, json_iterator, "callsStarted", calls_started_); @@ -121,19 +85,62 @@ grpc_json* ChannelNode::RenderJson() { json_iterator = grpc_json_create_child(json_iterator, json, "lastCallStartedTimestamp", gpr_format_timespec(ts), GRPC_JSON_STRING, true); - json = top_level_json; - json_iterator = nullptr; - PopulateChildRefs(json); - return top_level_json; } -char* ChannelNode::RenderJsonString() { +char* CallCountingBase::RenderJsonString() { grpc_json* json = RenderJson(); char* json_str = grpc_json_dump_to_string(json, 0); grpc_json_destroy(json); return json_str; } +ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, + bool is_top_level_channel) + : CallCountingBase(channel_tracer_max_nodes), + channel_(channel), + is_top_level_channel_(is_top_level_channel) { + target_ = UniquePtr(grpc_channel_get_target(channel_)); + channel_uuid_ = ChannelzRegistry::RegisterChannelNode(this); +} + +ChannelNode::~ChannelNode() { + ChannelzRegistry::UnregisterChannelNode(channel_uuid_); +} + +void ChannelNode::PopulateTarget(grpc_json* json) { + GPR_ASSERT(target_.get() != nullptr); + grpc_json_create_child(nullptr, json, "target", target_.get(), + GRPC_JSON_STRING, false); +} + +grpc_json* ChannelNode::RenderJson() { + // We need to track these three json objects to build our object + grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); + grpc_json* json = top_level_json; + grpc_json* json_iterator = nullptr; + // create and fill the ref child + json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr, + GRPC_JSON_OBJECT, false); + json = json_iterator; + json_iterator = nullptr; + json_iterator = grpc_json_add_number_string_child(json, json_iterator, + "channelId", channel_uuid_); + // reset json iterators to top level object + json = top_level_json; + json_iterator = nullptr; + // create and fill the data child. + grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr, + GRPC_JSON_OBJECT, false); + json = data; + json_iterator = nullptr; + PopulateConnectivityState(json); + PopulateTarget(json); + PopulateTrace(json); + PopulateCallData(json); + PopulateChildRefs(json); + return top_level_json; +} + RefCountedPtr ChannelNode::MakeChannelNode( grpc_channel* channel, size_t channel_tracer_max_nodes, bool is_top_level_channel) { @@ -141,7 +148,8 @@ RefCountedPtr ChannelNode::MakeChannelNode( channel, channel_tracer_max_nodes, is_top_level_channel); } -SubchannelNode::SubchannelNode() { +SubchannelNode::SubchannelNode(size_t channel_tracer_max_nodes) + : CallCountingBase(channel_tracer_max_nodes) { subchannel_uuid_ = ChannelzRegistry::RegisterSubchannelNode(this); } @@ -149,5 +157,31 @@ SubchannelNode::~SubchannelNode() { ChannelzRegistry::UnregisterSubchannelNode(subchannel_uuid_); } +grpc_json* SubchannelNode::RenderJson() { + grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); + grpc_json* json = top_level_json; + grpc_json* json_iterator = nullptr; + json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr, + GRPC_JSON_OBJECT, false); + json = json_iterator; + json_iterator = nullptr; + json_iterator = grpc_json_add_number_string_child( + json, json_iterator, "subchannelId", subchannel_uuid_); + // reset json iterators to top level object + json = top_level_json; + json_iterator = nullptr; + // create and fill the data child. + grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr, + GRPC_JSON_OBJECT, false); + json = data; + json_iterator = nullptr; + PopulateConnectivityState(json); + PopulateTarget(json); + PopulateTrace(json); + PopulateCallData(json); + PopulateChildRefs(json); + return top_level_json; +} + } // namespace channelz } // namespace grpc_core diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 07eb73d6269..97e27c69fc1 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -46,11 +46,44 @@ namespace testing { class ChannelNodePeer; } -class ChannelNode : public RefCounted { +// base class for all channelz entities +class ChannelzBaseNode : public RefCounted { public: - static RefCountedPtr MakeChannelNode( - grpc_channel* channel, size_t channel_tracer_max_nodes, - bool is_top_level_channel); + ChannelzBaseNode() {} + virtual ~ChannelzBaseNode() {} + private: + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW +}; + +// Handles channelz bookkeeping for sockets +// TODO(ncteisen): implement in subsequent PR. +class SocketNode : public ChannelzBaseNode { + public: + SocketNode() : ChannelzBaseNode() {} + ~SocketNode() override {} + private: + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW +}; + +// This class is the parent for the channelz entities that deal with Channels +// Subchannels, and Servers, since those have similar proto definitions. +// This class has the ability to: +// - track calls_{started,succeeded,failed} +// - track last_call_started_timestamp +// - hold the channel trace. +// - perform common rendering. +// +// This class also defines some fat interfaces so that its children can +// implement the functionality different. For example, querying the +// connectivity state looks different for channels and subchannels, and does +// not make sense for servers. So servers will not override, and channels and +// subchannels will override with their own way to query connectivity state. +class CallCountingBase : public ChannelzBaseNode { + public: + CallCountingBase(size_t channel_tracer_max_nodes); + ~CallCountingBase() override; void RecordCallStarted(); void RecordCallFailed() { @@ -59,66 +92,106 @@ class ChannelNode : public RefCounted { void RecordCallSucceeded() { gpr_atm_no_barrier_fetch_add(&calls_succeeded_, (gpr_atm(1))); } + ChannelTrace* trace() { return trace_.get(); } + + // Fat interface for ConnectivityState. Default is to leave it out, however, + // things like Channel and Subchannel will override with their mechanism + // for querying connectivity state. + virtual void PopulateConnectivityState(grpc_json* json) {} + + // Fat interface for Targets. + virtual void PopulateTarget(grpc_json* json) {} + + // Fat interface for ChildRefs. Allows children to populate with whatever + // combination of child_refs, subchannel_refs, and socket_refs is correct. + virtual void PopulateChildRefs(grpc_json* json) {} - grpc_json* RenderJson(); + // All children must implement their custom JSON rendering. + virtual grpc_json* RenderJson() GRPC_ABSTRACT; + + // Common rendering of the channel trace. + void PopulateTrace(grpc_json* json); + + // Common rendering of the call count data and last_call_started_timestamp. + void PopulateCallData(grpc_json* json); + + // Common rendering of grpc_json from RenderJson() to allocated string. char* RenderJsonString(); - // helper for getting and populating connectivity state. It is virtual - // because it allows the client_channel specific code to live in ext/ - // instead of lib/ - virtual void PopulateConnectivityState(grpc_json* json); + private: + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - virtual void PopulateChildRefs(grpc_json* json); + gpr_atm calls_started_ = 0; + gpr_atm calls_succeeded_ = 0; + gpr_atm calls_failed_ = 0; + gpr_atm last_call_started_millis_ = 0; + ManualConstructor trace_; +}; - ChannelTrace* trace() { return trace_.get(); } +// Handles channelz bookkeeping for servers +// TODO(ncteisen): implement in subsequent PR. +class ServerNode : public CallCountingBase { + public: + ServerNode(size_t channel_tracer_max_nodes) + : CallCountingBase(channel_tracer_max_nodes) {} + ~ServerNode() override {} + private: + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW +}; + +// Overrides Channel specific functionality. +class ChannelNode : public CallCountingBase { + public: + static RefCountedPtr MakeChannelNode( + grpc_channel* channel, size_t channel_tracer_max_nodes, + bool is_top_level_channel); void MarkChannelDestroyed() { GPR_ASSERT(channel_ != nullptr); channel_ = nullptr; } + grpc_json* RenderJson() override; + + void PopulateTarget(grpc_json* json) override; + bool ChannelIsDestroyed() { return channel_ == nullptr; } intptr_t channel_uuid() { return channel_uuid_; } bool is_top_level_channel() { return is_top_level_channel_; } protected: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, bool is_top_level_channel); - virtual ~ChannelNode(); + ~ChannelNode() override; private: + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + // testing peer friend. friend class testing::ChannelNodePeer; grpc_channel* channel_ = nullptr; UniquePtr target_; - gpr_atm calls_started_ = 0; - gpr_atm calls_succeeded_ = 0; - gpr_atm calls_failed_ = 0; - gpr_atm last_call_started_millis_ = 0; intptr_t channel_uuid_; bool is_top_level_channel_ = true; - ManualConstructor trace_; }; -// Placeholds channelz class for subchannels. All this can do now is track its -// uuid (this information is needed by the parent channelz class). -// TODO(ncteisen): build this out to support the GetSubchannel channelz request. -class SubchannelNode : public RefCounted { +// Overrides Subchannel specific functionality. +class SubchannelNode : public CallCountingBase { public: - SubchannelNode(); - virtual ~SubchannelNode(); - + SubchannelNode(size_t channel_tracer_max_nodes); + ~SubchannelNode() override; + grpc_json* RenderJson() override; intptr_t subchannel_uuid() { return subchannel_uuid_; } - protected: + private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - - private: + intptr_t subchannel_uuid_; }; diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index 38496b3d78c..aeeb6958e44 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -142,3 +142,19 @@ char* grpc_channelz_get_channel(intptr_t channel_id) { grpc_json_destroy(top_level_json); return json_str; } + +char* grpc_channelz_get_subchannel(intptr_t subchannel_id) { + grpc_core::channelz::SubchannelNode* subchannel_node = + grpc_core::channelz::ChannelzRegistry::GetSubchannelNode(subchannel_id); + if (subchannel_node == nullptr) { + return nullptr; + } + grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); + grpc_json* json = top_level_json; + grpc_json* subchannel_json = subchannel_node->RenderJson(); + subchannel_json->key = "subchannel"; + grpc_json_link_child(json, subchannel_json, nullptr); + char* json_str = grpc_json_dump_to_string(top_level_json, 0); + grpc_json_destroy(top_level_json); + return json_str; +} diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index 7cbd61adef5..01caadaabac 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -417,6 +417,9 @@ void grpc_channel_internal_unref(grpc_channel* c REF_ARG) { static void destroy_channel(void* arg, grpc_error* error) { grpc_channel* channel = static_cast(arg); if (channel->channelz_channel != nullptr) { + channel->channelz_channel->trace()->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("Channel destroyed")); channel->channelz_channel->MarkChannelDestroyed(); channel->channelz_channel.reset(); } diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index ad5f86d9341..b8e65ebfb31 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -163,6 +163,14 @@ void ValidateChannel(ChannelNode* channel, validate_channel_data_args args) { gpr_free(core_api_json_str); } +void ValidateSubchannel(SubchannelNode* subchannel, + validate_channel_data_args args) { + char* json_str = subchannel->RenderJsonString(); + grpc::testing::ValidateSubchannelProtoJsonTranslation(json_str); + ValidateCounters(json_str, args); + gpr_free(json_str); +} + grpc_millis GetLastCallStartedMillis(ChannelNode* channel) { ChannelNodePeer peer(channel); return peer.last_call_started_millis(); @@ -275,8 +283,29 @@ TEST(ChannelzGetTopChannelsTest, InternalChannelTest) { grpc_channel_destroy(internal_channel); } +class ChannelzSubchannelTest : public ::testing::TestWithParam {}; + +TEST_P(ChannelzSubchannelTest, BasicTest) { + grpc_core::ExecCtx exec_ctx; + RefCountedPtr channelz_subchannel = + MakeRefCounted(GetParam()); + channelz_subchannel->RecordCallStarted(); + channelz_subchannel->RecordCallFailed(); + channelz_subchannel->RecordCallSucceeded(); + ValidateSubchannel(channelz_subchannel.get(), {1, 1, 1}); + channelz_subchannel->RecordCallStarted(); + channelz_subchannel->RecordCallFailed(); + channelz_subchannel->RecordCallSucceeded(); + channelz_subchannel->RecordCallStarted(); + channelz_subchannel->RecordCallFailed(); + channelz_subchannel->RecordCallSucceeded(); + ValidateSubchannel(channelz_subchannel.get(), {3, 3, 3}); +} + INSTANTIATE_TEST_CASE_P(ChannelzChannelTestSweep, ChannelzChannelTest, ::testing::Values(0, 1, 2, 6, 10, 15)); +INSTANTIATE_TEST_CASE_P(ChannelzSubchannelTestSweep, ChannelzSubchannelTest, + ::testing::Values(0, 1, 10, 15)); } // namespace testing } // namespace channelz diff --git a/test/cpp/util/channel_trace_proto_helper.cc b/test/cpp/util/channel_trace_proto_helper.cc index b4704bfe6a8..e416a0375f0 100644 --- a/test/cpp/util/channel_trace_proto_helper.cc +++ b/test/cpp/util/channel_trace_proto_helper.cc @@ -82,5 +82,9 @@ void ValidateGetChannelResponseProtoJsonTranslation(char* json_c_str) { json_c_str); } +void ValidateSubchannelProtoJsonTranslation(char* json_c_str) { + VaidateProtoJsonTranslation(json_c_str); +} + } // namespace testing } // namespace grpc diff --git a/test/cpp/util/channel_trace_proto_helper.h b/test/cpp/util/channel_trace_proto_helper.h index 18e3d54b6b8..a1ebbcd1100 100644 --- a/test/cpp/util/channel_trace_proto_helper.h +++ b/test/cpp/util/channel_trace_proto_helper.h @@ -26,6 +26,7 @@ void ValidateChannelTraceProtoJsonTranslation(char* json_c_str); void ValidateChannelProtoJsonTranslation(char* json_c_str); void ValidateGetTopChannelsResponseProtoJsonTranslation(char* json_c_str); void ValidateGetChannelResponseProtoJsonTranslation(char* json_c_str); +void ValidateSubchannelProtoJsonTranslation(char* json_c_str); } // namespace testing } // namespace grpc From ca32a8a85286ae0c9c94c3eaeaee3100d0304f99 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 19 Jul 2018 16:59:50 -0700 Subject: [PATCH 031/546] reviewer feedback --- .../client_channel/client_channel_channelz.cc | 8 +++--- src/core/lib/channel/channelz.h | 25 +++++++++++-------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 5a0eec5d152..0688ee2abbc 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -113,10 +113,10 @@ RefCountedPtr ClientChannelNode::MakeClientChannelNode( ClientChannelSubchannelNode::ClientChannelSubchannelNode( size_t channel_tracer_max_nodes, grpc_subchannel* subchannel) - : SubchannelNode(channel_tracer_max_nodes), subchannel_(subchannel) { - target_ = - UniquePtr(gpr_strdup(grpc_subchannel_get_target(subchannel_))); -} + : SubchannelNode(channel_tracer_max_nodes), + subchannel_(subchannel), + target_(UniquePtr( + gpr_strdup(grpc_subchannel_get_target(subchannel_)))) {} void ClientChannelSubchannelNode::PopulateTarget(grpc_json* json) { GPR_ASSERT(target_.get() != nullptr); diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 97e27c69fc1..1cd55bab430 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -47,10 +47,11 @@ class ChannelNodePeer; } // base class for all channelz entities -class ChannelzBaseNode : public RefCounted { +class BaseNode : public RefCounted { public: - ChannelzBaseNode() {} - virtual ~ChannelzBaseNode() {} + BaseNode() {} + virtual ~BaseNode() {} + private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW @@ -58,10 +59,11 @@ class ChannelzBaseNode : public RefCounted { // Handles channelz bookkeeping for sockets // TODO(ncteisen): implement in subsequent PR. -class SocketNode : public ChannelzBaseNode { +class SocketNode : public BaseNode { public: - SocketNode() : ChannelzBaseNode() {} + SocketNode() : BaseNode() {} ~SocketNode() override {} + private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW @@ -76,11 +78,11 @@ class SocketNode : public ChannelzBaseNode { // - perform common rendering. // // This class also defines some fat interfaces so that its children can -// implement the functionality different. For example, querying the -// connectivity state looks different for channels and subchannels, and does -// not make sense for servers. So servers will not override, and channels and -// subchannels will override with their own way to query connectivity state. -class CallCountingBase : public ChannelzBaseNode { +// implement the functionality differently. For example, querying the +// connectivity state looks different for channels than for subchannels, and +// does not make sense for servers. So servers will not override, and channels +// and subchannels will override with their own way to query connectivity state. +class CallCountingBase : public BaseNode { public: CallCountingBase(size_t channel_tracer_max_nodes); ~CallCountingBase() override; @@ -136,6 +138,7 @@ class ServerNode : public CallCountingBase { ServerNode(size_t channel_tracer_max_nodes) : CallCountingBase(channel_tracer_max_nodes) {} ~ServerNode() override {} + private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW @@ -191,7 +194,7 @@ class SubchannelNode : public CallCountingBase { private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - + intptr_t subchannel_uuid_; }; From 8cb2d0c64afd9c766ea6b4c41f3125879091d08a Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 20 Jul 2018 14:26:04 -0700 Subject: [PATCH 032/546] Restructure everything --- .../client_channel/client_channel_channelz.cc | 79 ++++++++++-- .../client_channel/client_channel_channelz.h | 37 +++--- .../ext/filters/client_channel/subchannel.cc | 8 +- src/core/lib/channel/channelz.cc | 89 ++++--------- src/core/lib/channel/channelz.h | 122 ++++++++---------- src/core/lib/channel/channelz_registry.cc | 51 ++++---- src/core/lib/channel/channelz_registry.h | 50 ++----- test/core/channel/channelz_registry_test.cc | 30 ++--- test/core/channel/channelz_test.cc | 42 +----- 9 files changed, 223 insertions(+), 285 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 0688ee2abbc..1d72b9c9d20 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -20,6 +20,7 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/client_channel_channelz.h" +#include "src/core/lib/channel/channelz_registry.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/transport/connectivity_state.h" @@ -97,6 +98,38 @@ void ClientChannelNode::PopulateChildRefs(grpc_json* json) { } } +grpc_json* ClientChannelNode::RenderJson() { + // We need to track these three json objects to build our object + grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); + grpc_json* json = top_level_json; + grpc_json* json_iterator = nullptr; + // create and fill the ref child + json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr, + GRPC_JSON_OBJECT, false); + json = json_iterator; + json_iterator = nullptr; + json_iterator = grpc_json_add_number_string_child( + json, json_iterator, "channelId", channel_uuid()); + // reset json iterators to top level object + json = top_level_json; + json_iterator = nullptr; + // create and fill the data child. + grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr, + GRPC_JSON_OBJECT, false); + json = data; + json_iterator = nullptr; + PopulateConnectivityState(json); + // populate the target. + GPR_ASSERT(target_view() != nullptr); + grpc_json_create_child(nullptr, json, "target", target_view(), + GRPC_JSON_STRING, false); + // as CallCountingAndTracingNode to populate trace and call count data. + PopulateTrace(json); + PopulateCallData(json); + PopulateChildRefs(json); + return top_level_json; +} + grpc_arg ClientChannelNode::CreateChannelArg() { return grpc_channel_arg_pointer_create( const_cast(GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC), @@ -111,20 +144,21 @@ RefCountedPtr ClientChannelNode::MakeClientChannelNode( channel, channel_tracer_max_nodes, is_top_level_channel); } -ClientChannelSubchannelNode::ClientChannelSubchannelNode( - size_t channel_tracer_max_nodes, grpc_subchannel* subchannel) - : SubchannelNode(channel_tracer_max_nodes), +SubchannelNode::SubchannelNode(grpc_subchannel* subchannel, + size_t channel_tracer_max_nodes) + : CallCountingAndTracingNode(EntityType::kSubchannel, + channel_tracer_max_nodes), subchannel_(subchannel), target_(UniquePtr( - gpr_strdup(grpc_subchannel_get_target(subchannel_)))) {} + gpr_strdup(grpc_subchannel_get_target(subchannel_)))) { + subchannel_uuid_ = ChannelzRegistry::Register(this); +} -void ClientChannelSubchannelNode::PopulateTarget(grpc_json* json) { - GPR_ASSERT(target_.get() != nullptr); - grpc_json_create_child(nullptr, json, "target", target_.get(), - GRPC_JSON_STRING, false); +SubchannelNode::~SubchannelNode() { + ChannelzRegistry::Unregister(subchannel_uuid_); } -void ClientChannelSubchannelNode::PopulateConnectivityState(grpc_json* json) { +void SubchannelNode::PopulateConnectivityState(grpc_json* json) { grpc_connectivity_state state; if (subchannel_ == nullptr) { state = GRPC_CHANNEL_SHUTDOWN; @@ -138,5 +172,32 @@ void ClientChannelSubchannelNode::PopulateConnectivityState(grpc_json* json) { false); } +grpc_json* SubchannelNode::RenderJson() { + grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); + grpc_json* json = top_level_json; + grpc_json* json_iterator = nullptr; + json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr, + GRPC_JSON_OBJECT, false); + json = json_iterator; + json_iterator = nullptr; + json_iterator = grpc_json_add_number_string_child( + json, json_iterator, "subchannelId", subchannel_uuid_); + // reset json iterators to top level object + json = top_level_json; + json_iterator = nullptr; + // create and fill the data child. + grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr, + GRPC_JSON_OBJECT, false); + json = data; + json_iterator = nullptr; + PopulateConnectivityState(json); + GPR_ASSERT(target_.get() != nullptr); + grpc_json_create_child(nullptr, json, "target", target_.get(), + GRPC_JSON_STRING, false); + PopulateTrace(json); + PopulateCallData(json); + return top_level_json; +} + } // namespace channelz } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index b1bd8db89e5..73eea7cecf2 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -45,12 +45,7 @@ class ClientChannelNode : public ChannelNode { grpc_channel* channel, size_t channel_tracer_max_nodes, bool is_top_level_channel); - // Override this functionality since client_channels have a notion of - // channel connectivity. - void PopulateConnectivityState(grpc_json* json) override; - - // Override this functionality since client_channels have subchannels - void PopulateChildRefs(grpc_json* json) override; + grpc_json* RenderJson() override; // Helper to create a channel arg to ensure this type of ChannelNode is // created. @@ -65,35 +60,35 @@ class ClientChannelNode : public ChannelNode { GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW grpc_channel_element* client_channel_; + + // helpers + void PopulateConnectivityState(grpc_json* json); + void PopulateChildRefs(grpc_json* json); }; -// Subtype of SubchannelNode that overrides and provides client_channel -// specific functionality like querying for connectivity_state and -// subchannel target. -class ClientChannelSubchannelNode : public SubchannelNode { +// Handles channelz bookkeeping for sockets +class SubchannelNode : public CallCountingAndTracingNode { public: - ClientChannelSubchannelNode(size_t channel_tracer_max_nodes, - grpc_subchannel* subchannel); - ~ClientChannelSubchannelNode() override {} - - // Override this functionality since subchannels have a notion of - // channel connectivity. - void PopulateConnectivityState(grpc_json* json) override; - - // Override this functionality since client_channels subchannels hold - // their own target. - void PopulateTarget(grpc_json* json) override; + SubchannelNode(grpc_subchannel* subchannel, size_t channel_tracer_max_nodes); + ~SubchannelNode() override; void MarkSubchannelDestroyed() { GPR_ASSERT(subchannel_ != nullptr); subchannel_ = nullptr; } + grpc_json* RenderJson() override; + + intptr_t subchannel_uuid() { return subchannel_uuid_; } + private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + intptr_t subchannel_uuid_; grpc_subchannel* subchannel_; UniquePtr target_; + + void PopulateConnectivityState(grpc_json* json); }; } // namespace channelz diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 0c3313c5de9..8dfbd33ffed 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -135,7 +135,7 @@ struct grpc_subchannel { /** our alarm */ grpc_timer alarm; - grpc_core::RefCountedPtr + grpc_core::RefCountedPtr channelz_subchannel; }; @@ -393,9 +393,9 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, size_t channel_tracer_max_nodes = (size_t)grpc_channel_arg_get_integer(arg, options); if (channelz_enabled) { - c->channelz_subchannel = grpc_core::MakeRefCounted< - grpc_core::channelz::ClientChannelSubchannelNode>( - channel_tracer_max_nodes, c); + c->channelz_subchannel = + grpc_core::MakeRefCounted( + c, channel_tracer_max_nodes); c->channelz_subchannel->trace()->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Subchannel created")); diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 7fe086da3cf..d7f2d6a9a23 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -41,21 +41,30 @@ namespace grpc_core { namespace channelz { -CallCountingBase::CallCountingBase(size_t channel_tracer_max_nodes) { +char* BaseNode::RenderJsonString() { + grpc_json* json = RenderJson(); + char* json_str = grpc_json_dump_to_string(json, 0); + grpc_json_destroy(json); + return json_str; +} + +CallCountingAndTracingNode::CallCountingAndTracingNode( + EntityType type, size_t channel_tracer_max_nodes) + : BaseNode(type) { trace_.Init(channel_tracer_max_nodes); gpr_atm_no_barrier_store(&last_call_started_millis_, (gpr_atm)ExecCtx::Get()->Now()); } -CallCountingBase::~CallCountingBase() { trace_.Destroy(); } +CallCountingAndTracingNode::~CallCountingAndTracingNode() { trace_.Destroy(); } -void CallCountingBase::RecordCallStarted() { +void CallCountingAndTracingNode::RecordCallStarted() { gpr_atm_no_barrier_fetch_add(&calls_started_, (gpr_atm)1); gpr_atm_no_barrier_store(&last_call_started_millis_, (gpr_atm)ExecCtx::Get()->Now()); } -void CallCountingBase::PopulateTrace(grpc_json* json) { +void CallCountingAndTracingNode::PopulateTrace(grpc_json* json) { // fill in the channel trace if applicable grpc_json* trace_json = trace_->RenderJson(); if (trace_json != nullptr) { @@ -66,7 +75,7 @@ void CallCountingBase::PopulateTrace(grpc_json* json) { } } -void CallCountingBase::PopulateCallData(grpc_json* json) { +void CallCountingAndTracingNode::PopulateCallData(grpc_json* json) { grpc_json* json_iterator = nullptr; if (calls_started_ != 0) { json_iterator = grpc_json_add_number_string_child( @@ -87,31 +96,18 @@ void CallCountingBase::PopulateCallData(grpc_json* json) { gpr_format_timespec(ts), GRPC_JSON_STRING, true); } -char* CallCountingBase::RenderJsonString() { - grpc_json* json = RenderJson(); - char* json_str = grpc_json_dump_to_string(json, 0); - grpc_json_destroy(json); - return json_str; -} - ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, bool is_top_level_channel) - : CallCountingBase(channel_tracer_max_nodes), + : CallCountingAndTracingNode(is_top_level_channel + ? EntityType::kTopLevelChannel + : EntityType::kInternalChannel, + channel_tracer_max_nodes), channel_(channel), - is_top_level_channel_(is_top_level_channel) { - target_ = UniquePtr(grpc_channel_get_target(channel_)); - channel_uuid_ = ChannelzRegistry::RegisterChannelNode(this); + target_(UniquePtr(grpc_channel_get_target(channel_))) { + channel_uuid_ = ChannelzRegistry::Register(this); } -ChannelNode::~ChannelNode() { - ChannelzRegistry::UnregisterChannelNode(channel_uuid_); -} - -void ChannelNode::PopulateTarget(grpc_json* json) { - GPR_ASSERT(target_.get() != nullptr); - grpc_json_create_child(nullptr, json, "target", target_.get(), - GRPC_JSON_STRING, false); -} +ChannelNode::~ChannelNode() { ChannelzRegistry::Unregister(channel_uuid_); } grpc_json* ChannelNode::RenderJson() { // We need to track these three json objects to build our object @@ -133,11 +129,13 @@ grpc_json* ChannelNode::RenderJson() { GRPC_JSON_OBJECT, false); json = data; json_iterator = nullptr; - PopulateConnectivityState(json); - PopulateTarget(json); + // populate the target. + GPR_ASSERT(target_.get() != nullptr); + grpc_json_create_child(nullptr, json, "target", target_.get(), + GRPC_JSON_STRING, false); + // as CallCountingAndTracingNode to populate trace and call count data. PopulateTrace(json); PopulateCallData(json); - PopulateChildRefs(json); return top_level_json; } @@ -148,40 +146,5 @@ RefCountedPtr ChannelNode::MakeChannelNode( channel, channel_tracer_max_nodes, is_top_level_channel); } -SubchannelNode::SubchannelNode(size_t channel_tracer_max_nodes) - : CallCountingBase(channel_tracer_max_nodes) { - subchannel_uuid_ = ChannelzRegistry::RegisterSubchannelNode(this); -} - -SubchannelNode::~SubchannelNode() { - ChannelzRegistry::UnregisterSubchannelNode(subchannel_uuid_); -} - -grpc_json* SubchannelNode::RenderJson() { - grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); - grpc_json* json = top_level_json; - grpc_json* json_iterator = nullptr; - json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr, - GRPC_JSON_OBJECT, false); - json = json_iterator; - json_iterator = nullptr; - json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "subchannelId", subchannel_uuid_); - // reset json iterators to top level object - json = top_level_json; - json_iterator = nullptr; - // create and fill the data child. - grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr, - GRPC_JSON_OBJECT, false); - json = data; - json_iterator = nullptr; - PopulateConnectivityState(json); - PopulateTarget(json); - PopulateTrace(json); - PopulateCallData(json); - PopulateChildRefs(json); - return top_level_json; -} - } // namespace channelz } // namespace grpc_core diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 1cd55bab430..12735456633 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -43,30 +43,40 @@ namespace grpc_core { namespace channelz { namespace testing { -class ChannelNodePeer; +class CallCountingAndTracingNodePeer; } // base class for all channelz entities class BaseNode : public RefCounted { public: - BaseNode() {} + // There are only four high level channelz entities. However, to support + // GetTopChannelsRequest, we split the Channel entity into two different + // types. All children of BaseNode must be one of these types. + enum class EntityType { + kTopLevelChannel, + kInternalChannel, + kSubchannel, + kServer, + kSocket, + }; + + // we track is_top_level_channel to support GetTopChannels + BaseNode(EntityType type) : type_(type) {} virtual ~BaseNode() {} - private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW -}; + // All children must implement this function. + virtual grpc_json* RenderJson() GRPC_ABSTRACT; -// Handles channelz bookkeeping for sockets -// TODO(ncteisen): implement in subsequent PR. -class SocketNode : public BaseNode { - public: - SocketNode() : BaseNode() {} - ~SocketNode() override {} + // Renders the json and returns allocated string that must be freed by the + // caller. + char* RenderJsonString(); + + EntityType type() const { return type_; } private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + EntityType type_; }; // This class is the parent for the channelz entities that deal with Channels @@ -76,16 +86,10 @@ class SocketNode : public BaseNode { // - track last_call_started_timestamp // - hold the channel trace. // - perform common rendering. -// -// This class also defines some fat interfaces so that its children can -// implement the functionality differently. For example, querying the -// connectivity state looks different for channels than for subchannels, and -// does not make sense for servers. So servers will not override, and channels -// and subchannels will override with their own way to query connectivity state. -class CallCountingBase : public BaseNode { +class CallCountingAndTracingNode : public BaseNode { public: - CallCountingBase(size_t channel_tracer_max_nodes); - ~CallCountingBase() override; + CallCountingAndTracingNode(EntityType type, size_t channel_tracer_max_nodes); + ~CallCountingAndTracingNode() override; void RecordCallStarted(); void RecordCallFailed() { @@ -96,34 +100,19 @@ class CallCountingBase : public BaseNode { } ChannelTrace* trace() { return trace_.get(); } - // Fat interface for ConnectivityState. Default is to leave it out, however, - // things like Channel and Subchannel will override with their mechanism - // for querying connectivity state. - virtual void PopulateConnectivityState(grpc_json* json) {} - - // Fat interface for Targets. - virtual void PopulateTarget(grpc_json* json) {} - - // Fat interface for ChildRefs. Allows children to populate with whatever - // combination of child_refs, subchannel_refs, and socket_refs is correct. - virtual void PopulateChildRefs(grpc_json* json) {} - - // All children must implement their custom JSON rendering. - virtual grpc_json* RenderJson() GRPC_ABSTRACT; - // Common rendering of the channel trace. void PopulateTrace(grpc_json* json); // Common rendering of the call count data and last_call_started_timestamp. void PopulateCallData(grpc_json* json); - // Common rendering of grpc_json from RenderJson() to allocated string. - char* RenderJsonString(); - private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + // testing peer friend. + friend class testing::CallCountingAndTracingNodePeer; + gpr_atm calls_started_ = 0; gpr_atm calls_succeeded_ = 0; gpr_atm calls_failed_ = 0; @@ -131,71 +120,64 @@ class CallCountingBase : public BaseNode { ManualConstructor trace_; }; -// Handles channelz bookkeeping for servers -// TODO(ncteisen): implement in subsequent PR. -class ServerNode : public CallCountingBase { - public: - ServerNode(size_t channel_tracer_max_nodes) - : CallCountingBase(channel_tracer_max_nodes) {} - ~ServerNode() override {} - - private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW -}; - -// Overrides Channel specific functionality. -class ChannelNode : public CallCountingBase { +// Handles channelz bookkeeping for channels +class ChannelNode : public CallCountingAndTracingNode { public: static RefCountedPtr MakeChannelNode( grpc_channel* channel, size_t channel_tracer_max_nodes, bool is_top_level_channel); + grpc_json* RenderJson() override; + void MarkChannelDestroyed() { GPR_ASSERT(channel_ != nullptr); channel_ = nullptr; } - grpc_json* RenderJson() override; - - void PopulateTarget(grpc_json* json) override; - bool ChannelIsDestroyed() { return channel_ == nullptr; } intptr_t channel_uuid() { return channel_uuid_; } - bool is_top_level_channel() { return is_top_level_channel_; } protected: ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, bool is_top_level_channel); ~ChannelNode() override; + // provides view of target for child. + char* target_view() { return target_.get(); } private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - // testing peer friend. - friend class testing::ChannelNodePeer; - grpc_channel* channel_ = nullptr; UniquePtr target_; intptr_t channel_uuid_; - bool is_top_level_channel_ = true; }; -// Overrides Subchannel specific functionality. -class SubchannelNode : public CallCountingBase { +// Handles channelz bookkeeping for servers +// TODO(ncteisen): implement in subsequent PR. +class ServerNode : public CallCountingAndTracingNode { public: - SubchannelNode(size_t channel_tracer_max_nodes); - ~SubchannelNode() override; - grpc_json* RenderJson() override; - intptr_t subchannel_uuid() { return subchannel_uuid_; } + ServerNode(size_t channel_tracer_max_nodes) + : CallCountingAndTracingNode(EntityType::kServer, + channel_tracer_max_nodes) {} + ~ServerNode() override {} private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW +}; - intptr_t subchannel_uuid_; +// Handles channelz bookkeeping for sockets +// TODO(ncteisen): implement in subsequent PR. +class SocketNode : public BaseNode { + public: + SocketNode() : BaseNode(EntityType::kSocket) {} + ~SocketNode() override {} + + private: + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW }; // Creation functions diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index aeeb6958e44..7f709089896 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -52,54 +52,46 @@ ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); } ChannelzRegistry::~ChannelzRegistry() { gpr_mu_destroy(&mu_); } -intptr_t ChannelzRegistry::InternalRegisterEntry(const RegistryEntry& entry) { +intptr_t ChannelzRegistry::InternalRegister(BaseNode* node) { mu_guard guard(&mu_); - entities_.push_back(entry); + entities_.push_back(node); intptr_t uuid = entities_.size(); return uuid; } -void ChannelzRegistry::InternalUnregisterEntry(intptr_t uuid, EntityType type) { +void ChannelzRegistry::InternalUnregister(intptr_t uuid) { GPR_ASSERT(uuid >= 1); mu_guard guard(&mu_); GPR_ASSERT(static_cast(uuid) <= entities_.size()); - GPR_ASSERT(entities_[uuid - 1].type == type); - entities_[uuid - 1].object = nullptr; - entities_[uuid - 1].type = EntityType::kUnset; + entities_[uuid - 1] = nullptr; } -void* ChannelzRegistry::InternalGetEntry(intptr_t uuid, EntityType type) { +BaseNode* ChannelzRegistry::InternalGet(intptr_t uuid) { mu_guard guard(&mu_); if (uuid < 1 || uuid > static_cast(entities_.size())) { return nullptr; } - if (entities_[uuid - 1].type == type) { - return entities_[uuid - 1].object; - } else { - return nullptr; - } + return entities_[uuid - 1]; } char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; - InlinedVector top_level_channels; + InlinedVector top_level_channels; // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is // reserved). However, we want to support requests coming in with // start_channel_id=0, which signifies "give me everything." Hence this // funky looking line below. size_t start_idx = start_channel_id == 0 ? 0 : start_channel_id - 1; for (size_t i = start_idx; i < entities_.size(); ++i) { - if (entities_[i].type == EntityType::kChannelNode) { - ChannelNode* channel_node = - static_cast(entities_[i].object); - if (channel_node->is_top_level_channel()) { - top_level_channels.push_back(channel_node); - } + if (entities_[i] != nullptr && + entities_[i]->type() == + grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel) { + top_level_channels.push_back(entities_[i]); } } - if (top_level_channels.size() > 0) { + if (!top_level_channels.empty()) { // create list of channels grpc_json* array_parent = grpc_json_create_child( nullptr, json, "channel", nullptr, GRPC_JSON_ARRAY, false); @@ -128,9 +120,14 @@ char* grpc_channelz_get_top_channels(intptr_t start_channel_id) { } char* grpc_channelz_get_channel(intptr_t channel_id) { - grpc_core::channelz::ChannelNode* channel_node = - grpc_core::channelz::ChannelzRegistry::GetChannelNode(channel_id); - if (channel_node == nullptr) { + grpc_core::channelz::BaseNode* channel_node = + grpc_core::channelz::ChannelzRegistry::Get(channel_id); + if (channel_node == nullptr || + + (channel_node->type() != + grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel && + channel_node->type() != + grpc_core::channelz::BaseNode::EntityType::kInternalChannel)) { return nullptr; } grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); @@ -144,9 +141,11 @@ char* grpc_channelz_get_channel(intptr_t channel_id) { } char* grpc_channelz_get_subchannel(intptr_t subchannel_id) { - grpc_core::channelz::SubchannelNode* subchannel_node = - grpc_core::channelz::ChannelzRegistry::GetSubchannelNode(subchannel_id); - if (subchannel_node == nullptr) { + grpc_core::channelz::BaseNode* subchannel_node = + grpc_core::channelz::ChannelzRegistry::Get(subchannel_id); + if (subchannel_node == nullptr || + subchannel_node->type() != + grpc_core::channelz::BaseNode::EntityType::kSubchannel) { return nullptr; } grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h index 5d7c9367265..142c039220d 100644 --- a/src/core/lib/channel/channelz_registry.h +++ b/src/core/lib/channel/channelz_registry.h @@ -40,32 +40,11 @@ class ChannelzRegistry { // To be called in grpc_shutdown(); static void Shutdown(); - // Register/Unregister/Get for ChannelNode - static intptr_t RegisterChannelNode(ChannelNode* channel_node) { - RegistryEntry entry(channel_node, EntityType::kChannelNode); - return Default()->InternalRegisterEntry(entry); - } - static void UnregisterChannelNode(intptr_t uuid) { - Default()->InternalUnregisterEntry(uuid, EntityType::kChannelNode); - } - static ChannelNode* GetChannelNode(intptr_t uuid) { - void* gotten = Default()->InternalGetEntry(uuid, EntityType::kChannelNode); - return gotten == nullptr ? nullptr : static_cast(gotten); - } - - // Register/Unregister/Get for SubchannelNode - static intptr_t RegisterSubchannelNode(SubchannelNode* channel_node) { - RegistryEntry entry(channel_node, EntityType::kSubchannelNode); - return Default()->InternalRegisterEntry(entry); - } - static void UnregisterSubchannelNode(intptr_t uuid) { - Default()->InternalUnregisterEntry(uuid, EntityType::kSubchannelNode); - } - static SubchannelNode* GetSubchannelNode(intptr_t uuid) { - void* gotten = - Default()->InternalGetEntry(uuid, EntityType::kSubchannelNode); - return gotten == nullptr ? nullptr : static_cast(gotten); + static intptr_t Register(BaseNode* node) { + return Default()->InternalRegister(node); } + static void Unregister(intptr_t uuid) { Default()->InternalUnregister(uuid); } + static BaseNode* Get(intptr_t uuid) { return Default()->InternalGet(uuid); } // Returns the allocated JSON string that represents the proto // GetTopChannelsResponse as per channelz.proto. @@ -74,19 +53,6 @@ class ChannelzRegistry { } private: - enum class EntityType { - kChannelNode, - kSubchannelNode, - kUnset, - }; - - struct RegistryEntry { - RegistryEntry(void* object_in, EntityType type_in) - : object(object_in), type(type_in) {} - void* object; - EntityType type; - }; - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE @@ -97,21 +63,21 @@ class ChannelzRegistry { static ChannelzRegistry* Default(); // globally registers an Entry. Returns its unique uuid - intptr_t InternalRegisterEntry(const RegistryEntry& entry); + intptr_t InternalRegister(BaseNode* node); // globally unregisters the object that is associated to uuid. Also does // sanity check that an object doesn't try to unregister the wrong type. - void InternalUnregisterEntry(intptr_t uuid, EntityType type); + void InternalUnregister(intptr_t uuid); // if object with uuid has previously been registered as the correct type, // returns the void* associated with that uuid. Else returns nullptr. - void* InternalGetEntry(intptr_t uuid, EntityType type); + BaseNode* InternalGet(intptr_t uuid); char* InternalGetTopChannels(intptr_t start_channel_id); // protects entities_ and uuid_ gpr_mu mu_; - InlinedVector entities_; + InlinedVector entities_; }; } // namespace channelz diff --git a/test/core/channel/channelz_registry_test.cc b/test/core/channel/channelz_registry_test.cc index 581e867584c..c02d525c819 100644 --- a/test/core/channel/channelz_registry_test.cc +++ b/test/core/channel/channelz_registry_test.cc @@ -44,22 +44,22 @@ namespace channelz { namespace testing { TEST(ChannelzRegistryTest, UuidStartsAboveZeroTest) { - ChannelNode* channelz_channel = nullptr; - intptr_t uuid = ChannelzRegistry::RegisterChannelNode(channelz_channel); + BaseNode* channelz_channel = nullptr; + intptr_t uuid = ChannelzRegistry::Register(channelz_channel); EXPECT_GT(uuid, 0) << "First uuid chose must be greater than zero. Zero if " "reserved according to " "https://github.com/grpc/proposal/blob/master/" "A14-channelz.md"; - ChannelzRegistry::UnregisterChannelNode(uuid); + ChannelzRegistry::Unregister(uuid); } TEST(ChannelzRegistryTest, UuidsAreIncreasing) { - ChannelNode* channelz_channel = nullptr; + BaseNode* channelz_channel = nullptr; std::vector uuids; uuids.reserve(10); for (int i = 0; i < 10; ++i) { // reregister the same object. It's ok since we are just testing uuids - uuids.push_back(ChannelzRegistry::RegisterChannelNode(channelz_channel)); + uuids.push_back(ChannelzRegistry::Register(channelz_channel)); } for (size_t i = 1; i < uuids.size(); ++i) { EXPECT_LT(uuids[i - 1], uuids[i]) << "Uuids must always be increasing"; @@ -68,30 +68,30 @@ TEST(ChannelzRegistryTest, UuidsAreIncreasing) { TEST(ChannelzRegistryTest, RegisterGetTest) { // we hackily jam an intptr_t into this pointer to check for equality later - ChannelNode* channelz_channel = (ChannelNode*)42; - intptr_t uuid = ChannelzRegistry::RegisterChannelNode(channelz_channel); - ChannelNode* retrieved = ChannelzRegistry::GetChannelNode(uuid); + BaseNode* channelz_channel = (BaseNode*)42; + intptr_t uuid = ChannelzRegistry::Register(channelz_channel); + BaseNode* retrieved = ChannelzRegistry::Get(uuid); EXPECT_EQ(channelz_channel, retrieved); } TEST(ChannelzRegistryTest, RegisterManyItems) { // we hackily jam an intptr_t into this pointer to check for equality later - ChannelNode* channelz_channel = (ChannelNode*)42; + BaseNode* channelz_channel = (BaseNode*)42; for (int i = 0; i < 100; i++) { - intptr_t uuid = ChannelzRegistry::RegisterChannelNode(channelz_channel); - ChannelNode* retrieved = ChannelzRegistry::GetChannelNode(uuid); + intptr_t uuid = ChannelzRegistry::Register(channelz_channel); + BaseNode* retrieved = ChannelzRegistry::Get(uuid); EXPECT_EQ(channelz_channel, retrieved); } } TEST(ChannelzRegistryTest, NullIfNotPresentTest) { // we hackily jam an intptr_t into this pointer to check for equality later - ChannelNode* channelz_channel = (ChannelNode*)42; - intptr_t uuid = ChannelzRegistry::RegisterChannelNode(channelz_channel); + BaseNode* channelz_channel = (BaseNode*)42; + intptr_t uuid = ChannelzRegistry::Register(channelz_channel); // try to pull out a uuid that does not exist. - ChannelNode* nonexistant = ChannelzRegistry::GetChannelNode(uuid + 1); + BaseNode* nonexistant = ChannelzRegistry::Get(uuid + 1); EXPECT_EQ(nonexistant, nullptr); - ChannelNode* retrieved = ChannelzRegistry::GetChannelNode(uuid); + BaseNode* retrieved = ChannelzRegistry::Get(uuid); EXPECT_EQ(channelz_channel, retrieved); } diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index b8e65ebfb31..ec1c9f6faff 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -44,16 +44,17 @@ namespace channelz { namespace testing { // testing peer to access channel internals -class ChannelNodePeer { +class CallCountingAndTracingNodePeer { public: - ChannelNodePeer(ChannelNode* channel) : channel_(channel) {} + CallCountingAndTracingNodePeer(CallCountingAndTracingNode* node) + : node_(node) {} grpc_millis last_call_started_millis() { return (grpc_millis)gpr_atm_no_barrier_load( - &channel_->last_call_started_millis_); + &node_->last_call_started_millis_); } private: - ChannelNode* channel_; + CallCountingAndTracingNode* node_; }; namespace { @@ -163,16 +164,8 @@ void ValidateChannel(ChannelNode* channel, validate_channel_data_args args) { gpr_free(core_api_json_str); } -void ValidateSubchannel(SubchannelNode* subchannel, - validate_channel_data_args args) { - char* json_str = subchannel->RenderJsonString(); - grpc::testing::ValidateSubchannelProtoJsonTranslation(json_str); - ValidateCounters(json_str, args); - gpr_free(json_str); -} - -grpc_millis GetLastCallStartedMillis(ChannelNode* channel) { - ChannelNodePeer peer(channel); +grpc_millis GetLastCallStartedMillis(CallCountingAndTracingNode* channel) { + CallCountingAndTracingNodePeer peer(channel); return peer.last_call_started_millis(); } @@ -283,29 +276,8 @@ TEST(ChannelzGetTopChannelsTest, InternalChannelTest) { grpc_channel_destroy(internal_channel); } -class ChannelzSubchannelTest : public ::testing::TestWithParam {}; - -TEST_P(ChannelzSubchannelTest, BasicTest) { - grpc_core::ExecCtx exec_ctx; - RefCountedPtr channelz_subchannel = - MakeRefCounted(GetParam()); - channelz_subchannel->RecordCallStarted(); - channelz_subchannel->RecordCallFailed(); - channelz_subchannel->RecordCallSucceeded(); - ValidateSubchannel(channelz_subchannel.get(), {1, 1, 1}); - channelz_subchannel->RecordCallStarted(); - channelz_subchannel->RecordCallFailed(); - channelz_subchannel->RecordCallSucceeded(); - channelz_subchannel->RecordCallStarted(); - channelz_subchannel->RecordCallFailed(); - channelz_subchannel->RecordCallSucceeded(); - ValidateSubchannel(channelz_subchannel.get(), {3, 3, 3}); -} - INSTANTIATE_TEST_CASE_P(ChannelzChannelTestSweep, ChannelzChannelTest, ::testing::Values(0, 1, 2, 6, 10, 15)); -INSTANTIATE_TEST_CASE_P(ChannelzSubchannelTestSweep, ChannelzSubchannelTest, - ::testing::Values(0, 1, 10, 15)); } // namespace testing } // namespace channelz From 835dab6a464b3246f6bdc3b1bb0fe706551a0260 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 20 Jul 2018 16:17:48 -0700 Subject: [PATCH 033/546] Full subchannel support --- .../filters/client_channel/client_channel.cc | 5 ++- .../client_channel/client_channel_channelz.cc | 2 ++ .../ext/filters/client_channel/subchannel.cc | 33 ++++++++++++------- .../ext/filters/client_channel/subchannel.h | 10 +++++- src/core/lib/channel/channel_stack.h | 1 + src/core/lib/surface/call.cc | 22 ++++++++++++- src/core/lib/surface/call.h | 13 ++++++++ test/core/channel/channel_stack_test.cc | 3 +- test/core/end2end/tests/channelz.cc | 4 +++ 9 files changed, 77 insertions(+), 16 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 024c9d737e8..13a0b955115 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -892,6 +892,7 @@ typedef struct client_channel_call_data { grpc_millis deadline; gpr_arena* arena; grpc_call_stack* owning_call; + grpc_call* call; grpc_call_combiner* call_combiner; grpc_core::RefCountedPtr retry_throttle_data; @@ -2561,7 +2562,8 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { calld->arena, // arena calld->pick.subchannel_call_context, // context calld->call_combiner, // call_combiner - parent_data_size // parent_data_size + parent_data_size, // parent_data_size + calld->call // call }; grpc_error* new_error = calld->pick.connected_subchannel->CreateCall( call_args, &calld->subchannel_call); @@ -3092,6 +3094,7 @@ static grpc_error* cc_init_call_elem(grpc_call_element* elem, calld->arena = args->arena; calld->owning_call = args->call_stack; calld->call_combiner = args->call_combiner; + calld->call = args->call; if (GPR_LIKELY(chand->deadline_checking_enabled)) { grpc_deadline_state_init(elem, args->call_stack, args->call_combiner, calld->deadline); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 0db9799a659..a1ecbe75a20 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -126,6 +126,8 @@ grpc_json* ClientChannelNode::RenderJson() { // as CallCountingAndTracingNode to populate trace and call count data. PopulateTrace(json); PopulateCallData(json); + // reset to the top level + json = top_level_json; PopulateChildRefs(json); return top_level_json; } diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 8dfbd33ffed..a15cfd43c34 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -46,6 +46,7 @@ #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/channel_init.h" #include "src/core/lib/transport/connectivity_state.h" @@ -640,8 +641,8 @@ static bool publish_transport_locked(grpc_subchannel* c) { } /* publish */ - c->connected_subchannel.reset( - grpc_core::New(stk)); + c->connected_subchannel.reset(grpc_core::New( + stk, c->channelz_subchannel.get())); gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", c->connected_subchannel.get(), c); @@ -796,9 +797,12 @@ grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) { namespace grpc_core { -ConnectedSubchannel::ConnectedSubchannel(grpc_channel_stack* channel_stack) +ConnectedSubchannel::ConnectedSubchannel( + grpc_channel_stack* channel_stack, + channelz::SubchannelNode* channelz_subchannel) : RefCountedWithTracing(&grpc_trace_stream_refcount), - channel_stack_(channel_stack) {} + channel_stack_(channel_stack), + channelz_subchannel_(channelz_subchannel) {} ConnectedSubchannel::~ConnectedSubchannel() { GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); @@ -845,14 +849,15 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, connection.release(); // Ref is passed to the grpc_subchannel_call object. (*call)->connection = this; const grpc_call_element_args call_args = { - callstk, /* call_stack */ - nullptr, /* server_transport_data */ - args.context, /* context */ - args.path, /* path */ - args.start_time, /* start_time */ - args.deadline, /* deadline */ - args.arena, /* arena */ - args.call_combiner /* call_combiner */ + callstk, /* call_stack */ + nullptr, /* server_transport_data */ + args.context, /* context */ + args.path, /* path */ + args.start_time, /* start_time */ + args.deadline, /* deadline */ + args.arena, /* arena */ + args.call_combiner, /* call_combiner */ + args.call /* call */ }; grpc_error* error = grpc_call_stack_init( channel_stack_, 1, subchannel_call_destroy, *call, &call_args); @@ -861,6 +866,10 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, gpr_log(GPR_ERROR, "error: %s", error_string); return error; } + if (channelz_subchannel_ != nullptr) { + channelz_subchannel_->RecordCallStarted(); + grpc_call_set_channelz_subchannel(args.call, channelz_subchannel_); + } grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); return GRPC_ERROR_NONE; } diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index dd3a2d96214..d62348488ee 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -83,9 +83,11 @@ class ConnectedSubchannel : public RefCountedWithTracing { grpc_call_context_element* context; grpc_call_combiner* call_combiner; size_t parent_data_size; + grpc_call* call; }; - explicit ConnectedSubchannel(grpc_channel_stack* channel_stack); + explicit ConnectedSubchannel(grpc_channel_stack* channel_stack, + channelz::SubchannelNode* channelz_subchannel); ~ConnectedSubchannel(); grpc_channel_stack* channel_stack() { return channel_stack_; } @@ -94,9 +96,15 @@ class ConnectedSubchannel : public RefCountedWithTracing { grpc_closure* closure); void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call); + channelz::SubchannelNode* channelz_subchannel() { + return channelz_subchannel_; + } private: grpc_channel_stack* channel_stack_; + // backpointer to the channelz node in this connected subchannel's + // owning subchannel. + channelz::SubchannelNode* channelz_subchannel_; }; } // namespace grpc_core diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 7581f937b64..727f36a6f88 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -71,6 +71,7 @@ typedef struct { grpc_millis deadline; gpr_arena* arena; grpc_call_combiner* call_combiner; + grpc_call* call; } grpc_call_element_args; typedef struct { diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 88e015ce22f..6545af8f723 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -170,6 +170,11 @@ struct grpc_call { /* parent_call* */ gpr_atm parent_call_atm; child_call* child; + // the call holds onto this so that once the call knows if the RPC was + // a success or failure, it can update the channelz bookkeeping for the + // subchannel that sent it. + grpc_core::channelz::CallCountingAndTracingNode* channelz_subchannel_; + /* client or server call */ bool is_client; /** has grpc_call_unref been called */ @@ -269,6 +274,11 @@ struct grpc_call { gpr_atm recv_state; }; +void grpc_call_set_channelz_subchannel( + grpc_call* call, grpc_core::channelz::CallCountingAndTracingNode* node) { + call->channelz_subchannel_ = node; +} + grpc_core::TraceFlag grpc_call_error_trace(false, "call_error"); grpc_core::TraceFlag grpc_compression_trace(false, "compression"); @@ -444,7 +454,8 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, call->start_time, send_deadline, call->arena, - &call->call_combiner}; + &call->call_combiner, + call}; add_init_error(&error, grpc_call_stack_init(channel_stack, 1, destroy_call, call, &call_args)); // Publish this call to parent only after the call stack has been initialized. @@ -1263,6 +1274,7 @@ static void post_batch_completion(batch_control* bctl) { get_final_status(call, set_cancelled_value, call->final_op.server.cancelled, nullptr, nullptr); } + // Record channelz data for the channel. grpc_core::channelz::ChannelNode* channelz_channel = grpc_channel_get_channelz_node(call->channel); if (channelz_channel != nullptr) { @@ -1272,6 +1284,14 @@ static void post_batch_completion(batch_control* bctl) { channelz_channel->RecordCallSucceeded(); } } + // Record channelz data for the subchannel. + if (call->channelz_subchannel_ != nullptr) { + if (*call->final_op.client.status != GRPC_STATUS_OK) { + call->channelz_subchannel_->RecordCallFailed(); + } else { + call->channelz_subchannel_->RecordCallSucceeded(); + } + } GRPC_ERROR_UNREF(error); error = GRPC_ERROR_NONE; } diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index b3b06059d4d..200c840c61f 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -110,6 +110,19 @@ size_t grpc_call_get_initial_size_estimate(); grpc_compression_algorithm grpc_call_compression_for_level( grpc_call* call, grpc_compression_level level); +namespace grpc_core { +namespace channelz { +class CallCountingAndTracingNode; +} // namespace channelz +} // namespace grpc_core + +// We need this so that a subchannel selected for a call can add itself to +// the call's data structure. This allows the call to trigger the correct +// channelz bookkeeping on the subchannel once the call knows if the RPC was +// successful or not. +void grpc_call_set_channelz_subchannel( + grpc_call* call, grpc_core::channelz::CallCountingAndTracingNode* node); + extern grpc_core::TraceFlag grpc_call_error_trace; extern grpc_core::TraceFlag grpc_compression_trace; diff --git a/test/core/channel/channel_stack_test.cc b/test/core/channel/channel_stack_test.cc index 2f5329a96d4..4dc2ee3f558 100644 --- a/test/core/channel/channel_stack_test.cc +++ b/test/core/channel/channel_stack_test.cc @@ -124,7 +124,8 @@ static void test_create_channel_stack(void) { gpr_now(GPR_CLOCK_MONOTONIC), /* start_time */ GRPC_MILLIS_INF_FUTURE, /* deadline */ nullptr, /* arena */ - nullptr /* call_combiner */ + nullptr, /* call_combiner */ + nullptr /* call */ }; grpc_error* error = grpc_call_stack_init(channel_stack, 1, free_call, call_stack, &args); diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 533703a2bec..754c3d37419 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -241,6 +241,10 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); gpr_free(json); + json = grpc_channelz_get_subchannel(2); + gpr_log(GPR_INFO, "%s", json); + gpr_free(json); + end_test(&f); config.tear_down_data(&f); } From f081cf67d16049dc07141420601272d9f5988b1c Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 20 Jul 2018 17:55:36 -0700 Subject: [PATCH 034/546] refactor --- .../client_channel/client_channel_channelz.cc | 16 ++- .../client_channel/client_channel_channelz.h | 2 - .../client_channel/lb_policy/grpclb/grpclb.cc | 2 +- .../lb_policy/subchannel_list.h | 2 +- src/core/lib/channel/channel_trace.cc | 42 ++++---- src/core/lib/channel/channel_trace.h | 26 ++--- src/core/lib/channel/channelz.cc | 14 ++- src/core/lib/channel/channelz.h | 10 +- test/core/channel/channel_trace_test.cc | 100 +++++++++--------- test/core/channel/channelz_test.cc | 2 +- 10 files changed, 102 insertions(+), 114 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index a1ecbe75a20..996a871f387 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -108,8 +108,8 @@ grpc_json* ClientChannelNode::RenderJson() { GRPC_JSON_OBJECT, false); json = json_iterator; json_iterator = nullptr; - json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "channelId", channel_uuid()); + json_iterator = grpc_json_add_number_string_child(json, json_iterator, + "channelId", uuid()); // reset json iterators to top level object json = top_level_json; json_iterator = nullptr; @@ -152,13 +152,9 @@ SubchannelNode::SubchannelNode(grpc_subchannel* subchannel, channel_tracer_max_nodes), subchannel_(subchannel), target_(UniquePtr( - gpr_strdup(grpc_subchannel_get_target(subchannel_)))) { - subchannel_uuid_ = ChannelzRegistry::Register(this); -} + gpr_strdup(grpc_subchannel_get_target(subchannel_)))) {} -SubchannelNode::~SubchannelNode() { - ChannelzRegistry::Unregister(subchannel_uuid_); -} +SubchannelNode::~SubchannelNode() {} void SubchannelNode::PopulateConnectivityState(grpc_json* json) { grpc_connectivity_state state; @@ -182,8 +178,8 @@ grpc_json* SubchannelNode::RenderJson() { GRPC_JSON_OBJECT, false); json = json_iterator; json_iterator = nullptr; - json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "subchannelId", subchannel_uuid_); + json_iterator = grpc_json_add_number_string_child(json, json_iterator, + "subchannelId", uuid()); // reset json iterators to top level object json = top_level_json; json_iterator = nullptr; diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 73eea7cecf2..45df756b910 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -79,8 +79,6 @@ class SubchannelNode : public CallCountingAndTracingNode { grpc_json* RenderJson() override; - intptr_t subchannel_uuid() { return subchannel_uuid_; } - private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW 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 959c7441a37..dc475d3d68a 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 @@ -1294,7 +1294,7 @@ void GrpcLb::FillChildRefsForChannelz(ChildRefsList* child_subchannels, grpc_core::channelz::ChannelNode* channel_node = grpc_channel_get_channelz_node(lb_channel_); if (channel_node != nullptr) { - child_channels->push_back(channel_node->channel_uuid()); + child_channels->push_back(channel_node->uuid()); } } } 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 018ac3bb868..199b9a3c13e 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 @@ -196,7 +196,7 @@ class SubchannelList grpc_core::channelz::SubchannelNode* subchannel_node = grpc_subchannel_get_channelz_node(subchannels_[i].subchannel()); if (subchannel_node != nullptr) { - refs_list->push_back(subchannel_node->subchannel_uuid()); + refs_list->push_back(subchannel_node->uuid()); } } } diff --git a/src/core/lib/channel/channel_trace.cc b/src/core/lib/channel/channel_trace.cc index dd6fdeed545..ba2b3bcad68 100644 --- a/src/core/lib/channel/channel_trace.cc +++ b/src/core/lib/channel/channel_trace.cc @@ -41,16 +41,14 @@ namespace grpc_core { namespace channelz { -ChannelTrace::TraceEvent::TraceEvent( - Severity severity, grpc_slice data, - RefCountedPtr referenced_channel, ReferencedType type) +ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data, + RefCountedPtr referenced_entity) : severity_(severity), data_(data), timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(), GPR_CLOCK_REALTIME)), next_(nullptr), - referenced_channel_(std::move(referenced_channel)), - referenced_type_(type) {} + referenced_entity_(std::move(referenced_entity)) {} ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data) : severity_(severity), @@ -112,21 +110,11 @@ void ChannelTrace::AddTraceEvent(Severity severity, grpc_slice data) { void ChannelTrace::AddTraceEventReferencingChannel( Severity severity, grpc_slice data, - RefCountedPtr referenced_channel) { - if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0 - // create and fill up the new event - AddTraceEventHelper(New( - severity, data, std::move(referenced_channel), ReferencedType::Channel)); -} - -void ChannelTrace::AddTraceEventReferencingSubchannel( - Severity severity, grpc_slice data, - RefCountedPtr referenced_subchannel) { + RefCountedPtr referenced_entity) { if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0 // create and fill up the new event - AddTraceEventHelper(New(severity, data, - std::move(referenced_subchannel), - ReferencedType::Subchannel)); + AddTraceEventHelper( + New(severity, data, std::move(referenced_entity))); } namespace { @@ -157,18 +145,24 @@ void ChannelTrace::TraceEvent::RenderTraceEvent(grpc_json* json) const { json_iterator = grpc_json_create_child(json_iterator, json, "timestamp", gpr_format_timespec(timestamp_), GRPC_JSON_STRING, true); - if (referenced_channel_ != nullptr) { + if (referenced_entity_ != nullptr) { + GPR_ASSERT( + referenced_entity_->type() == BaseNode::EntityType::kSubchannel || + referenced_entity_->type() == BaseNode::EntityType::kTopLevelChannel || + referenced_entity_->type() == BaseNode::EntityType::kInternalChannel); char* uuid_str; - gpr_asprintf(&uuid_str, "%" PRIdPTR, referenced_channel_->channel_uuid()); + gpr_asprintf(&uuid_str, "%" PRIdPTR, referenced_entity_->uuid()); grpc_json* child_ref = grpc_json_create_child( json_iterator, json, - (referenced_type_ == ReferencedType::Channel) ? "channelRef" - : "subchannelRef", + (referenced_entity_->type() == BaseNode::EntityType::kSubchannel) + ? "subchannelRef" + : "channelRef", nullptr, GRPC_JSON_OBJECT, false); json_iterator = grpc_json_create_child( nullptr, child_ref, - (referenced_type_ == ReferencedType::Channel) ? "channelId" - : "subchannelId", + (referenced_entity_->type() == BaseNode::EntityType::kSubchannel) + ? "subchannelId" + : "channelId", uuid_str, GRPC_JSON_STRING, true); json_iterator = child_ref; } diff --git a/src/core/lib/channel/channel_trace.h b/src/core/lib/channel/channel_trace.h index 596af7402f0..cef8814d5fa 100644 --- a/src/core/lib/channel/channel_trace.h +++ b/src/core/lib/channel/channel_trace.h @@ -30,7 +30,7 @@ namespace grpc_core { namespace channelz { -class ChannelNode; +class BaseNode; // Object used to hold live data for a channel. This data is exposed via the // channelz service: @@ -55,35 +55,32 @@ class ChannelTrace { void AddTraceEvent(Severity severity, grpc_slice data); // Adds a new trace event to the tracing object. This trace event refers to a - // an event on a child of the channel. For example, if this channel has - // created a new subchannel, then it would record that with a TraceEvent - // referencing the new subchannel. + // an event that concerns a different channelz entity. For example, if this + // channel has created a new subchannel, then it would record that with + // a TraceEvent referencing the new subchannel. // // TODO(ncteisen): as this call is used more and more throughout the gRPC // stack, determine if it makes more sense to accept a char* instead of a // slice. void AddTraceEventReferencingChannel( Severity severity, grpc_slice data, - RefCountedPtr referenced_channel); - void AddTraceEventReferencingSubchannel( - Severity severity, grpc_slice data, - RefCountedPtr referenced_subchannel); + RefCountedPtr referenced_entity); + // void AddTraceEventWithReference( + // Severity severity, grpc_slice data, + // RefCountedPtr referenced_entity); // Creates and returns the raw grpc_json object, so a parent channelz // object may incorporate the json before rendering. grpc_json* RenderJson() const; private: - // Types of objects that can be references by trace events. - enum class ReferencedType { Channel, Subchannel }; // Private class to encapsulate all the data and bookkeeping needed for a // a trace event. class TraceEvent { public: // Constructor for a TraceEvent that references a different channel. TraceEvent(Severity severity, grpc_slice data, - RefCountedPtr referenced_channel, - ReferencedType type); + RefCountedPtr referenced); // Constructor for a TraceEvent that does not reverence a different // channel. @@ -105,10 +102,7 @@ class ChannelTrace { gpr_timespec timestamp_; TraceEvent* next_; // the tracer object for the (sub)channel that this trace event refers to. - RefCountedPtr referenced_channel_; - // the type that the referenced tracer points to. Unused if this trace - // does not point to any channel or subchannel - ReferencedType referenced_type_; + RefCountedPtr referenced_entity_; }; // TraceEvent // Internal helper to add and link in a trace event diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index d7f2d6a9a23..eec2cd61b2b 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -41,6 +41,12 @@ namespace grpc_core { namespace channelz { +BaseNode::BaseNode(EntityType type) : type_(type) { + uuid_ = ChannelzRegistry::Register(this); +} + +BaseNode::~BaseNode() { ChannelzRegistry::Unregister(uuid_); } + char* BaseNode::RenderJsonString() { grpc_json* json = RenderJson(); char* json_str = grpc_json_dump_to_string(json, 0); @@ -103,11 +109,9 @@ ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, : EntityType::kInternalChannel, channel_tracer_max_nodes), channel_(channel), - target_(UniquePtr(grpc_channel_get_target(channel_))) { - channel_uuid_ = ChannelzRegistry::Register(this); -} + target_(UniquePtr(grpc_channel_get_target(channel_))) {} -ChannelNode::~ChannelNode() { ChannelzRegistry::Unregister(channel_uuid_); } +ChannelNode::~ChannelNode() {} grpc_json* ChannelNode::RenderJson() { // We need to track these three json objects to build our object @@ -120,7 +124,7 @@ grpc_json* ChannelNode::RenderJson() { json = json_iterator; json_iterator = nullptr; json_iterator = grpc_json_add_number_string_child(json, json_iterator, - "channelId", channel_uuid_); + "channelId", uuid()); // reset json iterators to top level object json = top_level_json; json_iterator = nullptr; diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 12735456633..67cd1fec2dd 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -60,9 +60,8 @@ class BaseNode : public RefCounted { kSocket, }; - // we track is_top_level_channel to support GetTopChannels - BaseNode(EntityType type) : type_(type) {} - virtual ~BaseNode() {} + BaseNode(EntityType type); + virtual ~BaseNode(); // All children must implement this function. virtual grpc_json* RenderJson() GRPC_ABSTRACT; @@ -72,11 +71,14 @@ class BaseNode : public RefCounted { char* RenderJsonString(); EntityType type() const { return type_; } + intptr_t uuid() const { return uuid_; } private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + friend class ChannelTrace; EntityType type_; + intptr_t uuid_; }; // This class is the parent for the channelz entities that deal with Channels @@ -136,8 +138,6 @@ class ChannelNode : public CallCountingAndTracingNode { bool ChannelIsDestroyed() { return channel_ == nullptr; } - intptr_t channel_uuid() { return channel_uuid_; } - protected: ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, bool is_top_level_channel); diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index 99d9a4847fd..703a9e457f4 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -156,7 +156,7 @@ TEST_P(ChannelTracerTest, ComplexTest) { ChannelFixture channel1(GetParam()); RefCountedPtr sc1 = MakeRefCounted(channel1.channel(), GetParam(), true); - tracer.AddTraceEventReferencingSubchannel( + tracer.AddTraceEventReferencingChannel( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel one created"), sc1); ValidateChannelTrace(&tracer, 3, GetParam()); @@ -177,7 +177,7 @@ TEST_P(ChannelTracerTest, ComplexTest) { tracer.AddTraceEventReferencingChannel( ChannelTrace::Severity::Info, grpc_slice_from_static_string("LB channel two created"), sc2); - tracer.AddTraceEventReferencingSubchannel( + tracer.AddTraceEventReferencingChannel( ChannelTrace::Severity::Warning, grpc_slice_from_static_string("subchannel one inactive"), sc1); ValidateChannelTrace(&tracer, 7, GetParam()); @@ -191,53 +191,55 @@ TEST_P(ChannelTracerTest, ComplexTest) { sc2.reset(nullptr); } -// Test a case in which the parent channel has subchannels and the subchannels -// have connections. Ensures that everything lives as long as it should then -// gets deleted. -TEST_P(ChannelTracerTest, TestNesting) { - grpc_core::ExecCtx exec_ctx; - ChannelTrace tracer(GetParam()); - AddSimpleTrace(&tracer); - AddSimpleTrace(&tracer); - ValidateChannelTrace(&tracer, 2, GetParam()); - ChannelFixture channel1(GetParam()); - RefCountedPtr sc1 = - MakeRefCounted(channel1.channel(), GetParam(), true); - tracer.AddTraceEventReferencingChannel( - ChannelTrace::Severity::Info, - grpc_slice_from_static_string("subchannel one created"), sc1); - ValidateChannelTrace(&tracer, 3, GetParam()); - AddSimpleTrace(sc1->trace()); - ChannelFixture channel2(GetParam()); - RefCountedPtr conn1 = - MakeRefCounted(channel2.channel(), GetParam(), true); - // nesting one level deeper. - sc1->trace()->AddTraceEventReferencingSubchannel( - ChannelTrace::Severity::Info, - grpc_slice_from_static_string("connection one created"), conn1); - ValidateChannelTrace(&tracer, 3, GetParam()); - AddSimpleTrace(conn1->trace()); - AddSimpleTrace(&tracer); - AddSimpleTrace(&tracer); - ValidateChannelTrace(&tracer, 5, GetParam()); - ValidateChannelTrace(conn1->trace(), 1, GetParam()); - ChannelFixture channel3(GetParam()); - RefCountedPtr sc2 = - MakeRefCounted(channel3.channel(), GetParam(), true); - tracer.AddTraceEventReferencingSubchannel( - ChannelTrace::Severity::Info, - grpc_slice_from_static_string("subchannel two created"), sc2); - // this trace should not get added to the parents children since it is already - // present in the tracer. - tracer.AddTraceEventReferencingChannel( - ChannelTrace::Severity::Warning, - grpc_slice_from_static_string("subchannel one inactive"), sc1); - AddSimpleTrace(&tracer); - ValidateChannelTrace(&tracer, 8, GetParam()); - sc1.reset(nullptr); - sc2.reset(nullptr); - conn1.reset(nullptr); -} +// // Test a case in which the parent channel has subchannels and the +// subchannels +// // have connections. Ensures that everything lives as long as it should then +// // gets deleted. +// TEST_P(ChannelTracerTest, TestNesting) { +// grpc_core::ExecCtx exec_ctx; +// ChannelTrace tracer(GetParam()); +// AddSimpleTrace(&tracer); +// AddSimpleTrace(&tracer); +// ValidateChannelTrace(&tracer, 2, GetParam()); +// ChannelFixture channel1(GetParam()); +// RefCountedPtr sc1 = +// MakeRefCounted(channel1.channel(), GetParam(), true); +// tracer.AddTraceEventReferencingChannel( +// ChannelTrace::Severity::Info, +// grpc_slice_from_static_string("subchannel one created"), sc1); +// ValidateChannelTrace(&tracer, 3, GetParam()); +// AddSimpleTrace(sc1->trace()); +// ChannelFixture channel2(GetParam()); +// RefCountedPtr conn1 = +// MakeRefCounted(channel2.channel(), GetParam(), true); +// // nesting one level deeper. +// sc1->trace()->AddTraceEventReferencingChannel( +// ChannelTrace::Severity::Info, +// grpc_slice_from_static_string("connection one created"), conn1); +// ValidateChannelTrace(&tracer, 3, GetParam()); +// AddSimpleTrace(conn1->trace()); +// AddSimpleTrace(&tracer); +// AddSimpleTrace(&tracer); +// ValidateChannelTrace(&tracer, 5, GetParam()); +// ValidateChannelTrace(conn1->trace(), 1, GetParam()); +// ChannelFixture channel3(GetParam()); +// RefCountedPtr sc2 = +// MakeRefCounted(channel3.channel(), GetParam(), true); +// tracer.AddTraceEventReferencingChannel( +// ChannelTrace::Severity::Info, +// grpc_slice_from_static_string("subchannel two created"), sc2); +// // this trace should not get added to the parents children since it is +// already +// // present in the tracer. +// tracer.AddTraceEventReferencingChannel( +// ChannelTrace::Severity::Warning, +// grpc_slice_from_static_string("subchannel one inactive"), sc1); +// AddSimpleTrace(&tracer); +// ValidateChannelTrace(&tracer, 8, GetParam()); +// sc1.reset(nullptr); +// sc2.reset(nullptr); +// conn1.reset(nullptr); +// } INSTANTIATE_TEST_CASE_P(ChannelTracerTestSweep, ChannelTracerTest, ::testing::Values(0, 1, 2, 6, 10, 15)); diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index ec1c9f6faff..9f3756c182e 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -158,7 +158,7 @@ void ValidateChannel(ChannelNode* channel, validate_channel_data_args args) { ValidateCounters(json_str, args); gpr_free(json_str); // also check that the core API formats this the correct way - char* core_api_json_str = grpc_channelz_get_channel(channel->channel_uuid()); + char* core_api_json_str = grpc_channelz_get_channel(channel->uuid()); grpc::testing::ValidateGetChannelResponseProtoJsonTranslation( core_api_json_str); gpr_free(core_api_json_str); From 1dc063c093745279452877861da2bacfcaaea95f Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 23 Jul 2018 19:05:27 -0700 Subject: [PATCH 035/546] Refactor ChannelTrace to compile --- src/core/lib/channel/channel_trace.cc | 63 +++++++++++++++++---------- src/core/lib/channel/channel_trace.h | 20 ++++++--- src/core/lib/gprpp/ref_counted.h | 3 +- 3 files changed, 56 insertions(+), 30 deletions(-) diff --git a/src/core/lib/channel/channel_trace.cc b/src/core/lib/channel/channel_trace.cc index ba2b3bcad68..7d8bb391f87 100644 --- a/src/core/lib/channel/channel_trace.cc +++ b/src/core/lib/channel/channel_trace.cc @@ -41,14 +41,25 @@ namespace grpc_core { namespace channelz { -ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data, - RefCountedPtr referenced_entity) +ChannelTrace::TraceEvent::TraceEvent( + Severity severity, grpc_slice data, + RefCountedPtr referenced_channel) : severity_(severity), data_(data), timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(), GPR_CLOCK_REALTIME)), next_(nullptr), - referenced_entity_(std::move(referenced_entity)) {} + referenced_channel_(std::move(referenced_channel)) {} + +// ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data, +// RefCountedPtr +// referenced_subchannel) +// : severity_(severity), +// data_(data), +// timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(), +// GPR_CLOCK_REALTIME)), +// next_(nullptr), +// referenced_subchannel_(std::move(referenced_subchannel)) {} ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data) : severity_(severity), @@ -110,13 +121,22 @@ void ChannelTrace::AddTraceEvent(Severity severity, grpc_slice data) { void ChannelTrace::AddTraceEventReferencingChannel( Severity severity, grpc_slice data, - RefCountedPtr referenced_entity) { + RefCountedPtr referenced_channel) { if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0 // create and fill up the new event AddTraceEventHelper( - New(severity, data, std::move(referenced_entity))); + New(severity, data, std::move(referenced_channel))); } +// void ChannelTrace::AddTraceEventReferencingSubchannel( +// Severity severity, grpc_slice data, +// RefCountedPtr referenced_subchannel) { +// if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0 +// // create and fill up the new event +// AddTraceEventHelper( +// New(severity, data, std::move(referenced_subchannel))); +// } + namespace { const char* severity_string(ChannelTrace::Severity severity) { @@ -145,27 +165,26 @@ void ChannelTrace::TraceEvent::RenderTraceEvent(grpc_json* json) const { json_iterator = grpc_json_create_child(json_iterator, json, "timestamp", gpr_format_timespec(timestamp_), GRPC_JSON_STRING, true); - if (referenced_entity_ != nullptr) { - GPR_ASSERT( - referenced_entity_->type() == BaseNode::EntityType::kSubchannel || - referenced_entity_->type() == BaseNode::EntityType::kTopLevelChannel || - referenced_entity_->type() == BaseNode::EntityType::kInternalChannel); + if (referenced_channel_ != nullptr) { char* uuid_str; - gpr_asprintf(&uuid_str, "%" PRIdPTR, referenced_entity_->uuid()); + gpr_asprintf(&uuid_str, "%" PRIdPTR, referenced_channel_->uuid()); grpc_json* child_ref = grpc_json_create_child( - json_iterator, json, - (referenced_entity_->type() == BaseNode::EntityType::kSubchannel) - ? "subchannelRef" - : "channelRef", - nullptr, GRPC_JSON_OBJECT, false); - json_iterator = grpc_json_create_child( - nullptr, child_ref, - (referenced_entity_->type() == BaseNode::EntityType::kSubchannel) - ? "subchannelId" - : "channelId", - uuid_str, GRPC_JSON_STRING, true); + json_iterator, json, "channelRef", nullptr, GRPC_JSON_OBJECT, false); + json_iterator = grpc_json_create_child(nullptr, child_ref, "channelId", + uuid_str, GRPC_JSON_STRING, true); json_iterator = child_ref; } + // else { + // char* uuid_str; + // gpr_asprintf(&uuid_str, "%" PRIdPTR, referenced_subchannel_->uuid()); + // grpc_json* child_ref = grpc_json_create_child( + // json_iterator, json, "subchannelRef", + // nullptr, GRPC_JSON_OBJECT, false); + // json_iterator = grpc_json_create_child( + // nullptr, child_ref, "subchannelId", + // uuid_str, GRPC_JSON_STRING, true); + // json_iterator = child_ref; + // } } grpc_json* ChannelTrace::RenderJson() const { diff --git a/src/core/lib/channel/channel_trace.h b/src/core/lib/channel/channel_trace.h index cef8814d5fa..543eabf13a8 100644 --- a/src/core/lib/channel/channel_trace.h +++ b/src/core/lib/channel/channel_trace.h @@ -30,7 +30,8 @@ namespace grpc_core { namespace channelz { -class BaseNode; +class ChannelNode; +class SubchannelNode; // Object used to hold live data for a channel. This data is exposed via the // channelz service: @@ -64,10 +65,10 @@ class ChannelTrace { // slice. void AddTraceEventReferencingChannel( Severity severity, grpc_slice data, - RefCountedPtr referenced_entity); - // void AddTraceEventWithReference( + RefCountedPtr referenced_channel); + // void AddTraceEventReferencingSubchannel( // Severity severity, grpc_slice data, - // RefCountedPtr referenced_entity); + // RefCountedPtr referenced_subchannel); // Creates and returns the raw grpc_json object, so a parent channelz // object may incorporate the json before rendering. @@ -78,9 +79,13 @@ class ChannelTrace { // a trace event. class TraceEvent { public: - // Constructor for a TraceEvent that references a different channel. + // Constructor for a TraceEvent that references a channel. TraceEvent(Severity severity, grpc_slice data, - RefCountedPtr referenced); + RefCountedPtr referenced_channel); + + // Constructor for a TraceEvent that references a subchannel. + TraceEvent(Severity severity, grpc_slice data, + RefCountedPtr referenced_subchannel); // Constructor for a TraceEvent that does not reverence a different // channel. @@ -102,7 +107,8 @@ class ChannelTrace { gpr_timespec timestamp_; TraceEvent* next_; // the tracer object for the (sub)channel that this trace event refers to. - RefCountedPtr referenced_entity_; + RefCountedPtr referenced_channel_; + // RefCountedPtr referenced_subchannel_; }; // TraceEvent // Internal helper to add and link in a trace event diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h index ddac5bd4755..3d6a32ddcff 100644 --- a/src/core/lib/gprpp/ref_counted.h +++ b/src/core/lib/gprpp/ref_counted.h @@ -73,7 +73,8 @@ class RefCounted { private: // Allow RefCountedPtr<> to access IncrementRefCount(). - friend class RefCountedPtr; + template + friend class RefCountedPtr; void IncrementRefCount() { gpr_ref(&refs_); } From a8d5c21b8864202e205fc210e369dc72abe606f2 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 24 Jul 2018 09:41:07 -0700 Subject: [PATCH 036/546] reviewer feedback --- .../client_channel/client_channel_channelz.h | 14 ++++------- src/core/lib/channel/channelz.cc | 5 ++-- src/core/lib/channel/channelz.h | 24 ++++--------------- 3 files changed, 11 insertions(+), 32 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 45df756b910..1bc555448c3 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -45,20 +45,17 @@ class ClientChannelNode : public ChannelNode { grpc_channel* channel, size_t channel_tracer_max_nodes, bool is_top_level_channel); + ClientChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, + bool is_top_level_channel); + virtual ~ClientChannelNode() {} + grpc_json* RenderJson() override; // Helper to create a channel arg to ensure this type of ChannelNode is // created. static grpc_arg CreateChannelArg(); - protected: - ClientChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, - bool is_top_level_channel); - virtual ~ClientChannelNode() {} - private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW grpc_channel_element* client_channel_; // helpers @@ -80,9 +77,6 @@ class SubchannelNode : public CallCountingAndTracingNode { grpc_json* RenderJson() override; private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - intptr_t subchannel_uuid_; grpc_subchannel* subchannel_; UniquePtr target_; diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index eec2cd61b2b..4fbc441c0a2 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -41,9 +41,8 @@ namespace grpc_core { namespace channelz { -BaseNode::BaseNode(EntityType type) : type_(type) { - uuid_ = ChannelzRegistry::Register(this); -} +BaseNode::BaseNode(EntityType type) + : type_(type), uuid_(ChannelzRegistry::Register(this)) {} BaseNode::~BaseNode() { ChannelzRegistry::Unregister(uuid_); } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 67cd1fec2dd..5496163fb9f 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -74,11 +74,9 @@ class BaseNode : public RefCounted { intptr_t uuid() const { return uuid_; } private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW friend class ChannelTrace; EntityType type_; - intptr_t uuid_; + const intptr_t uuid_; }; // This class is the parent for the channelz entities that deal with Channels @@ -109,9 +107,6 @@ class CallCountingAndTracingNode : public BaseNode { void PopulateCallData(grpc_json* json); private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - // testing peer friend. friend class testing::CallCountingAndTracingNodePeer; @@ -129,6 +124,10 @@ class ChannelNode : public CallCountingAndTracingNode { grpc_channel* channel, size_t channel_tracer_max_nodes, bool is_top_level_channel); + ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, + bool is_top_level_channel); + ~ChannelNode() override; + grpc_json* RenderJson() override; void MarkChannelDestroyed() { @@ -139,19 +138,12 @@ class ChannelNode : public CallCountingAndTracingNode { bool ChannelIsDestroyed() { return channel_ == nullptr; } protected: - ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, - bool is_top_level_channel); - ~ChannelNode() override; // provides view of target for child. char* target_view() { return target_.get(); } private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - grpc_channel* channel_ = nullptr; UniquePtr target_; - intptr_t channel_uuid_; }; // Handles channelz bookkeeping for servers @@ -162,10 +154,6 @@ class ServerNode : public CallCountingAndTracingNode { : CallCountingAndTracingNode(EntityType::kServer, channel_tracer_max_nodes) {} ~ServerNode() override {} - - private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW }; // Handles channelz bookkeeping for sockets @@ -176,8 +164,6 @@ class SocketNode : public BaseNode { ~SocketNode() override {} private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW }; // Creation functions From bfdfe9fefbc92f78da6247a85e7e7de4b30727b9 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 24 Jul 2018 10:13:52 -0700 Subject: [PATCH 037/546] Restructure heirarchy --- .../filters/client_channel/client_channel.cc | 1 - .../client_channel/client_channel_channelz.cc | 16 +-- .../client_channel/client_channel_channelz.h | 7 +- .../ext/filters/client_channel/subchannel.cc | 9 +- src/core/lib/channel/channel_stack.h | 1 - src/core/lib/channel/channelz.cc | 16 ++- src/core/lib/channel/channelz.h | 21 ++-- src/core/lib/surface/call.cc | 27 +---- src/core/lib/surface/call.h | 13 -- src/core/lib/surface/channel.cc | 4 +- test/core/channel/channel_stack_test.cc | 1 - test/core/channel/channel_trace_test.cc | 112 +++++++++--------- test/core/channel/channelz_test.cc | 38 +++--- 13 files changed, 116 insertions(+), 150 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 13a0b955115..683cb0e01df 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -3094,7 +3094,6 @@ static grpc_error* cc_init_call_elem(grpc_call_element* elem, calld->arena = args->arena; calld->owning_call = args->call_stack; calld->call_combiner = args->call_combiner; - calld->call = args->call; if (GPR_LIKELY(chand->deadline_checking_enabled)) { grpc_deadline_state_init(elem, args->call_stack, args->call_combiner, calld->deadline); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 996a871f387..b209acc2ea5 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -124,8 +124,8 @@ grpc_json* ClientChannelNode::RenderJson() { grpc_json_create_child(nullptr, json, "target", target_view(), GRPC_JSON_STRING, false); // as CallCountingAndTracingNode to populate trace and call count data. - PopulateTrace(json); - PopulateCallData(json); + counter_and_tracer()->PopulateTrace(json); + counter_and_tracer()->PopulateCallData(json); // reset to the top level json = top_level_json; PopulateChildRefs(json); @@ -148,11 +148,11 @@ RefCountedPtr ClientChannelNode::MakeClientChannelNode( SubchannelNode::SubchannelNode(grpc_subchannel* subchannel, size_t channel_tracer_max_nodes) - : CallCountingAndTracingNode(EntityType::kSubchannel, - channel_tracer_max_nodes), + : BaseNode(EntityType::kSubchannel), subchannel_(subchannel), - target_(UniquePtr( - gpr_strdup(grpc_subchannel_get_target(subchannel_)))) {} + target_( + UniquePtr(gpr_strdup(grpc_subchannel_get_target(subchannel_)))), + counter_and_tracer_(channel_tracer_max_nodes) {} SubchannelNode::~SubchannelNode() {} @@ -192,8 +192,8 @@ grpc_json* SubchannelNode::RenderJson() { GPR_ASSERT(target_.get() != nullptr); grpc_json_create_child(nullptr, json, "target", target_.get(), GRPC_JSON_STRING, false); - PopulateTrace(json); - PopulateCallData(json); + counter_and_tracer_.PopulateTrace(json); + counter_and_tracer_.PopulateCallData(json); return top_level_json; } diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 1bc555448c3..f5344c049e9 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -64,7 +64,7 @@ class ClientChannelNode : public ChannelNode { }; // Handles channelz bookkeeping for sockets -class SubchannelNode : public CallCountingAndTracingNode { +class SubchannelNode : public BaseNode { public: SubchannelNode(grpc_subchannel* subchannel, size_t channel_tracer_max_nodes); ~SubchannelNode() override; @@ -76,9 +76,14 @@ class SubchannelNode : public CallCountingAndTracingNode { grpc_json* RenderJson() override; + CallCountingAndTracingNode* counter_and_tracer() { + return &counter_and_tracer_; + } + private: grpc_subchannel* subchannel_; UniquePtr target_; + CallCountingAndTracingNode counter_and_tracer_; void PopulateConnectivityState(grpc_json* json); }; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index a15cfd43c34..5894d52e6b2 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -183,7 +183,7 @@ static void connection_destroy(void* arg, grpc_error* error) { static void subchannel_destroy(void* arg, grpc_error* error) { grpc_subchannel* c = static_cast(arg); if (c->channelz_subchannel != nullptr) { - c->channelz_subchannel->trace()->AddTraceEvent( + c->channelz_subchannel->counter_and_tracer()->trace()->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Subchannel destroyed")); c->channelz_subchannel->MarkSubchannelDestroyed(); @@ -397,7 +397,7 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, c->channelz_subchannel = grpc_core::MakeRefCounted( c, channel_tracer_max_nodes); - c->channelz_subchannel->trace()->AddTraceEvent( + c->channelz_subchannel->counter_and_tracer()->trace()->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Subchannel created")); } @@ -857,7 +857,6 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, args.deadline, /* deadline */ args.arena, /* arena */ args.call_combiner, /* call_combiner */ - args.call /* call */ }; grpc_error* error = grpc_call_stack_init( channel_stack_, 1, subchannel_call_destroy, *call, &call_args); @@ -866,10 +865,6 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, gpr_log(GPR_ERROR, "error: %s", error_string); return error; } - if (channelz_subchannel_ != nullptr) { - channelz_subchannel_->RecordCallStarted(); - grpc_call_set_channelz_subchannel(args.call, channelz_subchannel_); - } grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); return GRPC_ERROR_NONE; } diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 727f36a6f88..7581f937b64 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -71,7 +71,6 @@ typedef struct { grpc_millis deadline; gpr_arena* arena; grpc_call_combiner* call_combiner; - grpc_call* call; } grpc_call_element_args; typedef struct { diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 4fbc441c0a2..ee1717ce9ff 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -54,8 +54,7 @@ char* BaseNode::RenderJsonString() { } CallCountingAndTracingNode::CallCountingAndTracingNode( - EntityType type, size_t channel_tracer_max_nodes) - : BaseNode(type) { + size_t channel_tracer_max_nodes) { trace_.Init(channel_tracer_max_nodes); gpr_atm_no_barrier_store(&last_call_started_millis_, (gpr_atm)ExecCtx::Get()->Now()); @@ -103,12 +102,11 @@ void CallCountingAndTracingNode::PopulateCallData(grpc_json* json) { ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, bool is_top_level_channel) - : CallCountingAndTracingNode(is_top_level_channel - ? EntityType::kTopLevelChannel - : EntityType::kInternalChannel, - channel_tracer_max_nodes), + : BaseNode(is_top_level_channel ? EntityType::kTopLevelChannel + : EntityType::kInternalChannel), channel_(channel), - target_(UniquePtr(grpc_channel_get_target(channel_))) {} + target_(UniquePtr(grpc_channel_get_target(channel_))), + counter_and_tracer_(channel_tracer_max_nodes) {} ChannelNode::~ChannelNode() {} @@ -137,8 +135,8 @@ grpc_json* ChannelNode::RenderJson() { grpc_json_create_child(nullptr, json, "target", target_.get(), GRPC_JSON_STRING, false); // as CallCountingAndTracingNode to populate trace and call count data. - PopulateTrace(json); - PopulateCallData(json); + counter_and_tracer_.PopulateTrace(json); + counter_and_tracer_.PopulateCallData(json); return top_level_json; } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 5496163fb9f..7bc4567ad2e 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -86,10 +86,10 @@ class BaseNode : public RefCounted { // - track last_call_started_timestamp // - hold the channel trace. // - perform common rendering. -class CallCountingAndTracingNode : public BaseNode { +class CallCountingAndTracingNode { public: - CallCountingAndTracingNode(EntityType type, size_t channel_tracer_max_nodes); - ~CallCountingAndTracingNode() override; + CallCountingAndTracingNode(size_t channel_tracer_max_nodes); + ~CallCountingAndTracingNode(); void RecordCallStarted(); void RecordCallFailed() { @@ -118,7 +118,7 @@ class CallCountingAndTracingNode : public BaseNode { }; // Handles channelz bookkeeping for channels -class ChannelNode : public CallCountingAndTracingNode { +class ChannelNode : public BaseNode { public: static RefCountedPtr MakeChannelNode( grpc_channel* channel, size_t channel_tracer_max_nodes, @@ -137,6 +137,10 @@ class ChannelNode : public CallCountingAndTracingNode { bool ChannelIsDestroyed() { return channel_ == nullptr; } + CallCountingAndTracingNode* counter_and_tracer() { + return &counter_and_tracer_; + } + protected: // provides view of target for child. char* target_view() { return target_.get(); } @@ -144,15 +148,14 @@ class ChannelNode : public CallCountingAndTracingNode { private: grpc_channel* channel_ = nullptr; UniquePtr target_; + CallCountingAndTracingNode counter_and_tracer_; }; // Handles channelz bookkeeping for servers // TODO(ncteisen): implement in subsequent PR. -class ServerNode : public CallCountingAndTracingNode { +class ServerNode : public BaseNode { public: - ServerNode(size_t channel_tracer_max_nodes) - : CallCountingAndTracingNode(EntityType::kServer, - channel_tracer_max_nodes) {} + ServerNode(size_t channel_tracer_max_nodes) : BaseNode(EntityType::kServer) {} ~ServerNode() override {} }; @@ -162,8 +165,6 @@ class SocketNode : public BaseNode { public: SocketNode() : BaseNode(EntityType::kSocket) {} ~SocketNode() override {} - - private: }; // Creation functions diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 6545af8f723..b86ff048cfd 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -170,11 +170,6 @@ struct grpc_call { /* parent_call* */ gpr_atm parent_call_atm; child_call* child; - // the call holds onto this so that once the call knows if the RPC was - // a success or failure, it can update the channelz bookkeeping for the - // subchannel that sent it. - grpc_core::channelz::CallCountingAndTracingNode* channelz_subchannel_; - /* client or server call */ bool is_client; /** has grpc_call_unref been called */ @@ -274,11 +269,6 @@ struct grpc_call { gpr_atm recv_state; }; -void grpc_call_set_channelz_subchannel( - grpc_call* call, grpc_core::channelz::CallCountingAndTracingNode* node) { - call->channelz_subchannel_ = node; -} - grpc_core::TraceFlag grpc_call_error_trace(false, "call_error"); grpc_core::TraceFlag grpc_compression_trace(false, "compression"); @@ -454,8 +444,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, call->start_time, send_deadline, call->arena, - &call->call_combiner, - call}; + &call->call_combiner}; add_init_error(&error, grpc_call_stack_init(channel_stack, 1, destroy_call, call, &call_args)); // Publish this call to parent only after the call stack has been initialized. @@ -500,7 +489,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, grpc_core::channelz::ChannelNode* channelz_channel = grpc_channel_get_channelz_node(call->channel); if (channelz_channel != nullptr) { - channelz_channel->RecordCallStarted(); + channelz_channel->counter_and_tracer()->RecordCallStarted(); } grpc_slice_unref_internal(path); @@ -1279,17 +1268,9 @@ static void post_batch_completion(batch_control* bctl) { grpc_channel_get_channelz_node(call->channel); if (channelz_channel != nullptr) { if (*call->final_op.client.status != GRPC_STATUS_OK) { - channelz_channel->RecordCallFailed(); - } else { - channelz_channel->RecordCallSucceeded(); - } - } - // Record channelz data for the subchannel. - if (call->channelz_subchannel_ != nullptr) { - if (*call->final_op.client.status != GRPC_STATUS_OK) { - call->channelz_subchannel_->RecordCallFailed(); + channelz_channel->counter_and_tracer()->RecordCallFailed(); } else { - call->channelz_subchannel_->RecordCallSucceeded(); + channelz_channel->counter_and_tracer()->RecordCallSucceeded(); } } GRPC_ERROR_UNREF(error); diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index 200c840c61f..b3b06059d4d 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -110,19 +110,6 @@ size_t grpc_call_get_initial_size_estimate(); grpc_compression_algorithm grpc_call_compression_for_level( grpc_call* call, grpc_compression_level level); -namespace grpc_core { -namespace channelz { -class CallCountingAndTracingNode; -} // namespace channelz -} // namespace grpc_core - -// We need this so that a subchannel selected for a call can add itself to -// the call's data structure. This allows the call to trigger the correct -// channelz bookkeeping on the subchannel once the call knows if the RPC was -// successful or not. -void grpc_call_set_channelz_subchannel( - grpc_call* call, grpc_core::channelz::CallCountingAndTracingNode* node); - extern grpc_core::TraceFlag grpc_call_error_trace; extern grpc_core::TraceFlag grpc_compression_trace; diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index 01caadaabac..16d3322a9d6 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -170,7 +170,7 @@ grpc_channel* grpc_channel_create_with_builder( bool is_top_level_channel = channel->is_client && !internal_channel; channel->channelz_channel = channel_node_create_func( channel, channel_tracer_max_nodes, is_top_level_channel); - channel->channelz_channel->trace()->AddTraceEvent( + channel->channelz_channel->counter_and_tracer()->trace()->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Channel created")); } @@ -417,7 +417,7 @@ void grpc_channel_internal_unref(grpc_channel* c REF_ARG) { static void destroy_channel(void* arg, grpc_error* error) { grpc_channel* channel = static_cast(arg); if (channel->channelz_channel != nullptr) { - channel->channelz_channel->trace()->AddTraceEvent( + channel->channelz_channel->counter_and_tracer()->trace()->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Channel destroyed")); channel->channelz_channel->MarkChannelDestroyed(); diff --git a/test/core/channel/channel_stack_test.cc b/test/core/channel/channel_stack_test.cc index 4dc2ee3f558..6f0bfa06d21 100644 --- a/test/core/channel/channel_stack_test.cc +++ b/test/core/channel/channel_stack_test.cc @@ -125,7 +125,6 @@ static void test_create_channel_stack(void) { GRPC_MILLIS_INF_FUTURE, /* deadline */ nullptr, /* arena */ nullptr, /* call_combiner */ - nullptr /* call */ }; grpc_error* error = grpc_call_stack_init(channel_stack, 1, free_call, call_stack, &args); diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index 703a9e457f4..3d6aff03ebc 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -160,14 +160,14 @@ TEST_P(ChannelTracerTest, ComplexTest) { ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel one created"), sc1); ValidateChannelTrace(&tracer, 3, GetParam()); - AddSimpleTrace(sc1->trace()); - AddSimpleTrace(sc1->trace()); - AddSimpleTrace(sc1->trace()); - ValidateChannelTrace(sc1->trace(), 3, GetParam()); - AddSimpleTrace(sc1->trace()); - AddSimpleTrace(sc1->trace()); - AddSimpleTrace(sc1->trace()); - ValidateChannelTrace(sc1->trace(), 6, GetParam()); + AddSimpleTrace(sc1->counter_and_tracer()->trace()); + AddSimpleTrace(sc1->counter_and_tracer()->trace()); + AddSimpleTrace(sc1->counter_and_tracer()->trace()); + ValidateChannelTrace(sc1->counter_and_tracer()->trace(), 3, GetParam()); + AddSimpleTrace(sc1->counter_and_tracer()->trace()); + AddSimpleTrace(sc1->counter_and_tracer()->trace()); + AddSimpleTrace(sc1->counter_and_tracer()->trace()); + ValidateChannelTrace(sc1->counter_and_tracer()->trace(), 6, GetParam()); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); ValidateChannelTrace(&tracer, 5, GetParam()); @@ -191,55 +191,53 @@ TEST_P(ChannelTracerTest, ComplexTest) { sc2.reset(nullptr); } -// // Test a case in which the parent channel has subchannels and the -// subchannels -// // have connections. Ensures that everything lives as long as it should then -// // gets deleted. -// TEST_P(ChannelTracerTest, TestNesting) { -// grpc_core::ExecCtx exec_ctx; -// ChannelTrace tracer(GetParam()); -// AddSimpleTrace(&tracer); -// AddSimpleTrace(&tracer); -// ValidateChannelTrace(&tracer, 2, GetParam()); -// ChannelFixture channel1(GetParam()); -// RefCountedPtr sc1 = -// MakeRefCounted(channel1.channel(), GetParam(), true); -// tracer.AddTraceEventReferencingChannel( -// ChannelTrace::Severity::Info, -// grpc_slice_from_static_string("subchannel one created"), sc1); -// ValidateChannelTrace(&tracer, 3, GetParam()); -// AddSimpleTrace(sc1->trace()); -// ChannelFixture channel2(GetParam()); -// RefCountedPtr conn1 = -// MakeRefCounted(channel2.channel(), GetParam(), true); -// // nesting one level deeper. -// sc1->trace()->AddTraceEventReferencingChannel( -// ChannelTrace::Severity::Info, -// grpc_slice_from_static_string("connection one created"), conn1); -// ValidateChannelTrace(&tracer, 3, GetParam()); -// AddSimpleTrace(conn1->trace()); -// AddSimpleTrace(&tracer); -// AddSimpleTrace(&tracer); -// ValidateChannelTrace(&tracer, 5, GetParam()); -// ValidateChannelTrace(conn1->trace(), 1, GetParam()); -// ChannelFixture channel3(GetParam()); -// RefCountedPtr sc2 = -// MakeRefCounted(channel3.channel(), GetParam(), true); -// tracer.AddTraceEventReferencingChannel( -// ChannelTrace::Severity::Info, -// grpc_slice_from_static_string("subchannel two created"), sc2); -// // this trace should not get added to the parents children since it is -// already -// // present in the tracer. -// tracer.AddTraceEventReferencingChannel( -// ChannelTrace::Severity::Warning, -// grpc_slice_from_static_string("subchannel one inactive"), sc1); -// AddSimpleTrace(&tracer); -// ValidateChannelTrace(&tracer, 8, GetParam()); -// sc1.reset(nullptr); -// sc2.reset(nullptr); -// conn1.reset(nullptr); -// } +// Test a case in which the parent channel has subchannels and the subchannels +// have connections. Ensures that everything lives as long as it should then +// gets deleted. +TEST_P(ChannelTracerTest, TestNesting) { + grpc_core::ExecCtx exec_ctx; + ChannelTrace tracer(GetParam()); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + ValidateChannelTrace(&tracer, 2, GetParam()); + ChannelFixture channel1(GetParam()); + RefCountedPtr sc1 = + MakeRefCounted(channel1.channel(), GetParam(), true); + tracer.AddTraceEventReferencingChannel( + ChannelTrace::Severity::Info, + grpc_slice_from_static_string("subchannel one created"), sc1); + ValidateChannelTrace(&tracer, 3, GetParam()); + AddSimpleTrace(sc1->counter_and_tracer()->trace()); + ChannelFixture channel2(GetParam()); + RefCountedPtr conn1 = + MakeRefCounted(channel2.channel(), GetParam(), true); + // nesting one level deeper. + sc1->counter_and_tracer()->trace()->AddTraceEventReferencingChannel( + ChannelTrace::Severity::Info, + grpc_slice_from_static_string("connection one created"), conn1); + ValidateChannelTrace(&tracer, 3, GetParam()); + AddSimpleTrace(conn1->counter_and_tracer()->trace()); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + ValidateChannelTrace(&tracer, 5, GetParam()); + ValidateChannelTrace(conn1->counter_and_tracer()->trace(), 1, GetParam()); + ChannelFixture channel3(GetParam()); + RefCountedPtr sc2 = + MakeRefCounted(channel3.channel(), GetParam(), true); + tracer.AddTraceEventReferencingChannel( + ChannelTrace::Severity::Info, + grpc_slice_from_static_string("subchannel two created"), sc2); + // this trace should not get added to the parents children since it is already + // present in the tracer. + tracer.AddTraceEventReferencingChannel( + ChannelTrace::Severity::Warning, + grpc_slice_from_static_string("subchannel one inactive"), sc1); + AddSimpleTrace(&tracer); + ValidateChannelTrace(&tracer, 8, GetParam()); + sc1.reset(nullptr); + sc2.reset(nullptr); + conn1.reset(nullptr); +} INSTANTIATE_TEST_CASE_P(ChannelTracerTestSweep, ChannelTracerTest, ::testing::Values(0, 1, 2, 6, 10, 15)); diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index 9f3756c182e..5e9a3f89a26 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -201,16 +201,16 @@ TEST_P(ChannelzChannelTest, BasicChannelAPIFunctionality) { ChannelFixture channel(GetParam()); ChannelNode* channelz_channel = grpc_channel_get_channelz_node(channel.channel()); - channelz_channel->RecordCallStarted(); - channelz_channel->RecordCallFailed(); - channelz_channel->RecordCallSucceeded(); + channelz_channel->counter_and_tracer()->RecordCallStarted(); + channelz_channel->counter_and_tracer()->RecordCallFailed(); + channelz_channel->counter_and_tracer()->RecordCallSucceeded(); ValidateChannel(channelz_channel, {1, 1, 1}); - channelz_channel->RecordCallStarted(); - channelz_channel->RecordCallFailed(); - channelz_channel->RecordCallSucceeded(); - channelz_channel->RecordCallStarted(); - channelz_channel->RecordCallFailed(); - channelz_channel->RecordCallSucceeded(); + channelz_channel->counter_and_tracer()->RecordCallStarted(); + channelz_channel->counter_and_tracer()->RecordCallFailed(); + channelz_channel->counter_and_tracer()->RecordCallSucceeded(); + channelz_channel->counter_and_tracer()->RecordCallStarted(); + channelz_channel->counter_and_tracer()->RecordCallFailed(); + channelz_channel->counter_and_tracer()->RecordCallSucceeded(); ValidateChannel(channelz_channel, {3, 3, 3}); } @@ -220,23 +220,27 @@ TEST_P(ChannelzChannelTest, LastCallStartedMillis) { ChannelNode* channelz_channel = grpc_channel_get_channelz_node(channel.channel()); // start a call to set the last call started timestamp - channelz_channel->RecordCallStarted(); - grpc_millis millis1 = GetLastCallStartedMillis(channelz_channel); + channelz_channel->counter_and_tracer()->RecordCallStarted(); + grpc_millis millis1 = + GetLastCallStartedMillis(channelz_channel->counter_and_tracer()); // time gone by should not affect the timestamp ChannelzSleep(100); - grpc_millis millis2 = GetLastCallStartedMillis(channelz_channel); + grpc_millis millis2 = + GetLastCallStartedMillis(channelz_channel->counter_and_tracer()); EXPECT_EQ(millis1, millis2); // calls succeeded or failed should not affect the timestamp ChannelzSleep(100); - channelz_channel->RecordCallFailed(); - channelz_channel->RecordCallSucceeded(); - grpc_millis millis3 = GetLastCallStartedMillis(channelz_channel); + channelz_channel->counter_and_tracer()->RecordCallFailed(); + channelz_channel->counter_and_tracer()->RecordCallSucceeded(); + grpc_millis millis3 = + GetLastCallStartedMillis(channelz_channel->counter_and_tracer()); EXPECT_EQ(millis1, millis3); // another call started should affect the timestamp // sleep for extra long to avoid flakes (since we cache Now()) ChannelzSleep(5000); - channelz_channel->RecordCallStarted(); - grpc_millis millis4 = GetLastCallStartedMillis(channelz_channel); + channelz_channel->counter_and_tracer()->RecordCallStarted(); + grpc_millis millis4 = + GetLastCallStartedMillis(channelz_channel->counter_and_tracer()); EXPECT_NE(millis1, millis4); } From 37f7b5399dcf5b29e41ac1c0ff2a1c81c9933a93 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 24 Jul 2018 10:18:54 -0700 Subject: [PATCH 038/546] reviewer feedback --- src/core/lib/channel/channelz_registry.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index 7f709089896..d2c403cc1bb 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -123,7 +123,6 @@ char* grpc_channelz_get_channel(intptr_t channel_id) { grpc_core::channelz::BaseNode* channel_node = grpc_core::channelz::ChannelzRegistry::Get(channel_id); if (channel_node == nullptr || - (channel_node->type() != grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel && channel_node->type() != From a4e3bed5fb8f9203fa580f00a5cb1136415c1949 Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Tue, 24 Jul 2018 12:11:33 -0700 Subject: [PATCH 039/546] changes --- src/core/lib/surface/call.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index d9feb108506..c92172f278e 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -532,7 +532,7 @@ static void destroy_call(void* call, grpc_error* error) { grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(c->status_error, c->send_deadline, &c->final_info.final_status, &slice, nullptr, - c->final_info.error_string); + &c->final_info.error_string); grpc_error* cancel_error = (grpc_error*)gpr_atm_no_barrier_load(&c->cancel_error); GRPC_ERROR_UNREF(cancel_error); @@ -1445,10 +1445,10 @@ static void receiving_initial_metadata_ready(void* bctlp, grpc_error* error) { static void receiving_trailing_metadata_ready(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; - GRPC_CALL_COMBINER_STOP(&call->call_combiner, "recv_trailing_metadata_ready"); grpc_metadata_batch* md = &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; recv_trailing_filter(call, md, GRPC_ERROR_REF(error)); + GRPC_CALL_COMBINER_STOP(&call->call_combiner, "recv_trailing_metadata_ready"); finish_batch_step(bctl); } From 65007f624e3a7be460dda7c979ae939c89519cad Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Tue, 24 Jul 2018 14:50:16 -0700 Subject: [PATCH 040/546] Channelz fixes --- src/core/lib/surface/call.cc | 38 +++++++++++++++++------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index c92172f278e..f5abf1a1a62 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -509,26 +509,6 @@ static void destroy_call(void* call, grpc_error* error) { GRPC_CQ_INTERNAL_UNREF(c->cq, "bind"); } - grpc_core::channelz::ChannelNode* channelz_channel = - grpc_channel_get_channelz_node(c->channel); - if (c->is_client) { - if (channelz_channel != nullptr) { - if (*c->final_op.client.status != GRPC_STATUS_OK) { - channelz_channel->RecordCallFailed(); - } else { - channelz_channel->RecordCallSucceeded(); - } - } - } else { - if (channelz_channel != nullptr) { - if (*c->final_op.server.cancelled || c->status_error != GRPC_ERROR_NONE) { - channelz_channel->RecordCallFailed(); - } else { - channelz_channel->RecordCallSucceeded(); - } - } - } - grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(c->status_error, c->send_deadline, &c->final_info.final_status, &slice, nullptr, @@ -734,6 +714,15 @@ static void set_final_status(grpc_call* call, grpc_error* error) { error_string); *call->final_op.client.status = code; *call->final_op.client.status_details = grpc_slice_ref_internal(slice); + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(call->channel); + if (channelz_channel != nullptr) { + if (code != GRPC_STATUS_OK) { + channelz_channel->RecordCallFailed(); + } else { + channelz_channel->RecordCallSucceeded(); + } + } } else { *call->final_op.server.cancelled = error != GRPC_ERROR_NONE || call->status_error != GRPC_ERROR_NONE; @@ -1683,6 +1672,15 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, static_cast( op->data.send_status_from_server.status)); call->status_error = status_error; + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(call->channel); + if (channelz_channel != nullptr) { + if (call->status_error != GRPC_ERROR_NONE) { + channelz_channel->RecordCallFailed(); + } else { + channelz_channel->RecordCallSucceeded(); + } + } if (!prepare_application_metadata( call, static_cast( From 961fe4b523d8d097f32d6bb1df12ec8e0dcdaa4a Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Wed, 25 Jul 2018 10:49:48 -0700 Subject: [PATCH 041/546] Revert "Channelz fixes" This reverts commit 65007f624e3a7be460dda7c979ae939c89519cad. --- src/core/lib/surface/call.cc | 38 +++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index f5abf1a1a62..c92172f278e 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -509,6 +509,26 @@ static void destroy_call(void* call, grpc_error* error) { GRPC_CQ_INTERNAL_UNREF(c->cq, "bind"); } + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(c->channel); + if (c->is_client) { + if (channelz_channel != nullptr) { + if (*c->final_op.client.status != GRPC_STATUS_OK) { + channelz_channel->RecordCallFailed(); + } else { + channelz_channel->RecordCallSucceeded(); + } + } + } else { + if (channelz_channel != nullptr) { + if (*c->final_op.server.cancelled || c->status_error != GRPC_ERROR_NONE) { + channelz_channel->RecordCallFailed(); + } else { + channelz_channel->RecordCallSucceeded(); + } + } + } + grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(c->status_error, c->send_deadline, &c->final_info.final_status, &slice, nullptr, @@ -714,15 +734,6 @@ static void set_final_status(grpc_call* call, grpc_error* error) { error_string); *call->final_op.client.status = code; *call->final_op.client.status_details = grpc_slice_ref_internal(slice); - grpc_core::channelz::ChannelNode* channelz_channel = - grpc_channel_get_channelz_node(call->channel); - if (channelz_channel != nullptr) { - if (code != GRPC_STATUS_OK) { - channelz_channel->RecordCallFailed(); - } else { - channelz_channel->RecordCallSucceeded(); - } - } } else { *call->final_op.server.cancelled = error != GRPC_ERROR_NONE || call->status_error != GRPC_ERROR_NONE; @@ -1672,15 +1683,6 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, static_cast( op->data.send_status_from_server.status)); call->status_error = status_error; - grpc_core::channelz::ChannelNode* channelz_channel = - grpc_channel_get_channelz_node(call->channel); - if (channelz_channel != nullptr) { - if (call->status_error != GRPC_ERROR_NONE) { - channelz_channel->RecordCallFailed(); - } else { - channelz_channel->RecordCallSucceeded(); - } - } if (!prepare_application_metadata( call, static_cast( From ac4b2527850f966c8204dab091247b05489ad9d2 Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Wed, 25 Jul 2018 10:50:01 -0700 Subject: [PATCH 042/546] Revert "changes" This reverts commit a4e3bed5fb8f9203fa580f00a5cb1136415c1949. --- src/core/lib/surface/call.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index c92172f278e..d9feb108506 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -532,7 +532,7 @@ static void destroy_call(void* call, grpc_error* error) { grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(c->status_error, c->send_deadline, &c->final_info.final_status, &slice, nullptr, - &c->final_info.error_string); + c->final_info.error_string); grpc_error* cancel_error = (grpc_error*)gpr_atm_no_barrier_load(&c->cancel_error); GRPC_ERROR_UNREF(cancel_error); @@ -1445,10 +1445,10 @@ static void receiving_initial_metadata_ready(void* bctlp, grpc_error* error) { static void receiving_trailing_metadata_ready(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; + GRPC_CALL_COMBINER_STOP(&call->call_combiner, "recv_trailing_metadata_ready"); grpc_metadata_batch* md = &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; recv_trailing_filter(call, md, GRPC_ERROR_REF(error)); - GRPC_CALL_COMBINER_STOP(&call->call_combiner, "recv_trailing_metadata_ready"); finish_batch_step(bctl); } From fa52bee77b34542566b40c8f368a90d2f12d8231 Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Wed, 25 Jul 2018 10:50:42 -0700 Subject: [PATCH 043/546] Revert "compile error fix" This reverts commit 5defb7354b620a67ef42cb2ad73bab7bdd512fa6. --- src/core/lib/surface/call.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index d9feb108506..ffba3856053 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -301,7 +301,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, gpr_arena_alloc(arena, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + channel_stack->call_stack_size)); gpr_ref_init(&call->ext_ref, 1); - gpr_atm_no_barrier_store(&call->cancel_error, (gpr_atm)GRPC_ERROR_NONE); + gpr_atm_no_barrier_store(&call->cancel_error, GRPC_ERROR_NONE); call->arena = arena; grpc_call_combiner_init(&call->call_combiner); *out_call = call; From 1987e391bcdd572003fe9b6e1e27671203adebab Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Wed, 25 Jul 2018 10:50:59 -0700 Subject: [PATCH 044/546] Revert "Make error strings consistent" This reverts commit a135059ce7d2db3180045810f66dd69a8fc88284. --- src/core/lib/iomgr/error.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index 93a5c20abb9..90ed34da11f 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -399,14 +399,14 @@ static grpc_error* copy_error_and_unref(grpc_error* in) { out = GRPC_ERROR_CREATE_FROM_STATIC_STRING("unknown"); if (in == GRPC_ERROR_NONE) { internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION, - grpc_slice_from_static_string("No Error")); + grpc_slice_from_static_string("no error")); internal_set_int(&out, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK); } else if (in == GRPC_ERROR_OOM) { internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION, - grpc_slice_from_static_string("Out of memory")); + grpc_slice_from_static_string("oom")); } else if (in == GRPC_ERROR_CANCELLED) { internal_set_str(&out, GRPC_ERROR_STR_DESCRIPTION, - grpc_slice_from_static_string("Cancelled")); + grpc_slice_from_static_string("cancelled")); internal_set_int(&out, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_CANCELLED); } } else if (gpr_ref_is_unique(&in->atomics.refs)) { From a7bd899970b01198a4ba66b7f9fa47e658e506aa Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Wed, 25 Jul 2018 10:51:18 -0700 Subject: [PATCH 045/546] Revert "Include cancellation error" This reverts commit 299c2c5e115b6a1204d67f3a4ae8de66c5386fe6. --- src/core/lib/surface/call.cc | 62 ++++++++++++------------------------ 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index ffba3856053..43dd795ce79 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -190,7 +190,7 @@ struct grpc_call { grpc_closure receiving_initial_metadata_ready; grpc_closure receiving_trailing_metadata_ready; uint32_t test_only_last_message_flags; - gpr_atm cancel_error; + gpr_atm cancelled; grpc_closure release_call; @@ -301,7 +301,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, gpr_arena_alloc(arena, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + channel_stack->call_stack_size)); gpr_ref_init(&call->ext_ref, 1); - gpr_atm_no_barrier_store(&call->cancel_error, GRPC_ERROR_NONE); + gpr_atm_no_barrier_store(&call->cancelled, 0); call->arena = arena; grpc_call_combiner_init(&call->call_combiner); *out_call = call; @@ -509,33 +509,10 @@ static void destroy_call(void* call, grpc_error* error) { GRPC_CQ_INTERNAL_UNREF(c->cq, "bind"); } - grpc_core::channelz::ChannelNode* channelz_channel = - grpc_channel_get_channelz_node(c->channel); - if (c->is_client) { - if (channelz_channel != nullptr) { - if (*c->final_op.client.status != GRPC_STATUS_OK) { - channelz_channel->RecordCallFailed(); - } else { - channelz_channel->RecordCallSucceeded(); - } - } - } else { - if (channelz_channel != nullptr) { - if (*c->final_op.server.cancelled || c->status_error != GRPC_ERROR_NONE) { - channelz_channel->RecordCallFailed(); - } else { - channelz_channel->RecordCallSucceeded(); - } - } - } - grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(c->status_error, c->send_deadline, &c->final_info.final_status, &slice, nullptr, c->final_info.error_string); - grpc_error* cancel_error = - (grpc_error*)gpr_atm_no_barrier_load(&c->cancel_error); - GRPC_ERROR_UNREF(cancel_error); GRPC_ERROR_UNREF(c->status_error); c->final_info.stats.latency = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time); @@ -668,12 +645,10 @@ static void done_termination(void* arg, grpc_error* error) { } static void cancel_with_error(grpc_call* c, grpc_error* error) { - if (!gpr_atm_rel_cas(&c->cancel_error, (gpr_atm)GRPC_ERROR_NONE, - (gpr_atm)error)) { + if (!gpr_atm_rel_cas(&c->cancelled, 0, 1)) { GRPC_ERROR_UNREF(error); return; } - GRPC_ERROR_REF(error); GRPC_CALL_INTERNAL_REF(c, "termination"); // Inform the call combiner of the cancellation, so that it can cancel // any in-flight asynchronous actions that may be holding the call @@ -707,26 +682,14 @@ static void cancel_with_status(grpc_call* c, grpc_status_code status, cancel_with_error(c, error_from_status(status, description)); } -// The final status of a call is determined when the -// recv_trailing_metadata_ready callback is invoked. The status is determined -// based on the following (in order). -// 1. The first cancellation error that has occured prior to the callback. -// 2. The error passed to the recv_trailing_metadata_ready callback. -// 3. The status from the metadata on the call (grpc-status). static void set_final_status(grpc_call* call, grpc_error* error) { if (grpc_call_error_trace.enabled()) { gpr_log(GPR_DEBUG, "set_final_status %s", call->is_client ? "CLI" : "SVR"); gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); } - grpc_error* cancel_error = - (grpc_error*)gpr_atm_no_barrier_load(&call->cancel_error); - if (cancel_error != GRPC_ERROR_NONE && error == GRPC_ERROR_NONE) { - error = GRPC_ERROR_REF(cancel_error); - } else if (cancel_error != GRPC_ERROR_NONE && cancel_error != error) { - error = grpc_error_add_child(GRPC_ERROR_REF(cancel_error), error); - } + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(call->channel); if (call->is_client) { - call->status_error = error; const char** error_string = call->final_op.client.error_string; grpc_status_code code; grpc_slice slice = grpc_empty_slice(); @@ -734,9 +697,24 @@ static void set_final_status(grpc_call* call, grpc_error* error) { error_string); *call->final_op.client.status = code; *call->final_op.client.status_details = grpc_slice_ref_internal(slice); + call->status_error = error; + if (channelz_channel != nullptr) { + if (*call->final_op.client.status != GRPC_STATUS_OK) { + channelz_channel->RecordCallFailed(); + } else { + channelz_channel->RecordCallSucceeded(); + } + } } else { *call->final_op.server.cancelled = error != GRPC_ERROR_NONE || call->status_error != GRPC_ERROR_NONE; + if (channelz_channel != nullptr) { + if (*call->final_op.server.cancelled) { + channelz_channel->RecordCallFailed(); + } else { + channelz_channel->RecordCallSucceeded(); + } + } GRPC_ERROR_UNREF(error); } } From ab9b61dfccfb1e14e102332ee2619a6ee12e8081 Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Wed, 25 Jul 2018 10:51:37 -0700 Subject: [PATCH 046/546] Revert "Roll back filter changes" This reverts commit a9e27ae2c4138d2bd8f9c49d999ac3adb5baabea. --- .../filters/http/client/http_client_filter.cc | 14 +++++- .../filters/http/server/http_server_filter.cc | 31 +++++++++++++ .../message_size/message_size_filter.cc | 45 ++++++++++++++++++- 3 files changed, 87 insertions(+), 3 deletions(-) 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 1678051beb1..04ac4ac947c 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -51,6 +51,7 @@ struct call_data { grpc_linked_mdelem user_agent; // State for handling recv_initial_metadata ops. grpc_metadata_batch* recv_initial_metadata; + grpc_error* recv_initial_metadata_error; grpc_closure* original_recv_initial_metadata_ready; grpc_closure recv_initial_metadata_ready; // State for handling recv_trailing_metadata ops. @@ -147,6 +148,7 @@ static void recv_initial_metadata_ready(void* user_data, grpc_error* error) { call_data* calld = static_cast(elem->call_data); if (error == GRPC_ERROR_NONE) { error = client_filter_incoming_metadata(elem, calld->recv_initial_metadata); + calld->recv_initial_metadata_error = GRPC_ERROR_REF(error); } else { GRPC_ERROR_REF(error); } @@ -162,6 +164,13 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { } else { GRPC_ERROR_REF(error); } + if (calld->recv_initial_metadata_error != GRPC_ERROR_NONE) { + if (error == GRPC_ERROR_NONE) { + error = GRPC_ERROR_REF(calld->recv_initial_metadata_error); + } else if (error != calld->recv_initial_metadata_error) { + error = grpc_error_add_child(error, calld->recv_initial_metadata_error); + } + } GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, error); } @@ -434,7 +443,10 @@ static grpc_error* init_call_elem(grpc_call_element* elem, /* Destructor for call_data */ static void destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, - grpc_closure* ignored) {} + grpc_closure* ignored) { + call_data* calld = static_cast(elem->call_data); + GRPC_ERROR_UNREF(calld->recv_initial_metadata_error); +} static grpc_mdelem scheme_from_args(const grpc_channel_args* args) { unsigned i; 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 3919447f264..01e5aa445eb 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -50,6 +50,7 @@ struct call_data { // State for intercepting recv_initial_metadata. grpc_closure recv_initial_metadata_ready; + grpc_error* recv_initial_metadata_ready_error; grpc_closure* original_recv_initial_metadata_ready; grpc_metadata_batch* recv_initial_metadata; uint32_t* recv_initial_metadata_flags; @@ -60,6 +61,9 @@ struct call_data { grpc_closure recv_message_ready; grpc_core::OrphanablePtr* recv_message; bool seen_recv_message_ready; + + grpc_closure recv_trailing_metadata_ready; + grpc_closure* original_recv_trailing_metadata_ready; }; } // namespace @@ -267,6 +271,7 @@ static void hs_recv_initial_metadata_ready(void* user_data, grpc_error* err) { calld->seen_recv_initial_metadata_ready = true; if (err == GRPC_ERROR_NONE) { err = hs_filter_incoming_metadata(elem, calld->recv_initial_metadata); + calld->recv_initial_metadata_ready_error = GRPC_ERROR_REF(err); if (calld->seen_recv_message_ready) { // We've already seen the recv_message callback, but we previously // deferred it, so we need to return it here. @@ -313,6 +318,23 @@ static void hs_recv_message_ready(void* user_data, grpc_error* err) { } } +static void hs_recv_trailing_metadata_ready(void* user_data, grpc_error* err) { + grpc_call_element* elem = static_cast(user_data); + call_data* calld = static_cast(elem->call_data); + if (calld->recv_initial_metadata_ready_error != GRPC_ERROR_NONE) { + if (err == GRPC_ERROR_NONE) { + err = GRPC_ERROR_REF(calld->recv_initial_metadata_ready_error); + } else if (err != calld->recv_initial_metadata_ready_error) { + err = grpc_error_add_child(err, calld->recv_initial_metadata_ready_error); + } else { + err = GRPC_ERROR_REF(err); + } + } else { + err = GRPC_ERROR_REF(err); + } + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); +} + static grpc_error* hs_mutate_op(grpc_call_element* elem, grpc_transport_stream_op_batch* op) { /* grab pointers to our data from the call element */ @@ -357,6 +379,11 @@ static grpc_error* hs_mutate_op(grpc_call_element* elem, op->payload->recv_message.recv_message_ready = &calld->recv_message_ready; } + if (op->recv_trailing_metadata) { + calld->original_recv_trailing_metadata_ready = + op->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + } + if (op->send_trailing_metadata) { grpc_error* error = hs_filter_outgoing_metadata( elem, op->payload->send_trailing_metadata.send_trailing_metadata); @@ -389,6 +416,9 @@ static grpc_error* hs_init_call_elem(grpc_call_element* elem, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&calld->recv_message_ready, hs_recv_message_ready, elem, grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, + hs_recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); return GRPC_ERROR_NONE; } @@ -397,6 +427,7 @@ static void hs_destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, grpc_closure* ignored) { call_data* calld = static_cast(elem->call_data); + GRPC_ERROR_UNREF(calld->recv_initial_metadata_ready_error); if (calld->have_read_stream) { calld->read_stream->Orphan(); } 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 c7fc3f2e627..deb5ae70ecc 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -99,10 +99,15 @@ struct call_data { // recv_message_ready up-call on transport_stream_op, and remember to // call our next_recv_message_ready member after handling it. grpc_closure recv_message_ready; + grpc_closure recv_trailing_metadata_ready; + // The error caused by a message that is too large, or GRPC_ERROR_NONE + grpc_error* error; // Used by recv_message_ready. grpc_core::OrphanablePtr* recv_message; // Original recv_message_ready callback, invoked after our own. grpc_closure* next_recv_message_ready; + // Original recv_trailing_metadata callback, invoked after our own. + grpc_closure* next_recv_trailing_metadata_ready; }; struct channel_data { @@ -130,12 +135,13 @@ static void recv_message_ready(void* user_data, grpc_error* error) { grpc_error* new_error = grpc_error_set_int( GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED); + GRPC_ERROR_UNREF(calld->error); if (error == GRPC_ERROR_NONE) { error = new_error; } else { error = grpc_error_add_child(error, new_error); - GRPC_ERROR_UNREF(new_error); } + calld->error = GRPC_ERROR_REF(error); gpr_free(message_string); } else { GRPC_ERROR_REF(error); @@ -144,6 +150,26 @@ static void recv_message_ready(void* user_data, grpc_error* error) { GRPC_CLOSURE_RUN(calld->next_recv_message_ready, error); } +// Callback invoked on completion of recv_trailing_metadata +// Notifies the recv_trailing_metadata batch of any message size failures +static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { + grpc_call_element* elem = static_cast(user_data); + call_data* calld = static_cast(elem->call_data); + if (calld->error != GRPC_ERROR_NONE) { + if (error == GRPC_ERROR_NONE) { + error = GRPC_ERROR_REF(calld->error); + } else if (error != calld->error) { + error = grpc_error_add_child(error, GRPC_ERROR_REF(calld->error)); + } else { + error = GRPC_ERROR_REF(error); + } + } else { + error = GRPC_ERROR_REF(error); + } + // Invoke the next callback. + GRPC_CLOSURE_RUN(calld->next_recv_trailing_metadata_ready, error); +} + // Start transport stream op. static void start_transport_stream_op_batch( grpc_call_element* elem, grpc_transport_stream_op_batch* op) { @@ -172,6 +198,13 @@ static void start_transport_stream_op_batch( calld->recv_message = op->payload->recv_message.recv_message; op->payload->recv_message.recv_message_ready = &calld->recv_message_ready; } + // Inject callback for receiving trailing metadata. + if (op->recv_trailing_metadata) { + calld->next_recv_trailing_metadata_ready = + op->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + op->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->recv_trailing_metadata_ready; + } // Chain to the next filter. grpc_call_next_op(elem, op); } @@ -183,8 +216,13 @@ static grpc_error* init_call_elem(grpc_call_element* elem, call_data* calld = static_cast(elem->call_data); calld->call_combiner = args->call_combiner; calld->next_recv_message_ready = nullptr; + calld->next_recv_trailing_metadata_ready = nullptr; + calld->error = GRPC_ERROR_NONE; GRPC_CLOSURE_INIT(&calld->recv_message_ready, recv_message_ready, elem, grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, + recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); // Get max sizes from channel data, then merge in per-method config values. // Note: Per-method config is only available on the client, so we // apply the max request size to the send limit and the max response @@ -213,7 +251,10 @@ static grpc_error* init_call_elem(grpc_call_element* elem, // Destructor for call_data. static void destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, - grpc_closure* ignored) {} + grpc_closure* ignored) { + call_data* calld = (call_data*)elem->call_data; + GRPC_ERROR_UNREF(calld->error); +} static int default_size(const grpc_channel_args* args, int without_minimal_stack) { From aa8043b7c8df2182e57cc561f5477fc3a35c6d95 Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Wed, 25 Jul 2018 10:59:06 -0700 Subject: [PATCH 047/546] changes --- src/core/lib/surface/call.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 43dd795ce79..1ee3667a58a 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -512,7 +512,7 @@ static void destroy_call(void* call, grpc_error* error) { grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(c->status_error, c->send_deadline, &c->final_info.final_status, &slice, nullptr, - c->final_info.error_string); + &c->final_info.error_string); GRPC_ERROR_UNREF(c->status_error); c->final_info.stats.latency = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time); From 864e68e96d20c91ead272c17ff36c74422c7de3f Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 27 Jul 2018 02:27:58 -0700 Subject: [PATCH 048/546] Fix channel trace polymorphism --- grpc.def | 1 + src/core/lib/channel/channel_trace.cc | 58 +++++-------------- src/core/lib/channel/channel_trace.h | 20 ++----- src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 + src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 + test/core/channel/channel_trace_test.cc | 15 ++--- .../core/surface/public_headers_must_be_c89.c | 1 + 7 files changed, 36 insertions(+), 64 deletions(-) diff --git a/grpc.def b/grpc.def index 5b98792662c..5d699e890a8 100644 --- a/grpc.def +++ b/grpc.def @@ -71,6 +71,7 @@ EXPORTS grpc_resource_quota_arg_vtable grpc_channelz_get_top_channels grpc_channelz_get_channel + grpc_channelz_get_subchannel grpc_insecure_channel_create_from_fd grpc_server_add_insecure_channel_from_fd grpc_use_signal diff --git a/src/core/lib/channel/channel_trace.cc b/src/core/lib/channel/channel_trace.cc index 7d8bb391f87..cfb2faba517 100644 --- a/src/core/lib/channel/channel_trace.cc +++ b/src/core/lib/channel/channel_trace.cc @@ -41,25 +41,14 @@ namespace grpc_core { namespace channelz { -ChannelTrace::TraceEvent::TraceEvent( - Severity severity, grpc_slice data, - RefCountedPtr referenced_channel) +ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data, + RefCountedPtr referenced_entity) : severity_(severity), data_(data), timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(), GPR_CLOCK_REALTIME)), next_(nullptr), - referenced_channel_(std::move(referenced_channel)) {} - -// ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data, -// RefCountedPtr -// referenced_subchannel) -// : severity_(severity), -// data_(data), -// timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(), -// GPR_CLOCK_REALTIME)), -// next_(nullptr), -// referenced_subchannel_(std::move(referenced_subchannel)) {} + referenced_entity_(std::move(referenced_entity)) {} ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data) : severity_(severity), @@ -119,24 +108,15 @@ void ChannelTrace::AddTraceEvent(Severity severity, grpc_slice data) { AddTraceEventHelper(New(severity, data)); } -void ChannelTrace::AddTraceEventReferencingChannel( +void ChannelTrace::AddTraceEventWithReference( Severity severity, grpc_slice data, - RefCountedPtr referenced_channel) { + RefCountedPtr referenced_entity) { if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0 // create and fill up the new event AddTraceEventHelper( - New(severity, data, std::move(referenced_channel))); + New(severity, data, std::move(referenced_entity))); } -// void ChannelTrace::AddTraceEventReferencingSubchannel( -// Severity severity, grpc_slice data, -// RefCountedPtr referenced_subchannel) { -// if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0 -// // create and fill up the new event -// AddTraceEventHelper( -// New(severity, data, std::move(referenced_subchannel))); -// } - namespace { const char* severity_string(ChannelTrace::Severity severity) { @@ -165,26 +145,20 @@ void ChannelTrace::TraceEvent::RenderTraceEvent(grpc_json* json) const { json_iterator = grpc_json_create_child(json_iterator, json, "timestamp", gpr_format_timespec(timestamp_), GRPC_JSON_STRING, true); - if (referenced_channel_ != nullptr) { + if (referenced_entity_ != nullptr) { + const bool is_channel = + (referenced_entity_->type() == BaseNode::EntityType::kTopLevelChannel || + referenced_entity_->type() == BaseNode::EntityType::kInternalChannel); char* uuid_str; - gpr_asprintf(&uuid_str, "%" PRIdPTR, referenced_channel_->uuid()); + gpr_asprintf(&uuid_str, "%" PRIdPTR, referenced_entity_->uuid()); grpc_json* child_ref = grpc_json_create_child( - json_iterator, json, "channelRef", nullptr, GRPC_JSON_OBJECT, false); - json_iterator = grpc_json_create_child(nullptr, child_ref, "channelId", - uuid_str, GRPC_JSON_STRING, true); + json_iterator, json, is_channel ? "channelRef" : "subchannelRef", + nullptr, GRPC_JSON_OBJECT, false); + json_iterator = grpc_json_create_child( + nullptr, child_ref, is_channel ? "channelId" : "subchannelId", uuid_str, + GRPC_JSON_STRING, true); json_iterator = child_ref; } - // else { - // char* uuid_str; - // gpr_asprintf(&uuid_str, "%" PRIdPTR, referenced_subchannel_->uuid()); - // grpc_json* child_ref = grpc_json_create_child( - // json_iterator, json, "subchannelRef", - // nullptr, GRPC_JSON_OBJECT, false); - // json_iterator = grpc_json_create_child( - // nullptr, child_ref, "subchannelId", - // uuid_str, GRPC_JSON_STRING, true); - // json_iterator = child_ref; - // } } grpc_json* ChannelTrace::RenderJson() const { diff --git a/src/core/lib/channel/channel_trace.h b/src/core/lib/channel/channel_trace.h index 543eabf13a8..230faa483e4 100644 --- a/src/core/lib/channel/channel_trace.h +++ b/src/core/lib/channel/channel_trace.h @@ -30,8 +30,7 @@ namespace grpc_core { namespace channelz { -class ChannelNode; -class SubchannelNode; +class BaseNode; // Object used to hold live data for a channel. This data is exposed via the // channelz service: @@ -63,12 +62,8 @@ class ChannelTrace { // TODO(ncteisen): as this call is used more and more throughout the gRPC // stack, determine if it makes more sense to accept a char* instead of a // slice. - void AddTraceEventReferencingChannel( - Severity severity, grpc_slice data, - RefCountedPtr referenced_channel); - // void AddTraceEventReferencingSubchannel( - // Severity severity, grpc_slice data, - // RefCountedPtr referenced_subchannel); + void AddTraceEventWithReference(Severity severity, grpc_slice data, + RefCountedPtr referenced_channel); // Creates and returns the raw grpc_json object, so a parent channelz // object may incorporate the json before rendering. @@ -81,11 +76,7 @@ class ChannelTrace { public: // Constructor for a TraceEvent that references a channel. TraceEvent(Severity severity, grpc_slice data, - RefCountedPtr referenced_channel); - - // Constructor for a TraceEvent that references a subchannel. - TraceEvent(Severity severity, grpc_slice data, - RefCountedPtr referenced_subchannel); + RefCountedPtr referenced_entity_); // Constructor for a TraceEvent that does not reverence a different // channel. @@ -107,8 +98,7 @@ class ChannelTrace { gpr_timespec timestamp_; TraceEvent* next_; // the tracer object for the (sub)channel that this trace event refers to. - RefCountedPtr referenced_channel_; - // RefCountedPtr referenced_subchannel_; + RefCountedPtr referenced_entity_; }; // TraceEvent // Internal helper to add and link in a trace event diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 2443532bb8e..5018bbbfa15 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -94,6 +94,7 @@ grpc_resource_quota_resize_type grpc_resource_quota_resize_import; grpc_resource_quota_arg_vtable_type grpc_resource_quota_arg_vtable_import; grpc_channelz_get_top_channels_type grpc_channelz_get_top_channels_import; grpc_channelz_get_channel_type grpc_channelz_get_channel_import; +grpc_channelz_get_subchannel_type grpc_channelz_get_subchannel_import; grpc_insecure_channel_create_from_fd_type grpc_insecure_channel_create_from_fd_import; grpc_server_add_insecure_channel_from_fd_type grpc_server_add_insecure_channel_from_fd_import; grpc_use_signal_type grpc_use_signal_import; @@ -344,6 +345,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_resource_quota_arg_vtable_import = (grpc_resource_quota_arg_vtable_type) GetProcAddress(library, "grpc_resource_quota_arg_vtable"); grpc_channelz_get_top_channels_import = (grpc_channelz_get_top_channels_type) GetProcAddress(library, "grpc_channelz_get_top_channels"); grpc_channelz_get_channel_import = (grpc_channelz_get_channel_type) GetProcAddress(library, "grpc_channelz_get_channel"); + grpc_channelz_get_subchannel_import = (grpc_channelz_get_subchannel_type) GetProcAddress(library, "grpc_channelz_get_subchannel"); grpc_insecure_channel_create_from_fd_import = (grpc_insecure_channel_create_from_fd_type) GetProcAddress(library, "grpc_insecure_channel_create_from_fd"); grpc_server_add_insecure_channel_from_fd_import = (grpc_server_add_insecure_channel_from_fd_type) GetProcAddress(library, "grpc_server_add_insecure_channel_from_fd"); grpc_use_signal_import = (grpc_use_signal_type) GetProcAddress(library, "grpc_use_signal"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index b08a1f94f7b..edb7e98605a 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -257,6 +257,9 @@ extern grpc_channelz_get_top_channels_type grpc_channelz_get_top_channels_import typedef char*(*grpc_channelz_get_channel_type)(intptr_t channel_id); extern grpc_channelz_get_channel_type grpc_channelz_get_channel_import; #define grpc_channelz_get_channel grpc_channelz_get_channel_import +typedef char*(*grpc_channelz_get_subchannel_type)(intptr_t subchannel_id); +extern grpc_channelz_get_subchannel_type grpc_channelz_get_subchannel_import; +#define grpc_channelz_get_subchannel grpc_channelz_get_subchannel_import typedef grpc_channel*(*grpc_insecure_channel_create_from_fd_type)(const char* target, int fd, const grpc_channel_args* args); extern grpc_insecure_channel_create_from_fd_type grpc_insecure_channel_create_from_fd_import; #define grpc_insecure_channel_create_from_fd grpc_insecure_channel_create_from_fd_import diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index efa625bccfb..9bc9dde8d61 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -89,6 +89,7 @@ void ValidateChannelTrace(ChannelTrace* tracer, grpc_json* json = tracer->RenderJson(); EXPECT_NE(json, nullptr); char* json_str = grpc_json_dump_to_string(json, 0); + gpr_log(GPR_ERROR, "%s", json_str); grpc_json_destroy(json); grpc::testing::ValidateChannelTraceProtoJsonTranslation(json_str); grpc_json* parsed_json = grpc_json_parse_string(json_str); @@ -156,7 +157,7 @@ TEST_P(ChannelTracerTest, ComplexTest) { ChannelFixture channel1(GetParam()); RefCountedPtr sc1 = MakeRefCounted(channel1.channel(), GetParam(), true); - tracer.AddTraceEventReferencingChannel( + tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel one created"), sc1); ValidateChannelTrace(&tracer, 3, GetParam()); @@ -174,10 +175,10 @@ TEST_P(ChannelTracerTest, ComplexTest) { ChannelFixture channel2(GetParam()); RefCountedPtr sc2 = MakeRefCounted(channel2.channel(), GetParam(), true); - tracer.AddTraceEventReferencingChannel( + tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("LB channel two created"), sc2); - tracer.AddTraceEventReferencingChannel( + tracer.AddTraceEventWithReference( ChannelTrace::Severity::Warning, grpc_slice_from_static_string("subchannel one inactive"), sc1); ValidateChannelTrace(&tracer, 7, GetParam()); @@ -203,7 +204,7 @@ TEST_P(ChannelTracerTest, TestNesting) { ChannelFixture channel1(GetParam()); RefCountedPtr sc1 = MakeRefCounted(channel1.channel(), GetParam(), true); - tracer.AddTraceEventReferencingChannel( + tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel one created"), sc1); ValidateChannelTrace(&tracer, 3, GetParam()); @@ -212,7 +213,7 @@ TEST_P(ChannelTracerTest, TestNesting) { RefCountedPtr conn1 = MakeRefCounted(channel2.channel(), GetParam(), true); // nesting one level deeper. - sc1->counter_and_tracer()->trace()->AddTraceEventReferencingChannel( + sc1->counter_and_tracer()->trace()->AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("connection one created"), conn1); ValidateChannelTrace(&tracer, 3, GetParam()); @@ -224,12 +225,12 @@ TEST_P(ChannelTracerTest, TestNesting) { ChannelFixture channel3(GetParam()); RefCountedPtr sc2 = MakeRefCounted(channel3.channel(), GetParam(), true); - tracer.AddTraceEventReferencingChannel( + tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel two created"), sc2); // this trace should not get added to the parents children since it is already // present in the tracer. - tracer.AddTraceEventReferencingChannel( + tracer.AddTraceEventWithReference( ChannelTrace::Severity::Warning, grpc_slice_from_static_string("subchannel one inactive"), sc1); AddSimpleTrace(&tracer); diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 9f4ad2b4d75..d492685915d 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -133,6 +133,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_resource_quota_arg_vtable); printf("%lx", (unsigned long) grpc_channelz_get_top_channels); printf("%lx", (unsigned long) grpc_channelz_get_channel); + printf("%lx", (unsigned long) grpc_channelz_get_subchannel); printf("%lx", (unsigned long) grpc_auth_property_iterator_next); printf("%lx", (unsigned long) grpc_auth_context_property_iterator); printf("%lx", (unsigned long) grpc_auth_context_peer_identity); From 1482d3f25c75d1773fd3ab7320403f93d173fc7f Mon Sep 17 00:00:00 2001 From: kpayson64 Date: Fri, 27 Jul 2018 12:21:05 -0700 Subject: [PATCH 049/546] PR Feedback Changes --- .../filters/http/server/http_server_filter.cc | 15 +++-------- .../message_size/message_size_filter.cc | 12 +-------- src/core/lib/iomgr/error.cc | 14 +++++++++++ src/core/lib/iomgr/error.h | 7 ++++++ .../security/transport/server_auth_filter.cc | 25 ++++++++++++++++++- src/core/lib/surface/call.cc | 2 +- src/core/lib/surface/server.cc | 23 +++++++++++++++-- 7 files changed, 72 insertions(+), 26 deletions(-) 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 01e5aa445eb..c66f531a891 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -321,17 +321,8 @@ static void hs_recv_message_ready(void* user_data, grpc_error* err) { static void hs_recv_trailing_metadata_ready(void* user_data, grpc_error* err) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); - if (calld->recv_initial_metadata_ready_error != GRPC_ERROR_NONE) { - if (err == GRPC_ERROR_NONE) { - err = GRPC_ERROR_REF(calld->recv_initial_metadata_ready_error); - } else if (err != calld->recv_initial_metadata_ready_error) { - err = grpc_error_add_child(err, calld->recv_initial_metadata_ready_error); - } else { - err = GRPC_ERROR_REF(err); - } - } else { - err = GRPC_ERROR_REF(err); - } + err = + grpc_error_maybe_add_child(err, calld->recv_initial_metadata_ready_error); GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); } @@ -382,6 +373,8 @@ static grpc_error* hs_mutate_op(grpc_call_element* elem, if (op->recv_trailing_metadata) { calld->original_recv_trailing_metadata_ready = op->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + op->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->recv_trailing_metadata_ready; } if (op->send_trailing_metadata) { 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 deb5ae70ecc..b5ca1be804f 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -155,17 +155,7 @@ static void recv_message_ready(void* user_data, grpc_error* error) { static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); - if (calld->error != GRPC_ERROR_NONE) { - if (error == GRPC_ERROR_NONE) { - error = GRPC_ERROR_REF(calld->error); - } else if (error != calld->error) { - error = grpc_error_add_child(error, GRPC_ERROR_REF(calld->error)); - } else { - error = GRPC_ERROR_REF(error); - } - } else { - error = GRPC_ERROR_REF(error); - } + error = grpc_error_maybe_add_child(error, calld->error); // Invoke the next callback. GRPC_CLOSURE_RUN(calld->next_recv_trailing_metadata_ready, error); } diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index 90ed34da11f..226b44c46d1 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -518,6 +518,20 @@ grpc_error* grpc_error_add_child(grpc_error* src, grpc_error* child) { return new_err; } +grpc_error* grpc_error_maybe_add_child(grpc_error* src, grpc_error* child) { + if (src != GRPC_ERROR_NONE) { + if (child == GRPC_ERROR_NONE) { + return GRPC_ERROR_REF(src); + } else if (child != src) { + return grpc_error_add_child(src, GRPC_ERROR_REF(child)); + } else { + return GRPC_ERROR_REF(src); + } + } else { + return GRPC_ERROR_REF(child); + } +} + static const char* no_error_string = "\"No Error\""; static const char* oom_error_string = "\"Out of memory\""; static const char* cancelled_error_string = "\"Cancelled\""; diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index 27c4d22fd18..4f65c447fdb 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -187,6 +187,13 @@ bool grpc_error_get_str(grpc_error* error, grpc_error_strs which, /// child error. grpc_error* grpc_error_add_child(grpc_error* src, grpc_error* child) GRPC_MUST_USE_RESULT; +/// Produce an error that is a combination of both src and child. +// If src or child, is GRPC_ERROR_NONE, a new reference to the other error is +// returned. Otherwise, a new error with src as the parent and child as the +// child is returned. +grpc_error* grpc_error_maybe_add_child(grpc_error* src, + grpc_error* child) GRPC_MUST_USE_RESULT; + grpc_error* grpc_os_error(const char* file, int line, int err, const char* call_name) GRPC_MUST_USE_RESULT; diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc index 2dbefdf1317..7732b695b32 100644 --- a/src/core/lib/security/transport/server_auth_filter.cc +++ b/src/core/lib/security/transport/server_auth_filter.cc @@ -41,6 +41,9 @@ struct call_data { grpc_transport_stream_op_batch* recv_initial_metadata_batch; grpc_closure* original_recv_initial_metadata_ready; grpc_closure recv_initial_metadata_ready; + grpc_error* error; + grpc_closure recv_trailing_metadata_ready; + grpc_closure* original_recv_trailing_metadata_ready; grpc_metadata_array md; const grpc_metadata* consumed_md; size_t num_consumed_md; @@ -111,6 +114,7 @@ static void on_md_processing_done_inner(grpc_call_element* elem, batch->payload->recv_initial_metadata.recv_initial_metadata, remove_consumed_md, elem, "Response metadata filtering error"); } + calld->error = GRPC_ERROR_REF(error); GRPC_CLOSURE_SCHED(calld->original_recv_initial_metadata_ready, error); } @@ -186,6 +190,13 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { GRPC_ERROR_REF(error)); } +static void recv_trailing_metadata_ready(void* user_data, grpc_error* err) { + grpc_call_element* elem = static_cast(user_data); + call_data* calld = static_cast(elem->call_data); + err = grpc_error_maybe_add_child(err, calld->error); + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); +} + static void auth_start_transport_stream_op_batch( grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { call_data* calld = static_cast(elem->call_data); @@ -197,6 +208,12 @@ static void auth_start_transport_stream_op_batch( batch->payload->recv_initial_metadata.recv_initial_metadata_ready = &calld->recv_initial_metadata_ready; } + if (batch->recv_trailing_metadata) { + calld->original_recv_trailing_metadata_ready = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->recv_trailing_metadata_ready; + } grpc_call_next_op(elem, batch); } @@ -210,6 +227,9 @@ static grpc_error* init_call_elem(grpc_call_element* elem, GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready, recv_initial_metadata_ready, elem, grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, + recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); // Create server security context. Set its auth context from channel // data and save it in the call context. grpc_server_security_context* server_ctx = @@ -229,7 +249,10 @@ static grpc_error* init_call_elem(grpc_call_element* elem, /* Destructor for call_data */ static void destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, - grpc_closure* ignored) {} + grpc_closure* ignored) { + call_data* calld = static_cast(elem->call_data); + GRPC_ERROR_UNREF(calld->error); +} /* Constructor for channel_data */ static grpc_error* init_channel_elem(grpc_channel_element* elem, diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 1ee3667a58a..151cf6c852a 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -512,7 +512,7 @@ static void destroy_call(void* call, grpc_error* error) { grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(c->status_error, c->send_deadline, &c->final_info.final_status, &slice, nullptr, - &c->final_info.error_string); + &(c->final_info.error_string)); GRPC_ERROR_UNREF(c->status_error); c->final_info.stats.latency = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index cb34def7403..4403caf044c 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -149,6 +149,9 @@ struct call_data { grpc_closure server_on_recv_initial_metadata; grpc_closure kill_zombie_closure; grpc_closure* on_done_recv_initial_metadata; + grpc_closure recv_trailing_metadata_ready; + grpc_error* error; + grpc_closure* original_recv_trailing_metadata_ready; grpc_closure publish; @@ -730,6 +733,14 @@ static void server_on_recv_initial_metadata(void* ptr, grpc_error* error) { GRPC_CLOSURE_RUN(calld->on_done_recv_initial_metadata, error); } +static void server_recv_trailing_metadata_ready(void* user_data, + grpc_error* err) { + grpc_call_element* elem = static_cast(user_data); + call_data* calld = static_cast(elem->call_data); + err = grpc_error_maybe_add_child(err, calld->error); + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); +} + static void server_mutate_op(grpc_call_element* elem, grpc_transport_stream_op_batch* op) { call_data* calld = static_cast(elem->call_data); @@ -745,6 +756,12 @@ static void server_mutate_op(grpc_call_element* elem, op->payload->recv_initial_metadata.recv_flags = &calld->recv_initial_metadata_flags; } + if (op->recv_trailing_metadata) { + calld->original_recv_trailing_metadata_ready = + op->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + op->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->recv_trailing_metadata_ready; + } } static void server_start_transport_stream_op_batch( @@ -828,7 +845,9 @@ static grpc_error* init_call_elem(grpc_call_element* elem, GRPC_CLOSURE_INIT(&calld->server_on_recv_initial_metadata, server_on_recv_initial_metadata, elem, grpc_schedule_on_exec_ctx); - + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, + server_recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); server_ref(chand->server); return GRPC_ERROR_NONE; } @@ -840,7 +859,7 @@ static void destroy_call_elem(grpc_call_element* elem, call_data* calld = static_cast(elem->call_data); GPR_ASSERT(calld->state != PENDING); - + GRPC_ERROR_UNREF(calld->error); if (calld->host_set) { grpc_slice_unref_internal(calld->host); } From 58db94e5d9f3e55f14760f936a42e5e6ddb6bd5b Mon Sep 17 00:00:00 2001 From: ncteisen Date: Sun, 29 Jul 2018 20:30:05 -0700 Subject: [PATCH 050/546] reviewer comments --- .../client_channel/client_channel_channelz.cc | 30 +++++++---- .../client_channel/client_channel_channelz.h | 11 ++-- .../ext/filters/client_channel/subchannel.cc | 4 +- src/core/lib/channel/channelz.cc | 39 ++++++-------- src/core/lib/channel/channelz.h | 41 +++++++------- src/core/lib/surface/call.cc | 6 +-- src/core/lib/surface/channel.cc | 4 +- test/core/channel/channel_trace_test.cc | 25 +++++---- test/core/channel/channelz_test.cc | 53 ++++++++----------- 9 files changed, 106 insertions(+), 107 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index f797ef1b094..7120ec57f1a 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -123,9 +123,14 @@ grpc_json* ClientChannelNode::RenderJson() { GPR_ASSERT(target_view() != nullptr); grpc_json_create_child(nullptr, json, "target", target_view(), GRPC_JSON_STRING, false); - // as CallCountingAndTracingNode to populate trace and call count data. - counter_and_tracer()->PopulateTrace(json); - counter_and_tracer()->PopulateCallData(json); + // fill in the channel trace if applicable + grpc_json* trace_json = trace()->RenderJson(); + if (trace_json != nullptr) { + trace_json->key = "trace"; // this object is named trace in channelz.proto + grpc_json_link_child(json, trace_json, nullptr); + } + // ask CallCountingHelper to populate trace and call count data. + call_counter()->PopulateCallData(json); // reset to the top level json = top_level_json; PopulateChildRefs(json); @@ -150,11 +155,12 @@ SubchannelNode::SubchannelNode(grpc_subchannel* subchannel, size_t channel_tracer_max_nodes) : BaseNode(EntityType::kSubchannel), subchannel_(subchannel), - target_( - UniquePtr(gpr_strdup(grpc_subchannel_get_target(subchannel_)))), - counter_and_tracer_(channel_tracer_max_nodes) {} + target_(UniquePtr( + gpr_strdup(grpc_subchannel_get_target(subchannel_)))) { + trace_.Init(channel_tracer_max_nodes); +} -SubchannelNode::~SubchannelNode() {} +SubchannelNode::~SubchannelNode() { trace_.Destroy(); } void SubchannelNode::PopulateConnectivityState(grpc_json* json) { grpc_connectivity_state state; @@ -192,8 +198,14 @@ grpc_json* SubchannelNode::RenderJson() { GPR_ASSERT(target_.get() != nullptr); grpc_json_create_child(nullptr, json, "target", target_.get(), GRPC_JSON_STRING, false); - counter_and_tracer_.PopulateTrace(json); - counter_and_tracer_.PopulateCallData(json); + // fill in the channel trace if applicable + grpc_json* trace_json = trace_->RenderJson(); + if (trace_json != nullptr) { + trace_json->key = "trace"; // this object is named trace in channelz.proto + grpc_json_link_child(json, trace_json, nullptr); + } + // ask CallCountingHelper to populate trace and call count data. + call_counter_.PopulateCallData(json); return top_level_json; } diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index f5344c049e9..735ffacfd25 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -76,14 +76,17 @@ class SubchannelNode : public BaseNode { grpc_json* RenderJson() override; - CallCountingAndTracingNode* counter_and_tracer() { - return &counter_and_tracer_; - } + // proxy methods to composed classes. + ChannelTrace* trace() { return trace_.get(); } + void RecordCallStarted() { call_counter_.RecordCallStarted(); } + void RecordCallFailed() { call_counter_.RecordCallFailed(); } + void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } private: grpc_subchannel* subchannel_; UniquePtr target_; - CallCountingAndTracingNode counter_and_tracer_; + CallCountingHelper call_counter_; + ManualConstructor trace_; void PopulateConnectivityState(grpc_json* json); }; diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index d7b64a900f6..f0f8d94ef47 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -183,7 +183,7 @@ static void connection_destroy(void* arg, grpc_error* error) { static void subchannel_destroy(void* arg, grpc_error* error) { grpc_subchannel* c = static_cast(arg); if (c->channelz_subchannel != nullptr) { - c->channelz_subchannel->counter_and_tracer()->trace()->AddTraceEvent( + c->channelz_subchannel->trace()->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Subchannel destroyed")); c->channelz_subchannel->MarkSubchannelDestroyed(); @@ -397,7 +397,7 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, c->channelz_subchannel = grpc_core::MakeRefCounted( c, channel_tracer_max_nodes); - c->channelz_subchannel->counter_and_tracer()->trace()->AddTraceEvent( + c->channelz_subchannel->trace()->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Subchannel created")); } diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index ee1717ce9ff..a75a05023af 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -53,33 +53,20 @@ char* BaseNode::RenderJsonString() { return json_str; } -CallCountingAndTracingNode::CallCountingAndTracingNode( - size_t channel_tracer_max_nodes) { - trace_.Init(channel_tracer_max_nodes); +CallCountingHelper::CallCountingHelper() { gpr_atm_no_barrier_store(&last_call_started_millis_, (gpr_atm)ExecCtx::Get()->Now()); } -CallCountingAndTracingNode::~CallCountingAndTracingNode() { trace_.Destroy(); } +CallCountingHelper::~CallCountingHelper() {} -void CallCountingAndTracingNode::RecordCallStarted() { +void CallCountingHelper::RecordCallStarted() { gpr_atm_no_barrier_fetch_add(&calls_started_, (gpr_atm)1); gpr_atm_no_barrier_store(&last_call_started_millis_, (gpr_atm)ExecCtx::Get()->Now()); } -void CallCountingAndTracingNode::PopulateTrace(grpc_json* json) { - // fill in the channel trace if applicable - grpc_json* trace_json = trace_->RenderJson(); - if (trace_json != nullptr) { - // we manually link up and fill the child since it was created for us in - // ChannelTrace::RenderJson - trace_json->key = "trace"; // this object is named trace in channelz.proto - grpc_json_link_child(json, trace_json, nullptr); - } -} - -void CallCountingAndTracingNode::PopulateCallData(grpc_json* json) { +void CallCountingHelper::PopulateCallData(grpc_json* json) { grpc_json* json_iterator = nullptr; if (calls_started_ != 0) { json_iterator = grpc_json_add_number_string_child( @@ -105,10 +92,11 @@ ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, : BaseNode(is_top_level_channel ? EntityType::kTopLevelChannel : EntityType::kInternalChannel), channel_(channel), - target_(UniquePtr(grpc_channel_get_target(channel_))), - counter_and_tracer_(channel_tracer_max_nodes) {} + target_(UniquePtr(grpc_channel_get_target(channel_))) { + trace_.Init(channel_tracer_max_nodes); +} -ChannelNode::~ChannelNode() {} +ChannelNode::~ChannelNode() { trace_.Destroy(); } grpc_json* ChannelNode::RenderJson() { // We need to track these three json objects to build our object @@ -134,9 +122,14 @@ grpc_json* ChannelNode::RenderJson() { GPR_ASSERT(target_.get() != nullptr); grpc_json_create_child(nullptr, json, "target", target_.get(), GRPC_JSON_STRING, false); - // as CallCountingAndTracingNode to populate trace and call count data. - counter_and_tracer_.PopulateTrace(json); - counter_and_tracer_.PopulateCallData(json); + // fill in the channel trace if applicable + grpc_json* trace_json = trace_->RenderJson(); + if (trace_json != nullptr) { + trace_json->key = "trace"; // this object is named trace in channelz.proto + grpc_json_link_child(json, trace_json, nullptr); + } + // ask CallCountingHelper to populate trace and call count data. + call_counter_.PopulateCallData(json); return top_level_json; } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 7bc4567ad2e..6e20f31b68e 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -43,7 +43,7 @@ namespace grpc_core { namespace channelz { namespace testing { -class CallCountingAndTracingNodePeer; +class CallCountingHelperPeer; } // base class for all channelz entities @@ -60,7 +60,7 @@ class BaseNode : public RefCounted { kSocket, }; - BaseNode(EntityType type); + explicit BaseNode(EntityType type); virtual ~BaseNode(); // All children must implement this function. @@ -74,22 +74,20 @@ class BaseNode : public RefCounted { intptr_t uuid() const { return uuid_; } private: - friend class ChannelTrace; - EntityType type_; + const EntityType type_; const intptr_t uuid_; }; -// This class is the parent for the channelz entities that deal with Channels +// This class is a helper class for channelz entities that deal with Channels // Subchannels, and Servers, since those have similar proto definitions. // This class has the ability to: // - track calls_{started,succeeded,failed} // - track last_call_started_timestamp -// - hold the channel trace. -// - perform common rendering. -class CallCountingAndTracingNode { +// - perform rendering of the above items +class CallCountingHelper { public: - CallCountingAndTracingNode(size_t channel_tracer_max_nodes); - ~CallCountingAndTracingNode(); + CallCountingHelper(); + ~CallCountingHelper(); void RecordCallStarted(); void RecordCallFailed() { @@ -98,23 +96,18 @@ class CallCountingAndTracingNode { void RecordCallSucceeded() { gpr_atm_no_barrier_fetch_add(&calls_succeeded_, (gpr_atm(1))); } - ChannelTrace* trace() { return trace_.get(); } - - // Common rendering of the channel trace. - void PopulateTrace(grpc_json* json); // Common rendering of the call count data and last_call_started_timestamp. void PopulateCallData(grpc_json* json); private: // testing peer friend. - friend class testing::CallCountingAndTracingNodePeer; + friend class testing::CallCountingHelperPeer; gpr_atm calls_started_ = 0; gpr_atm calls_succeeded_ = 0; gpr_atm calls_failed_ = 0; gpr_atm last_call_started_millis_ = 0; - ManualConstructor trace_; }; // Handles channelz bookkeeping for channels @@ -137,25 +130,31 @@ class ChannelNode : public BaseNode { bool ChannelIsDestroyed() { return channel_ == nullptr; } - CallCountingAndTracingNode* counter_and_tracer() { - return &counter_and_tracer_; - } + // proxy methods to composed classes. + ChannelTrace* trace() { return trace_.get(); } + void RecordCallStarted() { call_counter_.RecordCallStarted(); } + void RecordCallFailed() { call_counter_.RecordCallFailed(); } + void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } protected: // provides view of target for child. char* target_view() { return target_.get(); } + // provides access to call_counter_ for child. + CallCountingHelper* call_counter() { return &call_counter_; } private: grpc_channel* channel_ = nullptr; UniquePtr target_; - CallCountingAndTracingNode counter_and_tracer_; + CallCountingHelper call_counter_; + ManualConstructor trace_; }; // Handles channelz bookkeeping for servers // TODO(ncteisen): implement in subsequent PR. class ServerNode : public BaseNode { public: - ServerNode(size_t channel_tracer_max_nodes) : BaseNode(EntityType::kServer) {} + explicit ServerNode(size_t channel_tracer_max_nodes) + : BaseNode(EntityType::kServer) {} ~ServerNode() override {} }; diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 03b7cedcdbc..a6d626e495d 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -489,7 +489,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, grpc_core::channelz::ChannelNode* channelz_channel = grpc_channel_get_channelz_node(call->channel); if (channelz_channel != nullptr) { - channelz_channel->counter_and_tracer()->RecordCallStarted(); + channelz_channel->RecordCallStarted(); } grpc_slice_unref_internal(path); @@ -1269,9 +1269,9 @@ static void post_batch_completion(batch_control* bctl) { grpc_channel_get_channelz_node(call->channel); if (channelz_channel != nullptr) { if (*call->final_op.client.status != GRPC_STATUS_OK) { - channelz_channel->counter_and_tracer()->RecordCallFailed(); + channelz_channel->RecordCallFailed(); } else { - channelz_channel->counter_and_tracer()->RecordCallSucceeded(); + channelz_channel->RecordCallSucceeded(); } } GRPC_ERROR_UNREF(error); diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index 16d3322a9d6..01caadaabac 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -170,7 +170,7 @@ grpc_channel* grpc_channel_create_with_builder( bool is_top_level_channel = channel->is_client && !internal_channel; channel->channelz_channel = channel_node_create_func( channel, channel_tracer_max_nodes, is_top_level_channel); - channel->channelz_channel->counter_and_tracer()->trace()->AddTraceEvent( + channel->channelz_channel->trace()->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Channel created")); } @@ -417,7 +417,7 @@ void grpc_channel_internal_unref(grpc_channel* c REF_ARG) { static void destroy_channel(void* arg, grpc_error* error) { grpc_channel* channel = static_cast(arg); if (channel->channelz_channel != nullptr) { - channel->channelz_channel->counter_and_tracer()->trace()->AddTraceEvent( + channel->channelz_channel->trace()->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Channel destroyed")); channel->channelz_channel->MarkChannelDestroyed(); diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index 9bc9dde8d61..3f5aa85c8c4 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -89,7 +89,6 @@ void ValidateChannelTrace(ChannelTrace* tracer, grpc_json* json = tracer->RenderJson(); EXPECT_NE(json, nullptr); char* json_str = grpc_json_dump_to_string(json, 0); - gpr_log(GPR_ERROR, "%s", json_str); grpc_json_destroy(json); grpc::testing::ValidateChannelTraceProtoJsonTranslation(json_str); grpc_json* parsed_json = grpc_json_parse_string(json_str); @@ -161,14 +160,14 @@ TEST_P(ChannelTracerTest, ComplexTest) { ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel one created"), sc1); ValidateChannelTrace(&tracer, 3, GetParam()); - AddSimpleTrace(sc1->counter_and_tracer()->trace()); - AddSimpleTrace(sc1->counter_and_tracer()->trace()); - AddSimpleTrace(sc1->counter_and_tracer()->trace()); - ValidateChannelTrace(sc1->counter_and_tracer()->trace(), 3, GetParam()); - AddSimpleTrace(sc1->counter_and_tracer()->trace()); - AddSimpleTrace(sc1->counter_and_tracer()->trace()); - AddSimpleTrace(sc1->counter_and_tracer()->trace()); - ValidateChannelTrace(sc1->counter_and_tracer()->trace(), 6, GetParam()); + AddSimpleTrace(sc1->trace()); + AddSimpleTrace(sc1->trace()); + AddSimpleTrace(sc1->trace()); + ValidateChannelTrace(sc1->trace(), 3, GetParam()); + AddSimpleTrace(sc1->trace()); + AddSimpleTrace(sc1->trace()); + AddSimpleTrace(sc1->trace()); + ValidateChannelTrace(sc1->trace(), 6, GetParam()); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); ValidateChannelTrace(&tracer, 5, GetParam()); @@ -208,20 +207,20 @@ TEST_P(ChannelTracerTest, TestNesting) { ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel one created"), sc1); ValidateChannelTrace(&tracer, 3, GetParam()); - AddSimpleTrace(sc1->counter_and_tracer()->trace()); + AddSimpleTrace(sc1->trace()); ChannelFixture channel2(GetParam()); RefCountedPtr conn1 = MakeRefCounted(channel2.channel(), GetParam(), true); // nesting one level deeper. - sc1->counter_and_tracer()->trace()->AddTraceEventWithReference( + sc1->trace()->AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("connection one created"), conn1); ValidateChannelTrace(&tracer, 3, GetParam()); - AddSimpleTrace(conn1->counter_and_tracer()->trace()); + AddSimpleTrace(conn1->trace()); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); ValidateChannelTrace(&tracer, 5, GetParam()); - ValidateChannelTrace(conn1->counter_and_tracer()->trace(), 1, GetParam()); + ValidateChannelTrace(conn1->trace(), 1, GetParam()); ChannelFixture channel3(GetParam()); RefCountedPtr sc2 = MakeRefCounted(channel3.channel(), GetParam(), true); diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index 5e9a3f89a26..8fa46a18dae 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -44,17 +44,16 @@ namespace channelz { namespace testing { // testing peer to access channel internals -class CallCountingAndTracingNodePeer { +class CallCountingHelperPeer { public: - CallCountingAndTracingNodePeer(CallCountingAndTracingNode* node) - : node_(node) {} + CallCountingHelperPeer(CallCountingHelper* node) : node_(node) {} grpc_millis last_call_started_millis() { return (grpc_millis)gpr_atm_no_barrier_load( &node_->last_call_started_millis_); } private: - CallCountingAndTracingNode* node_; + CallCountingHelper* node_; }; namespace { @@ -164,8 +163,8 @@ void ValidateChannel(ChannelNode* channel, validate_channel_data_args args) { gpr_free(core_api_json_str); } -grpc_millis GetLastCallStartedMillis(CallCountingAndTracingNode* channel) { - CallCountingAndTracingNodePeer peer(channel); +grpc_millis GetLastCallStartedMillis(CallCountingHelper* channel) { + CallCountingHelperPeer peer(channel); return peer.last_call_started_millis(); } @@ -201,46 +200,40 @@ TEST_P(ChannelzChannelTest, BasicChannelAPIFunctionality) { ChannelFixture channel(GetParam()); ChannelNode* channelz_channel = grpc_channel_get_channelz_node(channel.channel()); - channelz_channel->counter_and_tracer()->RecordCallStarted(); - channelz_channel->counter_and_tracer()->RecordCallFailed(); - channelz_channel->counter_and_tracer()->RecordCallSucceeded(); + channelz_channel->RecordCallStarted(); + channelz_channel->RecordCallFailed(); + channelz_channel->RecordCallSucceeded(); ValidateChannel(channelz_channel, {1, 1, 1}); - channelz_channel->counter_and_tracer()->RecordCallStarted(); - channelz_channel->counter_and_tracer()->RecordCallFailed(); - channelz_channel->counter_and_tracer()->RecordCallSucceeded(); - channelz_channel->counter_and_tracer()->RecordCallStarted(); - channelz_channel->counter_and_tracer()->RecordCallFailed(); - channelz_channel->counter_and_tracer()->RecordCallSucceeded(); + channelz_channel->RecordCallStarted(); + channelz_channel->RecordCallFailed(); + channelz_channel->RecordCallSucceeded(); + channelz_channel->RecordCallStarted(); + channelz_channel->RecordCallFailed(); + channelz_channel->RecordCallSucceeded(); ValidateChannel(channelz_channel, {3, 3, 3}); } TEST_P(ChannelzChannelTest, LastCallStartedMillis) { grpc_core::ExecCtx exec_ctx; - ChannelFixture channel(GetParam()); - ChannelNode* channelz_channel = - grpc_channel_get_channelz_node(channel.channel()); + CallCountingHelper counter; // start a call to set the last call started timestamp - channelz_channel->counter_and_tracer()->RecordCallStarted(); - grpc_millis millis1 = - GetLastCallStartedMillis(channelz_channel->counter_and_tracer()); + counter.RecordCallStarted(); + grpc_millis millis1 = GetLastCallStartedMillis(&counter); // time gone by should not affect the timestamp ChannelzSleep(100); - grpc_millis millis2 = - GetLastCallStartedMillis(channelz_channel->counter_and_tracer()); + grpc_millis millis2 = GetLastCallStartedMillis(&counter); EXPECT_EQ(millis1, millis2); // calls succeeded or failed should not affect the timestamp ChannelzSleep(100); - channelz_channel->counter_and_tracer()->RecordCallFailed(); - channelz_channel->counter_and_tracer()->RecordCallSucceeded(); - grpc_millis millis3 = - GetLastCallStartedMillis(channelz_channel->counter_and_tracer()); + counter.RecordCallFailed(); + counter.RecordCallSucceeded(); + grpc_millis millis3 = GetLastCallStartedMillis(&counter); EXPECT_EQ(millis1, millis3); // another call started should affect the timestamp // sleep for extra long to avoid flakes (since we cache Now()) ChannelzSleep(5000); - channelz_channel->counter_and_tracer()->RecordCallStarted(); - grpc_millis millis4 = - GetLastCallStartedMillis(channelz_channel->counter_and_tracer()); + counter.RecordCallStarted(); + grpc_millis millis4 = GetLastCallStartedMillis(&counter); EXPECT_NE(millis1, millis4); } From 844d4efcd2325504c6d916f7ad3b3cc638fada70 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Sun, 29 Jul 2018 20:43:05 -0700 Subject: [PATCH 051/546] Count calls for subchannels --- .../filters/client_channel/client_channel.cc | 22 +++++-------------- .../ext/filters/client_channel/subchannel.cc | 3 +++ 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 683cb0e01df..0368590a6aa 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1154,16 +1154,6 @@ static void pending_batches_add(grpc_call_element* elem, 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_INFO, - "chand=%p calld=%p: disabling retries before first attempt", - chand, calld); - } - calld->enable_retries = false; - } } } } @@ -1942,6 +1932,12 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { grpc_mdelem* server_pushback_md = nullptr; get_call_status(batch_data, GRPC_ERROR_REF(error), &status, &server_pushback_md); + if (status == GRPC_STATUS_OK) { + calld->pick.connected_subchannel->channelz_subchannel() + ->RecordCallSucceeded(); + } else { + calld->pick.connected_subchannel->channelz_subchannel()->RecordCallFailed(); + } if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: call finished, status=%s", chand, calld, grpc_status_code_to_string(status)); @@ -2797,12 +2793,6 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) { } } } - // 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; - } } // Invoked once resolver results are available. diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index f0f8d94ef47..b74a354e9e8 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -865,6 +865,9 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, gpr_log(GPR_ERROR, "error: %s", error_string); return error; } + if (channelz_subchannel_ != nullptr) { + channelz_subchannel_->RecordCallStarted(); + } grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); return GRPC_ERROR_NONE; } From d030114058b167ba3cbe71796ae30b99bc0c2e22 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 30 Jul 2018 22:06:46 -0700 Subject: [PATCH 052/546] Add back in disable retries --- .../ext/filters/client_channel/client_channel.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 0368590a6aa..888a5efda3f 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1154,6 +1154,16 @@ static void pending_batches_add(grpc_call_element* elem, 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_INFO, + "chand=%p calld=%p: disabling retries before first attempt", + chand, calld); + } + calld->enable_retries = false; + } } } } @@ -2793,6 +2803,12 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) { } } } + // 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; + } } // Invoked once resolver results are available. From e888e93293310259b9d4bbabff2baf312cdd8973 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 30 Jul 2018 22:29:47 -0700 Subject: [PATCH 053/546] reviewer feedback --- .../client_channel/client_channel_channelz.h | 9 ++++- .../ext/filters/client_channel/subchannel.cc | 4 +- src/core/lib/channel/channelz.h | 16 +++++++- src/core/lib/surface/channel.cc | 4 +- test/core/channel/channel_trace_test.cc | 38 +++++++++++++------ 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 735ffacfd25..5e01fdf2a38 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -77,7 +77,14 @@ class SubchannelNode : public BaseNode { grpc_json* RenderJson() override; // proxy methods to composed classes. - ChannelTrace* trace() { return trace_.get(); } + void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { + trace_->AddTraceEvent(severity, data); + } + void AddTraceEventWithReference(ChannelTrace::Severity severity, + grpc_slice data, + RefCountedPtr referenced_channel) { + trace_->AddTraceEventWithReference(severity, data, referenced_channel); + } void RecordCallStarted() { call_counter_.RecordCallStarted(); } void RecordCallFailed() { call_counter_.RecordCallFailed(); } void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index b74a354e9e8..639a5fe9dbd 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -183,7 +183,7 @@ static void connection_destroy(void* arg, grpc_error* error) { static void subchannel_destroy(void* arg, grpc_error* error) { grpc_subchannel* c = static_cast(arg); if (c->channelz_subchannel != nullptr) { - c->channelz_subchannel->trace()->AddTraceEvent( + c->channelz_subchannel->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Subchannel destroyed")); c->channelz_subchannel->MarkSubchannelDestroyed(); @@ -397,7 +397,7 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, c->channelz_subchannel = grpc_core::MakeRefCounted( c, channel_tracer_max_nodes); - c->channelz_subchannel->trace()->AddTraceEvent( + c->channelz_subchannel->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Subchannel created")); } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 6e20f31b68e..74b203af443 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -44,7 +44,8 @@ namespace channelz { namespace testing { class CallCountingHelperPeer; -} +class ChannelNodePeer; +} // namespace testing // base class for all channelz entities class BaseNode : public RefCounted { @@ -131,7 +132,14 @@ class ChannelNode : public BaseNode { bool ChannelIsDestroyed() { return channel_ == nullptr; } // proxy methods to composed classes. - ChannelTrace* trace() { return trace_.get(); } + void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { + trace_->AddTraceEvent(severity, data); + } + void AddTraceEventWithReference(ChannelTrace::Severity severity, + grpc_slice data, + RefCountedPtr referenced_channel) { + trace_->AddTraceEventWithReference(severity, data, referenced_channel); + } void RecordCallStarted() { call_counter_.RecordCallStarted(); } void RecordCallFailed() { call_counter_.RecordCallFailed(); } void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } @@ -141,8 +149,12 @@ class ChannelNode : public BaseNode { char* target_view() { return target_.get(); } // provides access to call_counter_ for child. CallCountingHelper* call_counter() { return &call_counter_; } + // provides access to channel trace for child. + ChannelTrace* trace() { return trace_.get(); } private: + // to allow the channel trace test to access trace(); + friend class testing::ChannelNodePeer; grpc_channel* channel_ = nullptr; UniquePtr target_; CallCountingHelper call_counter_; diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index 01caadaabac..0b3508e27ca 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -170,7 +170,7 @@ grpc_channel* grpc_channel_create_with_builder( bool is_top_level_channel = channel->is_client && !internal_channel; channel->channelz_channel = channel_node_create_func( channel, channel_tracer_max_nodes, is_top_level_channel); - channel->channelz_channel->trace()->AddTraceEvent( + channel->channelz_channel->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Channel created")); } @@ -417,7 +417,7 @@ void grpc_channel_internal_unref(grpc_channel* c REF_ARG) { static void destroy_channel(void* arg, grpc_error* error) { grpc_channel* channel = static_cast(arg); if (channel->channelz_channel != nullptr) { - channel->channelz_channel->trace()->AddTraceEvent( + channel->channelz_channel->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Channel destroyed")); channel->channelz_channel->MarkChannelDestroyed(); diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index 3f5aa85c8c4..8a5ddc2723a 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -40,6 +40,17 @@ namespace grpc_core { namespace channelz { namespace testing { + +// testing peer to access channel internals +class ChannelNodePeer { + public: + ChannelNodePeer(ChannelNode* node) : node_(node) {} + ChannelTrace* trace() { return node_->trace_.get(); } + + private: + ChannelNode* node_; +}; + namespace { grpc_json* GetJsonChild(grpc_json* parent, const char* key) { @@ -156,18 +167,19 @@ TEST_P(ChannelTracerTest, ComplexTest) { ChannelFixture channel1(GetParam()); RefCountedPtr sc1 = MakeRefCounted(channel1.channel(), GetParam(), true); + ChannelNodePeer sc1_peer(sc1.get()); tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel one created"), sc1); ValidateChannelTrace(&tracer, 3, GetParam()); - AddSimpleTrace(sc1->trace()); - AddSimpleTrace(sc1->trace()); - AddSimpleTrace(sc1->trace()); - ValidateChannelTrace(sc1->trace(), 3, GetParam()); - AddSimpleTrace(sc1->trace()); - AddSimpleTrace(sc1->trace()); - AddSimpleTrace(sc1->trace()); - ValidateChannelTrace(sc1->trace(), 6, GetParam()); + AddSimpleTrace(sc1_peer.trace()); + AddSimpleTrace(sc1_peer.trace()); + AddSimpleTrace(sc1_peer.trace()); + ValidateChannelTrace(sc1_peer.trace(), 3, GetParam()); + AddSimpleTrace(sc1_peer.trace()); + AddSimpleTrace(sc1_peer.trace()); + AddSimpleTrace(sc1_peer.trace()); + ValidateChannelTrace(sc1_peer.trace(), 6, GetParam()); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); ValidateChannelTrace(&tracer, 5, GetParam()); @@ -203,24 +215,26 @@ TEST_P(ChannelTracerTest, TestNesting) { ChannelFixture channel1(GetParam()); RefCountedPtr sc1 = MakeRefCounted(channel1.channel(), GetParam(), true); + ChannelNodePeer sc1_peer(sc1.get()); tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel one created"), sc1); ValidateChannelTrace(&tracer, 3, GetParam()); - AddSimpleTrace(sc1->trace()); + AddSimpleTrace(sc1_peer.trace()); ChannelFixture channel2(GetParam()); RefCountedPtr conn1 = MakeRefCounted(channel2.channel(), GetParam(), true); + ChannelNodePeer conn1_peer(conn1.get()); // nesting one level deeper. - sc1->trace()->AddTraceEventWithReference( + sc1_peer.trace()->AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("connection one created"), conn1); ValidateChannelTrace(&tracer, 3, GetParam()); - AddSimpleTrace(conn1->trace()); + AddSimpleTrace(conn1_peer.trace()); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); ValidateChannelTrace(&tracer, 5, GetParam()); - ValidateChannelTrace(conn1->trace(), 1, GetParam()); + ValidateChannelTrace(conn1_peer.trace(), 1, GetParam()); ChannelFixture channel3(GetParam()); RefCountedPtr sc2 = MakeRefCounted(channel3.channel(), GetParam(), true); From 885c33da8bb363014e4231f8b5f3da024923f287 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 30 Jul 2018 22:36:25 -0700 Subject: [PATCH 054/546] reviewer feedback --- .../filters/client_channel/client_channel_channelz.cc | 11 +++++------ .../filters/client_channel/client_channel_channelz.h | 7 ++++--- src/core/lib/channel/channelz.cc | 9 ++++----- src/core/lib/channel/channelz.h | 8 ++++---- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 7120ec57f1a..d904fc28b2a 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -155,12 +155,11 @@ SubchannelNode::SubchannelNode(grpc_subchannel* subchannel, size_t channel_tracer_max_nodes) : BaseNode(EntityType::kSubchannel), subchannel_(subchannel), - target_(UniquePtr( - gpr_strdup(grpc_subchannel_get_target(subchannel_)))) { - trace_.Init(channel_tracer_max_nodes); -} + target_( + UniquePtr(gpr_strdup(grpc_subchannel_get_target(subchannel_)))), + trace_(channel_tracer_max_nodes) {} -SubchannelNode::~SubchannelNode() { trace_.Destroy(); } +SubchannelNode::~SubchannelNode() {} void SubchannelNode::PopulateConnectivityState(grpc_json* json) { grpc_connectivity_state state; @@ -199,7 +198,7 @@ grpc_json* SubchannelNode::RenderJson() { grpc_json_create_child(nullptr, json, "target", target_.get(), GRPC_JSON_STRING, false); // fill in the channel trace if applicable - grpc_json* trace_json = trace_->RenderJson(); + grpc_json* trace_json = trace_.RenderJson(); if (trace_json != nullptr) { trace_json->key = "trace"; // this object is named trace in channelz.proto grpc_json_link_child(json, trace_json, nullptr); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 5e01fdf2a38..9a3fc1d6f1a 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -23,6 +23,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channelz.h" #include "src/core/lib/gprpp/inlined_vector.h" @@ -78,12 +79,12 @@ class SubchannelNode : public BaseNode { // proxy methods to composed classes. void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { - trace_->AddTraceEvent(severity, data); + trace_.AddTraceEvent(severity, data); } void AddTraceEventWithReference(ChannelTrace::Severity severity, grpc_slice data, RefCountedPtr referenced_channel) { - trace_->AddTraceEventWithReference(severity, data, referenced_channel); + trace_.AddTraceEventWithReference(severity, data, referenced_channel); } void RecordCallStarted() { call_counter_.RecordCallStarted(); } void RecordCallFailed() { call_counter_.RecordCallFailed(); } @@ -93,7 +94,7 @@ class SubchannelNode : public BaseNode { grpc_subchannel* subchannel_; UniquePtr target_; CallCountingHelper call_counter_; - ManualConstructor trace_; + ChannelTrace trace_; void PopulateConnectivityState(grpc_json* json); }; diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index a75a05023af..b908363b1b7 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -92,11 +92,10 @@ ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, : BaseNode(is_top_level_channel ? EntityType::kTopLevelChannel : EntityType::kInternalChannel), channel_(channel), - target_(UniquePtr(grpc_channel_get_target(channel_))) { - trace_.Init(channel_tracer_max_nodes); -} + target_(UniquePtr(grpc_channel_get_target(channel_))), + trace_(channel_tracer_max_nodes) {} -ChannelNode::~ChannelNode() { trace_.Destroy(); } +ChannelNode::~ChannelNode() {} grpc_json* ChannelNode::RenderJson() { // We need to track these three json objects to build our object @@ -123,7 +122,7 @@ grpc_json* ChannelNode::RenderJson() { grpc_json_create_child(nullptr, json, "target", target_.get(), GRPC_JSON_STRING, false); // fill in the channel trace if applicable - grpc_json* trace_json = trace_->RenderJson(); + grpc_json* trace_json = trace_.RenderJson(); if (trace_json != nullptr) { trace_json->key = "trace"; // this object is named trace in channelz.proto grpc_json_link_child(json, trace_json, nullptr); diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 74b203af443..66753c96eec 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -133,12 +133,12 @@ class ChannelNode : public BaseNode { // proxy methods to composed classes. void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { - trace_->AddTraceEvent(severity, data); + trace_.AddTraceEvent(severity, data); } void AddTraceEventWithReference(ChannelTrace::Severity severity, grpc_slice data, RefCountedPtr referenced_channel) { - trace_->AddTraceEventWithReference(severity, data, referenced_channel); + trace_.AddTraceEventWithReference(severity, data, referenced_channel); } void RecordCallStarted() { call_counter_.RecordCallStarted(); } void RecordCallFailed() { call_counter_.RecordCallFailed(); } @@ -150,7 +150,7 @@ class ChannelNode : public BaseNode { // provides access to call_counter_ for child. CallCountingHelper* call_counter() { return &call_counter_; } // provides access to channel trace for child. - ChannelTrace* trace() { return trace_.get(); } + ChannelTrace* trace() { return &trace_; } private: // to allow the channel trace test to access trace(); @@ -158,7 +158,7 @@ class ChannelNode : public BaseNode { grpc_channel* channel_ = nullptr; UniquePtr target_; CallCountingHelper call_counter_; - ManualConstructor trace_; + ChannelTrace trace_; }; // Handles channelz bookkeeping for servers From 016a3354a5d9915dfd8a15822b0874eab6cbc7ba Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 30 Jul 2018 22:45:44 -0700 Subject: [PATCH 055/546] reviewer comments --- .../filters/client_channel/client_channel.cc | 18 +++++++++++++----- .../client_channel/client_channel_channelz.cc | 4 ++-- .../ext/filters/client_channel/subchannel.cc | 3 --- src/core/lib/channel/channelz.cc | 4 ++-- src/core/lib/channel/channelz.h | 2 +- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 888a5efda3f..b3c9268bd87 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1942,11 +1942,14 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { grpc_mdelem* server_pushback_md = nullptr; get_call_status(batch_data, GRPC_ERROR_REF(error), &status, &server_pushback_md); - if (status == GRPC_STATUS_OK) { - calld->pick.connected_subchannel->channelz_subchannel() - ->RecordCallSucceeded(); - } else { - calld->pick.connected_subchannel->channelz_subchannel()->RecordCallFailed(); + grpc_core::channelz::SubchannelNode* channelz_subchannel = + calld->pick.connected_subchannel->channelz_subchannel(); + if (channelz_subchannel != nullptr) { + if (status == GRPC_STATUS_OK) { + channelz_subchannel->RecordCallSucceeded(); + } else { + channelz_subchannel->RecordCallFailed(); + } } if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: call finished, status=%s", chand, @@ -2581,6 +2584,11 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { new_error = grpc_error_add_child(new_error, error); pending_batches_fail(elem, new_error, true /* yield_call_combiner */); } else { + grpc_core::channelz::SubchannelNode* channelz_subchannel = + calld->pick.connected_subchannel->channelz_subchannel(); + if (channelz_subchannel != nullptr) { + channelz_subchannel->RecordCallStarted(); + } if (parent_data_size > 0) { subchannel_call_retry_state* retry_state = static_cast( diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index d904fc28b2a..06b4d2ab956 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -130,7 +130,7 @@ grpc_json* ClientChannelNode::RenderJson() { grpc_json_link_child(json, trace_json, nullptr); } // ask CallCountingHelper to populate trace and call count data. - call_counter()->PopulateCallData(json); + call_counter()->PopulateCallCounts(json); // reset to the top level json = top_level_json; PopulateChildRefs(json); @@ -204,7 +204,7 @@ grpc_json* SubchannelNode::RenderJson() { grpc_json_link_child(json, trace_json, nullptr); } // ask CallCountingHelper to populate trace and call count data. - call_counter_.PopulateCallData(json); + call_counter_.PopulateCallCounts(json); return top_level_json; } diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 639a5fe9dbd..a7df2ee6ccb 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -865,9 +865,6 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, gpr_log(GPR_ERROR, "error: %s", error_string); return error; } - if (channelz_subchannel_ != nullptr) { - channelz_subchannel_->RecordCallStarted(); - } grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); return GRPC_ERROR_NONE; } diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index b908363b1b7..1ac7bd3976d 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -66,7 +66,7 @@ void CallCountingHelper::RecordCallStarted() { (gpr_atm)ExecCtx::Get()->Now()); } -void CallCountingHelper::PopulateCallData(grpc_json* json) { +void CallCountingHelper::PopulateCallCounts(grpc_json* json) { grpc_json* json_iterator = nullptr; if (calls_started_ != 0) { json_iterator = grpc_json_add_number_string_child( @@ -128,7 +128,7 @@ grpc_json* ChannelNode::RenderJson() { grpc_json_link_child(json, trace_json, nullptr); } // ask CallCountingHelper to populate trace and call count data. - call_counter_.PopulateCallData(json); + call_counter_.PopulateCallCounts(json); return top_level_json; } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 66753c96eec..14edc75123b 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -99,7 +99,7 @@ class CallCountingHelper { } // Common rendering of the call count data and last_call_started_timestamp. - void PopulateCallData(grpc_json* json); + void PopulateCallCounts(grpc_json* json); private: // testing peer friend. From 97a5bca26164b0f2c5763018f710ee75a9b817b1 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 31 Jul 2018 10:13:58 -0700 Subject: [PATCH 056/546] reviewer feedback --- src/core/ext/filters/client_channel/client_channel.cc | 4 +--- src/core/ext/filters/client_channel/subchannel.cc | 1 - src/core/ext/filters/client_channel/subchannel.h | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index b3c9268bd87..3ea4b21ebd7 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -892,7 +892,6 @@ typedef struct client_channel_call_data { grpc_millis deadline; gpr_arena* arena; grpc_call_stack* owning_call; - grpc_call* call; grpc_call_combiner* call_combiner; grpc_core::RefCountedPtr retry_throttle_data; @@ -2571,8 +2570,7 @@ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) { calld->arena, // arena calld->pick.subchannel_call_context, // context calld->call_combiner, // call_combiner - parent_data_size, // parent_data_size - calld->call // call + parent_data_size // parent_data_size }; grpc_error* new_error = calld->pick.connected_subchannel->CreateCall( call_args, &calld->subchannel_call); diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index a7df2ee6ccb..abf3a039f36 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -46,7 +46,6 @@ #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/channel_init.h" #include "src/core/lib/transport/connectivity_state.h" diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index d62348488ee..e3d9296c262 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -83,7 +83,6 @@ class ConnectedSubchannel : public RefCountedWithTracing { grpc_call_context_element* context; grpc_call_combiner* call_combiner; size_t parent_data_size; - grpc_call* call; }; explicit ConnectedSubchannel(grpc_channel_stack* channel_stack, From bdd13cb0aef7d3f6dbc467148b4b3158485359eb Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 1 Aug 2018 11:22:40 -0700 Subject: [PATCH 057/546] Revert "Revert "Restrict the number of threads in C++ sync server"" --- grpc.def | 1 + include/grpc/grpc.h | 4 + include/grpcpp/resource_quota.h | 16 +- include/grpcpp/server.h | 3 +- src/core/lib/iomgr/resource_quota.cc | 78 +++++++++ src/core/lib/iomgr/resource_quota.h | 16 ++ src/cpp/common/resource_quota_cc.cc | 4 + src/cpp/server/server_builder.cc | 2 +- src/cpp/server/server_cc.cc | 31 +++- src/cpp/thread_manager/thread_manager.cc | 53 +++++-- src/cpp/thread_manager/thread_manager.h | 48 +++++- src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 + src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 + test/core/iomgr/resource_quota_test.cc | 97 ++++++++++++ .../core/surface/public_headers_must_be_c89.c | 1 + .../cpp/thread_manager/thread_manager_test.cc | 149 +++++++++++++----- 16 files changed, 445 insertions(+), 63 deletions(-) diff --git a/grpc.def b/grpc.def index 5b98792662c..312e9166824 100644 --- a/grpc.def +++ b/grpc.def @@ -68,6 +68,7 @@ EXPORTS grpc_resource_quota_ref grpc_resource_quota_unref grpc_resource_quota_resize + grpc_resource_quota_set_max_threads grpc_resource_quota_arg_vtable grpc_channelz_get_top_channels grpc_channelz_get_channel diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index f0eb2c0121b..eb0251443c1 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -450,6 +450,10 @@ GRPCAPI void grpc_resource_quota_unref(grpc_resource_quota* resource_quota); GRPCAPI void grpc_resource_quota_resize(grpc_resource_quota* resource_quota, size_t new_size); +/** Update the size of the maximum number of threads allowed */ +GRPCAPI void grpc_resource_quota_set_max_threads( + grpc_resource_quota* resource_quota, int new_max_threads); + /** Fetch a vtable for a grpc_channel_arg that points to a grpc_resource_quota */ GRPCAPI const grpc_arg_pointer_vtable* grpc_resource_quota_arg_vtable(void); diff --git a/include/grpcpp/resource_quota.h b/include/grpcpp/resource_quota.h index 554437a40d1..50bd1cb849a 100644 --- a/include/grpcpp/resource_quota.h +++ b/include/grpcpp/resource_quota.h @@ -26,10 +26,10 @@ struct grpc_resource_quota; namespace grpc { -/// ResourceQuota represents a bound on memory usage by the gRPC library. -/// A ResourceQuota can be attached to a server (via \a ServerBuilder), +/// ResourceQuota represents a bound on memory and thread usage by the gRPC +/// library. A ResourceQuota can be attached to a server (via \a ServerBuilder), /// or a client channel (via \a ChannelArguments). -/// gRPC will attempt to keep memory used by all attached entities +/// gRPC will attempt to keep memory and threads used by all attached entities /// below the ResourceQuota bound. class ResourceQuota final : private GrpcLibraryCodegen { public: @@ -44,6 +44,16 @@ class ResourceQuota final : private GrpcLibraryCodegen { /// No time bound is given for this to occur however. ResourceQuota& Resize(size_t new_size); + /// Set the max number of threads that can be allocated from this + /// ResourceQuota object. + /// + /// If the new_max_threads value is smaller than the current value, no new + /// threads are allocated until the number of active threads fall below + /// new_max_threads. There is no time bound on when this may happen i.e none + /// of the current threads are forcefully destroyed and all threads run their + /// normal course. + ResourceQuota& SetMaxThreads(int new_max_threads); + grpc_resource_quota* c_resource_quota() const { return impl_; } private: diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 81c3907f86d..189cf8accf7 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -144,7 +144,8 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { Server(int max_message_size, ChannelArguments* args, std::shared_ptr>> sync_server_cqs, - int min_pollers, int max_pollers, int sync_cq_timeout_msec); + grpc_resource_quota* server_rq, int min_pollers, int max_pollers, + int sync_cq_timeout_msec); /// Start the server. /// diff --git a/src/core/lib/iomgr/resource_quota.cc b/src/core/lib/iomgr/resource_quota.cc index 539bc120cec..b6fc7579f7e 100644 --- a/src/core/lib/iomgr/resource_quota.cc +++ b/src/core/lib/iomgr/resource_quota.cc @@ -96,6 +96,9 @@ struct grpc_resource_user { list, false otherwise */ bool added_to_free_pool; + /* The number of threads currently allocated to this resource user */ + gpr_atm num_threads_allocated; + /* Reclaimers: index 0 is the benign reclaimer, 1 is the destructive reclaimer */ grpc_closure* reclaimers[2]; @@ -135,12 +138,33 @@ struct grpc_resource_quota { gpr_atm last_size; + /* Mutex to protect max_threads and num_threads_allocated */ + /* Note: We could have used gpr_atm for max_threads and num_threads_allocated + * and avoid having this mutex; but in that case, each invocation of the + * function grpc_resource_user_allocate_threads() would have had to do at + * least two atomic loads (for max_threads and num_threads_allocated) followed + * by a CAS (on num_threads_allocated). + * Moreover, we expect grpc_resource_user_allocate_threads() to be often + * called concurrently thereby increasing the chances of failing the CAS + * operation. This additional complexity is not worth the tiny perf gain we + * may (or may not) have by using atomics */ + gpr_mu thread_count_mu; + + /* Max number of threads allowed */ + int max_threads; + + /* Number of threads currently allocated via this resource_quota object */ + int num_threads_allocated; + /* Has rq_step been scheduled to occur? */ bool step_scheduled; + /* Are we currently reclaiming memory */ bool reclaiming; + /* Closure around rq_step */ grpc_closure rq_step_closure; + /* Closure around rq_reclamation_done */ grpc_closure rq_reclamation_done_closure; @@ -524,6 +548,11 @@ static void ru_shutdown(void* ru, grpc_error* error) { static void ru_destroy(void* ru, grpc_error* error) { grpc_resource_user* resource_user = static_cast(ru); GPR_ASSERT(gpr_atm_no_barrier_load(&resource_user->refs) == 0); + // Free all the remaining thread quota + grpc_resource_user_free_threads(resource_user, + static_cast(gpr_atm_no_barrier_load( + &resource_user->num_threads_allocated))); + for (int i = 0; i < GRPC_RULIST_COUNT; i++) { rulist_remove(resource_user, static_cast(i)); } @@ -594,6 +623,9 @@ grpc_resource_quota* grpc_resource_quota_create(const char* name) { resource_quota->free_pool = INT64_MAX; resource_quota->size = INT64_MAX; gpr_atm_no_barrier_store(&resource_quota->last_size, GPR_ATM_MAX); + gpr_mu_init(&resource_quota->thread_count_mu); + resource_quota->max_threads = INT_MAX; + resource_quota->num_threads_allocated = 0; resource_quota->step_scheduled = false; resource_quota->reclaiming = false; gpr_atm_no_barrier_store(&resource_quota->memory_usage_estimation, 0); @@ -616,6 +648,8 @@ grpc_resource_quota* grpc_resource_quota_create(const char* name) { void grpc_resource_quota_unref_internal(grpc_resource_quota* resource_quota) { if (gpr_unref(&resource_quota->refs)) { + // No outstanding thread quota + GPR_ASSERT(resource_quota->num_threads_allocated == 0); GRPC_COMBINER_UNREF(resource_quota->combiner, "resource_quota"); gpr_free(resource_quota->name); gpr_free(resource_quota); @@ -646,6 +680,15 @@ double grpc_resource_quota_get_memory_pressure( (static_cast(MEMORY_USAGE_ESTIMATION_MAX)); } +/* Public API */ +void grpc_resource_quota_set_max_threads(grpc_resource_quota* resource_quota, + int new_max_threads) { + GPR_ASSERT(new_max_threads >= 0); + gpr_mu_lock(&resource_quota->thread_count_mu); + resource_quota->max_threads = new_max_threads; + gpr_mu_unlock(&resource_quota->thread_count_mu); +} + /* Public API */ void grpc_resource_quota_resize(grpc_resource_quota* resource_quota, size_t size) { @@ -731,6 +774,7 @@ grpc_resource_user* grpc_resource_user_create( grpc_closure_list_init(&resource_user->on_allocated); resource_user->allocating = false; resource_user->added_to_free_pool = false; + gpr_atm_no_barrier_store(&resource_user->num_threads_allocated, 0); resource_user->reclaimers[0] = nullptr; resource_user->reclaimers[1] = nullptr; resource_user->new_reclaimers[0] = nullptr; @@ -785,6 +829,40 @@ void grpc_resource_user_shutdown(grpc_resource_user* resource_user) { } } +bool grpc_resource_user_allocate_threads(grpc_resource_user* resource_user, + int thread_count) { + GPR_ASSERT(thread_count >= 0); + bool is_success = false; + gpr_mu_lock(&resource_user->resource_quota->thread_count_mu); + grpc_resource_quota* rq = resource_user->resource_quota; + if (rq->num_threads_allocated + thread_count <= rq->max_threads) { + rq->num_threads_allocated += thread_count; + gpr_atm_no_barrier_fetch_add(&resource_user->num_threads_allocated, + thread_count); + is_success = true; + } + gpr_mu_unlock(&resource_user->resource_quota->thread_count_mu); + return is_success; +} + +void grpc_resource_user_free_threads(grpc_resource_user* resource_user, + int thread_count) { + GPR_ASSERT(thread_count >= 0); + gpr_mu_lock(&resource_user->resource_quota->thread_count_mu); + grpc_resource_quota* rq = resource_user->resource_quota; + rq->num_threads_allocated -= thread_count; + int old_count = static_cast(gpr_atm_no_barrier_fetch_add( + &resource_user->num_threads_allocated, -thread_count)); + if (old_count < thread_count || rq->num_threads_allocated < 0) { + gpr_log(GPR_ERROR, + "Releasing more threads (%d) than currently allocated (rq threads: " + "%d, ru threads: %d)", + thread_count, rq->num_threads_allocated + thread_count, old_count); + abort(); + } + gpr_mu_unlock(&resource_user->resource_quota->thread_count_mu); +} + void grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size, grpc_closure* optional_on_done) { gpr_mu_lock(&resource_user->mu); diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h index 937daf87282..1d5e95e04a4 100644 --- a/src/core/lib/iomgr/resource_quota.h +++ b/src/core/lib/iomgr/resource_quota.h @@ -93,6 +93,22 @@ void grpc_resource_user_ref(grpc_resource_user* resource_user); void grpc_resource_user_unref(grpc_resource_user* resource_user); void grpc_resource_user_shutdown(grpc_resource_user* resource_user); +/* Attempts to get quota (from the resource_user) to create 'thd_count' number + * of threads. Returns true if successful (i.e the caller is now free to create + * 'thd_count' number of threads) or false if quota is not available */ +bool grpc_resource_user_allocate_threads(grpc_resource_user* resource_user, + int thd_count); +/* Releases 'thd_count' worth of quota back to the resource user. The quota + * should have been previously obtained successfully by calling + * grpc_resource_user_allocate_threads(). + * + * Note: There need not be an exact one-to-one correspondence between + * grpc_resource_user_allocate_threads() and grpc_resource_user_free_threads() + * calls. The only requirement is that the number of threads allocated should + * all be eventually released */ +void grpc_resource_user_free_threads(grpc_resource_user* resource_user, + int thd_count); + /* Allocate from the resource user (and its quota). If optional_on_done is NULL, then allocate immediately. This may push the quota over-limit, at which point reclamation will kick in. diff --git a/src/cpp/common/resource_quota_cc.cc b/src/cpp/common/resource_quota_cc.cc index daeb0ba171c..276e5f79548 100644 --- a/src/cpp/common/resource_quota_cc.cc +++ b/src/cpp/common/resource_quota_cc.cc @@ -33,4 +33,8 @@ ResourceQuota& ResourceQuota::Resize(size_t new_size) { return *this; } +ResourceQuota& ResourceQuota::SetMaxThreads(int new_max_threads) { + grpc_resource_quota_set_max_threads(impl_, new_max_threads); + return *this; +} } // namespace grpc diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index e0b9b7a62bd..0ab3cd0e323 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -261,7 +261,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { } std::unique_ptr server(new Server( - max_receive_message_size_, &args, sync_server_cqs, + max_receive_message_size_, &args, sync_server_cqs, resource_quota_, sync_server_settings_.min_pollers, sync_server_settings_.max_pollers, sync_server_settings_.cq_timeout_msec)); diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 0d77510e29d..472c5035fc1 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -47,6 +47,12 @@ namespace grpc { namespace { +// The default value for maximum number of threads that can be created in the +// sync server. This value of 500 is empirically chosen. To increase the max +// number of threads in a sync server, pass a custom ResourceQuota object (with +// the desired number of max-threads set) to the server builder +#define DEFAULT_MAX_SYNC_SERVER_THREADS 500 + class DefaultGlobalCallbacks final : public Server::GlobalCallbacks { public: ~DefaultGlobalCallbacks() override {} @@ -266,9 +272,9 @@ class Server::SyncRequestThreadManager : public ThreadManager { public: SyncRequestThreadManager(Server* server, CompletionQueue* server_cq, std::shared_ptr global_callbacks, - int min_pollers, int max_pollers, - int cq_timeout_msec) - : ThreadManager(min_pollers, max_pollers), + grpc_resource_quota* rq, int min_pollers, + int max_pollers, int cq_timeout_msec) + : ThreadManager("SyncServer", rq, min_pollers, max_pollers), server_(server), server_cq_(server_cq), cq_timeout_msec_(cq_timeout_msec), @@ -376,7 +382,8 @@ Server::Server( int max_receive_message_size, ChannelArguments* args, std::shared_ptr>> sync_server_cqs, - int min_pollers, int max_pollers, int sync_cq_timeout_msec) + grpc_resource_quota* server_rq, int min_pollers, int max_pollers, + int sync_cq_timeout_msec) : max_receive_message_size_(max_receive_message_size), sync_server_cqs_(std::move(sync_server_cqs)), started_(false), @@ -392,10 +399,22 @@ Server::Server( global_callbacks_->UpdateArguments(args); if (sync_server_cqs_ != nullptr) { + bool default_rq_created = false; + if (server_rq == nullptr) { + server_rq = grpc_resource_quota_create("SyncServer-default-rq"); + grpc_resource_quota_set_max_threads(server_rq, + DEFAULT_MAX_SYNC_SERVER_THREADS); + default_rq_created = true; + } + for (const auto& it : *sync_server_cqs_) { sync_req_mgrs_.emplace_back(new SyncRequestThreadManager( - this, it.get(), global_callbacks_, min_pollers, max_pollers, - sync_cq_timeout_msec)); + this, it.get(), global_callbacks_, server_rq, min_pollers, + max_pollers, sync_cq_timeout_msec)); + } + + if (default_rq_created) { + grpc_resource_quota_unref(server_rq); } } diff --git a/src/cpp/thread_manager/thread_manager.cc b/src/cpp/thread_manager/thread_manager.cc index 02ac56a3fdc..fa9eec5f9ba 100644 --- a/src/cpp/thread_manager/thread_manager.cc +++ b/src/cpp/thread_manager/thread_manager.cc @@ -22,8 +22,8 @@ #include #include - #include "src/core/lib/gprpp/thd.h" +#include "src/core/lib/iomgr/exec_ctx.h" namespace grpc { @@ -48,12 +48,17 @@ ThreadManager::WorkerThread::~WorkerThread() { thd_.Join(); } -ThreadManager::ThreadManager(int min_pollers, int max_pollers) +ThreadManager::ThreadManager(const char* name, + grpc_resource_quota* resource_quota, + int min_pollers, int max_pollers) : shutdown_(false), num_pollers_(0), min_pollers_(min_pollers), max_pollers_(max_pollers == -1 ? INT_MAX : max_pollers), - num_threads_(0) {} + num_threads_(0), + max_active_threads_sofar_(0) { + resource_user_ = grpc_resource_user_create(resource_quota, name); +} ThreadManager::~ThreadManager() { { @@ -61,6 +66,8 @@ ThreadManager::~ThreadManager() { GPR_ASSERT(num_threads_ == 0); } + grpc_core::ExecCtx exec_ctx; // grpc_resource_user_unref needs an exec_ctx + grpc_resource_user_unref(resource_user_); CleanupCompletedThreads(); } @@ -81,17 +88,27 @@ bool ThreadManager::IsShutdown() { return shutdown_; } +int ThreadManager::GetMaxActiveThreadsSoFar() { + std::lock_guard list_lock(list_mu_); + return max_active_threads_sofar_; +} + void ThreadManager::MarkAsCompleted(WorkerThread* thd) { { std::lock_guard list_lock(list_mu_); completed_threads_.push_back(thd); } - std::lock_guard lock(mu_); - num_threads_--; - if (num_threads_ == 0) { - shutdown_cv_.notify_one(); + { + std::lock_guard lock(mu_); + num_threads_--; + if (num_threads_ == 0) { + shutdown_cv_.notify_one(); + } } + + // Give a thread back to the resource quota + grpc_resource_user_free_threads(resource_user_, 1); } void ThreadManager::CleanupCompletedThreads() { @@ -106,14 +123,22 @@ void ThreadManager::CleanupCompletedThreads() { } void ThreadManager::Initialize() { + if (!grpc_resource_user_allocate_threads(resource_user_, min_pollers_)) { + gpr_log(GPR_ERROR, + "No thread quota available to even create the minimum required " + "polling threads (i.e %d). Unable to start the thread manager", + min_pollers_); + abort(); + } + { std::unique_lock lock(mu_); num_pollers_ = min_pollers_; num_threads_ = min_pollers_; + max_active_threads_sofar_ = min_pollers_; } for (int i = 0; i < min_pollers_; i++) { - // Create a new thread (which ends up calling the MainWorkLoop() function new WorkerThread(this); } } @@ -139,11 +164,15 @@ void ThreadManager::MainWorkLoop() { done = true; break; case WORK_FOUND: - // If we got work and there are now insufficient pollers, start a new - // one - if (!shutdown_ && num_pollers_ < min_pollers_) { + // If we got work and there are now insufficient pollers and there is + // quota available to create a new thread, start a new poller thread + if (!shutdown_ && num_pollers_ < min_pollers_ && + grpc_resource_user_allocate_threads(resource_user_, 1)) { num_pollers_++; num_threads_++; + if (num_threads_ > max_active_threads_sofar_) { + max_active_threads_sofar_ = num_threads_; + } // Drop lock before spawning thread to avoid contention lock.unlock(); new WorkerThread(this); @@ -196,6 +225,8 @@ void ThreadManager::MainWorkLoop() { } }; + // This thread is exiting. Do some cleanup work i.e delete already completed + // worker threads CleanupCompletedThreads(); // If we are here, either ThreadManager is shutting down or it already has diff --git a/src/cpp/thread_manager/thread_manager.h b/src/cpp/thread_manager/thread_manager.h index 5a40f2de477..01043edb31e 100644 --- a/src/cpp/thread_manager/thread_manager.h +++ b/src/cpp/thread_manager/thread_manager.h @@ -27,12 +27,14 @@ #include #include "src/core/lib/gprpp/thd.h" +#include "src/core/lib/iomgr/resource_quota.h" namespace grpc { class ThreadManager { public: - explicit ThreadManager(int min_pollers, int max_pollers); + explicit ThreadManager(const char* name, grpc_resource_quota* resource_quota, + int min_pollers, int max_pollers); virtual ~ThreadManager(); // Initializes and Starts the Rpc Manager threads @@ -84,6 +86,11 @@ class ThreadManager { // all the threads have drained all the outstanding work virtual void Wait(); + // Max number of concurrent threads that were ever active in this thread + // manager so far. This is useful for debugging purposes (and in unit tests) + // to check if resource_quota is properly being enforced. + int GetMaxActiveThreadsSoFar(); + private: // Helper wrapper class around grpc_core::Thread. Takes a ThreadManager object // and starts a new grpc_core::Thread to calls the Run() function. @@ -91,6 +98,24 @@ class ThreadManager { // The Run() function calls ThreadManager::MainWorkLoop() function and once // that completes, it marks the WorkerThread completed by calling // ThreadManager::MarkAsCompleted() + // + // WHY IS THIS NEEDED?: + // When a thread terminates, some other thread *must* call Join() on that + // thread so that the resources are released. Having a WorkerThread wrapper + // will make this easier. Once Run() completes, each thread calls the + // following two functions: + // ThreadManager::CleanupCompletedThreads() + // ThreadManager::MarkAsCompleted() + // + // - MarkAsCompleted() puts the WorkerThread object in the ThreadManger's + // completed_threads_ list + // - CleanupCompletedThreads() calls "Join()" on the threads that are already + // in the completed_threads_ list (since a thread cannot call Join() on + // itself, it calls CleanupCompletedThreads() *before* calling + // MarkAsCompleted()) + // + // TODO(sreek): Consider creating the threads 'detached' so that Join() need + // not be called (and the need for this WorkerThread class is eliminated) class WorkerThread { public: WorkerThread(ThreadManager* thd_mgr); @@ -111,13 +136,21 @@ class ThreadManager { void MarkAsCompleted(WorkerThread* thd); void CleanupCompletedThreads(); - // Protects shutdown_, num_pollers_ and num_threads_ - // TODO: sreek - Change num_pollers and num_threads_ to atomics + // Protects shutdown_, num_pollers_, num_threads_ and + // max_active_threads_sofar_ std::mutex mu_; bool shutdown_; std::condition_variable shutdown_cv_; + // The resource user object to use when requesting quota to create threads + // + // Note: The user of this ThreadManager object must create grpc_resource_quota + // object (that contains the actual max thread quota) and a grpc_resource_user + // object through which quota is requested whenver new threads need to be + // created + grpc_resource_user* resource_user_; + // Number of threads doing polling int num_pollers_; @@ -125,10 +158,15 @@ class ThreadManager { int min_pollers_; int max_pollers_; - // The total number of threads (includes threads includes the threads that are - // currently polling i.e num_pollers_) + // The total number of threads currently active (includes threads includes the + // threads that are currently polling i.e num_pollers_) int num_threads_; + // See GetMaxActiveThreadsSoFar()'s description. + // To be more specific, this variable tracks the max value num_threads_ was + // ever set so far + int max_active_threads_sofar_; + std::mutex list_mu_; std::list completed_threads_; }; diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 2443532bb8e..78090afd6c4 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -91,6 +91,7 @@ grpc_resource_quota_create_type grpc_resource_quota_create_import; grpc_resource_quota_ref_type grpc_resource_quota_ref_import; grpc_resource_quota_unref_type grpc_resource_quota_unref_import; grpc_resource_quota_resize_type grpc_resource_quota_resize_import; +grpc_resource_quota_set_max_threads_type grpc_resource_quota_set_max_threads_import; grpc_resource_quota_arg_vtable_type grpc_resource_quota_arg_vtable_import; grpc_channelz_get_top_channels_type grpc_channelz_get_top_channels_import; grpc_channelz_get_channel_type grpc_channelz_get_channel_import; @@ -341,6 +342,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_resource_quota_ref_import = (grpc_resource_quota_ref_type) GetProcAddress(library, "grpc_resource_quota_ref"); grpc_resource_quota_unref_import = (grpc_resource_quota_unref_type) GetProcAddress(library, "grpc_resource_quota_unref"); grpc_resource_quota_resize_import = (grpc_resource_quota_resize_type) GetProcAddress(library, "grpc_resource_quota_resize"); + grpc_resource_quota_set_max_threads_import = (grpc_resource_quota_set_max_threads_type) GetProcAddress(library, "grpc_resource_quota_set_max_threads"); grpc_resource_quota_arg_vtable_import = (grpc_resource_quota_arg_vtable_type) GetProcAddress(library, "grpc_resource_quota_arg_vtable"); grpc_channelz_get_top_channels_import = (grpc_channelz_get_top_channels_type) GetProcAddress(library, "grpc_channelz_get_top_channels"); grpc_channelz_get_channel_import = (grpc_channelz_get_channel_type) GetProcAddress(library, "grpc_channelz_get_channel"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index b08a1f94f7b..1807efa761e 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -248,6 +248,9 @@ extern grpc_resource_quota_unref_type grpc_resource_quota_unref_import; typedef void(*grpc_resource_quota_resize_type)(grpc_resource_quota* resource_quota, size_t new_size); extern grpc_resource_quota_resize_type grpc_resource_quota_resize_import; #define grpc_resource_quota_resize grpc_resource_quota_resize_import +typedef void(*grpc_resource_quota_set_max_threads_type)(grpc_resource_quota* resource_quota, int new_max_threads); +extern grpc_resource_quota_set_max_threads_type grpc_resource_quota_set_max_threads_import; +#define grpc_resource_quota_set_max_threads grpc_resource_quota_set_max_threads_import typedef const grpc_arg_pointer_vtable*(*grpc_resource_quota_arg_vtable_type)(void); extern grpc_resource_quota_arg_vtable_type grpc_resource_quota_arg_vtable_import; #define grpc_resource_quota_arg_vtable grpc_resource_quota_arg_vtable_import diff --git a/test/core/iomgr/resource_quota_test.cc b/test/core/iomgr/resource_quota_test.cc index 059ff7b5f8b..f3b35fed327 100644 --- a/test/core/iomgr/resource_quota_test.cc +++ b/test/core/iomgr/resource_quota_test.cc @@ -798,6 +798,98 @@ static void test_negative_rq_free_pool(void) { } } +// Simple test to check resource quota thread limits +static void test_thread_limit() { + grpc_core::ExecCtx exec_ctx; + + grpc_resource_quota* rq = grpc_resource_quota_create("test_thread_limit"); + grpc_resource_user* ru1 = grpc_resource_user_create(rq, "ru1"); + grpc_resource_user* ru2 = grpc_resource_user_create(rq, "ru2"); + + // Max threads = 100 + grpc_resource_quota_set_max_threads(rq, 100); + + // Request quota for 100 threads (50 for ru1, 50 for ru2) + GPR_ASSERT(grpc_resource_user_allocate_threads(ru1, 10)); + GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 10)); + GPR_ASSERT(grpc_resource_user_allocate_threads(ru1, 40)); + GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 40)); + + // Threads exhausted. Next request must fail + GPR_ASSERT(!grpc_resource_user_allocate_threads(ru2, 20)); + + // Free 20 threads from two different users + grpc_resource_user_free_threads(ru1, 10); + grpc_resource_user_free_threads(ru2, 10); + + // Next request to 20 threads must succeed + GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 20)); + + // No more thread quota again + GPR_ASSERT(!grpc_resource_user_allocate_threads(ru1, 20)); + + // Free 10 more + grpc_resource_user_free_threads(ru1, 10); + + GPR_ASSERT(grpc_resource_user_allocate_threads(ru1, 5)); + GPR_ASSERT( + !grpc_resource_user_allocate_threads(ru2, 10)); // Only 5 available + GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 5)); + + // Teardown (ru1 and ru2 release all the quota back to rq) + grpc_resource_user_unref(ru1); + grpc_resource_user_unref(ru2); + grpc_resource_quota_unref(rq); +} + +// Change max quota in either direction dynamically +static void test_thread_maxquota_change() { + grpc_core::ExecCtx exec_ctx; + + grpc_resource_quota* rq = + grpc_resource_quota_create("test_thread_maxquota_change"); + grpc_resource_user* ru1 = grpc_resource_user_create(rq, "ru1"); + grpc_resource_user* ru2 = grpc_resource_user_create(rq, "ru2"); + + // Max threads = 100 + grpc_resource_quota_set_max_threads(rq, 100); + + // Request quota for 100 threads (50 for ru1, 50 for ru2) + GPR_ASSERT(grpc_resource_user_allocate_threads(ru1, 50)); + GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 50)); + + // Threads exhausted. Next request must fail + GPR_ASSERT(!grpc_resource_user_allocate_threads(ru2, 20)); + + // Increase maxquota and retry + // Max threads = 150; + grpc_resource_quota_set_max_threads(rq, 150); + GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 20)); // ru2=70, ru1=50 + + // Decrease maxquota (Note: Quota already given to ru1 and ru2 is unaffected) + // Max threads = 10; + grpc_resource_quota_set_max_threads(rq, 10); + + // New requests will fail until quota is available + GPR_ASSERT(!grpc_resource_user_allocate_threads(ru1, 10)); + + // Make quota available + grpc_resource_user_free_threads(ru1, 50); // ru1 now has 0 + GPR_ASSERT(!grpc_resource_user_allocate_threads(ru1, 10)); // not enough + + grpc_resource_user_free_threads(ru2, 70); // ru2 now has 0 + + // Now we can get quota up-to 10, the current max + GPR_ASSERT(grpc_resource_user_allocate_threads(ru2, 10)); + // No more thread quota again + GPR_ASSERT(!grpc_resource_user_allocate_threads(ru1, 10)); + + // Teardown (ru1 and ru2 release all the quota back to rq) + grpc_resource_user_unref(ru1); + grpc_resource_user_unref(ru2); + grpc_resource_quota_unref(rq); +} + int main(int argc, char** argv) { grpc_test_init(argc, argv); grpc_init(); @@ -827,6 +919,11 @@ int main(int argc, char** argv) { test_negative_rq_free_pool(); gpr_mu_destroy(&g_mu); gpr_cv_destroy(&g_cv); + + // Resource quota thread related + test_thread_limit(); + test_thread_maxquota_change(); + grpc_shutdown(); return 0; } diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 9f4ad2b4d75..497f7194d57 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -130,6 +130,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_resource_quota_ref); printf("%lx", (unsigned long) grpc_resource_quota_unref); printf("%lx", (unsigned long) grpc_resource_quota_resize); + printf("%lx", (unsigned long) grpc_resource_quota_set_max_threads); printf("%lx", (unsigned long) grpc_resource_quota_arg_vtable); printf("%lx", (unsigned long) grpc_channelz_get_top_channels); printf("%lx", (unsigned long) grpc_channelz_get_channel); diff --git a/test/cpp/thread_manager/thread_manager_test.cc b/test/cpp/thread_manager/thread_manager_test.cc index 7a95a9f17da..838f5f72adb 100644 --- a/test/cpp/thread_manager/thread_manager_test.cc +++ b/test/cpp/thread_manager/thread_manager_test.cc @@ -30,30 +30,44 @@ #include "test/cpp/util/test_config.h" namespace grpc { + +struct ThreadManagerTestSettings { + // The min number of pollers that SHOULD be active in ThreadManager + int min_pollers; + // The max number of pollers that could be active in ThreadManager + int max_pollers; + // The sleep duration in PollForWork() function to simulate "polling" + int poll_duration_ms; + // The sleep duration in DoWork() function to simulate "work" + int work_duration_ms; + // Max number of times PollForWork() is called before shutting down + int max_poll_calls; +}; + class ThreadManagerTest final : public grpc::ThreadManager { public: - ThreadManagerTest() - : ThreadManager(kMinPollers, kMaxPollers), + ThreadManagerTest(const char* name, grpc_resource_quota* rq, + const ThreadManagerTestSettings& settings) + : ThreadManager(name, rq, settings.min_pollers, settings.max_pollers), + settings_(settings), num_do_work_(0), num_poll_for_work_(0), num_work_found_(0) {} grpc::ThreadManager::WorkStatus PollForWork(void** tag, bool* ok) override; void DoWork(void* tag, bool ok) override; - void PerformTest(); + + // Get number of times PollForWork() returned WORK_FOUND + int GetNumWorkFound(); + // Get number of times DoWork() was called + int GetNumDoWork(); private: void SleepForMs(int sleep_time_ms); - static const int kMinPollers = 2; - static const int kMaxPollers = 10; - - static const int kPollingTimeoutMsec = 10; - static const int kDoWorkDurationMsec = 1; - - // PollForWork will return SHUTDOWN after these many number of invocations - static const int kMaxNumPollForWork = 50; + ThreadManagerTestSettings settings_; + // Counters gpr_atm num_do_work_; // Number of calls to DoWork gpr_atm num_poll_for_work_; // Number of calls to PollForWork gpr_atm num_work_found_; // Number of times WORK_FOUND was returned @@ -69,54 +83,117 @@ void ThreadManagerTest::SleepForMs(int duration_ms) { grpc::ThreadManager::WorkStatus ThreadManagerTest::PollForWork(void** tag, bool* ok) { int call_num = gpr_atm_no_barrier_fetch_add(&num_poll_for_work_, 1); - - if (call_num >= kMaxNumPollForWork) { + if (call_num >= settings_.max_poll_calls) { Shutdown(); return SHUTDOWN; } - // Simulate "polling for work" by sleeping for sometime - SleepForMs(kPollingTimeoutMsec); - + SleepForMs(settings_.poll_duration_ms); // Simulate "polling" duration *tag = nullptr; *ok = true; - // Return timeout roughly 1 out of every 3 calls + // Return timeout roughly 1 out of every 3 calls just to make the test a bit + // more interesting if (call_num % 3 == 0) { return TIMEOUT; - } else { - gpr_atm_no_barrier_fetch_add(&num_work_found_, 1); - return WORK_FOUND; } + + gpr_atm_no_barrier_fetch_add(&num_work_found_, 1); + return WORK_FOUND; } void ThreadManagerTest::DoWork(void* tag, bool ok) { gpr_atm_no_barrier_fetch_add(&num_do_work_, 1); - SleepForMs(kDoWorkDurationMsec); // Simulate doing work by sleeping + SleepForMs(settings_.work_duration_ms); // Simulate work by sleeping } -void ThreadManagerTest::PerformTest() { - // Initialize() starts the ThreadManager - Initialize(); - - // Wait for all the threads to gracefully terminate - Wait(); +int ThreadManagerTest::GetNumWorkFound() { + return static_cast(gpr_atm_no_barrier_load(&num_work_found_)); +} - // The number of times DoWork() was called is equal to the number of times - // WORK_FOUND was returned - gpr_log(GPR_DEBUG, "DoWork() called %" PRIdPTR " times", - gpr_atm_no_barrier_load(&num_do_work_)); - GPR_ASSERT(gpr_atm_no_barrier_load(&num_do_work_) == - gpr_atm_no_barrier_load(&num_work_found_)); +int ThreadManagerTest::GetNumDoWork() { + return static_cast(gpr_atm_no_barrier_load(&num_do_work_)); } } // namespace grpc +// Test that the number of times DoWork() is called is equal to the number of +// times PollForWork() returned WORK_FOUND +static void TestPollAndWork() { + grpc_resource_quota* rq = grpc_resource_quota_create("Test-poll-and-work"); + grpc::ThreadManagerTestSettings settings = { + 2 /* min_pollers */, 10 /* max_pollers */, 10 /* poll_duration_ms */, + 1 /* work_duration_ms */, 50 /* max_poll_calls */}; + + grpc::ThreadManagerTest test_thread_mgr("TestThreadManager", rq, settings); + grpc_resource_quota_unref(rq); + + test_thread_mgr.Initialize(); // Start the thread manager + test_thread_mgr.Wait(); // Wait for all threads to finish + + // Verify that The number of times DoWork() was called is equal to the number + // of times WORK_FOUND was returned + gpr_log(GPR_DEBUG, "DoWork() called %d times", + test_thread_mgr.GetNumDoWork()); + GPR_ASSERT(test_thread_mgr.GetNumDoWork() == + test_thread_mgr.GetNumWorkFound()); +} + +static void TestThreadQuota() { + const int kMaxNumThreads = 3; + grpc_resource_quota* rq = grpc_resource_quota_create("Test-thread-quota"); + grpc_resource_quota_set_max_threads(rq, kMaxNumThreads); + + // Set work_duration_ms to be much greater than poll_duration_ms. This way, + // the thread manager will be forced to create more 'polling' threads to + // honor the min_pollers guarantee + grpc::ThreadManagerTestSettings settings = { + 1 /* min_pollers */, 1 /* max_pollers */, 1 /* poll_duration_ms */, + 10 /* work_duration_ms */, 50 /* max_poll_calls */}; + + // Create two thread managers (but with same resource quota). This means + // that the max number of active threads across BOTH the thread managers + // cannot be greater than kMaxNumthreads + grpc::ThreadManagerTest test_thread_mgr_1("TestThreadManager-1", rq, + settings); + grpc::ThreadManagerTest test_thread_mgr_2("TestThreadManager-2", rq, + settings); + // It is ok to unref resource quota before starting thread managers. + grpc_resource_quota_unref(rq); + + // Start both thread managers + test_thread_mgr_1.Initialize(); + test_thread_mgr_2.Initialize(); + + // Wait for both to finish + test_thread_mgr_1.Wait(); + test_thread_mgr_2.Wait(); + + // Now verify that the total number of active threads in either thread manager + // never exceeds kMaxNumThreads + // + // NOTE: Actually the total active threads across *both* thread managers at + // any point of time never exceeds kMaxNumThreads but unfortunately there is + // no easy way to verify it (i.e we can't just do (max1 + max2 <= k)) + // Its okay to not test this case here. The resource quota c-core tests + // provide enough coverage to resource quota object with multiple resource + // users + int max1 = test_thread_mgr_1.GetMaxActiveThreadsSoFar(); + int max2 = test_thread_mgr_2.GetMaxActiveThreadsSoFar(); + gpr_log( + GPR_DEBUG, + "MaxActiveThreads in TestThreadManager_1: %d, TestThreadManager_2: %d", + max1, max2); + GPR_ASSERT(max1 <= kMaxNumThreads && max2 <= kMaxNumThreads); +} + int main(int argc, char** argv) { std::srand(std::time(nullptr)); - grpc::testing::InitTest(&argc, &argv, true); - grpc::ThreadManagerTest test_rpc_manager; - test_rpc_manager.PerformTest(); + grpc_init(); + + TestPollAndWork(); + TestThreadQuota(); + grpc_shutdown(); return 0; } From 9ce673f86176a203811c0429872a2acf639f5285 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 1 Aug 2018 12:12:46 -0700 Subject: [PATCH 058/546] Make resource quota argument optional to the Server constructor --- include/grpcpp/server.h | 8 ++++++-- src/cpp/server/server_builder.cc | 4 ++-- src/cpp/server/server_cc.cc | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 189cf8accf7..5fab0714662 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -120,6 +120,10 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { int AddListeningPort(const grpc::string& addr, ServerCredentials* creds) override; + /// NOTE: This is *NOT* a public API. The server constructors are supposed to + /// be used by \a ServerBuilder class only. The constructor will be made + /// 'private' very soon. + /// /// Server constructors. To be used by \a ServerBuilder only. /// /// \param max_message_size Maximum message length that the channel can @@ -144,8 +148,8 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { Server(int max_message_size, ChannelArguments* args, std::shared_ptr>> sync_server_cqs, - grpc_resource_quota* server_rq, int min_pollers, int max_pollers, - int sync_cq_timeout_msec); + int min_pollers, int max_pollers, int sync_cq_timeout_msec, + grpc_resource_quota* server_rq); /// Start the server. /// diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 0ab3cd0e323..8417c45e641 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -261,9 +261,9 @@ std::unique_ptr ServerBuilder::BuildAndStart() { } std::unique_ptr server(new Server( - max_receive_message_size_, &args, sync_server_cqs, resource_quota_, + max_receive_message_size_, &args, sync_server_cqs, sync_server_settings_.min_pollers, sync_server_settings_.max_pollers, - sync_server_settings_.cq_timeout_msec)); + sync_server_settings_.cq_timeout_msec, resource_quota_)); if (has_sync_methods) { // This is a Sync server diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 472c5035fc1..43e6b27de20 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -382,8 +382,8 @@ Server::Server( int max_receive_message_size, ChannelArguments* args, std::shared_ptr>> sync_server_cqs, - grpc_resource_quota* server_rq, int min_pollers, int max_pollers, - int sync_cq_timeout_msec) + int min_pollers, int max_pollers, int sync_cq_timeout_msec, + grpc_resource_quota* server_rq = nullptr) : max_receive_message_size_(max_receive_message_size), sync_server_cqs_(std::move(sync_server_cqs)), started_(false), From b35328f0127fda3f13b41ae91c885dc4be2dfb02 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 2 Aug 2018 17:39:55 -0700 Subject: [PATCH 059/546] Fix test build --- test/core/channel/channel_trace_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index 8a5ddc2723a..e33277753b5 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -45,7 +45,7 @@ namespace testing { class ChannelNodePeer { public: ChannelNodePeer(ChannelNode* node) : node_(node) {} - ChannelTrace* trace() { return node_->trace_.get(); } + ChannelTrace* trace() { return &node_->trace_; } private: ChannelNode* node_; From fde951db9c6f87597faa7ae1b3d0f521ff1adb51 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 2 Aug 2018 20:55:00 -0700 Subject: [PATCH 060/546] Intecept recv_trailing in client_channel for channelz --- .../filters/client_channel/client_channel.cc | 87 +++++++++++++++++-- src/core/lib/channel/connected_channel.cc | 12 +-- src/core/lib/surface/call.cc | 10 ++- test/core/end2end/tests/channelz.cc | 3 + 4 files changed, 94 insertions(+), 18 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index f4d5596270a..c3669189f45 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -923,6 +923,10 @@ typedef struct client_channel_call_data { grpc_closure pick_closure; grpc_closure pick_cancel_closure; + grpc_closure recv_trailing_metadata_ready_channelz; + grpc_closure* original_recv_trailing_metadata; + // metadata_batch recv_trailing_metadata_channelz; + grpc_polling_entity* pollent; bool pollent_added_to_interested_parties; @@ -984,6 +988,14 @@ 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 start_pick_locked(void* arg, grpc_error* ignored); +template +static pending_batch* pending_batch_find(grpc_call_element* elem, + const char* log_message, + Predicate predicate); +static void get_call_status(grpc_call_element* elem, + grpc_metadata_batch* md_batch, grpc_error* error, + grpc_status_code* status, + grpc_mdelem** server_pushback_md); // // send op data caching @@ -1258,6 +1270,59 @@ static void resume_pending_batch_in_call_combiner(void* arg, grpc_subchannel_call_process_op(subchannel_call, batch); } +static void recv_trailing_metadata_ready_channelz(void* arg, + grpc_error* error) { + grpc_call_element* elem = static_cast(arg); + channel_data* chand = static_cast(elem->channel_data); + call_data* calld = static_cast(elem->call_data); + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: got recv_trailing_metadata_ready_channelz, " + "error=%s", + chand, calld, grpc_error_string(error)); + } + // find the right pending batch. + pending_batch* pending = pending_batch_find( + elem, "invoking recv_trailing_metadata_channelz for", + [](grpc_transport_stream_op_batch* batch) { + return batch->recv_trailing_metadata && + batch->payload->recv_trailing_metadata + .recv_trailing_metadata_ready != nullptr; + }); + grpc_status_code status = GRPC_STATUS_OK; + grpc_metadata_batch* md_batch = + pending->batch->payload->recv_trailing_metadata.recv_trailing_metadata; + get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, nullptr); + grpc_core::channelz::SubchannelNode* channelz_subchannel = + calld->pick.connected_subchannel->channelz_subchannel(); + GPR_ASSERT(channelz_subchannel != nullptr); + if (status == GRPC_STATUS_OK) { + channelz_subchannel->RecordCallSucceeded(); + } else { + channelz_subchannel->RecordCallFailed(); + } + pending->batch = nullptr; + GRPC_CLOSURE_SCHED(calld->original_recv_trailing_metadata, error); +} + +static bool maybe_intercept_recv_trailing_for_channelz( + grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { + call_data* calld = static_cast(elem->call_data); + // only add interceptor is channelz is enabled. + if (calld->pick.connected_subchannel->channelz_subchannel() != nullptr) { + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_channelz, + recv_trailing_metadata_ready_channelz, elem, + grpc_schedule_on_exec_ctx); + calld->original_recv_trailing_metadata = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->recv_trailing_metadata_ready_channelz; + return true; + } else { + return false; + } +} + // This is called via the call combiner, so access to calld is synchronized. static void pending_batches_resume(grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); @@ -1282,13 +1347,17 @@ static void pending_batches_resume(grpc_call_element* elem) { pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { + bool intercepted = + maybe_intercept_recv_trailing_for_channelz(elem, batch); 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); closures.Add(&batch->handler_private.closure, GRPC_ERROR_NONE, "pending_batches_resume"); - pending_batch_clear(calld, pending); + if (!intercepted) { + pending_batch_clear(calld, pending); + } } } // Note: This will release the call combiner. @@ -1768,22 +1837,20 @@ static void recv_message_ready(void* arg, grpc_error* error) { // // Sets *status and *server_pushback_md based on batch_data and error. -static void get_call_status(subchannel_batch_data* batch_data, - grpc_error* error, grpc_status_code* status, +static void get_call_status(grpc_call_element* elem, + grpc_metadata_batch* md_batch, grpc_error* error, + grpc_status_code* status, grpc_mdelem** server_pushback_md) { - grpc_call_element* elem = batch_data->elem; call_data* calld = static_cast(elem->call_data); if (error != GRPC_ERROR_NONE) { grpc_error_get_status(error, calld->deadline, status, nullptr, nullptr, nullptr); } else { - 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) { + if (server_pushback_md != nullptr && + md_batch->idx.named.grpc_retry_pushback_ms != nullptr) { *server_pushback_md = &md_batch->idx.named.grpc_retry_pushback_ms->md; } } @@ -1956,7 +2023,9 @@ static void recv_trailing_metadata_ready(void* arg, grpc_error* error) { // Get the call's status and check for server pushback metadata. grpc_status_code status = GRPC_STATUS_OK; grpc_mdelem* server_pushback_md = nullptr; - get_call_status(batch_data, GRPC_ERROR_REF(error), &status, + grpc_metadata_batch* md_batch = + batch_data->batch.payload->recv_trailing_metadata.recv_trailing_metadata; + get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, &server_pushback_md); grpc_core::channelz::SubchannelNode* channelz_subchannel = calld->pick.connected_subchannel->channelz_subchannel(); diff --git a/src/core/lib/channel/connected_channel.cc b/src/core/lib/channel/connected_channel.cc index e2ea334dedf..90a02546633 100644 --- a/src/core/lib/channel/connected_channel.cc +++ b/src/core/lib/channel/connected_channel.cc @@ -104,18 +104,18 @@ static void con_start_transport_stream_op_batch( if (batch->recv_initial_metadata) { callback_state* state = &calld->recv_initial_metadata_ready; intercept_callback( - calld, state, false, "recv_initial_metadata_ready", + calld, state, false, "connected_recv_initial_metadata_ready", &batch->payload->recv_initial_metadata.recv_initial_metadata_ready); } if (batch->recv_message) { callback_state* state = &calld->recv_message_ready; - intercept_callback(calld, state, false, "recv_message_ready", + intercept_callback(calld, state, false, "connected_recv_message_ready", &batch->payload->recv_message.recv_message_ready); } if (batch->recv_trailing_metadata) { callback_state* state = &calld->recv_trailing_metadata_ready; intercept_callback( - calld, state, false, "recv_trailing_metadata_ready", + calld, state, false, "connected_recv_trailing_metadata_ready", &batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready); } if (batch->cancel_stream) { @@ -126,11 +126,13 @@ static void con_start_transport_stream_op_batch( // closure for each one. callback_state* state = static_cast(gpr_malloc(sizeof(*state))); - intercept_callback(calld, state, true, "on_complete (cancel_stream)", + intercept_callback(calld, state, true, + "connected_on_complete (cancel_stream)", &batch->on_complete); } else if (batch->on_complete != nullptr) { callback_state* state = get_state_for_batch(calld, batch); - intercept_callback(calld, state, false, "on_complete", &batch->on_complete); + intercept_callback(calld, state, false, "connected_on_complete", + &batch->on_complete); } grpc_transport_perform_stream_op( chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld), batch); diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 26dd361e0d3..859915affbc 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -1422,7 +1422,7 @@ static void receiving_stream_ready_in_call_combiner(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; - GRPC_CALL_COMBINER_STOP(&call->call_combiner, "recv_message_ready"); + GRPC_CALL_COMBINER_STOP(&call->call_combiner, "call_recv_message_ready"); receiving_stream_ready(bctlp, error); } @@ -1507,7 +1507,8 @@ static void receiving_initial_metadata_ready(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; - GRPC_CALL_COMBINER_STOP(&call->call_combiner, "recv_initial_metadata_ready"); + GRPC_CALL_COMBINER_STOP(&call->call_combiner, + "call_recv_initial_metadata_ready"); add_batch_error(bctl, GRPC_ERROR_REF(error), false); if (error == GRPC_ERROR_NONE) { @@ -1558,7 +1559,8 @@ static void receiving_initial_metadata_ready(void* bctlp, grpc_error* error) { static void receiving_trailing_metadata_ready(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; - GRPC_CALL_COMBINER_STOP(&call->call_combiner, "recv_trailing_metadata_ready"); + GRPC_CALL_COMBINER_STOP(&call->call_combiner, + "call_recv_trailing_metadata_ready"); add_batch_error(bctl, GRPC_ERROR_REF(error), false); grpc_metadata_batch* md = &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; @@ -1569,7 +1571,7 @@ static void receiving_trailing_metadata_ready(void* bctlp, grpc_error* error) { static void finish_batch(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; - GRPC_CALL_COMBINER_STOP(&call->call_combiner, "on_complete"); + GRPC_CALL_COMBINER_STOP(&call->call_combiner, "call_on_complete"); add_batch_error(bctl, GRPC_ERROR_REF(error), false); finish_batch_step(bctl); } diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 754c3d37419..562822c537d 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -243,6 +243,9 @@ static void test_channelz(grpc_end2end_test_config config) { json = grpc_channelz_get_subchannel(2); gpr_log(GPR_INFO, "%s", json); + GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"2\"")); + GPR_ASSERT(nullptr != strstr(json, "\"callsFailed\":\"1\"")); + GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"1\"")); gpr_free(json); end_test(&f); From 0db2b830eb95c12975cb69b945f837194f38d96c Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 3 Aug 2018 11:24:18 -0400 Subject: [PATCH 061/546] Refactor rendering to use template method pattern --- .../client_channel/client_channel_channelz.cc | 39 ------------------- .../client_channel/client_channel_channelz.h | 9 ++--- src/core/lib/channel/channelz.cc | 7 ++++ src/core/lib/channel/channelz.h | 20 ++++++---- 4 files changed, 23 insertions(+), 52 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 06b4d2ab956..7e8f59bcd33 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -98,45 +98,6 @@ void ClientChannelNode::PopulateChildRefs(grpc_json* json) { } } -grpc_json* ClientChannelNode::RenderJson() { - // We need to track these three json objects to build our object - grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); - grpc_json* json = top_level_json; - grpc_json* json_iterator = nullptr; - // create and fill the ref child - json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr, - GRPC_JSON_OBJECT, false); - json = json_iterator; - json_iterator = nullptr; - json_iterator = grpc_json_add_number_string_child(json, json_iterator, - "channelId", uuid()); - // reset json iterators to top level object - json = top_level_json; - json_iterator = nullptr; - // create and fill the data child. - grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr, - GRPC_JSON_OBJECT, false); - json = data; - json_iterator = nullptr; - PopulateConnectivityState(json); - // populate the target. - GPR_ASSERT(target_view() != nullptr); - grpc_json_create_child(nullptr, json, "target", target_view(), - GRPC_JSON_STRING, false); - // fill in the channel trace if applicable - grpc_json* trace_json = trace()->RenderJson(); - if (trace_json != nullptr) { - trace_json->key = "trace"; // this object is named trace in channelz.proto - grpc_json_link_child(json, trace_json, nullptr); - } - // ask CallCountingHelper to populate trace and call count data. - call_counter()->PopulateCallCounts(json); - // reset to the top level - json = top_level_json; - PopulateChildRefs(json); - return top_level_json; -} - grpc_arg ClientChannelNode::CreateChannelArg() { return grpc_channel_arg_pointer_create( const_cast(GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC), diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 9a3fc1d6f1a..a9e98deedb4 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -50,7 +50,10 @@ class ClientChannelNode : public ChannelNode { bool is_top_level_channel); virtual ~ClientChannelNode() {} - grpc_json* RenderJson() override; + // Overriding template methods from ChannelNode to render information that + // only ClientChannelNode knows about. + void PopulateConnectivityState(grpc_json* json) override; + void PopulateChildRefs(grpc_json* json) override; // Helper to create a channel arg to ensure this type of ChannelNode is // created. @@ -58,10 +61,6 @@ class ClientChannelNode : public ChannelNode { private: grpc_channel_element* client_channel_; - - // helpers - void PopulateConnectivityState(grpc_json* json); - void PopulateChildRefs(grpc_json* json); }; // Handles channelz bookkeeping for sockets diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 1ac7bd3976d..9f548500025 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -117,6 +117,9 @@ grpc_json* ChannelNode::RenderJson() { GRPC_JSON_OBJECT, false); json = data; json_iterator = nullptr; + // template method. Child classes may override this to add their specific + // functionality. + PopulateConnectivityState(json); // populate the target. GPR_ASSERT(target_.get() != nullptr); grpc_json_create_child(nullptr, json, "target", target_.get(), @@ -129,6 +132,10 @@ grpc_json* ChannelNode::RenderJson() { } // ask CallCountingHelper to populate trace and call count data. call_counter_.PopulateCallCounts(json); + json = top_level_json; + // template method. Child classes may override this to add their specific + // functionality. + PopulateChildRefs(json); return top_level_json; } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 14edc75123b..e2cef233e6d 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -124,6 +124,18 @@ class ChannelNode : public BaseNode { grpc_json* RenderJson() override; + // template methods. RenderJSON uses these methods to render its JSON + // representation. These are virtual so that children classes may provide + // their specific mechanism for populating these parts of the channelz + // object. + // + // ChannelNode does not have a notion of connectivity state or child refs, + // so it leaves these implementations blank. + // + // This is utilizing the template method design pattern. + virtual void PopulateConnectivityState(grpc_json* json) {} + virtual void PopulateChildRefs(grpc_json* json) {} + void MarkChannelDestroyed() { GPR_ASSERT(channel_ != nullptr); channel_ = nullptr; @@ -144,14 +156,6 @@ class ChannelNode : public BaseNode { void RecordCallFailed() { call_counter_.RecordCallFailed(); } void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } - protected: - // provides view of target for child. - char* target_view() { return target_.get(); } - // provides access to call_counter_ for child. - CallCountingHelper* call_counter() { return &call_counter_; } - // provides access to channel trace for child. - ChannelTrace* trace() { return &trace_; } - private: // to allow the channel trace test to access trace(); friend class testing::ChannelNodePeer; From e2a87dac6975b3cbf6e434e1bb5112269043653e Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 3 Aug 2018 11:31:19 -0400 Subject: [PATCH 062/546] Add some comments --- src/core/ext/filters/client_channel/client_channel.cc | 8 ++++++-- .../ext/filters/client_channel/client_channel_channelz.h | 3 ++- src/core/lib/channel/channelz.h | 3 ++- test/core/end2end/tests/channelz.cc | 7 ------- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index c3669189f45..4263e791c4a 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -925,7 +925,6 @@ typedef struct client_channel_call_data { grpc_closure recv_trailing_metadata_ready_channelz; grpc_closure* original_recv_trailing_metadata; - // metadata_batch recv_trailing_metadata_channelz; grpc_polling_entity* pollent; bool pollent_added_to_interested_parties; @@ -1305,6 +1304,9 @@ static void recv_trailing_metadata_ready_channelz(void* arg, GRPC_CLOSURE_SCHED(calld->original_recv_trailing_metadata, error); } +// If channelz is enabled, intercept recv_trailing so that we may check the +// status and associate it to a subchannel. +// Returns true if callback was intercepted, false otherwise. static bool maybe_intercept_recv_trailing_for_channelz( grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { call_data* calld = static_cast(elem->call_data); @@ -1355,6 +1357,7 @@ static void pending_batches_resume(grpc_call_element* elem) { grpc_schedule_on_exec_ctx); closures.Add(&batch->handler_private.closure, GRPC_ERROR_NONE, "pending_batches_resume"); + // Only clear if we haven't intercepted anything. if (!intercepted) { pending_batch_clear(calld, pending); } @@ -1836,7 +1839,8 @@ static void recv_message_ready(void* arg, grpc_error* error) { // recv_trailing_metadata handling // -// Sets *status and *server_pushback_md based on batch_data and error. +// Sets *status and *server_pushback_md based on md_batch and error. +// Only sets *server_pushback_md if server_pushback_md != nullptr. static void get_call_status(grpc_call_element* elem, grpc_metadata_batch* md_batch, grpc_error* error, grpc_status_code* status, diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index a9e98deedb4..8ce331e529d 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -83,7 +83,8 @@ class SubchannelNode : public BaseNode { void AddTraceEventWithReference(ChannelTrace::Severity severity, grpc_slice data, RefCountedPtr referenced_channel) { - trace_.AddTraceEventWithReference(severity, data, referenced_channel); + trace_.AddTraceEventWithReference(severity, data, + std::move(referenced_channel)); } void RecordCallStarted() { call_counter_.RecordCallStarted(); } void RecordCallFailed() { call_counter_.RecordCallFailed(); } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index e2cef233e6d..bd2735929c8 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -150,7 +150,8 @@ class ChannelNode : public BaseNode { void AddTraceEventWithReference(ChannelTrace::Severity severity, grpc_slice data, RefCountedPtr referenced_channel) { - trace_.AddTraceEventWithReference(severity, data, referenced_channel); + trace_.AddTraceEventWithReference(severity, data, + std::move(referenced_channel)); } void RecordCallStarted() { call_counter_.RecordCallStarted(); } void RecordCallFailed() { call_counter_.RecordCallFailed(); } diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 562822c537d..533703a2bec 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -241,13 +241,6 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); gpr_free(json); - json = grpc_channelz_get_subchannel(2); - gpr_log(GPR_INFO, "%s", json); - GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"2\"")); - GPR_ASSERT(nullptr != strstr(json, "\"callsFailed\":\"1\"")); - GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"1\"")); - gpr_free(json); - end_test(&f); config.tear_down_data(&f); } From 70a8aa4a7d145b230aa007b5d3da0256a90c0141 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 3 Aug 2018 14:40:25 -0700 Subject: [PATCH 063/546] Make Node perf build script idempotent, update to newer Node version --- tools/run_tests/performance/build_performance_node.sh | 4 +++- tools/run_tests/performance/run_worker_node.sh | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/performance/build_performance_node.sh b/tools/run_tests/performance/build_performance_node.sh index 74adde91f34..bd765f8a15e 100755 --- a/tools/run_tests/performance/build_performance_node.sh +++ b/tools/run_tests/performance/build_performance_node.sh @@ -17,7 +17,7 @@ set +ex . "$HOME/.nvm/nvm.sh" -nvm install 9 +nvm install 10 set -ex @@ -25,4 +25,6 @@ cd "$(dirname "$0")/../../../../grpc-node" npm install +./node_modules/.bin/gulp clean.all + ./node_modules/.bin/gulp setup diff --git a/tools/run_tests/performance/run_worker_node.sh b/tools/run_tests/performance/run_worker_node.sh index a9bbdccbc1c..3e5dd18edb3 100755 --- a/tools/run_tests/performance/run_worker_node.sh +++ b/tools/run_tests/performance/run_worker_node.sh @@ -15,7 +15,7 @@ . "$HOME/.nvm/nvm.sh" -nvm use 9 +nvm use 10 set -ex From 42c5fb98f6073101c9d25923d61f5bb745611071 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Mon, 6 Aug 2018 10:59:17 -0700 Subject: [PATCH 064/546] change thd_count to thread_count --- src/core/lib/iomgr/resource_quota.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h index 1d5e95e04a4..7b0ed7417a9 100644 --- a/src/core/lib/iomgr/resource_quota.h +++ b/src/core/lib/iomgr/resource_quota.h @@ -93,12 +93,12 @@ void grpc_resource_user_ref(grpc_resource_user* resource_user); void grpc_resource_user_unref(grpc_resource_user* resource_user); void grpc_resource_user_shutdown(grpc_resource_user* resource_user); -/* Attempts to get quota (from the resource_user) to create 'thd_count' number +/* Attempts to get quota from the resource_user to create 'thread_count' number * of threads. Returns true if successful (i.e the caller is now free to create - * 'thd_count' number of threads) or false if quota is not available */ + * 'thread_count' number of threads) or false if quota is not available */ bool grpc_resource_user_allocate_threads(grpc_resource_user* resource_user, - int thd_count); -/* Releases 'thd_count' worth of quota back to the resource user. The quota + int thread_count); +/* Releases 'thread_count' worth of quota back to the resource user. The quota * should have been previously obtained successfully by calling * grpc_resource_user_allocate_threads(). * @@ -107,7 +107,7 @@ bool grpc_resource_user_allocate_threads(grpc_resource_user* resource_user, * calls. The only requirement is that the number of threads allocated should * all be eventually released */ void grpc_resource_user_free_threads(grpc_resource_user* resource_user, - int thd_count); + int thread_count); /* Allocate from the resource user (and its quota). If optional_on_done is NULL, then allocate immediately. This may push the From a2a64e5ad352b7a9760b04ee02facfcf287c0d60 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Mon, 6 Aug 2018 11:58:20 -0700 Subject: [PATCH 065/546] Fix default argument(put it in header instead of source file) --- include/grpcpp/server.h | 2 +- src/cpp/server/server_cc.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 5fab0714662..189d8bec224 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -149,7 +149,7 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { std::shared_ptr>> sync_server_cqs, int min_pollers, int max_pollers, int sync_cq_timeout_msec, - grpc_resource_quota* server_rq); + grpc_resource_quota* server_rq = nullptr); /// Start the server. /// diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 43e6b27de20..d32d6b49043 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -383,7 +383,7 @@ Server::Server( std::shared_ptr>> sync_server_cqs, int min_pollers, int max_pollers, int sync_cq_timeout_msec, - grpc_resource_quota* server_rq = nullptr) + grpc_resource_quota* server_rq) : max_receive_message_size_(max_receive_message_size), sync_server_cqs_(std::move(sync_server_cqs)), started_(false), From e8f0e54dce41e4575cc48c390f6d7696be27f22a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 6 Aug 2018 18:55:45 -0700 Subject: [PATCH 066/546] Enable CFStream with environment variable --- BUILD | 1 + build.yaml | 1 + gRPC-Core.podspec | 1 + src/core/lib/iomgr/iomgr_posix_cfstream.cc | 76 +++++++++++++++++++ src/core/lib/iomgr/port.h | 5 +- src/core/lib/iomgr/tcp_client_cfstream.cc | 2 +- src/objective-c/GRPCClient/GRPCCall.m | 19 +++-- .../GRPCClient/private/GRPCCompletionQueue.m | 5 -- src/objective-c/GRPCClient/private/GRPCHost.m | 19 +++-- src/objective-c/tests/InteropTests.m | 5 ++ .../tests/Tests.xcodeproj/project.pbxproj | 30 ++++++++ .../generated/sources_and_headers.json | 1 + 12 files changed, 145 insertions(+), 20 deletions(-) create mode 100644 src/core/lib/iomgr/iomgr_posix_cfstream.cc diff --git a/BUILD b/BUILD index 81390dd1aa1..433ae27621e 100644 --- a/BUILD +++ b/BUILD @@ -1010,6 +1010,7 @@ grpc_cc_library( "src/core/lib/iomgr/cfstream_handle.cc", "src/core/lib/iomgr/endpoint_cfstream.cc", "src/core/lib/iomgr/error_cfstream.cc", + "src/core/lib/iomgr/iomgr_posix_cfstream.cc", "src/core/lib/iomgr/tcp_client_cfstream.cc", ], hdrs = [ diff --git a/build.yaml b/build.yaml index 70af96046cb..3473fa09d6d 100644 --- a/build.yaml +++ b/build.yaml @@ -548,6 +548,7 @@ filegroups: - src/core/lib/iomgr/cfstream_handle.cc - src/core/lib/iomgr/endpoint_cfstream.cc - src/core/lib/iomgr/error_cfstream.cc + - src/core/lib/iomgr/iomgr_posix_cfstream.cc - src/core/lib/iomgr/tcp_client_cfstream.cc uses: - grpc_base_headers diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 5c3649afbde..81323d2795b 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1112,6 +1112,7 @@ Pod::Spec.new do |s| ss.source_files = 'src/core/lib/iomgr/cfstream_handle.cc', 'src/core/lib/iomgr/endpoint_cfstream.cc', 'src/core/lib/iomgr/error_cfstream.cc', + 'src/core/lib/iomgr/iomgr_posix_cfstream.cc', 'src/core/lib/iomgr/tcp_client_cfstream.cc', 'src/core/lib/iomgr/cfstream_handle.h', 'src/core/lib/iomgr/endpoint_cfstream.h', diff --git a/src/core/lib/iomgr/iomgr_posix_cfstream.cc b/src/core/lib/iomgr/iomgr_posix_cfstream.cc new file mode 100644 index 00000000000..646dd9ee6d1 --- /dev/null +++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc @@ -0,0 +1,76 @@ +/* + * + * 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 + +#include "src/core/lib/iomgr/port.h" + +#ifdef GRPC_CFSTREAM_IOMGR + + +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/iomgr/ev_posix.h" +#include "src/core/lib/iomgr/iomgr_internal.h" +#include "src/core/lib/iomgr/iomgr_posix.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/iomgr/tcp_posix.h" +#include "src/core/lib/iomgr/tcp_server.h" +#include "src/core/lib/iomgr/timer.h" + +static const char *grpc_cfstream_env_var = "grpc_cfstream"; + +extern grpc_tcp_server_vtable grpc_posix_tcp_server_vtable; +extern grpc_tcp_client_vtable grpc_posix_tcp_client_vtable; +extern grpc_tcp_client_vtable grpc_cfstream_client_vtable; +extern grpc_timer_vtable grpc_generic_timer_vtable; +extern grpc_pollset_vtable grpc_posix_pollset_vtable; +extern grpc_pollset_set_vtable grpc_posix_pollset_set_vtable; +extern grpc_address_resolver_vtable grpc_posix_resolver_vtable; + +static void iomgr_platform_init(void) { + grpc_wakeup_fd_global_init(); + grpc_event_engine_init(); +} + +static void iomgr_platform_flush(void) {} + +static void iomgr_platform_shutdown(void) { + grpc_event_engine_shutdown(); + grpc_wakeup_fd_global_destroy(); +} + +static grpc_iomgr_platform_vtable vtable = { + iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown}; + +void grpc_set_default_iomgr_platform() { + char *enable_cfstream = getenv(grpc_cfstream_env_var); + grpc_tcp_client_vtable *client_vtable = &grpc_posix_tcp_client_vtable; + if (enable_cfstream != nullptr && enable_cfstream[0] == '1') { + client_vtable = &grpc_cfstream_client_vtable; + } + grpc_set_tcp_client_impl(client_vtable); + grpc_set_tcp_server_impl(&grpc_posix_tcp_server_vtable); + grpc_set_timer_impl(&grpc_generic_timer_vtable); + grpc_set_pollset_vtable(&grpc_posix_pollset_vtable); + grpc_set_pollset_set_vtable(&grpc_posix_pollset_set_vtable); + grpc_set_resolver_impl(&grpc_posix_resolver_vtable); + grpc_set_iomgr_platform_vtable(&vtable); +} + +#endif /* GRPC_CFSTREAM_IOMGR */ diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 80d8e63cdd0..1d0ecff802a 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -98,9 +98,9 @@ #define GRPC_POSIX_FORK 1 #define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1 #ifdef GRPC_CFSTREAM -#define GRPC_POSIX_SOCKET_IOMGR 1 -#define GRPC_CFSTREAM_ENDPOINT 1 +#define GRPC_CFSTREAM_IOMGR 1 #define GRPC_CFSTREAM_CLIENT 1 +#define GRPC_CFSTREAM_ENDPOINT 1 #define GRPC_POSIX_SOCKET_ARES_EV_DRIVER 1 #define GRPC_POSIX_SOCKET_EV 1 #define GRPC_POSIX_SOCKET_EV_EPOLL1 1 @@ -111,6 +111,7 @@ #define GRPC_POSIX_SOCKET_SOCKADDR 1 #define GRPC_POSIX_SOCKET_SOCKET_FACTORY 1 #define GRPC_POSIX_SOCKET_TCP 1 +#define GRPC_POSIX_SOCKET_TCP_CLIENT 1 #define GRPC_POSIX_SOCKET_TCP_SERVER 1 #define GRPC_POSIX_SOCKET_TCP_SERVER_UTILS_COMMON 1 #define GRPC_POSIX_SOCKET_UTILS_COMMON 1 diff --git a/src/core/lib/iomgr/tcp_client_cfstream.cc b/src/core/lib/iomgr/tcp_client_cfstream.cc index 5acea91792f..4b21322d746 100644 --- a/src/core/lib/iomgr/tcp_client_cfstream.cc +++ b/src/core/lib/iomgr/tcp_client_cfstream.cc @@ -211,6 +211,6 @@ static void CFStreamClientConnect(grpc_closure* closure, grpc_endpoint** ep, gpr_mu_unlock(&connect->mu); } -grpc_tcp_client_vtable grpc_posix_tcp_client_vtable = {CFStreamClientConnect}; +grpc_tcp_client_vtable grpc_cfstream_client_vtable = {CFStreamClientConnect}; #endif /* GRPC_CFSTREAM_CLIENT */ diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 9783b064402..b8337ab0cdf 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -45,6 +45,8 @@ static NSMutableDictionary *callFlags; static NSString *const kAuthorizationHeader = @"authorization"; static NSString *const kBearerPrefix = @"Bearer "; +const char *kCFStreamVarName = "grpc_cfstream"; + @interface GRPCCall () // Make them read-write. @property(atomic, strong) NSDictionary *responseHeaders; @@ -206,9 +208,12 @@ static NSString *const kBearerPrefix = @"Bearer "; } else { [_responseWriteable enqueueSuccessfulCompletion]; } -#ifndef GRPC_CFSTREAM - [GRPCConnectivityMonitor unregisterObserver:self]; -#endif + + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor unregisterObserver:self]; + } // If the call isn't retained anywhere else, it can be deallocated now. _retainSelf = nil; @@ -463,9 +468,11 @@ static NSString *const kBearerPrefix = @"Bearer "; [self sendHeaders:_requestHeaders]; [self invokeCall]; -#ifndef GRPC_CFSTREAM - [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; -#endif + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChanged:)]; + } } - (void)startWithWriteable:(id)writeable { diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m index bda1c3360be..f454a6dc57f 100644 --- a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m +++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m @@ -20,13 +20,8 @@ #import -#ifdef GRPC_CFSTREAM -const grpc_completion_queue_attributes kCompletionQueueAttr = {GRPC_CQ_CURRENT_VERSION, - GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING}; -#else const grpc_completion_queue_attributes kCompletionQueueAttr = { GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING}; -#endif @implementation GRPCCompletionQueue diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 2e9f9f243b3..862909f2384 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -34,6 +34,8 @@ NS_ASSUME_NONNULL_BEGIN +extern const char *kCFStreamVarName; + static NSMutableDictionary *kHostCache; @implementation GRPCHost { @@ -49,9 +51,11 @@ static NSMutableDictionary *kHostCache; if (_channelCreds != nil) { grpc_channel_credentials_release(_channelCreds); } -#ifndef GRPC_CFSTREAM - [GRPCConnectivityMonitor unregisterObserver:self]; -#endif + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor unregisterObserver:self]; + } } // Default initializer. @@ -87,9 +91,12 @@ static NSMutableDictionary *kHostCache; _compressAlgorithm = GRPC_COMPRESS_NONE; _retryEnabled = YES; } -#ifndef GRPC_CFSTREAM - [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)]; -#endif + + // Connectivity monitor is not required for CFStream + char *enableCFStream = getenv(kCFStreamVarName); + if (enableCFStream == nil || enableCFStream[0] != '1') { + [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)]; + } } return self; } diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 1e1da2dd664..5750dccd894 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -36,6 +36,8 @@ #define TEST_TIMEOUT 32 +extern const char *kCFStreamVarName; + // Convenience constructors for the generated proto messages: @interface RMTStreamingOutputCallRequest (Constructors) @@ -97,6 +99,9 @@ BOOL isRemoteInteropTest(NSString *host) { [Cronet start]; [GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]]; #endif +#ifdef GRPC_CFSTREAM + setenv(kCFStreamVarName, "1", 1); +#endif } - (void)setUp { diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 8ff46335826..ea1066219d4 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -1982,6 +1982,16 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + "$(inherited)", + "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", + "$(inherited)", + "PB_FIELD_32BIT=1", + "PB_NO_PACKED_STRUCTS=1", + "GRPC_CFSTREAM=1", + ); INFOPLIST_FILE = Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -2100,6 +2110,16 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + "$(inherited)", + "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", + "$(inherited)", + "PB_FIELD_32BIT=1", + "PB_NO_PACKED_STRUCTS=1", + "GRPC_CFSTREAM=1", + ); INFOPLIST_FILE = Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -2218,6 +2238,16 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + "$(inherited)", + "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", + "$(inherited)", + "PB_FIELD_32BIT=1", + "PB_NO_PACKED_STRUCTS=1", + "GRPC_CFSTREAM=1", + ); INFOPLIST_FILE = Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a686dae8b4a..fc5480fffd7 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9904,6 +9904,7 @@ "src/core/lib/iomgr/endpoint_cfstream.h", "src/core/lib/iomgr/error_cfstream.cc", "src/core/lib/iomgr/error_cfstream.h", + "src/core/lib/iomgr/iomgr_posix_cfstream.cc", "src/core/lib/iomgr/tcp_client_cfstream.cc" ], "third_party": false, From 68f549e43fe433fd5393453b2f407e061f7ca240 Mon Sep 17 00:00:00 2001 From: Matthew Bender Date: Tue, 7 Aug 2018 11:25:37 -0600 Subject: [PATCH 067/546] Update instructions to include how to satisfy gFlags prerequisite on a mac --- doc/command_line_tool.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/command_line_tool.md b/doc/command_line_tool.md index 6337acaf60a..a373cbea627 100644 --- a/doc/command_line_tool.md +++ b/doc/command_line_tool.md @@ -41,12 +41,16 @@ repository, you need to run the following command to update submodules: git submodule update --init ``` -You also need to have the gflags library installed on your system. On Linux -systems, gflags can be installed with the following command: - +You also need to have the gflags library installed on your system. gflags can be +installed with the following command: +Linux: ``` sudo apt-get install libgflags-dev ``` +Mac systems with Homebrew: +``` +brew install gflags +``` Once the prerequisites are satisfied, you can build the command line tool with the command: From df5205f74d3bfd3d77cb7e076e43e74fcb15c3cf Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 7 Aug 2018 10:43:51 -0700 Subject: [PATCH 068/546] clang-format --- src/core/lib/iomgr/iomgr_posix_cfstream.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/iomgr_posix_cfstream.cc b/src/core/lib/iomgr/iomgr_posix_cfstream.cc index 646dd9ee6d1..235a9e0712f 100644 --- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc +++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc @@ -22,7 +22,6 @@ #ifdef GRPC_CFSTREAM_IOMGR - #include "src/core/lib/debug/trace.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/iomgr_internal.h" @@ -33,7 +32,7 @@ #include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/iomgr/timer.h" -static const char *grpc_cfstream_env_var = "grpc_cfstream"; +static const char* grpc_cfstream_env_var = "grpc_cfstream"; extern grpc_tcp_server_vtable grpc_posix_tcp_server_vtable; extern grpc_tcp_client_vtable grpc_posix_tcp_client_vtable; @@ -59,8 +58,8 @@ static grpc_iomgr_platform_vtable vtable = { iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown}; void grpc_set_default_iomgr_platform() { - char *enable_cfstream = getenv(grpc_cfstream_env_var); - grpc_tcp_client_vtable *client_vtable = &grpc_posix_tcp_client_vtable; + char* enable_cfstream = getenv(grpc_cfstream_env_var); + grpc_tcp_client_vtable* client_vtable = &grpc_posix_tcp_client_vtable; if (enable_cfstream != nullptr && enable_cfstream[0] == '1') { client_vtable = &grpc_cfstream_client_vtable; } From e8e73bfd8d36ed545fe44946f33379ebfa949e25 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 7 Aug 2018 11:47:09 -0700 Subject: [PATCH 069/546] Update document --- src/objective-c/README-CFSTREAM.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/objective-c/README-CFSTREAM.md b/src/objective-c/README-CFSTREAM.md index 0b5215a7b3b..d0cd57b7cdd 100644 --- a/src/objective-c/README-CFSTREAM.md +++ b/src/objective-c/README-CFSTREAM.md @@ -13,17 +13,17 @@ interface that gRPC uses when it is ready for production. ## Usage If you use gRPC following the instructions in [README.md](https://github.com/grpc/grpc/blob/master/src/objective-c/README.md): -- Simply replace the -dependency on `gRPC-ProtoRPC` with `gRPC-ProtoRPC/CFStream`. The build system will take care of -everything else and switch networking to CFStream. +- Replace the +dependency on `gRPC-ProtoRPC` with `gRPC-ProtoRPC/CFStream`. +- Enable CFStream with environment variable `grpc_cfstream=1`. This can be done either in Xcode + console or by your code with `setenv()`. If your project directly depends on podspecs other than `gRPC-ProtoRPC` (e.g. `gRPC` or `gRPC-Core`): -- Make your projects depend on subspecs corresponding to CFStream in each gRPC podspec. For - `gRPC-Core`, you will need to make sure that the completion queue you create is of type - `GRPC_CQ_NON_POLLING`. This is expected to be fixed soon so that you do not have to modify the - completion queue type. +- Make your projects depend on subspecs corresponding to CFStream in each gRPC podspec. +- Enable CFStream with environment variable `grpc_cfstream=1`. This can be done either in Xcode + console or by your code with `setenv()`. ## Notes From b9e53ee368dce961f1098e57641439123df03794 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 7 Aug 2018 15:17:41 -0700 Subject: [PATCH 070/546] Nit polish on the user manual --- src/objective-c/README-CFSTREAM.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/README-CFSTREAM.md b/src/objective-c/README-CFSTREAM.md index d0cd57b7cdd..0cb25ab237b 100644 --- a/src/objective-c/README-CFSTREAM.md +++ b/src/objective-c/README-CFSTREAM.md @@ -16,14 +16,14 @@ If you use gRPC following the instructions in - Replace the dependency on `gRPC-ProtoRPC` with `gRPC-ProtoRPC/CFStream`. - Enable CFStream with environment variable `grpc_cfstream=1`. This can be done either in Xcode - console or by your code with `setenv()`. + console or by your code with `setenv()` before gRPC is initialized. If your project directly depends on podspecs other than `gRPC-ProtoRPC` (e.g. `gRPC` or `gRPC-Core`): - Make your projects depend on subspecs corresponding to CFStream in each gRPC podspec. - Enable CFStream with environment variable `grpc_cfstream=1`. This can be done either in Xcode - console or by your code with `setenv()`. + console or by your code with `setenv()` before gRPC is initialized. ## Notes From 5f2f984be15f00942bf0c7cebbff0e78f4702b03 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 7 Aug 2018 16:29:28 -0700 Subject: [PATCH 071/546] update environment_variable.md --- doc/environment_variables.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index bf2de927a4f..b472f7e1263 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -135,3 +135,7 @@ some configuration as environment variables that can be set. if set, flow control will be effectively disabled. Max out all values and assume the remote peer does the same. Thus we can ignore any flow control bookkeeping, error checking, and decision making + +* grpc_cfstream + set to 1 to turn on CFStream experiment. With this experiment gRPC uses CFStream API to make TCP + connections. The option is only available on iOS platform and when macro GRPC_CFSTREAM is defined. From 6e3938c829b00d4a6db542f3ebadef2e57819e10 Mon Sep 17 00:00:00 2001 From: Nathan Herring Date: Thu, 9 Aug 2018 11:11:37 -0500 Subject: [PATCH 072/546] This replaces mutually-exclusive flags for a single selector flag which defines the call credentials to composite over any channel credentials. It is the call credentials version of #16204. Fixes issue #16205. --- test/cpp/util/cli_credentials.cc | 69 +++++++++++++++++++++++++++----- test/cpp/util/cli_credentials.h | 3 ++ 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/test/cpp/util/cli_credentials.cc b/test/cpp/util/cli_credentials.cc index acf4ef8ef10..0a922617bb6 100644 --- a/test/cpp/util/cli_credentials.cc +++ b/test/cpp/util/cli_credentials.cc @@ -28,7 +28,8 @@ DEFINE_bool(use_auth, false, "--channel_creds_type=gdc."); DEFINE_string( access_token, "", - "The access token that will be sent to the server to authenticate RPCs."); + "The access token that will be sent to the server to authenticate RPCs. " + "Deprecated. Use --call_creds=access_token=."); DEFINE_string( ssl_target, "", "If not empty, treat the server host name as this for ssl/tls certificate " @@ -37,10 +38,34 @@ DEFINE_string( channel_creds_type, "", "The channel creds type: insecure, ssl, gdc (Google Default Credentials) " "or alts."); +DEFINE_string( + call_creds, "", + "Call credentials to use: none (default), or access_token=. If " + "provided, the call creds are composited on top of channel creds."); namespace grpc { namespace testing { +namespace { + +const char ACCESS_TOKEN_PREFIX[] = "access_token="; +constexpr int ACCESS_TOKEN_PREFIX_LEN = + sizeof(ACCESS_TOKEN_PREFIX) / sizeof(*ACCESS_TOKEN_PREFIX) - 1; + +bool IsAccessToken(const grpc::string& auth) { + return auth.length() > ACCESS_TOKEN_PREFIX_LEN && + auth.compare(0, ACCESS_TOKEN_PREFIX_LEN, ACCESS_TOKEN_PREFIX) == 0; +} + +grpc::string AccessToken(const grpc::string& auth) { + if (!IsAccessToken(auth)) { + return ""; + } + return grpc::string(auth, ACCESS_TOKEN_PREFIX_LEN); +} + +} // namespace + grpc::string CliCredentials::GetDefaultChannelCredsType() const { // Compatibility logic for --enable_ssl. if (FLAGS_enable_ssl) { @@ -59,6 +84,16 @@ grpc::string CliCredentials::GetDefaultChannelCredsType() const { return "insecure"; } +grpc::string CliCredentials::GetDefaultCallCreds() const { + if (!FLAGS_access_token.empty()) { + fprintf(stderr, + "warning: --access_token is deprecated. Use " + "--call_creds=access_token=.\n"); + return grpc::string("access_token=") + FLAGS_access_token; + } + return "none"; +} + std::shared_ptr CliCredentials::GetChannelCredentials() const { if (FLAGS_channel_creds_type.compare("insecure") == 0) { @@ -80,18 +115,30 @@ CliCredentials::GetChannelCredentials() const { std::shared_ptr CliCredentials::GetCallCredentials() const { - if (!FLAGS_access_token.empty()) { - if (FLAGS_use_auth) { - fprintf(stderr, - "warning: use_auth is ignored when access_token is provided."); - } - return grpc::AccessTokenCredentials(FLAGS_access_token); + if (IsAccessToken(FLAGS_call_creds)) { + return grpc::AccessTokenCredentials(AccessToken(FLAGS_call_creds)); } + if (FLAGS_call_creds.compare("none") != 0) { + // Nothing to do; creds, if any, are baked into the channel. + return std::shared_ptr(); + } + fprintf(stderr, + "--call_creds=%s invalid; must be none " + "or access_token=.\n", + FLAGS_call_creds.c_str()); return std::shared_ptr(); } std::shared_ptr CliCredentials::GetCredentials() const { + if (FLAGS_call_creds.empty()) { + FLAGS_call_creds = GetDefaultCallCreds(); + } else if (!FLAGS_access_token.empty() && !IsAccessToken(FLAGS_call_creds)) { + fprintf(stderr, + "warning: ignoring --access_token because --call_creds " + "already set to %s.\n", + FLAGS_call_creds.c_str()); + } if (FLAGS_channel_creds_type.empty()) { FLAGS_channel_creds_type = GetDefaultChannelCredsType(); } else if (FLAGS_enable_ssl && FLAGS_channel_creds_type.compare("ssl") != 0) { @@ -106,7 +153,7 @@ std::shared_ptr CliCredentials::GetCredentials() FLAGS_channel_creds_type.c_str()); } // Legacy transport upgrade logic for insecure requests. - if (!FLAGS_access_token.empty() && + if (IsAccessToken(FLAGS_call_creds) && FLAGS_channel_creds_type.compare("insecure") == 0) { fprintf(stderr, "warning: --channel_creds_type=insecure upgraded to ssl because " @@ -126,10 +173,14 @@ const grpc::string CliCredentials::GetCredentialUsage() const { return " --enable_ssl ; Set whether to use ssl (deprecated)\n" " --use_auth ; Set whether to create default google" " credentials\n" + " ; (deprecated)\n" " --access_token ; Set the access token in metadata," " overrides --use_auth\n" + " ; (deprecated)\n" " --ssl_target ; Set server host for ssl validation\n" - " --channel_creds_type ; Set to insecure, ssl, gdc, or alts\n"; + " --channel_creds_type ; Set to insecure, ssl, gdc, or alts\n" + " --call_creds ; Set to none, or" + " access_token=\n"; } const grpc::string CliCredentials::GetSslTargetNameOverride() const { diff --git a/test/cpp/util/cli_credentials.h b/test/cpp/util/cli_credentials.h index 4636d3ca149..472c7abef29 100644 --- a/test/cpp/util/cli_credentials.h +++ b/test/cpp/util/cli_credentials.h @@ -36,6 +36,9 @@ class CliCredentials { // Returns the appropriate channel_creds_type value for the set of legacy // flag arguments. virtual grpc::string GetDefaultChannelCredsType() const; + // Returns the appropriate call_creds value for the set of legacy flag + // arguments. + virtual grpc::string GetDefaultCallCreds() const; // Returns the base transport channel credentials. Child classes can override // to support additional channel_creds_types unknown to this base class. virtual std::shared_ptr GetChannelCredentials() From c173b196d66430d96cd52402707bd874fc2931db Mon Sep 17 00:00:00 2001 From: Nathan Herring Date: Thu, 9 Aug 2018 11:29:05 -0500 Subject: [PATCH 073/546] Add flags to use client certs for cli. This allows `grpc_cli` to act with the specific client identity when using SSL. It does _not_ however set the cert when using Google Default Credentials, as it does not have the necessary options to provide a client cert and key. --- test/cpp/util/cli_credentials.cc | 37 +++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/test/cpp/util/cli_credentials.cc b/test/cpp/util/cli_credentials.cc index acf4ef8ef10..a78027e5aa5 100644 --- a/test/cpp/util/cli_credentials.cc +++ b/test/cpp/util/cli_credentials.cc @@ -19,6 +19,11 @@ #include "test/cpp/util/cli_credentials.h" #include +#include +#include +#include + +#include "src/core/lib/iomgr/load_file.h" DEFINE_bool( enable_ssl, false, @@ -33,6 +38,14 @@ DEFINE_string( ssl_target, "", "If not empty, treat the server host name as this for ssl/tls certificate " "validation."); +DEFINE_string( + ssl_client_cert, "", + "If not empty, load this PEM formated client certificate file. Requires " + "use of --ssl_client_key."); +DEFINE_string( + ssl_client_key, "", + "If not empty, load this PEM formated private key. Requires use of " + "--ssl_client_cert"); DEFINE_string( channel_creds_type, "", "The channel creds type: insecure, ssl, gdc (Google Default Credentials) " @@ -64,7 +77,27 @@ CliCredentials::GetChannelCredentials() const { if (FLAGS_channel_creds_type.compare("insecure") == 0) { return grpc::InsecureChannelCredentials(); } else if (FLAGS_channel_creds_type.compare("ssl") == 0) { - return grpc::SslCredentials(grpc::SslCredentialsOptions()); + grpc::SslCredentialsOptions ssl_creds_options; + // TODO(@Capstan): This won't affect Google Default Credentials using SSL. + if (!FLAGS_ssl_client_cert.empty()) { + grpc_slice cert_slice = grpc_empty_slice(); + GRPC_LOG_IF_ERROR( + "load_file", + grpc_load_file(FLAGS_ssl_client_cert.c_str(), 1, &cert_slice)); + ssl_creds_options.pem_cert_chain = + grpc::StringFromCopiedSlice(cert_slice); + grpc_slice_unref(cert_slice); + } + if (!FLAGS_ssl_client_key.empty()) { + grpc_slice key_slice = grpc_empty_slice(); + GRPC_LOG_IF_ERROR( + "load_file", + grpc_load_file(FLAGS_ssl_client_key.c_str(), 1, &key_slice)); + ssl_creds_options.pem_private_key = + grpc::StringFromCopiedSlice(key_slice); + grpc_slice_unref(key_slice); + } + return grpc::SslCredentials(ssl_creds_options); } else if (FLAGS_channel_creds_type.compare("gdc") == 0) { return grpc::GoogleDefaultCredentials(); } else if (FLAGS_channel_creds_type.compare("alts") == 0) { @@ -129,6 +162,8 @@ const grpc::string CliCredentials::GetCredentialUsage() const { " --access_token ; Set the access token in metadata," " overrides --use_auth\n" " --ssl_target ; Set server host for ssl validation\n" + " --ssl_client_cert ; Client cert for ssl\n" + " --ssl_client_key ; Client private key for ssl\n" " --channel_creds_type ; Set to insecure, ssl, gdc, or alts\n"; } From 22f00acecbcd329c2706f0721533516b1772eccb Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 9 Aug 2018 12:13:02 -0700 Subject: [PATCH 074/546] add comments to transport --- .../chttp2/transport/chttp2_transport.cc | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 9ad271753ce..983dfa3c050 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -812,6 +812,12 @@ static void set_write_state(grpc_chttp2_transport* t, write_state_name(t->write_state), write_state_name(st), reason)); t->write_state = st; + // If the state is being reset back to idle, it means a write was just + // finished. Make sure all the run_after_write closures are scheduled. + // + // This is also our chance to close the transport if the transport was marked + // to be closed after all writes finish (for example, we received a go-away + // from peer while we had some pending writes) if (st == GRPC_CHTTP2_WRITE_STATE_IDLE) { grpc_chttp2_stream* s; while (grpc_chttp2_list_pop_waiting_for_write_stream(t, &s)) { @@ -903,6 +909,22 @@ void grpc_chttp2_initiate_write(grpc_chttp2_transport* t, grpc_chttp2_initiate_write_reason_string(reason)); t->is_first_write_in_batch = true; GRPC_CHTTP2_REF_TRANSPORT(t, "writing"); + /* Note that the 'write_action_begin_locked' closure is being scheduled + * on the 'finally_scheduler' of t->combiner. This means that + * 'write_action_begin_locked' is called only *after* all the other + * closures (some of which are potentially initiating more writes on the + * transport) are executed on the t->combiner. + * + * The reason for scheduling on finally_scheduler is to make sure we batch + * as many writes as possible. 'write_action_begin_locked' is the function + * that gathers all the relevant bytes (which are at various places in the + * grpc_chttp2_transport structure) and append them to 'outbuf' field in + * grpc_chttp2_transport thereby batching what would have been potentially + * multiple write operations. + * + * Also, 'write_action_begin_locked' only gathers the bytes into outbuf. + * It does not call the endpoint to write the bytes. That is done by the + * 'write_action' (which is scheduled by 'write_action_begin_locked') */ GRPC_CLOSURE_SCHED( GRPC_CLOSURE_INIT(&t->write_action_begin_locked, write_action_begin_locked, t, @@ -1014,6 +1036,7 @@ static void write_action(void* gt, grpc_error* error) { grpc_combiner_scheduler(t->combiner))); } +/* Callback from the grpc_endpoint after bytes have been written on the wire */ static void write_action_end_locked(void* tp, grpc_error* error) { GPR_TIMER_SCOPE("terminate_writing_with_lock", 0); grpc_chttp2_transport* t = static_cast(tp); From 17e3611c0d5c55da1c7ae69f956e6024502edc25 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 9 Aug 2018 09:18:17 -0700 Subject: [PATCH 075/546] Infrastructure for adding custom polling engines --- build.yaml | 1 + src/core/lib/iomgr/ev_posix.cc | 41 +++++++++++++++---- src/core/lib/iomgr/ev_posix.h | 10 ++--- .../microbenchmarks/bm_cq_multiple_threads.cc | 28 ++++++------- tools/run_tests/generated/tests.json | 2 +- 5 files changed, 53 insertions(+), 29 deletions(-) diff --git a/build.yaml b/build.yaml index 70af96046cb..53c93c2b161 100644 --- a/build.yaml +++ b/build.yaml @@ -4106,6 +4106,7 @@ targets: - mac - linux - posix + uses_polling: false - name: bm_error build: test language: c++ diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 0e45fc42cad..c30614e7e53 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -101,10 +101,15 @@ const grpc_event_engine_vtable* init_non_polling(bool explicit_request) { } } // namespace -static const event_engine_factory g_factories[] = { +#define ENGINE_HEAD_CUSTOM "head_custom" +#define ENGINE_TAIL_CUSTOM "tail_custom" + +static event_engine_factory g_factories[] = { + {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, {"epollex", grpc_init_epollex_linux}, {"epoll1", grpc_init_epoll1_linux}, {"epollsig", grpc_init_epollsig_linux}, {"poll", grpc_init_poll_posix}, {"poll-cv", grpc_init_poll_cv_posix}, {"none", init_non_polling}, + {ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr}, }; static void add(const char* beg, const char* end, char*** ss, size_t* ns) { @@ -138,7 +143,7 @@ static bool is(const char* want, const char* have) { static void try_engine(const char* engine) { for (size_t i = 0; i < GPR_ARRAY_SIZE(g_factories); i++) { - if (is(engine, g_factories[i].name)) { + if (g_factories[i].factory != nullptr && is(engine, g_factories[i].name)) { if ((g_event_engine = g_factories[i].factory( 0 == strcmp(engine, g_factories[i].name)))) { g_poll_strategy_name = g_factories[i].name; @@ -149,14 +154,32 @@ static void try_engine(const char* engine) { } } -/* This should be used for testing purposes ONLY */ -void grpc_set_event_engine_test_only( - const grpc_event_engine_vtable* ev_engine) { - g_event_engine = ev_engine; -} +/* Call this before calling grpc_event_engine_init() */ +void grpc_register_event_engine_factory(const char* name, + event_engine_factory_fn factory, + bool add_at_head) { + const char* custom_match = + add_at_head ? ENGINE_HEAD_CUSTOM : ENGINE_TAIL_CUSTOM; + + // Overwrite an existing registration if already registered + for (size_t i = 0; i < GPR_ARRAY_SIZE(g_factories); i++) { + if (0 == strcmp(name, g_factories[i].name)) { + g_factories[i].factory = factory; + return; + } + } + + // Otherwise fill in an available custom slot + for (size_t i = 0; i < GPR_ARRAY_SIZE(g_factories); i++) { + if (0 == strcmp(g_factories[i].name, custom_match)) { + g_factories[i].name = name; + g_factories[i].factory = factory; + return; + } + } -const grpc_event_engine_vtable* grpc_get_event_engine_test_only() { - return g_event_engine; + // Otherwise fail + GPR_ASSERT(false); } /* Call this only after calling grpc_event_engine_init() */ diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h index 8d0bcc07101..b8fb8f534b4 100644 --- a/src/core/lib/iomgr/ev_posix.h +++ b/src/core/lib/iomgr/ev_posix.h @@ -82,6 +82,11 @@ typedef struct grpc_event_engine_vtable { void (*shutdown_engine)(void); } grpc_event_engine_vtable; +/* register a new event engine factory */ +void grpc_register_event_engine_factory( + const char* name, const grpc_event_engine_vtable* (*factory)(bool), + bool add_at_head); + void grpc_event_engine_init(void); void grpc_event_engine_shutdown(void); @@ -173,9 +178,4 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd); typedef int (*grpc_poll_function_type)(struct pollfd*, nfds_t, int); extern grpc_poll_function_type grpc_poll_function; -/* WARNING: The following two functions should be used for testing purposes - * ONLY */ -void grpc_set_event_engine_test_only(const grpc_event_engine_vtable*); -const grpc_event_engine_vtable* grpc_get_event_engine_test_only(); - #endif /* GRPC_CORE_LIB_IOMGR_EV_POSIX_H */ diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc index da095c3e68b..2f66a6d53ec 100644 --- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc +++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc @@ -37,12 +37,9 @@ struct grpc_pollset { namespace grpc { namespace testing { -auto& force_library_initialization = Library::get(); - static void* g_tag = (void*)static_cast(10); // Some random number static grpc_completion_queue* g_cq; static grpc_event_engine_vtable g_vtable; -static const grpc_event_engine_vtable* g_old_vtable; static void pollset_shutdown(grpc_pollset* ps, grpc_closure* closure) { GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_NONE); @@ -83,7 +80,7 @@ static grpc_error* pollset_work(grpc_pollset* ps, grpc_pollset_worker** worker, return GRPC_ERROR_NONE; } -static void init_engine_vtable() { +static const grpc_event_engine_vtable* init_engine_vtable(bool) { memset(&g_vtable, 0, sizeof(g_vtable)); g_vtable.pollset_size = sizeof(grpc_pollset); @@ -92,17 +89,23 @@ static void init_engine_vtable() { g_vtable.pollset_destroy = pollset_destroy; g_vtable.pollset_work = pollset_work; g_vtable.pollset_kick = pollset_kick; + g_vtable.shutdown_engine = [] {}; + + return &g_vtable; } static void setup() { - grpc_init(); + // This test should only ever be run with a non or any polling engine + // Override the polling engine for the non-polling engine + // and add a custom polling engine + grpc_register_event_engine_factory("none", init_engine_vtable, false); + grpc_register_event_engine_factory("bm_cq_multiple_threads", + init_engine_vtable, true); - /* Override the event engine with our test event engine (g_vtable); but before - * that, save the current event engine in g_old_vtable. We will have to set - * g_old_vtable back before calling grpc_shutdown() */ - init_engine_vtable(); - g_old_vtable = grpc_get_event_engine_test_only(); - grpc_set_event_engine_test_only(&g_vtable); + grpc_init(); + GPR_ASSERT(strcmp(grpc_get_poll_strategy_name(), "none") == 0 || + strcmp(grpc_get_poll_strategy_name(), "bm_cq_multiple_threads") == + 0); g_cq = grpc_completion_queue_create_for_next(nullptr); } @@ -118,9 +121,6 @@ static void teardown() { } grpc_completion_queue_destroy(g_cq); - - /* Restore the old event engine before calling grpc_shutdown */ - grpc_set_event_engine_test_only(g_old_vtable); grpc_shutdown(); } diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index cf3b54e0440..03e809c298a 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3483,7 +3483,7 @@ "mac", "posix" ], - "uses_polling": true + "uses_polling": false }, { "args": [], From 2f4fabaf78fd63904754b979534ab37cb6ef00c3 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 9 Aug 2018 13:23:05 -0700 Subject: [PATCH 076/546] Remove added line in node perf build script --- tools/run_tests/performance/build_performance_node.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/run_tests/performance/build_performance_node.sh b/tools/run_tests/performance/build_performance_node.sh index bd765f8a15e..12e08722648 100755 --- a/tools/run_tests/performance/build_performance_node.sh +++ b/tools/run_tests/performance/build_performance_node.sh @@ -25,6 +25,4 @@ cd "$(dirname "$0")/../../../../grpc-node" npm install -./node_modules/.bin/gulp clean.all - ./node_modules/.bin/gulp setup From 5e9994bf309a4fbf0206bf5312758f0c2a23aa3d Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 8 Aug 2018 15:46:25 -0700 Subject: [PATCH 077/546] Add warning about AsyncNotifyWhenDone bug --- include/grpcpp/impl/codegen/server_context.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index 153b404d9e1..4416344f115 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -226,6 +226,8 @@ class ServerContext { /// Async only. Has to be called before the rpc starts. /// Returns the tag in completion queue when the rpc finishes. /// IsCancelled() can then be called to check whether the rpc was cancelled. + /// TODO(vjpai): Fix this so that the tag is returned even if the call never + /// starts (https://github.com/grpc/grpc/issues/10136). void AsyncNotifyWhenDone(void* tag) { has_notify_when_done_tag_ = true; async_notify_when_done_tag_ = tag; From 9b72650125cd0f8b21ebd77825388e7dc3a9d191 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 9 Aug 2018 18:50:53 -0700 Subject: [PATCH 078/546] PF: Check connectivity state before watching --- .../lb_policy/pick_first/pick_first.cc | 103 ++++++++++++------ .../lb_policy/subchannel_list.h | 20 +++- test/cpp/end2end/client_lb_end2end_test.cc | 40 +++++++ 3 files changed, 124 insertions(+), 39 deletions(-) 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 2b6a9ba8c53..2c08245a8e8 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 @@ -80,6 +80,11 @@ class PickFirst : public LoadBalancingPolicy { void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state, grpc_error* error) override; + + // Processes the connectivity change to READY for an unselected subchannel. + void ProcessUnselectedReadyLocked(); + + void StartConnectivityWatchLocked() override; }; class PickFirstSubchannelList @@ -519,41 +524,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // select in place of the current one. switch (connectivity_state) { case GRPC_CHANNEL_READY: { - // Case 2. Promote p->latest_pending_subchannel_list_ to - // p->subchannel_list_. - if (subchannel_list() == p->latest_pending_subchannel_list_.get()) { - if (grpc_lb_pick_first_trace.enabled()) { - gpr_log(GPR_INFO, - "Pick First %p promoting pending subchannel list %p to " - "replace %p", - p, p->latest_pending_subchannel_list_.get(), - p->subchannel_list_.get()); - } - p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); - } - // Cases 1 and 2. - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY, - GRPC_ERROR_NONE, "connecting_ready"); - p->selected_ = this; - if (grpc_lb_pick_first_trace.enabled()) { - gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, - subchannel()); - } - // Drop all other subchannels, since we are now connected. - p->DestroyUnselectedSubchannelsLocked(); - // Update any calls that were waiting for a pick. - PickState* pick; - while ((pick = p->pending_picks_)) { - p->pending_picks_ = pick->next; - pick->connected_subchannel = - p->selected_->connected_subchannel()->Ref(); - if (grpc_lb_pick_first_trace.enabled()) { - gpr_log(GPR_INFO, - "Servicing pending pick with selected subchannel %p", - p->selected_->subchannel()); - } - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); - } + ProcessUnselectedReadyLocked(); // Renew notification. RenewConnectivityWatchLocked(); break; @@ -595,6 +566,68 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( GRPC_ERROR_UNREF(error); } +void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { + PickFirst* p = static_cast(subchannel_list()->policy()); + GPR_ASSERT(p->selected_ != this); + GPR_ASSERT(connectivity_state() == GRPC_CHANNEL_READY); + // If we get here, there are two possible cases: + // 1. We do not currently have a selected subchannel, and the update is + // for a subchannel in p->subchannel_list_ that we're trying to + // connect to. The goal here is to find a subchannel that we can + // select. + // 2. We do currently have a selected subchannel, and the update is + // for a subchannel in p->latest_pending_subchannel_list_. The + // goal here is to find a subchannel from the update that we can + // select in place of the current one. + GPR_ASSERT(subchannel_list() == p->subchannel_list_.get() || + subchannel_list() == p->latest_pending_subchannel_list_.get()); + // Case 2. Promote p->latest_pending_subchannel_list_ to p->subchannel_list_. + if (subchannel_list() == p->latest_pending_subchannel_list_.get()) { + if (grpc_lb_pick_first_trace.enabled()) { + gpr_log(GPR_INFO, + "Pick First %p promoting pending subchannel list %p to " + "replace %p", + p, p->latest_pending_subchannel_list_.get(), + p->subchannel_list_.get()); + } + p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); + } + // Cases 1 and 2. + grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY, + GRPC_ERROR_NONE, "subchannel_ready"); + p->selected_ = this; + if (grpc_lb_pick_first_trace.enabled()) { + gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); + } + // Drop all other subchannels, since we are now connected. + p->DestroyUnselectedSubchannelsLocked(); + // Update any calls that were waiting for a pick. + PickState* pick; + while ((pick = p->pending_picks_)) { + p->pending_picks_ = pick->next; + pick->connected_subchannel = p->selected_->connected_subchannel()->Ref(); + if (grpc_lb_pick_first_trace.enabled()) { + gpr_log(GPR_INFO, "Servicing pending pick with selected subchannel %p", + p->selected_->subchannel()); + } + GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); + } +} + +void PickFirst::PickFirstSubchannelData::StartConnectivityWatchLocked() { + PickFirst* p = static_cast(subchannel_list()->policy()); + grpc_error* error = GRPC_ERROR_NONE; + if (p->selected_ != this && + CheckConnectivityStateLocked(&error) == GRPC_CHANNEL_READY) { + // We must process the READY subchannel before we start watching it. + // Otherwise, we won't know it's READY because we will be waiting for its + // connectivity state to change from READY. + ProcessUnselectedReadyLocked(); + } + GRPC_ERROR_UNREF(error); + SubchannelData::StartConnectivityWatchLocked(); +} + // // factory // 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 0fa2f04e73b..0a75fc10c09 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 @@ -115,7 +115,7 @@ class SubchannelData { // Starts watching the connectivity state of the subchannel. // ProcessConnectivityChangeLocked() will be called when the // connectivity state changes. - void StartConnectivityWatchLocked(); + virtual void StartConnectivityWatchLocked(); // Renews watching the connectivity state of the subchannel. void RenewConnectivityWatchLocked(); @@ -154,6 +154,10 @@ class SubchannelData { grpc_connectivity_state connectivity_state, grpc_error* error) GRPC_ABSTRACT; + // Returns the connectivity state. Must be called only while there is no + // connectivity notification pending. + grpc_connectivity_state connectivity_state() const; + private: // Updates connected_subchannel_ based on pending_connectivity_state_unsafe_. // Returns true if the connectivity state should be reported. @@ -316,6 +320,13 @@ void SubchannelData +grpc_connectivity_state SubchannelData< + SubchannelListType, SubchannelDataType>::connectivity_state() const { + GPR_ASSERT(!connectivity_notification_pending_); + return pending_connectivity_state_unsafe_; +} + template void SubchannelData::StartConnectivityWatchLocked() { @@ -350,7 +361,8 @@ void SubchannelDatapolicy()->interested_parties(), &pending_connectivity_state_unsafe_, &connectivity_changed_closure_); @@ -367,8 +379,7 @@ void SubchannelDatanum_subchannels(), subchannel_); } - GPR_ASSERT(connectivity_notification_pending_); - connectivity_notification_pending_ = false; + GPR_ASSERT(!connectivity_notification_pending_); subchannel_list()->Unref(DEBUG_LOCATION, "connectivity_watch"); } @@ -442,6 +453,7 @@ void SubchannelData:: grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe_), grpc_error_string(error), sd->subchannel_list_->shutting_down()); } + sd->connectivity_notification_pending_ = false; // If shutting down, unref subchannel and stop watching. if (sd->subchannel_list_->shutting_down() || error == GRPC_ERROR_CANCELLED) { sd->UnrefSubchannelLocked("connectivity_shutdown"); diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 7fe0da8aaec..94f62637ec1 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -573,6 +573,46 @@ TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } +TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) { + std::vector ports = {grpc_pick_unused_port_or_die()}; + StartServers(1, ports); + auto channel_1 = BuildChannel("pick_first"); + auto stub_1 = BuildStub(channel_1); + SetNextResolution(ports); + gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 1 *******"); + WaitForServer(stub_1, 0, DEBUG_LOCATION); + gpr_log(GPR_INFO, "****** CHANNEL 1 CONNECTED *******"); + servers_[0]->Shutdown(); + // Channel 1 will receive a re-resolution containing the same server. It will + // create a new subchannel and hold a ref to it. + servers_.clear(); + StartServers(1, ports); + gpr_log(GPR_INFO, "****** SERVER RESTARTED *******"); + auto channel_2 = BuildChannel("pick_first"); + auto stub_2 = BuildStub(channel_2); + SetNextResolution(ports); + gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 2 *******"); + WaitForServer(stub_2, 0, DEBUG_LOCATION, true); + gpr_log(GPR_INFO, "****** CHANNEL 2 CONNECTED *******"); + servers_[0]->Shutdown(); + // Channel 2 will also receive a re-resolution containing the same server. + // Both channels will ref the same subchannel that failed. + servers_.clear(); + StartServers(1, ports); + // Wait for a while so that the disconnection has triggered the connectivity + // notification. Otherwise, the subchannel may be picked but will fail soon. + sleep(1); + gpr_log(GPR_INFO, "****** SERVER RESTARTED AGAIN *******"); + gpr_log(GPR_INFO, "****** CHANNEL 2 STARTING A CALL *******"); + // The first call after the server restart will succeed. + CheckRpcSendOk(stub_2, DEBUG_LOCATION); + gpr_log(GPR_INFO, "****** CHANNEL 2 FINISHED A CALL *******"); + // Check LB policy name for the channel. + EXPECT_EQ("pick_first", channel_1->GetLoadBalancingPolicyName()); + // Check LB policy name for the channel. + EXPECT_EQ("pick_first", channel_2->GetLoadBalancingPolicyName()); +} + TEST_F(ClientLbEnd2endTest, RoundRobin) { // Start servers and send one RPC per server. const int kNumServers = 3; From 9043a4f56d899a377d8763fa868b277d23e7b213 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 10 Aug 2018 06:11:40 +0000 Subject: [PATCH 079/546] Some cleanup --- test/cpp/microbenchmarks/bm_cq_multiple_threads.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc index 2f66a6d53ec..4a5487f1c43 100644 --- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc +++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc @@ -141,8 +141,9 @@ static void teardown() { static void BM_Cq_Throughput(benchmark::State& state) { TrackCounters track_counters; gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); + auto thd_idx = state.thread_index; - if (state.thread_index == 0) { + if (thd_idx == 0) { setup(); } @@ -152,12 +153,11 @@ static void BM_Cq_Throughput(benchmark::State& state) { } state.SetItemsProcessed(state.iterations()); + track_counters.Finish(state); - if (state.thread_index == 0) { + if (thd_idx == 0) { teardown(); } - - track_counters.Finish(state); } BENCHMARK(BM_Cq_Throughput)->ThreadRange(1, 16)->UseRealTime(); From eaa51cbc9de8e06c5714d1347dec25dea389950b Mon Sep 17 00:00:00 2001 From: easy Date: Fri, 10 Aug 2018 16:28:58 +1000 Subject: [PATCH 080/546] Add explicit check that we're building with bazel. --- include/grpcpp/opencensus.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/grpcpp/opencensus.h b/include/grpcpp/opencensus.h index 29b221f7674..07a13339863 100644 --- a/include/grpcpp/opencensus.h +++ b/include/grpcpp/opencensus.h @@ -19,6 +19,10 @@ #ifndef GRPCPP_OPENCENSUS_H #define GRPCPP_OPENCENSUS_H +#ifndef GRPC_BAZEL_BUILD +#error OpenCensus for gRPC is only supported when building with bazel. +#endif + #include "opencensus/trace/span.h" namespace grpc { From fc566ddcc552e5019d914973cea3eba069f410ed Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 10 Aug 2018 11:04:31 -0700 Subject: [PATCH 081/546] Increase build timeout again --- tools/run_tests/run_performance_tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py index cfe7bfc6182..2b297c45223 100755 --- a/tools/run_tests/run_performance_tests.py +++ b/tools/run_tests/run_performance_tests.py @@ -249,9 +249,9 @@ def build_on_remote_hosts(hosts, languages=scenario_config.LANGUAGES.keys(), build_local=False): """Builds performance worker on remote hosts (and maybe also locally).""" - build_timeout = 30 * 60 + build_timeout = 45 * 60 # Kokoro VMs (which are local only) do not have caching, so they need more time to build - local_build_timeout = 45 * 60 + local_build_timeout = 60 * 60 build_jobs = [] for host in hosts: user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, host) From d760b26586b7c0621d39803df90af3ee2d3d5698 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Fri, 10 Aug 2018 14:31:21 -0700 Subject: [PATCH 082/546] Modify comments --- .../chttp2/transport/chttp2_transport.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 983dfa3c050..d8829ca0cd2 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -812,12 +812,12 @@ static void set_write_state(grpc_chttp2_transport* t, write_state_name(t->write_state), write_state_name(st), reason)); t->write_state = st; - // If the state is being reset back to idle, it means a write was just - // finished. Make sure all the run_after_write closures are scheduled. - // - // This is also our chance to close the transport if the transport was marked - // to be closed after all writes finish (for example, we received a go-away - // from peer while we had some pending writes) + /* If the state is being reset back to idle, it means a write was just + finished. Make sure all the run_after_write closures are scheduled. + + This is also our chance to close the transport if the transport was marked + to be closed after all writes finish (for example, if we received a go-away + from peer while we had some pending writes) */ if (st == GRPC_CHTTP2_WRITE_STATE_IDLE) { grpc_chttp2_stream* s; while (grpc_chttp2_list_pop_waiting_for_write_stream(t, &s)) { @@ -1036,7 +1036,8 @@ static void write_action(void* gt, grpc_error* error) { grpc_combiner_scheduler(t->combiner))); } -/* Callback from the grpc_endpoint after bytes have been written on the wire */ +/* Callback from the grpc_endpoint after bytes have been written by calling + * sendmsg */ static void write_action_end_locked(void* tp, grpc_error* error) { GPR_TIMER_SCOPE("terminate_writing_with_lock", 0); grpc_chttp2_transport* t = static_cast(tp); From e84096bbe5f0e471d90906e93cba9332c392aa60 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 9 Aug 2018 13:20:35 -0700 Subject: [PATCH 083/546] Experimental infrastructure for callback-based CQ --- grpc.def | 1 + include/grpc/grpc.h | 6 + include/grpc/impl/codegen/grpc_types.h | 19 ++- .../grpcpp/impl/codegen/client_unary_call.h | 4 +- .../grpcpp/impl/codegen/completion_queue.h | 5 +- include/grpcpp/impl/codegen/sync_stream.h | 12 +- src/core/lib/surface/completion_queue.cc | 150 +++++++++++++++++- src/core/lib/surface/completion_queue.h | 13 +- .../lib/surface/completion_queue_factory.cc | 17 +- .../GRPCClient/private/GRPCCompletionQueue.m | 6 +- src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 + src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 + .../core/surface/public_headers_must_be_c89.c | 1 + 13 files changed, 211 insertions(+), 28 deletions(-) diff --git a/grpc.def b/grpc.def index 5e9d86c769c..962a2ec716c 100644 --- a/grpc.def +++ b/grpc.def @@ -20,6 +20,7 @@ EXPORTS grpc_completion_queue_factory_lookup grpc_completion_queue_create_for_next grpc_completion_queue_create_for_pluck + grpc_completion_queue_create_for_callback grpc_completion_queue_create grpc_completion_queue_next grpc_completion_queue_pluck diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 348c7a316fb..4c3af451001 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -101,6 +101,12 @@ GRPCAPI grpc_completion_queue* grpc_completion_queue_create_for_next( GRPCAPI grpc_completion_queue* grpc_completion_queue_create_for_pluck( void* reserved); +/** Helper function to create a completion queue with grpc_cq_completion_type + of GRPC_CQ_CALLBACK and grpc_cq_polling_type of GRPC_CQ_DEFAULT_POLLING. + This function is experimental. */ +GRPCAPI grpc_completion_queue* grpc_completion_queue_create_for_callback( + void* shutdown_callback, void* reserved); + /** Create a completion queue */ GRPCAPI grpc_completion_queue* grpc_completion_queue_create( const grpc_completion_queue_factory* factory, diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 5fd080c48b2..b5353c1dea8 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -651,10 +651,16 @@ typedef enum { GRPC_CQ_NEXT, /** Events are popped out by calling grpc_completion_queue_pluck() API ONLY*/ - GRPC_CQ_PLUCK + GRPC_CQ_PLUCK, + + /** EXPERIMENTAL: Events trigger a callback specified as the tag */ + GRPC_CQ_CALLBACK } grpc_cq_completion_type; -#define GRPC_CQ_CURRENT_VERSION 1 +/* The upgrade to version 2 is currently experimental. */ + +#define GRPC_CQ_CURRENT_VERSION 2 +#define GRPC_CQ_VERSION_MINIMUM_FOR_CALLBACKABLE 2 typedef struct grpc_completion_queue_attributes { /** The version number of this structure. More fields might be added to this structure in future. */ @@ -663,6 +669,15 @@ typedef struct grpc_completion_queue_attributes { grpc_cq_completion_type cq_completion_type; grpc_cq_polling_type cq_polling_type; + + /* END OF VERSION 1 CQ ATTRIBUTES */ + + /* EXPERIMENTAL: START OF VERSION 2 CQ ATTRIBUTES */ + /** When creating a callbackable CQ, pass in a functor to get invoked when + * shutdown is complete */ + void* cq_shutdown_cb; + + /* END OF VERSION 2 CQ ATTRIBUTES */ } grpc_completion_queue_attributes; /** The completion queue factory structure is opaque to the callers of grpc */ diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h index a37a81b75b8..e4e8364e073 100644 --- a/include/grpcpp/impl/codegen/client_unary_call.h +++ b/include/grpcpp/impl/codegen/client_unary_call.h @@ -50,8 +50,8 @@ class BlockingUnaryCallImpl { ClientContext* context, const InputMessage& request, OutputMessage* result) { CompletionQueue cq(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, - GRPC_CQ_DEFAULT_POLLING}); // Pluckable completion queue + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}); // Pluckable completion queue Call call(channel->CreateCall(method, context, &cq)); CallOpSet, diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 5819e068bad..272575dac28 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -97,7 +97,8 @@ class CompletionQueue : private GrpcLibraryCodegen { /// instance. CompletionQueue() : CompletionQueue(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING}) {} + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING, + nullptr}) {} /// Wrap \a take, taking ownership of the instance. /// @@ -376,7 +377,7 @@ class ServerCompletionQueue : public CompletionQueue { /// frequently polled. ServerCompletionQueue(grpc_cq_polling_type polling_type) : CompletionQueue(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, polling_type}), + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, polling_type, nullptr}), polling_type_(polling_type) {} grpc_cq_polling_type polling_type_; diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h index 7152eaf41fe..cbfcf25d0a4 100644 --- a/include/grpcpp/impl/codegen/sync_stream.h +++ b/include/grpcpp/impl/codegen/sync_stream.h @@ -243,8 +243,8 @@ class ClientReader final : public ClientReaderInterface { ClientContext* context, const W& request) : context_(context), cq_(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, - GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}), // Pluckable cq call_(channel->CreateCall(method, context, &cq_)) { ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata, ::grpc::internal::CallOpSendMessage, @@ -377,8 +377,8 @@ class ClientWriter : public ClientWriterInterface { ClientContext* context, R* response) : context_(context), cq_(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, - GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}), // Pluckable cq call_(channel->CreateCall(method, context, &cq_)) { finish_ops_.RecvMessage(response); finish_ops_.AllowNoMessage(); @@ -551,8 +551,8 @@ class ClientReaderWriter final : public ClientReaderWriterInterface { ClientContext* context) : context_(context), cq_(grpc_completion_queue_attributes{ - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, - GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, + nullptr}), // Pluckable cq call_(channel->CreateCall(method, context, &cq_)) { if (!context_->initial_metadata_corked_) { ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata> diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 7da9e6b74ca..fd33ce044c2 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -184,7 +184,7 @@ static const cq_poller_vtable g_poller_vtable_by_poller_type[] = { typedef struct cq_vtable { grpc_cq_completion_type cq_completion_type; size_t data_size; - void (*init)(void* data); + void (*init)(void* data, grpc_core::CQCallbackInterface* shutdown_callback); void (*shutdown)(grpc_completion_queue* cq); void (*destroy)(void* data); bool (*begin_op)(grpc_completion_queue* cq, void* tag); @@ -253,6 +253,29 @@ typedef struct cq_pluck_data { plucker pluckers[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS]; } cq_pluck_data; +typedef struct cq_callback_data { + /** No actual completed events queue, unlike other types */ + + /** Number of pending events (+1 if we're not shutdown) */ + gpr_atm pending_events; + + /** Counter of how many things have ever been queued on this completion queue + useful for avoiding locks to check the queue */ + gpr_atm things_queued_ever; + + /** 0 initially. 1 once we completed shutting */ + /* TODO: (sreek) This is not needed since (shutdown == 1) if and only if + * (pending_events == 0). So consider removing this in future and use + * pending_events */ + gpr_atm shutdown; + + /** 0 initially. 1 once we initiated shutdown */ + bool shutdown_called; + + /** A callback that gets invoked when the CQ completes shutdown */ + grpc_core::CQCallbackInterface* shutdown_callback; +} cq_callback_data; + /* Completion queue structure */ struct grpc_completion_queue { /** Once owning_refs drops to zero, we will destroy the cq */ @@ -276,11 +299,14 @@ struct grpc_completion_queue { /* Forward declarations */ static void cq_finish_shutdown_next(grpc_completion_queue* cq); static void cq_finish_shutdown_pluck(grpc_completion_queue* cq); +static void cq_finish_shutdown_callback(grpc_completion_queue* cq); static void cq_shutdown_next(grpc_completion_queue* cq); static void cq_shutdown_pluck(grpc_completion_queue* cq); +static void cq_shutdown_callback(grpc_completion_queue* cq); static bool cq_begin_op_for_next(grpc_completion_queue* cq, void* tag); static bool cq_begin_op_for_pluck(grpc_completion_queue* cq, void* tag); +static bool cq_begin_op_for_callback(grpc_completion_queue* cq, void* tag); static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, grpc_error* error, @@ -294,16 +320,25 @@ static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, grpc_cq_completion* storage), void* done_arg, grpc_cq_completion* storage); +static void cq_end_op_for_callback(grpc_completion_queue* cq, void* tag, + grpc_error* error, + void (*done)(void* done_arg, + grpc_cq_completion* storage), + void* done_arg, grpc_cq_completion* storage); + static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, void* reserved); static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, gpr_timespec deadline, void* reserved); -static void cq_init_next(void* data); -static void cq_init_pluck(void* data); +static void cq_init_next(void* data, grpc_core::CQCallbackInterface*); +static void cq_init_pluck(void* data, grpc_core::CQCallbackInterface*); +static void cq_init_callback(void* data, + grpc_core::CQCallbackInterface* shutdown_callback); static void cq_destroy_next(void* data); static void cq_destroy_pluck(void* data); +static void cq_destroy_callback(void* data); /* Completion queue vtables based on the completion-type */ static const cq_vtable g_cq_vtable[] = { @@ -315,6 +350,10 @@ static const cq_vtable g_cq_vtable[] = { {GRPC_CQ_PLUCK, sizeof(cq_pluck_data), cq_init_pluck, cq_shutdown_pluck, cq_destroy_pluck, cq_begin_op_for_pluck, cq_end_op_for_pluck, nullptr, cq_pluck}, + /* GRPC_CQ_CALLBACK */ + {GRPC_CQ_CALLBACK, sizeof(cq_callback_data), cq_init_callback, + cq_shutdown_callback, cq_destroy_callback, cq_begin_op_for_callback, + cq_end_op_for_callback, nullptr, nullptr}, }; #define DATA_FROM_CQ(cq) ((void*)(cq + 1)) @@ -419,8 +458,8 @@ static long cq_event_queue_num_items(grpc_cq_event_queue* q) { } grpc_completion_queue* grpc_completion_queue_create_internal( - grpc_cq_completion_type completion_type, - grpc_cq_polling_type polling_type) { + grpc_cq_completion_type completion_type, grpc_cq_polling_type polling_type, + grpc_core::CQCallbackInterface* shutdown_callback) { GPR_TIMER_SCOPE("grpc_completion_queue_create_internal", 0); grpc_completion_queue* cq; @@ -448,14 +487,14 @@ grpc_completion_queue* grpc_completion_queue_create_internal( gpr_ref_init(&cq->owning_refs, 2); poller_vtable->init(POLLSET_FROM_CQ(cq), &cq->mu); - vtable->init(DATA_FROM_CQ(cq)); + vtable->init(DATA_FROM_CQ(cq), shutdown_callback); GRPC_CLOSURE_INIT(&cq->pollset_shutdown_done, on_pollset_shutdown_done, cq, grpc_schedule_on_exec_ctx); return cq; } -static void cq_init_next(void* ptr) { +static void cq_init_next(void* ptr, grpc_core::CQCallbackInterface*) { cq_next_data* cqd = static_cast(ptr); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); @@ -470,7 +509,7 @@ static void cq_destroy_next(void* ptr) { cq_event_queue_destroy(&cqd->queue); } -static void cq_init_pluck(void* ptr) { +static void cq_init_pluck(void* ptr, grpc_core::CQCallbackInterface*) { cq_pluck_data* cqd = static_cast(ptr); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); @@ -487,6 +526,19 @@ static void cq_destroy_pluck(void* ptr) { GPR_ASSERT(cqd->completed_head.next == (uintptr_t)&cqd->completed_head); } +static void cq_init_callback( + void* ptr, grpc_core::CQCallbackInterface* shutdown_callback) { + cq_callback_data* cqd = static_cast(ptr); + /* Initial count is dropped by grpc_completion_queue_shutdown */ + gpr_atm_no_barrier_store(&cqd->pending_events, 1); + gpr_atm_no_barrier_store(&cqd->shutdown, 0); + cqd->shutdown_called = false; + gpr_atm_no_barrier_store(&cqd->things_queued_ever, 0); + cqd->shutdown_callback = shutdown_callback; +} + +static void cq_destroy_callback(void* ptr) {} + grpc_cq_completion_type grpc_get_cq_completion_type(grpc_completion_queue* cq) { return cq->vtable->cq_completion_type; } @@ -596,6 +648,11 @@ static bool cq_begin_op_for_pluck(grpc_completion_queue* cq, void* tag) { return atm_inc_if_nonzero(&cqd->pending_events); } +static bool cq_begin_op_for_callback(grpc_completion_queue* cq, void* tag) { + cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); + return atm_inc_if_nonzero(&cqd->pending_events); +} + bool grpc_cq_begin_op(grpc_completion_queue* cq, void* tag) { #ifndef NDEBUG gpr_mu_lock(cq->mu); @@ -759,6 +816,47 @@ static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, GRPC_ERROR_UNREF(error); } +/* Complete an event on a completion queue of type GRPC_CQ_CALLBACK */ +static void cq_end_op_for_callback( + grpc_completion_queue* cq, void* tag, grpc_error* error, + void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, + grpc_cq_completion* storage) { + GPR_TIMER_SCOPE("cq_end_op_for_callback", 0); + + cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); + bool is_success = (error == GRPC_ERROR_NONE); + + if (grpc_api_trace.enabled() || + (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE)) { + const char* errmsg = grpc_error_string(error); + GRPC_API_TRACE( + "cq_end_op_for_callback(cq=%p, tag=%p, error=%s, " + "done=%p, done_arg=%p, storage=%p)", + 6, (cq, tag, errmsg, done, done_arg, storage)); + if (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg); + } + } + + /* We don't care for the storage content */ + done(done_arg, storage); + + gpr_mu_lock(cq->mu); + cq_check_tag(cq, tag, false); /* Used in debug builds only */ + + gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1); + if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + cq_finish_shutdown_callback(cq); + gpr_mu_unlock(cq->mu); + } else { + gpr_mu_unlock(cq->mu); + } + + GRPC_ERROR_UNREF(error); + + (static_cast(tag))->Run(is_success); +} + void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, grpc_cq_completion* storage), void* done_arg, grpc_cq_completion* storage) { @@ -1233,6 +1331,42 @@ static void cq_shutdown_pluck(grpc_completion_queue* cq) { GRPC_CQ_INTERNAL_UNREF(cq, "shutting_down (pluck cq)"); } +static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { + cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); + auto* callback = cqd->shutdown_callback; + + GPR_ASSERT(cqd->shutdown_called); + GPR_ASSERT(!gpr_atm_no_barrier_load(&cqd->shutdown)); + gpr_atm_no_barrier_store(&cqd->shutdown, 1); + + cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); + callback->Run(true); +} + +static void cq_shutdown_callback(grpc_completion_queue* cq) { + cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); + + /* Need an extra ref for cq here because: + * We call cq_finish_shutdown_pluck() below, that would call pollset shutdown. + * Pollset shutdown decrements the cq ref count which can potentially destroy + * the cq (if that happens to be the last ref). + * Creating an extra ref here prevents the cq from getting destroyed while + * this function is still active */ + GRPC_CQ_INTERNAL_REF(cq, "shutting_down (callback cq)"); + gpr_mu_lock(cq->mu); + if (cqd->shutdown_called) { + gpr_mu_unlock(cq->mu); + GRPC_CQ_INTERNAL_UNREF(cq, "shutting_down (callback cq)"); + return; + } + cqd->shutdown_called = true; + if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + cq_finish_shutdown_callback(cq); + } + gpr_mu_unlock(cq->mu); + GRPC_CQ_INTERNAL_UNREF(cq, "shutting_down (callback cq)"); +} + /* Shutdown simply drops a ref that we reserved at creation time; if we drop to zero here, then enter shutdown mode and wake up any waiters */ void grpc_completion_queue_shutdown(grpc_completion_queue* cq) { diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index 84446a4d924..6d8c6c9b06e 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -47,6 +47,16 @@ typedef struct grpc_cq_completion { uintptr_t next; } grpc_cq_completion; +/// For callback CQs, the following is what is actually intended by +/// the tag. +namespace grpc_core { +class CQCallbackInterface { + public: + virtual ~CQCallbackInterface() {} + virtual void Run(bool) = 0; +}; +} // namespace grpc_core + #ifndef NDEBUG void grpc_cq_internal_ref(grpc_completion_queue* cc, const char* reason, const char* file, int line); @@ -87,6 +97,7 @@ grpc_cq_completion_type grpc_get_cq_completion_type(grpc_completion_queue* cc); int grpc_get_cq_poll_num(grpc_completion_queue* cc); grpc_completion_queue* grpc_completion_queue_create_internal( - grpc_cq_completion_type completion_type, grpc_cq_polling_type polling_type); + grpc_cq_completion_type completion_type, grpc_cq_polling_type polling_type, + grpc_core::CQCallbackInterface* shutdown_callback); #endif /* GRPC_CORE_LIB_SURFACE_COMPLETION_QUEUE_H */ diff --git a/src/core/lib/surface/completion_queue_factory.cc b/src/core/lib/surface/completion_queue_factory.cc index 51c1183c5f4..ed92dd7eba6 100644 --- a/src/core/lib/surface/completion_queue_factory.cc +++ b/src/core/lib/surface/completion_queue_factory.cc @@ -30,8 +30,9 @@ static grpc_completion_queue* default_create( const grpc_completion_queue_factory* factory, const grpc_completion_queue_attributes* attr) { - return grpc_completion_queue_create_internal(attr->cq_completion_type, - attr->cq_polling_type); + return grpc_completion_queue_create_internal( + attr->cq_completion_type, attr->cq_polling_type, + static_cast(attr->cq_shutdown_cb)); } static grpc_completion_queue_factory_vtable default_vtable = {default_create}; @@ -60,14 +61,22 @@ const grpc_completion_queue_factory* grpc_completion_queue_factory_lookup( grpc_completion_queue* grpc_completion_queue_create_for_next(void* reserved) { GPR_ASSERT(!reserved); grpc_completion_queue_attributes attr = {1, GRPC_CQ_NEXT, - GRPC_CQ_DEFAULT_POLLING}; + GRPC_CQ_DEFAULT_POLLING, nullptr}; return g_default_cq_factory.vtable->create(&g_default_cq_factory, &attr); } grpc_completion_queue* grpc_completion_queue_create_for_pluck(void* reserved) { GPR_ASSERT(!reserved); grpc_completion_queue_attributes attr = {1, GRPC_CQ_PLUCK, - GRPC_CQ_DEFAULT_POLLING}; + GRPC_CQ_DEFAULT_POLLING, nullptr}; + return g_default_cq_factory.vtable->create(&g_default_cq_factory, &attr); +} + +grpc_completion_queue* grpc_completion_queue_create_for_callback( + void* shutdown_callback, void* reserved) { + GPR_ASSERT(!reserved); + grpc_completion_queue_attributes attr = { + 2, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING, shutdown_callback}; return g_default_cq_factory.vtable->create(&g_default_cq_factory, &attr); } diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m index bda1c3360be..69db340e983 100644 --- a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m +++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m @@ -21,11 +21,11 @@ #import #ifdef GRPC_CFSTREAM -const grpc_completion_queue_attributes kCompletionQueueAttr = {GRPC_CQ_CURRENT_VERSION, - GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING}; +const grpc_completion_queue_attributes kCompletionQueueAttr = { + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING, nullptr}; #else const grpc_completion_queue_attributes kCompletionQueueAttr = { - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING}; + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING, nullptr}; #endif @implementation GRPCCompletionQueue diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 38b68462df1..8a2edc41f89 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -43,6 +43,7 @@ grpc_g_stands_for_type grpc_g_stands_for_import; grpc_completion_queue_factory_lookup_type grpc_completion_queue_factory_lookup_import; grpc_completion_queue_create_for_next_type grpc_completion_queue_create_for_next_import; grpc_completion_queue_create_for_pluck_type grpc_completion_queue_create_for_pluck_import; +grpc_completion_queue_create_for_callback_type grpc_completion_queue_create_for_callback_import; grpc_completion_queue_create_type grpc_completion_queue_create_import; grpc_completion_queue_next_type grpc_completion_queue_next_import; grpc_completion_queue_pluck_type grpc_completion_queue_pluck_import; @@ -294,6 +295,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_completion_queue_factory_lookup_import = (grpc_completion_queue_factory_lookup_type) GetProcAddress(library, "grpc_completion_queue_factory_lookup"); grpc_completion_queue_create_for_next_import = (grpc_completion_queue_create_for_next_type) GetProcAddress(library, "grpc_completion_queue_create_for_next"); grpc_completion_queue_create_for_pluck_import = (grpc_completion_queue_create_for_pluck_type) GetProcAddress(library, "grpc_completion_queue_create_for_pluck"); + grpc_completion_queue_create_for_callback_import = (grpc_completion_queue_create_for_callback_type) GetProcAddress(library, "grpc_completion_queue_create_for_callback"); grpc_completion_queue_create_import = (grpc_completion_queue_create_type) GetProcAddress(library, "grpc_completion_queue_create"); grpc_completion_queue_next_import = (grpc_completion_queue_next_type) GetProcAddress(library, "grpc_completion_queue_next"); grpc_completion_queue_pluck_import = (grpc_completion_queue_pluck_type) GetProcAddress(library, "grpc_completion_queue_pluck"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index d6add00d12e..5a7884cdcd5 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -104,6 +104,9 @@ extern grpc_completion_queue_create_for_next_type grpc_completion_queue_create_f typedef grpc_completion_queue*(*grpc_completion_queue_create_for_pluck_type)(void* reserved); extern grpc_completion_queue_create_for_pluck_type grpc_completion_queue_create_for_pluck_import; #define grpc_completion_queue_create_for_pluck grpc_completion_queue_create_for_pluck_import +typedef grpc_completion_queue*(*grpc_completion_queue_create_for_callback_type)(void* shutdown_callback, void* reserved); +extern grpc_completion_queue_create_for_callback_type grpc_completion_queue_create_for_callback_import; +#define grpc_completion_queue_create_for_callback grpc_completion_queue_create_for_callback_import typedef grpc_completion_queue*(*grpc_completion_queue_create_type)(const grpc_completion_queue_factory* factory, const grpc_completion_queue_attributes* attributes, void* reserved); extern grpc_completion_queue_create_type grpc_completion_queue_create_import; #define grpc_completion_queue_create grpc_completion_queue_create_import diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 7b3e875cf0a..69b3de16c4f 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -82,6 +82,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_completion_queue_factory_lookup); printf("%lx", (unsigned long) grpc_completion_queue_create_for_next); printf("%lx", (unsigned long) grpc_completion_queue_create_for_pluck); + printf("%lx", (unsigned long) grpc_completion_queue_create_for_callback); printf("%lx", (unsigned long) grpc_completion_queue_create); printf("%lx", (unsigned long) grpc_completion_queue_next); printf("%lx", (unsigned long) grpc_completion_queue_pluck); From f023814bff78e4af440e66923276899c948c1d44 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Fri, 10 Aug 2018 14:58:08 -0700 Subject: [PATCH 084/546] minor comments format fix --- .../ext/transport/chttp2/transport/chttp2_transport.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index d8829ca0cd2..493d679b74a 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -813,11 +813,11 @@ static void set_write_state(grpc_chttp2_transport* t, write_state_name(st), reason)); t->write_state = st; /* If the state is being reset back to idle, it means a write was just - finished. Make sure all the run_after_write closures are scheduled. - - This is also our chance to close the transport if the transport was marked - to be closed after all writes finish (for example, if we received a go-away - from peer while we had some pending writes) */ + * finished. Make sure all the run_after_write closures are scheduled. + * + * This is also our chance to close the transport if the transport was marked + * to be closed after all writes finish (for example, if we received a go-away + * from peer while we had some pending writes) */ if (st == GRPC_CHTTP2_WRITE_STATE_IDLE) { grpc_chttp2_stream* s; while (grpc_chttp2_list_pop_waiting_for_write_stream(t, &s)) { From 186df431dec8eb09e146a667edf8cfc7d45958de Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 10 Aug 2018 15:00:16 -0700 Subject: [PATCH 085/546] As per review --- .../lb_policy/pick_first/pick_first.cc | 28 +++++++++++++------ .../lb_policy/subchannel_list.h | 20 +++---------- test/cpp/end2end/client_lb_end2end_test.cc | 21 ++++++++++++-- 3 files changed, 41 insertions(+), 28 deletions(-) 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 2c08245a8e8..1cd5ef065de 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 @@ -84,7 +84,7 @@ class PickFirst : public LoadBalancingPolicy { // Processes the connectivity change to READY for an unselected subchannel. void ProcessUnselectedReadyLocked(); - void StartConnectivityWatchLocked() override; + void CheckConnectivityStateAndStartWatchingLocked(); }; class PickFirstSubchannelList @@ -252,7 +252,8 @@ void PickFirst::StartPickingLocked() { if (subchannel_list_ != nullptr) { for (size_t i = 0; i < subchannel_list_->num_subchannels(); ++i) { if (subchannel_list_->subchannel(i)->subchannel() != nullptr) { - subchannel_list_->subchannel(i)->StartConnectivityWatchLocked(); + subchannel_list_->subchannel(i) + ->CheckConnectivityStateAndStartWatchingLocked(); break; } } @@ -391,7 +392,8 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) { // If we've started picking, start trying to connect to the first // subchannel in the new list. if (started_picking_) { - subchannel_list_->subchannel(0)->StartConnectivityWatchLocked(); + subchannel_list_->subchannel(0) + ->CheckConnectivityStateAndStartWatchingLocked(); } } else { // We do have a selected subchannel. @@ -445,7 +447,7 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) { // subchannel in the new list. if (started_picking_) { latest_pending_subchannel_list_->subchannel(0) - ->StartConnectivityWatchLocked(); + ->CheckConnectivityStateAndStartWatchingLocked(); } } } @@ -545,7 +547,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), "exhausted_subchannels"); } - sd->StartConnectivityWatchLocked(); + sd->CheckConnectivityStateAndStartWatchingLocked(); break; } case GRPC_CHANNEL_CONNECTING: @@ -568,8 +570,15 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { PickFirst* p = static_cast(subchannel_list()->policy()); - GPR_ASSERT(p->selected_ != this); - GPR_ASSERT(connectivity_state() == GRPC_CHANNEL_READY); + if (p->selected_ == this) { + if (grpc_lb_pick_first_trace.enabled()) { + gpr_log(GPR_ERROR, + "Pick First %p calling ProcessUnselectedReadyLocked() on " + "selected subchannel %p", + p, subchannel()); + } + return; + } // If we get here, there are two possible cases: // 1. We do not currently have a selected subchannel, and the update is // for a subchannel in p->subchannel_list_ that we're trying to @@ -614,7 +623,8 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { } } -void PickFirst::PickFirstSubchannelData::StartConnectivityWatchLocked() { +void PickFirst::PickFirstSubchannelData:: + CheckConnectivityStateAndStartWatchingLocked() { PickFirst* p = static_cast(subchannel_list()->policy()); grpc_error* error = GRPC_ERROR_NONE; if (p->selected_ != this && @@ -625,7 +635,7 @@ void PickFirst::PickFirstSubchannelData::StartConnectivityWatchLocked() { ProcessUnselectedReadyLocked(); } GRPC_ERROR_UNREF(error); - SubchannelData::StartConnectivityWatchLocked(); + StartConnectivityWatchLocked(); } // 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 0a75fc10c09..0fa2f04e73b 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 @@ -115,7 +115,7 @@ class SubchannelData { // Starts watching the connectivity state of the subchannel. // ProcessConnectivityChangeLocked() will be called when the // connectivity state changes. - virtual void StartConnectivityWatchLocked(); + void StartConnectivityWatchLocked(); // Renews watching the connectivity state of the subchannel. void RenewConnectivityWatchLocked(); @@ -154,10 +154,6 @@ class SubchannelData { grpc_connectivity_state connectivity_state, grpc_error* error) GRPC_ABSTRACT; - // Returns the connectivity state. Must be called only while there is no - // connectivity notification pending. - grpc_connectivity_state connectivity_state() const; - private: // Updates connected_subchannel_ based on pending_connectivity_state_unsafe_. // Returns true if the connectivity state should be reported. @@ -320,13 +316,6 @@ void SubchannelData -grpc_connectivity_state SubchannelData< - SubchannelListType, SubchannelDataType>::connectivity_state() const { - GPR_ASSERT(!connectivity_notification_pending_); - return pending_connectivity_state_unsafe_; -} - template void SubchannelData::StartConnectivityWatchLocked() { @@ -361,8 +350,7 @@ void SubchannelDatapolicy()->interested_parties(), &pending_connectivity_state_unsafe_, &connectivity_changed_closure_); @@ -379,7 +367,8 @@ void SubchannelDatanum_subchannels(), subchannel_); } - GPR_ASSERT(!connectivity_notification_pending_); + GPR_ASSERT(connectivity_notification_pending_); + connectivity_notification_pending_ = false; subchannel_list()->Unref(DEBUG_LOCATION, "connectivity_watch"); } @@ -453,7 +442,6 @@ void SubchannelData:: grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe_), grpc_error_string(error), sd->subchannel_list_->shutting_down()); } - sd->connectivity_notification_pending_ = false; // If shutting down, unref subchannel and stop watching. if (sd->subchannel_list_->shutting_down() || error == GRPC_ERROR_CANCELLED) { sd->UnrefSubchannelLocked("connectivity_shutdown"); diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 94f62637ec1..f2368ae7dd6 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -291,6 +291,17 @@ class ClientLbEnd2endTest : public ::testing::Test { ResetCounters(); } + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + bool SeenAllServers() { for (const auto& server : servers_) { if (server->service_.request_count() == 0) return false; @@ -590,18 +601,22 @@ TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) { gpr_log(GPR_INFO, "****** SERVER RESTARTED *******"); auto channel_2 = BuildChannel("pick_first"); auto stub_2 = BuildStub(channel_2); + // TODO(juanlishen): This resolution result will only be visible to channel 2 + // since the response generator is only associated with channel 2 now. We + // should change the response generator to be able to deliver updates to + // multiple channels at once. SetNextResolution(ports); gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 2 *******"); WaitForServer(stub_2, 0, DEBUG_LOCATION, true); gpr_log(GPR_INFO, "****** CHANNEL 2 CONNECTED *******"); servers_[0]->Shutdown(); + // Wait until the disconnection has triggered the connectivity notification. + // Otherwise, the subchannel may be picked for next call but will fail soon. + EXPECT_TRUE(WaitForChannelNotReady(channel_2.get())); // Channel 2 will also receive a re-resolution containing the same server. // Both channels will ref the same subchannel that failed. servers_.clear(); StartServers(1, ports); - // Wait for a while so that the disconnection has triggered the connectivity - // notification. Otherwise, the subchannel may be picked but will fail soon. - sleep(1); gpr_log(GPR_INFO, "****** SERVER RESTARTED AGAIN *******"); gpr_log(GPR_INFO, "****** CHANNEL 2 STARTING A CALL *******"); // The first call after the server restart will succeed. From e509e70b2da20fe837efdca0fe8c550ced1128a9 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 10 Aug 2018 15:01:25 -0700 Subject: [PATCH 086/546] Obj-c doesn't have nullptr, use NULL --- src/objective-c/GRPCClient/private/GRPCCompletionQueue.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m index 69db340e983..1e2537a5b18 100644 --- a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m +++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m @@ -22,10 +22,10 @@ #ifdef GRPC_CFSTREAM const grpc_completion_queue_attributes kCompletionQueueAttr = { - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING, nullptr}; + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING, NULL}; #else const grpc_completion_queue_attributes kCompletionQueueAttr = { - GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING, nullptr}; + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING, NULL}; #endif @implementation GRPCCompletionQueue From a0e92e7727ded204e3ada8f5cfa455805098852f Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 10 Aug 2018 14:57:52 -0700 Subject: [PATCH 087/546] Add proper synchronization so that stats are setup and destroyed cleanly --- .../microbenchmarks/bm_cq_multiple_threads.cc | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc index 4a5487f1c43..06922afda3c 100644 --- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc +++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc @@ -34,10 +34,13 @@ struct grpc_pollset { gpr_mu mu; }; +static gpr_mu g_mu; +static gpr_cv g_cv; +static int g_threads_active; +static bool g_active; + namespace grpc { namespace testing { - -static void* g_tag = (void*)static_cast(10); // Some random number static grpc_completion_queue* g_cq; static grpc_event_engine_vtable g_vtable; @@ -71,9 +74,11 @@ static grpc_error* pollset_work(grpc_pollset* ps, grpc_pollset_worker** worker, } gpr_mu_unlock(&ps->mu); - GPR_ASSERT(grpc_cq_begin_op(g_cq, g_tag)); + + void* tag = (void*)static_cast(10); // Some random number + GPR_ASSERT(grpc_cq_begin_op(g_cq, tag)); grpc_cq_end_op( - g_cq, g_tag, GRPC_ERROR_NONE, cq_done_cb, nullptr, + g_cq, tag, GRPC_ERROR_NONE, cq_done_cb, nullptr, static_cast(gpr_malloc(sizeof(grpc_cq_completion)))); grpc_core::ExecCtx::Get()->Flush(); gpr_mu_lock(&ps->mu); @@ -137,15 +142,31 @@ static void teardown() { code (i.e the code between two successive calls of state.KeepRunning()) if state.KeepRunning() returns false. So it is safe to do the teardown in one of the threads after state.keepRunning() returns false. + + However, our use requires synchronization because we do additional work at + each thread that requires specific ordering (TrackCounters must be constructed + after grpc_init because it needs the number of cores, initialized by grpc, + and its Finish call must take place before grpc_shutdown so that it can use + grpc_stats). */ static void BM_Cq_Throughput(benchmark::State& state) { - TrackCounters track_counters; gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC); auto thd_idx = state.thread_index; + gpr_mu_lock(&g_mu); + g_threads_active++; if (thd_idx == 0) { setup(); + g_active = true; + gpr_cv_broadcast(&g_cv); + } else { + while (!g_active) { + gpr_cv_wait(&g_cv, &g_mu, deadline); + } } + gpr_mu_unlock(&g_mu); + + TrackCounters track_counters; while (state.KeepRunning()) { GPR_ASSERT(grpc_completion_queue_next(g_cq, deadline, nullptr).type == @@ -155,8 +176,20 @@ static void BM_Cq_Throughput(benchmark::State& state) { state.SetItemsProcessed(state.iterations()); track_counters.Finish(state); + gpr_mu_lock(&g_mu); + g_threads_active--; + if (g_threads_active == 0) { + gpr_cv_broadcast(&g_cv); + } else { + while (g_threads_active > 0) { + gpr_cv_wait(&g_cv, &g_mu, deadline); + } + } + gpr_mu_unlock(&g_mu); + if (thd_idx == 0) { teardown(); + g_active = false; } } @@ -172,6 +205,8 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + gpr_mu_init(&g_mu); + gpr_cv_init(&g_cv); ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); From ccf04c45112ac43b880b7a28cb7c789fa47284fa Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 13 Aug 2018 07:28:54 -0700 Subject: [PATCH 088/546] WIP --- src/core/ext/filters/client_channel/client_channel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 82c844a8003..8b4f1b604ce 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1312,7 +1312,7 @@ static void recv_trailing_metadata_ready_channelz(void* arg, channelz_subchannel->RecordCallFailed(); } pending->batch = nullptr; - GRPC_CLOSURE_SCHED(calld->original_recv_trailing_metadata, error); + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata, error); } // If channelz is enabled, intercept recv_trailing so that we may check the From ec8a5f2d74cf997582b476b83332411c4defc57c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 13 Aug 2018 14:55:22 +0200 Subject: [PATCH 089/546] C# sanity test accepts [TestCase] attribute too --- src/csharp/Grpc.Core.Tests/SanityTest.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/SanityTest.cs b/src/csharp/Grpc.Core.Tests/SanityTest.cs index 73efad1f842..eaad409ec0b 100644 --- a/src/csharp/Grpc.Core.Tests/SanityTest.cs +++ b/src/csharp/Grpc.Core.Tests/SanityTest.cs @@ -65,13 +65,13 @@ namespace Grpc.Core.Tests { foreach (var m in t.GetMethods()) { - var attributes = m.GetCustomAttributes(typeof(NUnit.Framework.TestAttribute), true); - if (attributes.Length > 0) + var testAttributes = m.GetCustomAttributes(typeof(NUnit.Framework.TestAttribute), true); + var testCaseAttributes = m.GetCustomAttributes(typeof(NUnit.Framework.TestCaseAttribute), true); + if (testAttributes.Length > 0 || testCaseAttributes.Length > 0) { testClasses.Add(t.FullName); break; } - } } testClasses.Sort(); From c2f270fe37bcda78bd1c241a7d82339949fca6fd Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 13 Aug 2018 15:55:54 +0200 Subject: [PATCH 090/546] sync nunit version for all test projects --- src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj | 4 ++-- src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj | 4 ++-- .../Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj | 4 ++-- .../Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj | 4 ++-- src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index 18993a93e00..d58f0468244 100755 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj index d2cc5bbc65e..7493eb8051d 100755 --- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj +++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj index 9da0539dcb9..616e56df105 100755 --- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj +++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj @@ -16,8 +16,8 @@ - - + + diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index e4f36d8810d..ad7033b7829 100755 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -19,8 +19,8 @@ - - + + diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj index d3686971245..0c12f38f25a 100755 --- a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj +++ b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj @@ -16,8 +16,8 @@ - - + + From 4e1e6ceda98b0a196ddb7939153edb78a0a20dbe Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 13 Aug 2018 09:44:53 -0700 Subject: [PATCH 091/546] Fix pick_first to not throw away unused subchannels. --- .../lb_policy/pick_first/pick_first.cc | 22 +++---------------- .../lb_policy/subchannel_list.h | 9 ++++---- .../ext/filters/client_channel/resolver.h | 13 +---------- .../resolver/dns/c_ares/dns_resolver_ares.cc | 12 +--------- .../resolver/dns/native/dns_resolver.cc | 12 +--------- .../resolver/fake/fake_resolver.cc | 16 +------------- .../resolver/fake/fake_resolver.h | 3 ++- .../resolver/sockaddr/sockaddr_resolver.cc | 7 ------ test/cpp/end2end/client_lb_end2end_test.cc | 17 ++++++++++++++ 9 files changed, 30 insertions(+), 81 deletions(-) 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 1cd5ef065de..d88b2b2ea47 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 @@ -125,7 +125,6 @@ class PickFirst : public LoadBalancingPolicy { void ShutdownLocked() override; void StartPickingLocked(); - void DestroyUnselectedSubchannelsLocked(); void UpdateChildRefsLocked(); // All our subchannels. @@ -293,15 +292,6 @@ bool PickFirst::PickLocked(PickState* pick, grpc_error** error) { return false; } -void PickFirst::DestroyUnselectedSubchannelsLocked() { - for (size_t i = 0; i < subchannel_list_->num_subchannels(); ++i) { - PickFirstSubchannelData* sd = subchannel_list_->subchannel(i); - if (selected_ != sd) { - sd->UnrefSubchannelLocked("selected_different_subchannel"); - } - } -} - grpc_connectivity_state PickFirst::CheckConnectivityLocked(grpc_error** error) { return grpc_connectivity_state_get(&state_tracker_, error); } @@ -418,7 +408,6 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) { if (sd->CheckConnectivityStateLocked(&error) == GRPC_CHANNEL_READY) { selected_ = sd; subchannel_list_ = std::move(subchannel_list); - DestroyUnselectedSubchannelsLocked(); sd->StartConnectivityWatchLocked(); // If there was a previously pending update (which may or may // not have contained the currently selected subchannel), drop @@ -503,7 +492,6 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE); // In transient failure. Rely on re-resolution to recover. p->selected_ = nullptr; - UnrefSubchannelLocked("pf_selected_shutdown"); StopConnectivityWatchLocked(); } else { grpc_connectivity_state_set(&p->state_tracker_, connectivity_state, @@ -534,11 +522,9 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( case GRPC_CHANNEL_TRANSIENT_FAILURE: { StopConnectivityWatchLocked(); PickFirstSubchannelData* sd = this; - do { - size_t next_index = - (sd->Index() + 1) % subchannel_list()->num_subchannels(); - sd = subchannel_list()->subchannel(next_index); - } while (sd->subchannel() == nullptr); + size_t next_index = + (sd->Index() + 1) % subchannel_list()->num_subchannels(); + sd = subchannel_list()->subchannel(next_index); // Case 1: Only set state to TRANSIENT_FAILURE if we've tried // all subchannels. if (sd->Index() == 0 && subchannel_list() == p->subchannel_list_.get()) { @@ -608,8 +594,6 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); } - // Drop all other subchannels, since we are now connected. - p->DestroyUnselectedSubchannelsLocked(); // Update any calls that were waiting for a pick. PickState* pick; while ((pick = p->pending_picks_)) { 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 0fa2f04e73b..91ddaec8b8f 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 @@ -102,11 +102,6 @@ class SubchannelData { return pending_connectivity_state_unsafe_; } - // Unrefs the subchannel. May be used if an individual subchannel is - // no longer needed even though the subchannel list as a whole is not - // being unreffed. - virtual void UnrefSubchannelLocked(const char* reason); - // Resets the connection backoff. // TODO(roth): This method should go away when we move the backoff // code out of the subchannel and into the LB policies. @@ -154,6 +149,10 @@ class SubchannelData { grpc_connectivity_state connectivity_state, grpc_error* error) GRPC_ABSTRACT; + // Unrefs the subchannel. May be overridden by subclasses that need + // to perform extra cleanup when unreffing the subchannel. + virtual void UnrefSubchannelLocked(const char* reason); + private: // Updates connected_subchannel_ based on pending_connectivity_state_unsafe_. // Returns true if the connectivity state should be reported. diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h index 48f2e890952..e9acbb7c41c 100644 --- a/src/core/ext/filters/client_channel/resolver.h +++ b/src/core/ext/filters/client_channel/resolver.h @@ -81,18 +81,7 @@ class Resolver : public InternallyRefCountedWithTracing { /// /// If this causes new data to become available, then the currently /// pending call to \a NextLocked() will return the new result. - /// - /// Note: Currently, all resolvers are required to return a new result - /// shortly after this method is called. For pull-based mechanisms, if - /// the implementation decides to delay querying the name service, it - /// should immediately return a new copy of the previously returned - /// result (and it can then return the updated data later, when it - /// actually does query the name service). For push-based mechanisms, - /// the implementation should immediately return a new copy of the - /// last-seen result. - /// TODO(roth): Remove this requirement once we fix pick_first to not - /// throw away unselected subchannels. - virtual void RequestReresolutionLocked() GRPC_ABSTRACT; + virtual void RequestReresolutionLocked() {} /// Resets the re-resolution backoff, if any. /// This needs to be implemented only by pull-based implementations; 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 f2bb5f3c712..dfa52867d8b 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 @@ -373,13 +373,7 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { void AresDnsResolver::MaybeStartResolvingLocked() { // If there is an existing timer, the time it fires is the earliest time we // can start the next resolution. - if (have_next_resolution_timer_) { - // TODO(dgq): remove the following two lines once Pick First stops - // discarding subchannels after selecting. - ++resolved_version_; - MaybeFinishNextLocked(); - return; - } + if (have_next_resolution_timer_) return; if (last_resolution_timestamp_ >= 0) { const grpc_millis earliest_next_resolution = last_resolution_timestamp_ + min_time_between_resolutions_; @@ -401,10 +395,6 @@ void AresDnsResolver::MaybeStartResolvingLocked() { self.release(); grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution, &on_next_resolution_); - // TODO(dgq): remove the following two lines once Pick First stops - // discarding subchannels after selecting. - ++resolved_version_; - MaybeFinishNextLocked(); return; } } diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc index 282caf215c7..65ff1ec1a5b 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -247,13 +247,7 @@ void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { void NativeDnsResolver::MaybeStartResolvingLocked() { // If there is an existing timer, the time it fires is the earliest time we // can start the next resolution. - if (have_next_resolution_timer_) { - // TODO(dgq): remove the following two lines once Pick First stops - // discarding subchannels after selecting. - ++resolved_version_; - MaybeFinishNextLocked(); - return; - } + if (have_next_resolution_timer_) return; if (last_resolution_timestamp_ >= 0) { const grpc_millis earliest_next_resolution = last_resolution_timestamp_ + min_time_between_resolutions_; @@ -275,10 +269,6 @@ void NativeDnsResolver::MaybeStartResolvingLocked() { self.release(); grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution, &on_next_resolution_); - // TODO(dgq): remove the following two lines once Pick First stops - // discarding subchannels after selecting. - ++resolved_version_; - MaybeFinishNextLocked(); return; } } 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 99a33f2277e..d090545d0c0 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 @@ -73,11 +73,6 @@ class FakeResolver : public Resolver { // Results to use for the pretended re-resolution in // RequestReresolutionLocked(). grpc_channel_args* reresolution_results_ = nullptr; - // TODO(juanlishen): This can go away once pick_first is changed to not throw - // away its subchannels, since that will eliminate its dependence on - // channel_saw_error_locked() causing an immediate resolver return. - // A copy of the most-recently used resolution results. - grpc_channel_args* last_used_results_ = nullptr; // pending next completion, or NULL grpc_closure* next_completion_ = nullptr; // target result address for next completion @@ -96,7 +91,6 @@ FakeResolver::FakeResolver(const ResolverArgs& args) : Resolver(args.combiner) { FakeResolver::~FakeResolver() { grpc_channel_args_destroy(next_results_); grpc_channel_args_destroy(reresolution_results_); - grpc_channel_args_destroy(last_used_results_); grpc_channel_args_destroy(channel_args_); } @@ -109,17 +103,11 @@ void FakeResolver::NextLocked(grpc_channel_args** target_result, } void FakeResolver::RequestReresolutionLocked() { - // A resolution must have been returned before an error is seen. - GPR_ASSERT(last_used_results_ != nullptr); grpc_channel_args_destroy(next_results_); if (reresolution_results_ != nullptr) { next_results_ = grpc_channel_args_copy(reresolution_results_); - } else { - // If reresolution_results is unavailable, re-resolve with the most-recently - // used results to avoid a no-op re-resolution. - next_results_ = grpc_channel_args_copy(last_used_results_); + MaybeFinishNextLocked(); } - MaybeFinishNextLocked(); } void FakeResolver::MaybeFinishNextLocked() { @@ -161,8 +149,6 @@ void FakeResolverResponseGenerator::SetResponseLocked(void* arg, FakeResolver* resolver = closure_arg->generator->resolver_; grpc_channel_args_destroy(resolver->next_results_); resolver->next_results_ = closure_arg->response; - grpc_channel_args_destroy(resolver->last_used_results_); - resolver->last_used_results_ = grpc_channel_args_copy(closure_arg->response); resolver->MaybeFinishNextLocked(); Delete(closure_arg); } 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 e5175f9b7bc..708eaf11476 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 @@ -53,7 +53,8 @@ class FakeResolverResponseGenerator // The new re-resolution response replaces any previous re-resolution // response that may have been set by a previous call. // If the re-resolution response is set to NULL, then the fake - // resolver will return the last value set via \a SetResponse(). + // resolver will not return anything when \a RequestReresolutionLocked() + // is called. void SetReresolutionResponse(grpc_channel_args* response); // Tells the resolver to return a transient failure (signalled by 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 f74ac5aebe5..801734764b4 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 @@ -50,8 +50,6 @@ class SockaddrResolver : public Resolver { void NextLocked(grpc_channel_args** result, grpc_closure* on_complete) override; - void RequestReresolutionLocked() override; - void ShutdownLocked() override; private: @@ -90,11 +88,6 @@ void SockaddrResolver::NextLocked(grpc_channel_args** target_result, MaybeFinishNextLocked(); } -void SockaddrResolver::RequestReresolutionLocked() { - published_ = false; - MaybeFinishNextLocked(); -} - void SockaddrResolver::ShutdownLocked() { if (next_completion_ != nullptr) { *target_result_ = nullptr; diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index f2368ae7dd6..50ad78cf134 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -584,6 +584,23 @@ TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } +TEST_F(ClientLbEnd2endTest, PickFirstReconnectWithoutNewResolverResult) { + std::vector ports = {grpc_pick_unused_port_or_die()}; + StartServers(1, ports); + auto channel = BuildChannel("pick_first"); + auto stub = BuildStub(channel); + SetNextResolution(ports); + gpr_log(GPR_INFO, "****** INITIAL CONNECTION *******"); + WaitForServer(stub, 0, DEBUG_LOCATION); + gpr_log(GPR_INFO, "****** STOPPING SERVER ******"); + servers_[0]->Shutdown(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + gpr_log(GPR_INFO, "****** RESTARTING SERVER ******"); + servers_.clear(); + StartServers(1, ports); + WaitForServer(stub, 0, DEBUG_LOCATION); +} + TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) { std::vector ports = {grpc_pick_unused_port_or_die()}; StartServers(1, ports); From e0ae6c73ec97c5e62c82c99a603ac13730b23cff Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 13 Aug 2018 10:30:51 -0700 Subject: [PATCH 092/546] Fix bug with proxy end2end test --- .../filters/client_channel/client_channel.cc | 58 ++++++++++--------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 8b4f1b604ce..d3a4c498214 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -934,8 +934,10 @@ typedef struct client_channel_call_data { grpc_closure pick_closure; grpc_closure pick_cancel_closure; + // state needed to support channelz interception of recv trailing metadata. grpc_closure recv_trailing_metadata_ready_channelz; grpc_closure* original_recv_trailing_metadata; + grpc_transport_stream_op_batch* recv_trailing_metadata_batch; grpc_polling_entity* pollent; bool pollent_added_to_interested_parties; @@ -1291,17 +1293,11 @@ static void recv_trailing_metadata_ready_channelz(void* arg, "error=%s", chand, calld, grpc_error_string(error)); } - // find the right pending batch. - pending_batch* pending = pending_batch_find( - elem, "invoking recv_trailing_metadata_channelz for", - [](grpc_transport_stream_op_batch* batch) { - return batch->recv_trailing_metadata && - batch->payload->recv_trailing_metadata - .recv_trailing_metadata_ready != nullptr; - }); + GPR_ASSERT(calld->recv_trailing_metadata_batch != nullptr); grpc_status_code status = GRPC_STATUS_OK; grpc_metadata_batch* md_batch = - pending->batch->payload->recv_trailing_metadata.recv_trailing_metadata; + calld->recv_trailing_metadata_batch->payload->recv_trailing_metadata + .recv_trailing_metadata; get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, nullptr); grpc_core::channelz::SubchannelNode* channelz_subchannel = calld->pick.connected_subchannel->channelz_subchannel(); @@ -1311,29 +1307,39 @@ static void recv_trailing_metadata_ready_channelz(void* arg, } else { channelz_subchannel->RecordCallFailed(); } - pending->batch = nullptr; + calld->recv_trailing_metadata_batch = nullptr; GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata, error); } // If channelz is enabled, intercept recv_trailing so that we may check the // status and associate it to a subchannel. // Returns true if callback was intercepted, false otherwise. -static bool maybe_intercept_recv_trailing_for_channelz( +static void maybe_intercept_recv_trailing_for_channelz( grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { call_data* calld = static_cast(elem->call_data); + // only intercept payloads with recv trailing. + if (!batch->recv_trailing_metadata) { + return; + } // only add interceptor is channelz is enabled. - if (calld->pick.connected_subchannel->channelz_subchannel() != nullptr) { - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_channelz, - recv_trailing_metadata_ready_channelz, elem, - grpc_schedule_on_exec_ctx); - calld->original_recv_trailing_metadata = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &calld->recv_trailing_metadata_ready_channelz; - return true; - } else { - return false; + if (calld->pick.connected_subchannel->channelz_subchannel() == nullptr) { + return; + } + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, + "calld=%p batch=%p: intercepting recv trailing for channelz", calld, + batch); } + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_channelz, + recv_trailing_metadata_ready_channelz, elem, + grpc_schedule_on_exec_ctx); + // save some state needed for the interception callback. + GPR_ASSERT(calld->recv_trailing_metadata_batch == nullptr); + calld->recv_trailing_metadata_batch = batch; + calld->original_recv_trailing_metadata = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->recv_trailing_metadata_ready_channelz; } // This is called via the call combiner, so access to calld is synchronized. @@ -1360,18 +1366,14 @@ static void pending_batches_resume(grpc_call_element* elem) { pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { - bool intercepted = - maybe_intercept_recv_trailing_for_channelz(elem, batch); + maybe_intercept_recv_trailing_for_channelz(elem, batch); 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); closures.Add(&batch->handler_private.closure, GRPC_ERROR_NONE, "pending_batches_resume"); - // Only clear if we haven't intercepted anything. - if (!intercepted) { - pending_batch_clear(calld, pending); - } + pending_batch_clear(calld, pending); } } // Note: This will release the call combiner. From f6dea9ec6a2d3a9baa5ea16dd99f52dd0a3ca0ef Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 13 Aug 2018 10:33:28 -0700 Subject: [PATCH 093/546] Add another test. --- test/cpp/end2end/client_lb_end2end_test.cc | 50 +++++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 50ad78cf134..8e0ee7bd76a 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -129,12 +129,24 @@ class ClientLbEnd2endTest : public ::testing::Test { } } - void StartServers(size_t num_servers, - std::vector ports = std::vector()) { + void CreateServers(size_t num_servers, + std::vector ports = std::vector()) { for (size_t i = 0; i < num_servers; ++i) { int port = 0; if (ports.size() == num_servers) port = ports[i]; - servers_.emplace_back(new ServerData(server_host_, port)); + servers_.emplace_back(new ServerData(port)); + } + } + + void StartServer(size_t index) { + servers_[index]->Start(server_host_); + } + + void StartServers(size_t num_servers, + std::vector ports = std::vector()) { + if (servers_.empty()) CreateServers(num_servers, ports); + for (size_t i = 0; i < num_servers; ++i) { + StartServer(i); } } @@ -240,20 +252,23 @@ class ClientLbEnd2endTest : public ::testing::Test { std::unique_ptr thread_; bool server_ready_ = false; - explicit ServerData(const grpc::string& server_host, int port = 0) { + explicit ServerData(int port = 0) { port_ = port > 0 ? port : grpc_pick_unused_port_or_die(); + } + + void Start(const grpc::string& server_host) { gpr_log(GPR_INFO, "starting server on port %d", port_); std::mutex mu; std::unique_lock lock(mu); std::condition_variable cond; thread_.reset(new std::thread( - std::bind(&ServerData::Start, this, server_host, &mu, &cond))); + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); cond.wait(lock, [this] { return server_ready_; }); server_ready_ = false; gpr_log(GPR_INFO, "server startup complete"); } - void Start(const grpc::string& server_host, std::mutex* mu, + void Serve(const grpc::string& server_host, std::mutex* mu, std::condition_variable* cond) { std::ostringstream server_address; server_address << server_host << ":" << port_; @@ -601,6 +616,26 @@ TEST_F(ClientLbEnd2endTest, PickFirstReconnectWithoutNewResolverResult) { WaitForServer(stub, 0, DEBUG_LOCATION); } +TEST_F(ClientLbEnd2endTest, + PickFirstReconnectWithoutNewResolverResultStartsFromTopOfList) { + std::vector ports = {grpc_pick_unused_port_or_die(), + grpc_pick_unused_port_or_die()}; + CreateServers(2, ports); + StartServer(1); + auto channel = BuildChannel("pick_first"); + auto stub = BuildStub(channel); + SetNextResolution(ports); + gpr_log(GPR_INFO, "****** INITIAL CONNECTION *******"); + WaitForServer(stub, 1, DEBUG_LOCATION); + gpr_log(GPR_INFO, "****** STOPPING SERVER ******"); + servers_[1]->Shutdown(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + gpr_log(GPR_INFO, "****** STARTING SERVER 0 ******"); + servers_.clear(); + StartServers(2, ports); + WaitForServer(stub, 0, DEBUG_LOCATION); +} + TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) { std::vector ports = {grpc_pick_unused_port_or_die()}; StartServers(1, ports); @@ -921,7 +956,8 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { // No requests have gone to the deceased server. EXPECT_EQ(pre_death, post_death); // Bring the first server back up. - servers_[0].reset(new ServerData(server_host_, ports[0])); + servers_[0].reset(new ServerData(ports[0])); + StartServer(0); // Requests should start arriving at the first server either right away (if // the server managed to start before the RR policy retried the subchannel) or // after the subchannel retry delay otherwise (RR's subchannel retried before From 0ec6973b743e8e1f463bdcc8691e1869097c92f0 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 Aug 2018 10:48:41 -0700 Subject: [PATCH 094/546] Revert semantic changes for fd_notify_on_* --- src/core/lib/iomgr/buffer_list.h | 2 ++ src/core/lib/iomgr/ev_epoll1_linux.cc | 18 +++--------------- src/core/lib/iomgr/ev_epollex_linux.cc | 18 +++--------------- src/core/lib/iomgr/ev_epollsig_linux.cc | 18 +++--------------- src/core/lib/iomgr/internal_errqueue.cc | 2 +- 5 files changed, 12 insertions(+), 46 deletions(-) diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h index 0f66dcc8727..cbbf50a6575 100644 --- a/src/core/lib/iomgr/buffer_list.h +++ b/src/core/lib/iomgr/buffer_list.h @@ -31,6 +31,8 @@ namespace grpc_core { struct Timestamps { + /* TODO(yashykt): This would also need to store OPTSTAT once support is added + */ gpr_timespec sendmsg_time; gpr_timespec scheduled_time; gpr_timespec sent_time; diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index e8ee5c4ce94..86a0243d2ef 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -386,27 +386,15 @@ static bool fd_is_shutdown(grpc_fd* fd) { } static void fd_notify_on_read(grpc_fd* fd, grpc_closure* closure) { - if (closure != nullptr) { - fd->read_closure->NotifyOn(closure); - } else { - fd->read_closure->SetReady(); - } + fd->read_closure->NotifyOn(closure); } static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) { - if (closure != nullptr) { - fd->write_closure->NotifyOn(closure); - } else { - fd->write_closure->SetReady(); - } + fd->write_closure->NotifyOn(closure); } static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) { - if (closure != nullptr) { - fd->error_closure->NotifyOn(closure); - } else { - fd->error_closure->SetReady(); - } + fd->error_closure->NotifyOn(closure); } static void fd_become_readable(grpc_fd* fd, grpc_pollset* notifier) { diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index b17aa905738..7b368410cf6 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -539,27 +539,15 @@ static void fd_shutdown(grpc_fd* fd, grpc_error* why) { } static void fd_notify_on_read(grpc_fd* fd, grpc_closure* closure) { - if (closure != nullptr) { - fd->read_closure->NotifyOn(closure); - } else { - fd->read_closure->SetReady(); - } + fd->read_closure->NotifyOn(closure); } static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) { - if (closure != nullptr) { - fd->write_closure->NotifyOn(closure); - } else { - fd->write_closure->SetReady(); - } + fd->write_closure->NotifyOn(closure); } static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) { - if (closure != nullptr) { - fd->error_closure->NotifyOn(closure); - } else { - fd->error_closure->SetReady(); - } + fd->error_closure->NotifyOn(closure); } /******************************************************************************* diff --git a/src/core/lib/iomgr/ev_epollsig_linux.cc b/src/core/lib/iomgr/ev_epollsig_linux.cc index 7bdfa22b8e4..2189801c187 100644 --- a/src/core/lib/iomgr/ev_epollsig_linux.cc +++ b/src/core/lib/iomgr/ev_epollsig_linux.cc @@ -947,27 +947,15 @@ static void fd_shutdown(grpc_fd* fd, grpc_error* why) { } static void fd_notify_on_read(grpc_fd* fd, grpc_closure* closure) { - if (closure != nullptr) { - fd->read_closure->NotifyOn(closure); - } else { - fd->read_closure->SetReady(); - } + fd->read_closure->NotifyOn(closure); } static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) { - if (closure != nullptr) { - fd->write_closure->NotifyOn(closure); - } else { - fd->write_closure->SetReady(); - } + fd->write_closure->NotifyOn(closure); } static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) { - if (closure != nullptr) { - fd->error_closure->NotifyOn(closure); - } else { - fd->error_closure->SetReady(); - } + fd->error_closure->NotifyOn(closure); } /******************************************************************************* diff --git a/src/core/lib/iomgr/internal_errqueue.cc b/src/core/lib/iomgr/internal_errqueue.cc index 3f3da668406..8823737e494 100644 --- a/src/core/lib/iomgr/internal_errqueue.cc +++ b/src/core/lib/iomgr/internal_errqueue.cc @@ -30,7 +30,7 @@ bool kernel_supports_errqueue() { #ifdef LINUX_VERSION_CODE -#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) return true; #endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) */ #endif /* LINUX_VERSION_CODE */ From 82af3609dd58fcdbbfd4fc50c4232840df69a52d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 13 Aug 2018 19:52:16 +0200 Subject: [PATCH 095/546] use correct target name for gflags-config.cmake --- cmake/gflags.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/gflags.cmake b/cmake/gflags.cmake index 01e0a75b60b..c301b1cdb6d 100644 --- a/cmake/gflags.cmake +++ b/cmake/gflags.cmake @@ -28,8 +28,8 @@ if("${gRPC_GFLAGS_PROVIDER}" STREQUAL "module") elseif("${gRPC_GFLAGS_PROVIDER}" STREQUAL "package") # Use "CONFIG" as there is no built-in cmake module for gflags. find_package(gflags REQUIRED CONFIG) - if(TARGET gflags::gflags) - set(_gRPC_GFLAGS_LIBRARIES gflags::gflags) + if(TARGET gflags) + set(_gRPC_GFLAGS_LIBRARIES gflags) set(_gRPC_GFLAGS_INCLUDE_DIR ${GFLAGS_INCLUDE_DIR}) endif() set(_gRPC_FIND_GFLAGS "if(NOT gflags_FOUND)\n find_package(gflags CONFIG)\nendif()") From 965102527f402a7e7fd0246f4fb597023f1728d1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 7 May 2018 19:33:20 +0200 Subject: [PATCH 096/546] make should generate pkg-config file for gpr as well --- Makefile | 19 +++++++++++++++++-- templates/Makefile.template | 19 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 9d23de866cd..225098e3e0d 100644 --- a/Makefile +++ b/Makefile @@ -767,6 +767,15 @@ else LDLIBS_SECURE += $(addprefix -l, $(LIBS_SECURE)) endif +# gpr .pc file +PC_NAME = gpr +PC_DESCRIPTION = gRPC platform support library +PC_CFLAGS = +PC_REQUIRES_PRIVATE = $(PC_REQUIRES_GPR) +PC_LIBS_PRIVATE = $(PC_LIBS_GPR) +PC_LIB = -lgpr +GPR_PC_FILE := $(CORE_PC_TEMPLATE) + # grpc .pc file PC_NAME = gRPC PC_DESCRIPTION = high performance general RPC framework @@ -1398,9 +1407,9 @@ plugins: $(PROTOC_PLUGINS) privatelibs: privatelibs_c privatelibs_cxx privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a -pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc +pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc -pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc +pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc @@ -2519,6 +2528,11 @@ cache.mk:: $(E) "[MAKE] Generating $@" $(Q) echo "$(CACHE_MK)" | tr , '\n' >$@ +$(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc: + $(E) "[MAKE] Generating $@" + $(Q) mkdir -p $(@D) + $(Q) echo "$(GPR_PC_FILE)" | tr , '\n' >$@ + $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc: $(E) "[MAKE] Generating $@" $(Q) mkdir -p $(@D) @@ -3129,6 +3143,7 @@ install-grpc-cli: grpc_cli install-pkg-config_c: pc_c pc_c_unsecure $(E) "[INSTALL] Installing C pkg-config files" $(Q) $(INSTALL) -d $(prefix)/lib/pkgconfig + $(Q) $(INSTALL) -m 0644 $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc $(prefix)/lib/pkgconfig/gpr.pc $(Q) $(INSTALL) -m 0644 $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc $(prefix)/lib/pkgconfig/grpc.pc $(Q) $(INSTALL) -m 0644 $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc $(prefix)/lib/pkgconfig/grpc_unsecure.pc diff --git a/templates/Makefile.template b/templates/Makefile.template index 50b81e5f9f2..e48e87b86e4 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -668,6 +668,15 @@ LDLIBS_SECURE += $(addprefix -l, $(LIBS_SECURE)) endif + # gpr .pc file + PC_NAME = gpr + PC_DESCRIPTION = gRPC platform support library + PC_CFLAGS = + PC_REQUIRES_PRIVATE = $(PC_REQUIRES_GPR) + PC_LIBS_PRIVATE = $(PC_LIBS_GPR) + PC_LIB = -lgpr + GPR_PC_FILE := $(CORE_PC_TEMPLATE) + # grpc .pc file PC_NAME = gRPC PC_DESCRIPTION = high performance general RPC framework @@ -976,9 +985,9 @@ % endif % endfor - pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc + pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc - pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc + pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc @@ -1199,6 +1208,11 @@ $(E) "[MAKE] Generating $@" $(Q) echo "$(CACHE_MK)" | tr , '\n' >$@ + $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc: + $(E) "[MAKE] Generating $@" + $(Q) mkdir -p $(@D) + $(Q) echo "$(GPR_PC_FILE)" | tr , '\n' >$@ + $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc: $(E) "[MAKE] Generating $@" $(Q) mkdir -p $(@D) @@ -1397,6 +1411,7 @@ install-pkg-config_c: pc_c pc_c_unsecure $(E) "[INSTALL] Installing C pkg-config files" $(Q) $(INSTALL) -d $(prefix)/lib/pkgconfig + $(Q) $(INSTALL) -m 0644 $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc $(prefix)/lib/pkgconfig/gpr.pc $(Q) $(INSTALL) -m 0644 $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc $(prefix)/lib/pkgconfig/grpc.pc $(Q) $(INSTALL) -m 0644 $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc $(prefix)/lib/pkgconfig/grpc_unsecure.pc From cf8546255795cac575a11f696126abc4fe10b10a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 13 Aug 2018 21:00:19 +0200 Subject: [PATCH 097/546] pkgconfig: add gpr to grpc's Requires.private --- Makefile | 4 ++-- templates/Makefile.template | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 225098e3e0d..aa6f8d076b1 100644 --- a/Makefile +++ b/Makefile @@ -780,7 +780,7 @@ GPR_PC_FILE := $(CORE_PC_TEMPLATE) PC_NAME = gRPC PC_DESCRIPTION = high performance general RPC framework PC_CFLAGS = -PC_REQUIRES_PRIVATE = $(PC_REQUIRES_GRPC) $(PC_REQUIRES_SECURE) +PC_REQUIRES_PRIVATE = gpr $(PC_REQUIRES_GRPC) $(PC_REQUIRES_SECURE) PC_LIBS_PRIVATE = $(PC_LIBS_GRPC) $(PC_LIBS_SECURE) PC_LIB = -lgrpc GRPC_PC_FILE := $(CORE_PC_TEMPLATE) @@ -789,7 +789,7 @@ GRPC_PC_FILE := $(CORE_PC_TEMPLATE) PC_NAME = gRPC unsecure PC_DESCRIPTION = high performance general RPC framework without SSL PC_CFLAGS = -PC_REQUIRES_PRIVATE = $(PC_REQUIRES_GRPC) +PC_REQUIRES_PRIVATE = gpr $(PC_REQUIRES_GRPC) PC_LIBS_PRIVATE = $(PC_LIBS_GRPC) PC_LIB = -lgrpc GRPC_UNSECURE_PC_FILE := $(CORE_PC_TEMPLATE) diff --git a/templates/Makefile.template b/templates/Makefile.template index e48e87b86e4..2e3d75d819e 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -681,7 +681,7 @@ PC_NAME = gRPC PC_DESCRIPTION = high performance general RPC framework PC_CFLAGS = - PC_REQUIRES_PRIVATE = $(PC_REQUIRES_GRPC) $(PC_REQUIRES_SECURE) + PC_REQUIRES_PRIVATE = gpr $(PC_REQUIRES_GRPC) $(PC_REQUIRES_SECURE) PC_LIBS_PRIVATE = $(PC_LIBS_GRPC) $(PC_LIBS_SECURE) PC_LIB = -lgrpc GRPC_PC_FILE := $(CORE_PC_TEMPLATE) @@ -690,7 +690,7 @@ PC_NAME = gRPC unsecure PC_DESCRIPTION = high performance general RPC framework without SSL PC_CFLAGS = - PC_REQUIRES_PRIVATE = $(PC_REQUIRES_GRPC) + PC_REQUIRES_PRIVATE = gpr $(PC_REQUIRES_GRPC) PC_LIBS_PRIVATE = $(PC_LIBS_GRPC) PC_LIB = -lgrpc GRPC_UNSECURE_PC_FILE := $(CORE_PC_TEMPLATE) From 4af7ef8c1fe10f08d52e1223342cbbcbaeee4137 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 Aug 2018 12:29:56 -0700 Subject: [PATCH 098/546] Reviewer comments --- src/core/lib/iomgr/buffer_list.cc | 28 +++++----- src/core/lib/iomgr/tcp_posix.cc | 90 ++++++++++++++++++------------- 2 files changed, 66 insertions(+), 52 deletions(-) diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc index 8d1645d0dec..6ada23db1c2 100644 --- a/src/core/lib/iomgr/buffer_list.cc +++ b/src/core/lib/iomgr/buffer_list.cc @@ -69,9 +69,7 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head, TracedBuffer* next = nullptr; while (elem != nullptr) { /* The byte number refers to the sequence number of the last byte which this - * timestamp relates to. For scheduled and send, we are interested in the - * timestamp for the first byte, whereas for ack, we are interested in the - * last */ + * timestamp relates to. */ if (serr->ee_data >= elem->seq_no_) { switch (serr->ee_info) { case SCM_TSTAMP_SCHED: @@ -83,19 +81,17 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head, elem = elem->next_; break; case SCM_TSTAMP_ACK: - if (serr->ee_data >= elem->seq_no_) { - fill_gpr_from_timestamp(&(elem->ts_.acked_time), &(tss->ts[0])); - /* Got all timestamps. Do the callback and free this TracedBuffer. - * The thing below can be passed by value if we don't want the - * restriction on the lifetime. */ - timestamps_callback(elem->arg_, &(elem->ts_), GRPC_ERROR_NONE); - next = elem->next_; - Delete(elem); - *head = elem = next; - break; - default: - abort(); - } + fill_gpr_from_timestamp(&(elem->ts_.acked_time), &(tss->ts[0])); + /* Got all timestamps. Do the callback and free this TracedBuffer. + * The thing below can be passed by value if we don't want the + * restriction on the lifetime. */ + timestamps_callback(elem->arg_, &(elem->ts_), GRPC_ERROR_NONE); + next = elem->next_; + Delete(elem); + *head = elem = next; + break; + default: + abort(); } } else { break; diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 6a16b8d628b..d8f58408c7c 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -107,11 +107,22 @@ struct grpc_tcp { grpc_resource_user* resource_user; grpc_resource_user_slice_allocator slice_allocator; - grpc_core::TracedBuffer* head; /* List of traced buffers */ - gpr_mu traced_buffer_lock; /* Lock for access to list of traced buffers */ - void* outgoing_buffer_arg; /* buffer arg provided on grpc_endpoint_write */ - int bytes_counter; /* Current TCP relative sequence number. Used for - timestamping traced buffers. */ + grpc_core::TracedBuffer* tb_head; /* List of traced buffers */ + gpr_mu tb_mu; /* Lock for access to list of traced buffers */ + + /* grpc_endpoint_write takes an argument which if non-null means that the + * transport layer wants the TCP layer to collect timestamps for this write. + * This arg is forwarded to the timestamps callback function when the ACK + * timestamp is received from the kernel. This arg is a (void *) which allows + * users of this API to pass in a pointer to any kind of structure. This + * structure could actually be a tag or any book-keeping object that the user + * can use to distinguish between different traced writes. The only + * requirement from the TCP endpoint layer is that this arg should be non-null + * if the user wants timestamps for the write. */ + void* outgoing_buffer_arg; + /* Current TCP relative sequence number as defined in RFC 793. Used for + * timestamping traced buffers. */ + int bytes_counter; bool socket_ts_enabled; /* True if timestamping options are set on the socket */ gpr_atm @@ -318,7 +329,7 @@ static void tcp_free(grpc_tcp* tcp) { grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); gpr_free(tcp->peer_string); - gpr_mu_destroy(&tcp->traced_buffer_lock); + gpr_mu_destroy(&tcp->tb_mu); gpr_free(tcp); } @@ -586,11 +597,11 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, *sent_length = length; /* Only save timestamps if all the bytes were taken by sendmsg. */ if (sending_length == static_cast(length)) { - gpr_mu_lock(&tcp->traced_buffer_lock); + gpr_mu_lock(&tcp->tb_mu); grpc_core::TracedBuffer::AddNewEntry( - &tcp->head, static_cast(tcp->bytes_counter + length), + &tcp->tb_head, static_cast(tcp->bytes_counter + length), tcp->outgoing_buffer_arg); - gpr_mu_unlock(&tcp->traced_buffer_lock); + gpr_mu_unlock(&tcp->tb_mu); tcp->outgoing_buffer_arg = nullptr; } return true; @@ -633,17 +644,16 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, /* The error handling can potentially be done on another thread so we need * to protect the traced buffer list. A lock free list might be better. Using * a simple mutex for now. */ - gpr_mu_lock(&tcp->traced_buffer_lock); - grpc_core::TracedBuffer::ProcessTimestamp(&tcp->head, serr, tss); - gpr_mu_unlock(&tcp->traced_buffer_lock); + gpr_mu_lock(&tcp->tb_mu); + grpc_core::TracedBuffer::ProcessTimestamp(&tcp->tb_head, serr, tss); + gpr_mu_unlock(&tcp->tb_mu); return next_cmsg; } /** For linux platforms, reads the socket's error queue and processes error * messages from the queue. Returns true if all the errors processed were * timestamps. Returns false if any of the errors were not timestamps. For - * non-linux platforms, error processing is not enabled currently, and hence - * crashes out. + * non-linux platforms, error processing is not used/enabled currently. */ static bool process_errors(grpc_tcp* tcp) { while (true) { @@ -686,16 +696,18 @@ static bool process_errors(grpc_tcp* tcp) { } if (msg.msg_controllen == 0) { - /* There was no control message read. Return now */ + /* There was no control message found. It was probably spurious. */ return true; } for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg && cmsg->cmsg_len; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_TIMESTAMPING) { - /* Got a weird control message, not a timestamp */ + /* Got a control message that is not a timestamp. Don't know how to + * handle this. */ if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_INFO, "weird control message cmsg_level:%d cmsg_type:%d", + gpr_log(GPR_INFO, + "unknown control message cmsg_level:%d cmsg_type:%d", cmsg->cmsg_level, cmsg->cmsg_type); } return false; @@ -715,20 +727,23 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { static_cast(gpr_atm_acq_load(&tcp->stop_error_notification))) { /* We aren't going to register to hear on error anymore, so it is safe to * unref. */ - grpc_core::TracedBuffer::Shutdown(&tcp->head, GRPC_ERROR_REF(error)); - TCP_UNREF(tcp, "error"); - } else { - if (!process_errors(tcp)) { - /* This was not a timestamps error. This was an actual error. Set the - * read and write closures to be ready. - */ - grpc_fd_set_readable(tcp->em_fd); - grpc_fd_set_writable(tcp->em_fd); - } - GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, - grpc_schedule_on_exec_ctx); - grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); + grpc_core::TracedBuffer::Shutdown(&tcp->tb_head, GRPC_ERROR_REF(error)); + TCP_UNREF(tcp, "error-tracking"); + return; } + + /* We are still interested in collecting timestamps, so let's try reading + * them. */ + if (!process_errors(tcp)) { + /* This was not a timestamps error. This was an actual error. Set the + * read and write closures to be ready. + */ + grpc_fd_set_readable(tcp->em_fd); + grpc_fd_set_writable(tcp->em_fd); + } + GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, + grpc_schedule_on_exec_ctx); + grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); } #else /* GRPC_LINUX_ERRQUEUE */ @@ -915,7 +930,9 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, tcp->outgoing_buffer = buf; tcp->outgoing_byte_idx = 0; tcp->outgoing_buffer_arg = arg; - if (arg) GPR_ASSERT(grpc_event_engine_can_track_errors()); + if (arg) { + GPR_ASSERT(grpc_event_engine_can_track_errors()); + } if (!tcp_flush(tcp, &error)) { TCP_REF(tcp, "write"); @@ -933,8 +950,6 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, } } -namespace {} /* namespace */ - static void tcp_add_to_pollset(grpc_endpoint* ep, grpc_pollset* pollset) { grpc_tcp* tcp = reinterpret_cast(ep); grpc_pollset_add_fd(pollset, tcp->em_fd); @@ -1048,11 +1063,14 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, /* Tell network status tracker about new endpoint */ grpc_network_status_register_endpoint(&tcp->base); grpc_resource_quota_unref_internal(resource_quota); - gpr_mu_init(&tcp->traced_buffer_lock); - tcp->head = nullptr; + gpr_mu_init(&tcp->tb_mu); + tcp->tb_head = nullptr; /* Start being notified on errors if event engine can track errors. */ if (grpc_event_engine_can_track_errors()) { - TCP_REF(tcp, "error"); + /* Grab a ref to tcp so that we can safely access the tcp struct when + * processing errors. We unref when we no longer want to track errors + * separately. */ + TCP_REF(tcp, "error-tracking"); gpr_atm_rel_store(&tcp->stop_error_notification, 0); GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, grpc_schedule_on_exec_ctx); From b8f030bc0b507903e9d156fb44d161015273d0c6 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 13 Aug 2018 13:55:44 -0700 Subject: [PATCH 099/546] reformat --- .../ext/filters/client_channel/subchannel.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 4a45ca081c4..e94186da00c 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -866,14 +866,14 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, connection.release(); // Ref is passed to the grpc_subchannel_call object. (*call)->connection = this; const grpc_call_element_args call_args = { - callstk, /* call_stack */ - nullptr, /* server_transport_data */ - args.context, /* context */ - args.path, /* path */ - args.start_time, /* start_time */ - args.deadline, /* deadline */ - args.arena, /* arena */ - args.call_combiner, /* call_combiner */ + callstk, /* call_stack */ + nullptr, /* server_transport_data */ + args.context, /* context */ + args.path, /* path */ + args.start_time, /* start_time */ + args.deadline, /* deadline */ + args.arena, /* arena */ + args.call_combiner /* call_combiner */ }; grpc_error* error = grpc_call_stack_init( channel_stack_, 1, subchannel_call_destroy, *call, &call_args); From 0bf39e2a13cdb49a72beae8df07f6b489e45aa4f Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 20 Jul 2018 16:18:04 -0700 Subject: [PATCH 100/546] Subchannel support to C++ --- src/cpp/server/channelz/channelz_service.cc | 16 ++++ src/cpp/server/channelz/channelz_service.h | 4 + test/cpp/end2end/channelz_service_test.cc | 82 ++++++++++++++++++--- 3 files changed, 91 insertions(+), 11 deletions(-) diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc index 77c175e5b8f..f6f6e47917b 100644 --- a/src/cpp/server/channelz/channelz_service.cc +++ b/src/cpp/server/channelz/channelz_service.cc @@ -32,6 +32,7 @@ Status ChannelzService::GetTopChannels( ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request, channelz::v1::GetTopChannelsResponse* response) { char* json_str = grpc_channelz_get_top_channels(request->start_channel_id()); + // gpr_log(GPR_ERROR, "%s", json_str); google::protobuf::util::Status s = google::protobuf::util::JsonStringToMessage(json_str, response); gpr_free(json_str); @@ -45,6 +46,21 @@ Status ChannelzService::GetChannel( ServerContext* unused, const channelz::v1::GetChannelRequest* request, channelz::v1::GetChannelResponse* response) { char* json_str = grpc_channelz_get_channel(request->channel_id()); + // gpr_log(GPR_ERROR, "%s", json_str); + google::protobuf::util::Status s = + google::protobuf::util::JsonStringToMessage(json_str, response); + gpr_free(json_str); + if (s != google::protobuf::util::Status::OK) { + return Status(INTERNAL, s.ToString()); + } + return Status::OK; +} + +Status ChannelzService::GetSubchannel( + ServerContext* unused, const channelz::v1::GetSubchannelRequest* request, + channelz::v1::GetSubchannelResponse* response) { + char* json_str = grpc_channelz_get_subchannel(request->subchannel_id()); + // gpr_log(GPR_ERROR, "%s", json_str); google::protobuf::util::Status s = google::protobuf::util::JsonStringToMessage(json_str, response); gpr_free(json_str); diff --git a/src/cpp/server/channelz/channelz_service.h b/src/cpp/server/channelz/channelz_service.h index f619ea49e04..95d6f47cff1 100644 --- a/src/cpp/server/channelz/channelz_service.h +++ b/src/cpp/server/channelz/channelz_service.h @@ -36,6 +36,10 @@ class ChannelzService final : public channelz::v1::Channelz::Service { Status GetChannel(ServerContext* unused, const channelz::v1::GetChannelRequest* request, channelz::v1::GetChannelResponse* response) override; + // implementation of GetSubchannel rpc + Status GetSubchannel(ServerContext* unused, + const channelz::v1::GetSubchannelRequest* request, + channelz::v1::GetSubchannelResponse* response) override; }; } // namespace grpc diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index 933e4a1ff67..84f6b89384a 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -35,10 +35,14 @@ #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" +#include + #include using grpc::channelz::v1::GetChannelRequest; using grpc::channelz::v1::GetChannelResponse; +using grpc::channelz::v1::GetSubchannelRequest; +using grpc::channelz::v1::GetSubchannelResponse; using grpc::channelz::v1::GetTopChannelsRequest; using grpc::channelz::v1::GetTopChannelsResponse; @@ -140,7 +144,7 @@ class ChannelzServerTest : public ::testing::Test { ClientContext context; Status s = echo_stub_->Echo(&context, request, &response); EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); } void SendFailedEcho(int channel_idx) { @@ -190,7 +194,7 @@ TEST_F(ChannelzServerTest, BasicTest) { request.set_start_channel_id(0); ClientContext context; Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel_size(), 1); } @@ -202,7 +206,7 @@ TEST_F(ChannelzServerTest, HighStartId) { request.set_start_channel_id(10000); ClientContext context; Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel_size(), 0); } @@ -215,7 +219,7 @@ TEST_F(ChannelzServerTest, SuccessfulRequestTest) { request.set_channel_id(1); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), 1); EXPECT_EQ(response.channel().data().calls_succeeded(), 1); EXPECT_EQ(response.channel().data().calls_failed(), 0); @@ -230,7 +234,7 @@ TEST_F(ChannelzServerTest, FailedRequestTest) { request.set_channel_id(1); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), 1); EXPECT_EQ(response.channel().data().calls_succeeded(), 0); EXPECT_EQ(response.channel().data().calls_failed(), 1); @@ -253,7 +257,7 @@ TEST_F(ChannelzServerTest, ManyRequestsTest) { request.set_channel_id(1); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess + kNumFailed); EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); @@ -269,7 +273,7 @@ TEST_F(ChannelzServerTest, ManyChannels) { request.set_start_channel_id(0); ClientContext context; Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel_size(), kNumChannels); } @@ -295,7 +299,7 @@ TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { request.set_channel_id(1); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess); EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); EXPECT_EQ(response.channel().data().calls_failed(), 0); @@ -308,7 +312,7 @@ TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { request.set_channel_id(2); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), kNumFailed); EXPECT_EQ(response.channel().data().calls_succeeded(), 0); EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed); @@ -321,7 +325,7 @@ TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { request.set_channel_id(3); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess + kNumFailed); EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); @@ -335,13 +339,69 @@ TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { request.set_channel_id(4); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), 0); EXPECT_EQ(response.channel().data().calls_succeeded(), 0); EXPECT_EQ(response.channel().data().calls_failed(), 0); } } +TEST_F(ChannelzServerTest, ManySubchannels) { + ResetStubs(); + const int kNumChannels = 4; + ConfigureProxy(kNumChannels); + const int kNumSuccess = 10; + const int kNumFailed = 11; + for (int i = 0; i < kNumSuccess; ++i) { + SendSuccessfulEcho(0); + SendSuccessfulEcho(2); + } + for (int i = 0; i < kNumFailed; ++i) { + SendFailedEcho(1); + SendFailedEcho(2); + } + + GetTopChannelsRequest gtc_request; + GetTopChannelsResponse gtc_response; + gtc_request.set_start_channel_id(0); + ClientContext context; + Status s = + channelz_stub_->GetTopChannels(&context, gtc_request, >c_response); + EXPECT_TRUE(s.ok()) << s.error_message(); + EXPECT_EQ(gtc_response.channel_size(), kNumChannels); + + // std::string gtc_str; + // google::protobuf::TextFormat::PrintToString(gtc_response, >c_str); + // std::cout << "GetTopChannels:\n" << gtc_str << "\n"; + + for (int i = 0; i < gtc_response.channel_size(); ++i) { + // if the channel sent no RPCs, then expect no subchannels to have been + // created. + if (gtc_response.channel(i).data().calls_started() == 0) { + EXPECT_EQ(gtc_response.channel(i).subchannel_ref_size(), 0); + continue; + } + // Since this is pick first, we know that there was only one subchannel + // used. We request it here. + ASSERT_GT(gtc_response.channel(i).subchannel_ref_size(), 0); + EXPECT_EQ(gtc_response.channel(i).subchannel_ref_size(), 1); + GetSubchannelRequest gsc_request; + GetSubchannelResponse gsc_response; + gsc_request.set_subchannel_id( + gtc_response.channel(i).subchannel_ref(0).subchannel_id()); + ClientContext context; + Status s = + channelz_stub_->GetSubchannel(&context, gsc_request, &gsc_response); + EXPECT_TRUE(s.ok()) << s.error_message(); + EXPECT_EQ(gtc_response.channel(i).data().calls_started(), + gsc_response.subchannel().data().calls_started()); + EXPECT_EQ(gtc_response.channel(i).data().calls_succeeded(), + gsc_response.subchannel().data().calls_succeeded()); + EXPECT_EQ(gtc_response.channel(i).data().calls_failed(), + gsc_response.subchannel().data().calls_failed()); + } +} + } // namespace testing } // namespace grpc From ac50c81a08025e36dd5a6e9127c98e08d3195c9c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 Aug 2018 14:28:36 -0700 Subject: [PATCH 101/546] Try --- src/core/lib/iomgr/internal_errqueue.h | 30 -------------------------- src/core/lib/iomgr/port.h | 4 ++++ 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h index bbe3377b430..50037bf0e98 100644 --- a/src/core/lib/iomgr/internal_errqueue.h +++ b/src/core/lib/iomgr/internal_errqueue.h @@ -41,36 +41,6 @@ #endif /* GRPC_LINUX_ERRQUEUE */ namespace grpc_core { -/* Redefining scm_timestamping in the same way that defines - * it, so that code compiles on systems that don't have it. */ -struct scm_timestamping { - struct timespec ts[3]; -}; - -/* Also redefine timestamp types */ -/* The timestamp type for when the driver passed skb to NIC, or HW. */ -constexpr int SCM_TSTAMP_SND = 0; -/* The timestamp type for when data entered the packet scheduler. */ -constexpr int SCM_TSTAMP_SCHED = 1; -/* The timestamp type for when data acknowledged by peer. */ -constexpr int SCM_TSTAMP_ACK = 2; - -/* Redefine required constants from */ -constexpr uint32_t SOF_TIMESTAMPING_TX_SOFTWARE = 1u << 1; -constexpr uint32_t SOF_TIMESTAMPING_SOFTWARE = 1u << 4; -constexpr uint32_t SOF_TIMESTAMPING_OPT_ID = 1u << 7; -constexpr uint32_t SOF_TIMESTAMPING_TX_SCHED = 1u << 8; -constexpr uint32_t SOF_TIMESTAMPING_TX_ACK = 1u << 9; -constexpr uint32_t SOF_TIMESTAMPING_OPT_TSONLY = 1u << 11; - -constexpr uint32_t kTimestampingSocketOptions = SOF_TIMESTAMPING_SOFTWARE | - SOF_TIMESTAMPING_OPT_ID | - SOF_TIMESTAMPING_OPT_TSONLY; - -constexpr uint32_t kTimestampingRecordingOptions = - SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE | - SOF_TIMESTAMPING_TX_ACK; - /* Returns true if kernel is capable of supporting errqueue and timestamping. * Currently allowing only linux kernels above 4.0.0 */ diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index b68305ce0ec..375f1844ac7 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -60,7 +60,11 @@ #define GRPC_HAVE_IP_PKTINFO 1 #define GRPC_HAVE_MSG_NOSIGNAL 1 #define GRPC_HAVE_UNIX_SOCKET 1 +#ifdef LINUX_VERSION_CODE +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) #define GRPC_LINUX_ERRQUEUE 1 +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */ +#endif /* LINUX_VERSION_CODE */ #define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1 #define GRPC_POSIX_FORK 1 #define GRPC_POSIX_HOST_NAME_MAX 1 From 82b1a08e15e3fbc26e1fdd8c6ad4231b89391856 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 Aug 2018 14:55:49 -0700 Subject: [PATCH 102/546] Try1 --- src/core/lib/iomgr/ev_posix.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 2ce9b0f97d1..681a11291bf 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -194,7 +194,12 @@ void grpc_event_engine_shutdown(void) { } bool grpc_event_engine_can_track_errors(void) { +/* Only track errors if platform supports errqueue. */ +#ifdef GRPC_LINUX_ERRQUEUE return g_event_engine->can_track_err; +#else + return false; +#endif /* GRPC_LINUX_ERRQUEUE */ } grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) { From 5e1cf109da7713592b894366cdb78413e28e44f3 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 13 Aug 2018 14:55:30 -0700 Subject: [PATCH 103/546] Fix clamp for window update --- src/core/ext/transport/chttp2/transport/flow_control.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/flow_control.cc b/src/core/ext/transport/chttp2/transport/flow_control.cc index 5f3dd984611..53932bcb7f5 100644 --- a/src/core/ext/transport/chttp2/transport/flow_control.cc +++ b/src/core/ext/transport/chttp2/transport/flow_control.cc @@ -40,6 +40,7 @@ namespace chttp2 { namespace { static constexpr const int kTracePadding = 30; +static constexpr const uint32_t kMaxWindowUpdateSize = (1u << 31) - 1; static char* fmt_int64_diff_str(int64_t old_val, int64_t new_val) { char* str; @@ -193,7 +194,7 @@ uint32_t TransportFlowControl::MaybeSendUpdate(bool writing_anyway) { if ((writing_anyway || announced_window_ <= target_announced_window / 2) && announced_window_ != target_announced_window) { const uint32_t announce = static_cast GPR_CLAMP( - target_announced_window - announced_window_, 0, UINT32_MAX); + target_announced_window - announced_window_, 0, kMaxWindowUpdateSize); announced_window_ += announce; return announce; } @@ -267,7 +268,7 @@ uint32_t StreamFlowControl::MaybeSendUpdate() { FlowControlTrace trace("s updt sent", tfc_, this); if (local_window_delta_ > announced_window_delta_) { uint32_t announce = static_cast GPR_CLAMP( - local_window_delta_ - announced_window_delta_, 0, UINT32_MAX); + local_window_delta_ - announced_window_delta_, 0, kMaxWindowUpdateSize); UpdateAnnouncedWindowDelta(tfc_, announce); return announce; } From b49f47d4f26b48392950029762cd33e6365657c6 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 Aug 2018 16:28:53 -0700 Subject: [PATCH 104/546] linux version needs to be defined --- src/core/lib/iomgr/internal_errqueue.h | 10 ++++++++++ src/core/lib/iomgr/port.h | 1 + src/core/lib/iomgr/tcp_posix.cc | 3 +-- test/core/iomgr/buffer_list_test.cc | 6 +++--- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h index 50037bf0e98..fc11be9a6dd 100644 --- a/src/core/lib/iomgr/internal_errqueue.h +++ b/src/core/lib/iomgr/internal_errqueue.h @@ -41,6 +41,16 @@ #endif /* GRPC_LINUX_ERRQUEUE */ namespace grpc_core { + +#ifdef GRPC_LINUX_ERRQUEUE +constexpr uint32_t kTimestampingSocketOptions = SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_OPT_ID | + SOF_TIMESTAMPING_OPT_TSONLY; +constexpr uint32_t kTimestampingRecordingOptions = + SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_TX_ACK; +#endif /* GRPC_LINUX_ERRQUEUE */ + /* Returns true if kernel is capable of supporting errqueue and timestamping. * Currently allowing only linux kernels above 4.0.0 */ diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 375f1844ac7..4d728a75fbe 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -60,6 +60,7 @@ #define GRPC_HAVE_IP_PKTINFO 1 #define GRPC_HAVE_MSG_NOSIGNAL 1 #define GRPC_HAVE_UNIX_SOCKET 1 +#include #ifdef LINUX_VERSION_CODE #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) #define GRPC_LINUX_ERRQUEUE 1 diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index d8f58408c7c..6d4c0962176 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -633,8 +633,7 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, return cmsg; } - auto tss = - reinterpret_cast(CMSG_DATA(cmsg)); + auto tss = reinterpret_cast(CMSG_DATA(cmsg)); auto serr = reinterpret_cast(CMSG_DATA(next_cmsg)); if (serr->ee_errno != ENOMSG || serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) { diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index 9ffb71c85ff..f1773580bd2 100644 --- a/test/core/iomgr/buffer_list_test.cc +++ b/test/core/iomgr/buffer_list_test.cc @@ -75,8 +75,8 @@ static void TestVerifierCalledOnAckVerifier(void* arg, static void TestVerifierCalledOnAck() { struct sock_extended_err serr; serr.ee_data = 213; - serr.ee_info = grpc_core::SCM_TSTAMP_ACK; - struct grpc_core::scm_timestamping tss; + serr.ee_info = SCM_TSTAMP_ACK; + struct scm_timestamping tss; tss.ts[0].tv_sec = 123; tss.ts[0].tv_nsec = 456; grpc_core::grpc_tcp_set_write_timestamps_callback( @@ -106,6 +106,6 @@ int main(int argc, char** argv) { #else /* GRPC_LINUX_ERRQUEUE */ -int main(int argc, char** argv) { return 1; } +int main(int argc, char** argv) { return 0; } #endif /* GRPC_LINUX_ERRQUEUE */ From ca832cea906247c2a160995869af0666be24a97b Mon Sep 17 00:00:00 2001 From: Naresh Date: Tue, 14 Aug 2018 11:20:45 +0530 Subject: [PATCH 105/546] Add GSoC report (Naresh) --- summerofcode/2018/naresh.md | 191 ++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 summerofcode/2018/naresh.md diff --git a/summerofcode/2018/naresh.md b/summerofcode/2018/naresh.md new file mode 100644 index 00000000000..0d196bd6001 --- /dev/null +++ b/summerofcode/2018/naresh.md @@ -0,0 +1,191 @@ +# Project overview + +## Title + +Enable Building of gRPC Python with Bazel + +## Overview + +gRPC Python currently has a constellation of scripts written to build the +project, but it has a lot of limitations in terms of speed and maintainability. +[Bazel](https://bazel.build/) is the open-sourced variant of Google's internal +system, Blaze, which is an ideal replacement for building such projects in a +fast and declarative fashion. But Bazel in itself is still in active +development, especially in terms of Python (amongst a few other languages). + +The project aimed to fill this gap and build gRPC Python with Bazel. + +[Project page](https://summerofcode.withgoogle.com/projects/#6482576244473856) + +[Link to proposal](https://storage.googleapis.com/summerofcode-prod.appspot.com/gsoc/core_project/doc/5316764725411840_1522049732_Naresh_Ramesh_-_GSoC_proposal.pdf) + +## Thoughts and challenges + +### State of Bazel for Python + +Although previously speculated, the project didn't require any contributions +directly to [bazelbuild/bazel](https://github.com/bazelbuild/bazel). The Bazel +rules for Python are currently being separated out into their own repo at +[bazelbuild/rules_python](https://github.com/bazelbuild/rules_python/). + +Bazel is [still very much in active development for +Python](https://groups.google.com/forum/#!topic/bazel-sig-python/iQjV9sfSufw) +though. There's still challenges when it comes to building for Python 2 vs 3. +Using pip packages is still in experimental. Bazel Python support is currently +distributed across these two repositories and is yet to begin migration to one +place (which will be +[bazelbuild/rules_python](https://github.com/bazelbuild/rules_python/)). + +Bazel's roadmap for Python is publicly available [here as a Google +doc](https://docs.google.com/document/d/1A6J3j3y1SQ0HliS86_mZBnB5UeBe7vExWL2Ryd_EONI/edit). + +### Cross collaboration between projects + +Cross contribution surprisingly came up because of building protobuf sources +for Python, which is still not natively supported by Bazel. An existing +repository, [pubref/rules_protobuf](https://github.com/pubref/rules_protobuf), +which was maintained by an independent maintainer (i.e. not a part of Bazel) +helped solve this problem, but had [one major blocking +issue](https://github.com/pubref/rules_protobuf/issues/233) and could not be +resolved at the source. But [a solution to the +issue](https://github.com/pubref/rules_protobuf/pull/196) was proposed by user +dududko, which was not merged because of failing golang tests but worked well +for Python. Hence, a fork of this repo was made and is to be used with gRPC +until the solution can be merged back at the source. + +### Building Cython code + +Building Cython code is still not supported by Bazel, but the team at +[cython/cython](https://github.com/cython/cython) have added support for Bazel +on their side. The way it works is by including Cython as a third-party Bazel +dependency and using custom Bazel rules for building our Cython code using the +binary within the dependency. + +### Packaging Python code using Bazel + +pip and PyPI still remain the de-facto standard for distributing Python +packages. Although Bazel is pretty versatile and is amazing for it's +reproducible and incremental build capabilities, these can only be still used +by the contributors and developers for building and testing the gRPC code. But +there's no way yet to build Python packages for distribution. + +### Building gRPC Python with Bazel on Kokoro (internal CI) + +Integration with the internal CI was one of the areas that highlighted how +simple Bazel can be to use. gRPC was already using a dockerized Bazel setup to +build some of it's core code (but not as the primary build setup). Adding a new +job on the internal CI ended up being as simple as creating a new shell script +to install the required dependencies (which were python-dev and Bazel) and a +new configuration file which pointed to the subdirectiory (src/python) under +which to look for targets and run the tests accordingly. + +### Handling imports in Python code + +When writing Python packages, imports in nested modules are typically made +relative to the package root. But because of the way Bazel works, these paths +wouldn't make sense from the Workspace root. So, the folks at Bazel have added +a nifty `imports` parameter to all the Python rules which lets us specify for +each target, which path to consider as the root. This parameter allows for +relative paths like `imports = ["../",]`. + +### Fetching Python headers for Cython code to use + +Cython code makes use of `Python.h`, which pulls in the Python API for C +extension modules to use, but it's location depending on the Python version and +operating system the code is building on. To make this easier, the folks at +Tensorflow wrote [repository rules for Python +autoconfiguration](https://github.com/tensorflow/tensorflow/tree/e447ae4759317156d31a9421290716f0ffbffcd8/third_party/py). +This has been [adapted with some some +modifications](https://github.com/grpc/grpc/pull/15992) for use in gRPC Python +as well. + +## How to use + +All the Bazel tests for gRPC Python can be run using a single command: + +```bash +bazel test --spawn_strategy=standalone --genrule_strategy=standalone //src/python/... +``` + +If any specific test is to be run, like say `LoggingPoolTest` (which is present +in +`src/python/grpcio_tests/tests/unit/framework/foundation/_logging_pool_test.py`), +the command to run would be: + +```bash +bazel test --spawn_strategy=standalone --genrule_strategy=standalone //src/python/grpcio_tests/tests/unit/framework/foundation:logging_pool_test +``` + +where, `logging_pool_test` is the name of the Bazel target for this test. + +Similarly, to run a particular method, use: + +```bash +bazel test --spawn_strategy=standalone --genrule_strategy=standalone //src/python/grpcio_tests/tests/unit/_rpc_test --test_arg=RPCTest.testUnrecognizedMethod +``` + +## Useful Bazel flags + +- Use `bazel build` with a `-s` flag to see the logs being printed out to + standard output while building. +- Similarly, use `bazel test` with a `--test_output=streamed` to see the the + test logs while testing. Something to know while using this flag is that all + tests will be run locally, without sharding, one at a time. + +## Contributions + +### Related to the project + +- [435c6f8](https://github.com/grpc/grpc/commit/435c6f8d1e53783ec049b3482445813afd8bc514) + Update grpc_gevent cython files to include .pxi +- [74426fd](https://github.com/grpc/grpc/commit/74426fd2164c51d6754732ebe372133c19ba718c) + Add gevent_util.h to grpc_base_c Bazel target +- [b6518af](https://github.com/grpc/grpc/commit/b6518afdd610f0115b42aee1ffc71520c6b0d6b1) + Upgrade Bazel to 0.15.0 +- [ebcf04d](https://github.com/grpc/grpc/commit/ebcf04d075333c42979536c5dd2091d363f67e5a) + Kokoro setup for building gRPC Python with Bazel +- [3af1aaa](https://github.com/grpc/grpc/commit/3af1aaadabf49bc6274711a11f81627c0f351a9a) + Basic setup to build gRPC Python with Bazel +- [11f199e](https://github.com/grpc/grpc/commit/11f199e34dc416a2bd8b56391b242a867bedade4) + Workspace changes to build gRPC Python with Bazel +- [848fd9d](https://github.com/grpc/grpc/commit/848fd9d75f6df10f00e8328ff052c0237b3002ab) + Minimal Bazel BUILD files for grpcio Python + +### Other contibutions + +- [89ce16b](https://github.com/grpc/grpc/commit/89ce16b6daaad4caeb1c9ba670c6c4b62ea1a93c) + Update Dockerfiles for python artifacts to use latest git version +- [32f7c48](https://github.com/grpc/grpc/commit/32f7c48dad71cac7af652bf994ab1dde3ddb0607) + Revert removals from python artifact dockerfiles +- [712eb9f](https://github.com/grpc/grpc/commit/712eb9ff91cde66af94e8381ec01ad512ed6d03c) + Make logging after success in jobset more apparent +- [c6e4372](https://github.com/grpc/grpc/commit/c6e4372f8a93bb0eb996b5f202465785422290f2) + Create README for gRPC Python reflection package +- [2e113ca](https://github.com/grpc/grpc/commit/2e113ca6b2cc31aa8a9687d40ee1bd759381654f) + Update logging in Python to use module-level logger + +### Pending PRs + +- BUILD files for all tests in + [tests.json](https://github.com/ghostwriternr/grpc/blob/70c8a58b2918a5369905e5a203d7ce7897b6207e/src/python/grpcio_tests/tests/tests.json). +- BUILD files for gRPC testing, gRPC health checking, gRPC reflection. +- (Yet to complete) BUILD files for grpcio_tools. One test depends on this. + +## Known issues + +- [grpc/grpc #16336](https://github.com/grpc/grpc/issues/16336) RuntimeError + for `_reconnect_test` Python unit test with Bazel +- Some tests in Bazel pass despite throwing an exception. Example: + `testAbortedStreamStream` in + `src/python/grpcio_tests/tests/unit/_metadata_code_details_test.py`. +- [#14557](https://github.com/grpc/grpc/pull/14557) introduced a minor bug + where the module level loggers don't initialize a default logging handler. +- Sanity test doesn't make sense in the context of Bazel, and thus fails. +- There are some issues with Python2 vs Python3. Specifically, + - On some machines, “cygrpc.so: undefined symbol: _Py_FalseStruct” error + shows up. This is because of incorrect Python version being used to build + Cython. + - Some external packages like enum34 throw errors when used with Python 3 and + some extra packages are currently installed as Python version in current + build scripts. For now, the extra packages are added to a + `requirements.bazel.txt` file in the repository root. From a4326eb7b829cb479d14d1c4029c8522ab7f572b Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 13 Aug 2018 23:01:23 -0700 Subject: [PATCH 106/546] Add comment to address reviewer comment --- test/cpp/microbenchmarks/bm_cq_multiple_threads.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc index 06922afda3c..85767c8758f 100644 --- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc +++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc @@ -166,6 +166,8 @@ static void BM_Cq_Throughput(benchmark::State& state) { } gpr_mu_unlock(&g_mu); + // Use a TrackCounters object to monitor the gRPC performance statistics + // (optionally including low-level counters) before and after the test TrackCounters track_counters; while (state.KeepRunning()) { From 4eff37345fbe03f850ec0ddb039e73035eaa931b Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 13 Aug 2018 23:13:41 -0700 Subject: [PATCH 107/546] Add detailed comment for g_factories --- src/core/lib/iomgr/ev_posix.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index c30614e7e53..b8fe017ce7d 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -104,12 +104,25 @@ const grpc_event_engine_vtable* init_non_polling(bool explicit_request) { #define ENGINE_HEAD_CUSTOM "head_custom" #define ENGINE_TAIL_CUSTOM "tail_custom" +// The global array of event-engine factories. Each entry is a pair with a name +// and an event-engine generator function (nullptr if there is no generator +// registered for this name). The middle entries are the engines predefined by +// open-source gRPC. The head entries represent an opportunity for specific +// high-priority custom pollers to be added by the initializer plugins of +// custom-built gRPC libraries. The tail entries represent the same, but for +// low-priority custom pollers. The actual poller selected is either the first +// available one in the list if no specific poller is requested, or the first +// specific poller that is requested by name in the GRPC_POLL_STRATEGY +// environment variable if that variable is set (which should be a +// comma-separated list of one or more event engine names) static event_engine_factory g_factories[] = { + {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, {"epollex", grpc_init_epollex_linux}, {"epoll1", grpc_init_epoll1_linux}, {"epollsig", grpc_init_epollsig_linux}, {"poll", grpc_init_poll_posix}, {"poll-cv", grpc_init_poll_cv_posix}, {"none", init_non_polling}, {ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr}, + {ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr}, }; static void add(const char* beg, const char* end, char*** ss, size_t* ns) { From fe7f79189be8c774a3cc210d4b86191179742ca6 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 14 Aug 2018 00:58:33 -0700 Subject: [PATCH 108/546] Address reviewer comments --- src/core/lib/surface/completion_queue.cc | 39 +++++++++++++++--------- src/core/lib/surface/completion_queue.h | 9 ++++-- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index fd33ce044c2..9086578f7c4 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -263,12 +263,6 @@ typedef struct cq_callback_data { useful for avoiding locks to check the queue */ gpr_atm things_queued_ever; - /** 0 initially. 1 once we completed shutting */ - /* TODO: (sreek) This is not needed since (shutdown == 1) if and only if - * (pending_events == 0). So consider removing this in future and use - * pending_events */ - gpr_atm shutdown; - /** 0 initially. 1 once we initiated shutdown */ bool shutdown_called; @@ -308,6 +302,12 @@ static bool cq_begin_op_for_next(grpc_completion_queue* cq, void* tag); static bool cq_begin_op_for_pluck(grpc_completion_queue* cq, void* tag); static bool cq_begin_op_for_callback(grpc_completion_queue* cq, void* tag); +// A cq_end_op function is called when an operation on a given CQ with +// a given tag has completed. The storage argument is a reference to the +// space reserved for this completion as it is placed into the corresponding +// queue. The done argument is a callback that will be invoked when it is +// safe to free up that storage. The storage MUST NOT be freed until the +// done callback is invoked. static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, grpc_error* error, void (*done)(void* done_arg, @@ -332,8 +332,11 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, gpr_timespec deadline, void* reserved); -static void cq_init_next(void* data, grpc_core::CQCallbackInterface*); -static void cq_init_pluck(void* data, grpc_core::CQCallbackInterface*); +// Note that cq_init_next and cq_init_pluck do not use the shutdown_callback +static void cq_init_next(void* data, + grpc_core::CQCallbackInterface* shutdown_callback); +static void cq_init_pluck(void* data, + grpc_core::CQCallbackInterface* shutdown_callback); static void cq_init_callback(void* data, grpc_core::CQCallbackInterface* shutdown_callback); static void cq_destroy_next(void* data); @@ -494,7 +497,11 @@ grpc_completion_queue* grpc_completion_queue_create_internal( return cq; } -static void cq_init_next(void* ptr, grpc_core::CQCallbackInterface*) { +static void cq_init_next(void* ptr, + grpc_core::CQCallbackInterface* shutdown_callback) { + // shutdown_callback should not be provided to this CQ variant + GPR_ASSERT(shutdown_callback == nullptr); + cq_next_data* cqd = static_cast(ptr); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); @@ -509,7 +516,11 @@ static void cq_destroy_next(void* ptr) { cq_event_queue_destroy(&cqd->queue); } -static void cq_init_pluck(void* ptr, grpc_core::CQCallbackInterface*) { +static void cq_init_pluck(void* ptr, + grpc_core::CQCallbackInterface* shutdown_callback) { + // shutdown_callback should not be provided to this CQ variant + GPR_ASSERT(shutdown_callback == nullptr); + cq_pluck_data* cqd = static_cast(ptr); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); @@ -531,7 +542,6 @@ static void cq_init_callback( cq_callback_data* cqd = static_cast(ptr); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); - gpr_atm_no_barrier_store(&cqd->shutdown, 0); cqd->shutdown_called = false; gpr_atm_no_barrier_store(&cqd->things_queued_ever, 0); cqd->shutdown_callback = shutdown_callback; @@ -838,7 +848,8 @@ static void cq_end_op_for_callback( } } - /* We don't care for the storage content */ + // The callback-based CQ isn't really a queue at all and thus has no need + // for reserved storage. Invoke the done callback right away to release it. done(done_arg, storage); gpr_mu_lock(cq->mu); @@ -1336,8 +1347,6 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { auto* callback = cqd->shutdown_callback; GPR_ASSERT(cqd->shutdown_called); - GPR_ASSERT(!gpr_atm_no_barrier_load(&cqd->shutdown)); - gpr_atm_no_barrier_store(&cqd->shutdown, 1); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); callback->Run(true); @@ -1347,7 +1356,7 @@ static void cq_shutdown_callback(grpc_completion_queue* cq) { cq_callback_data* cqd = static_cast DATA_FROM_CQ(cq); /* Need an extra ref for cq here because: - * We call cq_finish_shutdown_pluck() below, that would call pollset shutdown. + * We call cq_finish_shutdown_callback() below, which calls pollset shutdown. * Pollset shutdown decrements the cq ref count which can potentially destroy * the cq (if that happens to be the last ref). * Creating an extra ref here prevents the cq from getting destroyed while diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index 6d8c6c9b06e..5aa54682e01 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -47,8 +47,13 @@ typedef struct grpc_cq_completion { uintptr_t next; } grpc_cq_completion; -/// For callback CQs, the following is what is actually intended by -/// the tag. +/// For callback CQs, the tag that is passed in for an operation must +/// actually be a pointer to an implementation of the following class. +/// When the operation completes, the tag will be typecasted from void* +/// to grpc_core::CQCallbackInterface* and then the Run method will be +/// invoked on it. In practice, the language binding (e.g., C++ API +/// implementation) is responsible for providing and using an implementation +/// of this abstract base class. namespace grpc_core { class CQCallbackInterface { public: From 217d460ee261fddb2a94b1bd8a8c5e6947bbc07b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 14 Aug 2018 10:09:02 +0200 Subject: [PATCH 109/546] fix performance benchmarks on windows --- tools/run_tests/run_performance_tests.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py index 9a9f74e9e5a..bde2cff8f99 100755 --- a/tools/run_tests/run_performance_tests.py +++ b/tools/run_tests/run_performance_tests.py @@ -189,7 +189,11 @@ def create_netperf_jobspec(server_host='localhost', def archive_repo(languages): """Archives local version of repo including submodules.""" - cmdline = ['tar', '-cf', '../grpc.tar', '../grpc/'] + # Directory contains symlinks that can't be correctly untarred on Windows + # so we just skip them as a workaround. + # See https://github.com/grpc/grpc/issues/16334 + bad_symlinks_dir = '../grpc/third_party/libcxx/test/std/experimental/filesystem/Inputs/static_test_env' + cmdline = ['tar', '--exclude', bad_symlinks_dir, '-cf','../grpc.tar', '../grpc/'] if 'java' in languages: cmdline.append('../grpc-java') if 'go' in languages: From 52e17d7d0b346863b35bf5069f8c3427e95f780b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 14 Aug 2018 10:37:13 +0200 Subject: [PATCH 110/546] correctly set performance job metadata on kokoro --- tools/run_tests/performance/bq_upload_result.py | 14 ++++++++------ .../run_tests/python_utils/upload_test_results.py | 14 ++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tools/run_tests/performance/bq_upload_result.py b/tools/run_tests/performance/bq_upload_result.py index 67025875578..b442f0cf83a 100755 --- a/tools/run_tests/performance/bq_upload_result.py +++ b/tools/run_tests/performance/bq_upload_result.py @@ -128,14 +128,16 @@ def _flatten_result_inplace(scenario_result): def _populate_metadata_inplace(scenario_result): """Populates metadata based on environment variables set by Jenkins.""" - # NOTE: Grabbing the Jenkins environment variables will only work if the - # driver is running locally on the same machine where Jenkins has started + # NOTE: Grabbing the Kokoro environment variables will only work if the + # driver is running locally on the same machine where Kokoro has started # the job. For our setup, this is currently the case, so just assume that. - build_number = os.getenv('BUILD_NUMBER') - build_url = os.getenv('BUILD_URL') - job_name = os.getenv('JOB_NAME') - git_commit = os.getenv('GIT_COMMIT') + build_number = os.getenv('KOKORO_BUILD_NUMBER') + build_url = 'https://source.cloud.google.com/results/invocations/%s' % os.getenv( + 'KOKORO_BUILD_ID') + job_name = os.getenv('KOKORO_JOB_NAME') + git_commit = os.getenv('KOKORO_GIT_COMMIT') # actual commit is the actual head of PR that is getting tested + # TODO(jtattermusch): unclear how to obtain on Kokoro git_actual_commit = os.getenv('ghprbActualCommit') utc_timestamp = str(calendar.timegm(time.gmtime())) diff --git a/tools/run_tests/python_utils/upload_test_results.py b/tools/run_tests/python_utils/upload_test_results.py index cbb4c32a2af..9d997037259 100644 --- a/tools/run_tests/python_utils/upload_test_results.py +++ b/tools/run_tests/python_utils/upload_test_results.py @@ -68,15 +68,13 @@ _INTEROP_RESULTS_SCHEMA = [ def _get_build_metadata(test_results): - """Add Jenkins/Kokoro build metadata to test_results based on environment - variables set by Jenkins/Kokoro. + """Add Kokoro build metadata to test_results based on environment + variables set by Kokoro. """ - build_id = os.getenv('BUILD_ID') or os.getenv('KOKORO_BUILD_NUMBER') - build_url = os.getenv('BUILD_URL') - if os.getenv('KOKORO_BUILD_ID'): - build_url = 'https://source.cloud.google.com/results/invocations/%s' % os.getenv( - 'KOKORO_BUILD_ID') - job_name = os.getenv('JOB_BASE_NAME') or os.getenv('KOKORO_JOB_NAME') + build_id = os.getenv('KOKORO_BUILD_NUMBER') + build_url = 'https://source.cloud.google.com/results/invocations/%s' % os.getenv( + 'KOKORO_BUILD_ID') + job_name = os.getenv('KOKORO_JOB_NAME') if build_id: test_results['build_id'] = build_id From d0f116c885af5b7b4570373c33f6960108bc8baa Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 14 Aug 2018 01:43:56 -0700 Subject: [PATCH 111/546] Can't count on shutdown_cb nullptr if version is 1 --- src/core/lib/surface/completion_queue.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 9086578f7c4..3ded712b70e 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -499,9 +499,6 @@ grpc_completion_queue* grpc_completion_queue_create_internal( static void cq_init_next(void* ptr, grpc_core::CQCallbackInterface* shutdown_callback) { - // shutdown_callback should not be provided to this CQ variant - GPR_ASSERT(shutdown_callback == nullptr); - cq_next_data* cqd = static_cast(ptr); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); @@ -518,9 +515,6 @@ static void cq_destroy_next(void* ptr) { static void cq_init_pluck(void* ptr, grpc_core::CQCallbackInterface* shutdown_callback) { - // shutdown_callback should not be provided to this CQ variant - GPR_ASSERT(shutdown_callback == nullptr); - cq_pluck_data* cqd = static_cast(ptr); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); From e91ae9d69489d7b031aa09240ba6f044b2692ad6 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 14 Aug 2018 02:18:15 -0700 Subject: [PATCH 112/546] Fix abstract base class definition --- src/core/lib/surface/completion_queue.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index 5aa54682e01..a7c524d8e8f 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -25,6 +25,7 @@ #include #include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/abstract.h" #include "src/core/lib/iomgr/pollset.h" /* These trace flags default to 1. The corresponding lines are only traced @@ -58,7 +59,9 @@ namespace grpc_core { class CQCallbackInterface { public: virtual ~CQCallbackInterface() {} - virtual void Run(bool) = 0; + virtual void Run(bool) GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS }; } // namespace grpc_core From a59e48e889f6afd6f915fce5d0638f0a3697df06 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 14 Aug 2018 02:18:32 -0700 Subject: [PATCH 113/546] Add a test of callback CQ --- test/core/surface/completion_queue_test.cc | 80 +++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index 68129146cc7..b889fd0fc66 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -22,6 +22,7 @@ #include #include #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/iomgr.h" #include "test/core/util/test_config.h" @@ -41,11 +42,18 @@ static void shutdown_and_destroy(grpc_completion_queue* cc) { case GRPC_CQ_NEXT: { ev = grpc_completion_queue_next(cc, gpr_inf_past(GPR_CLOCK_REALTIME), nullptr); + GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN); break; } case GRPC_CQ_PLUCK: { ev = grpc_completion_queue_pluck( cc, create_test_tag(), gpr_inf_past(GPR_CLOCK_REALTIME), nullptr); + GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN); + break; + } + case GRPC_CQ_CALLBACK: { + // Nothing to do here. The shutdown callback will be invoked when + // possible. break; } default: { @@ -54,7 +62,6 @@ static void shutdown_and_destroy(grpc_completion_queue* cc) { } } - GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN); grpc_completion_queue_destroy(cc); } @@ -350,6 +357,76 @@ static void test_pluck_after_shutdown(void) { } } +static void test_callback(void) { + grpc_completion_queue* cc; + void* tags[128]; + grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)]; + grpc_cq_polling_type polling_types[] = { + GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_NON_LISTENING, GRPC_CQ_NON_POLLING}; + grpc_completion_queue_attributes attr; + unsigned i; + + LOG_TEST("test_callback"); + + bool got_shutdown = false; + class ShutdownCallback : public grpc_core::CQCallbackInterface { + public: + ShutdownCallback(bool* done) : done_(done) {} + ~ShutdownCallback() {} + void Run(bool ok) override { *done_ = ok; } + + private: + bool* done_; + }; + ShutdownCallback shutdown_cb(&got_shutdown); + + attr.version = 2; + attr.cq_completion_type = GRPC_CQ_CALLBACK; + attr.cq_shutdown_cb = &shutdown_cb; + + for (size_t pidx = 0; pidx < GPR_ARRAY_SIZE(polling_types); pidx++) { + grpc_core::ExecCtx exec_ctx; // reset exec_ctx + attr.cq_polling_type = polling_types[pidx]; + cc = grpc_completion_queue_create( + grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); + + int counter = 0; + class TagCallback : public grpc_core::CQCallbackInterface { + public: + TagCallback(int* counter, int tag) : counter_(counter), tag_(tag) {} + ~TagCallback() {} + void Run(bool ok) override { + GPR_ASSERT(ok); + *counter_ += tag_; + grpc_core::Delete(this); + }; + + private: + int* counter_; + int tag_; + }; + + int sumtags = 0; + for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { + tags[i] = static_cast(grpc_core::New(&counter, i)); + sumtags += i; + } + + for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { + GPR_ASSERT(grpc_cq_begin_op(cc, tags[i])); + grpc_cq_end_op(cc, tags[i], GRPC_ERROR_NONE, do_nothing_end_completion, + nullptr, &completions[i]); + } + + GPR_ASSERT(sumtags == counter); + + shutdown_and_destroy(cc); + + GPR_ASSERT(got_shutdown); + got_shutdown = false; + } +} + struct thread_state { grpc_completion_queue* cc; void* tag; @@ -368,6 +445,7 @@ int main(int argc, char** argv) { test_pluck_after_shutdown(); test_cq_tls_cache_full(); test_cq_tls_cache_empty(); + test_callback(); grpc_shutdown(); return 0; } From 4bfff0a0ffe865623b6878e89771256272ef8dd0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 14 Aug 2018 17:49:25 +0200 Subject: [PATCH 114/546] yapf code --- tools/run_tests/run_performance_tests.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py index bde2cff8f99..5bf30e0050a 100755 --- a/tools/run_tests/run_performance_tests.py +++ b/tools/run_tests/run_performance_tests.py @@ -193,7 +193,9 @@ def archive_repo(languages): # so we just skip them as a workaround. # See https://github.com/grpc/grpc/issues/16334 bad_symlinks_dir = '../grpc/third_party/libcxx/test/std/experimental/filesystem/Inputs/static_test_env' - cmdline = ['tar', '--exclude', bad_symlinks_dir, '-cf','../grpc.tar', '../grpc/'] + cmdline = [ + 'tar', '--exclude', bad_symlinks_dir, '-cf', '../grpc.tar', '../grpc/' + ] if 'java' in languages: cmdline.append('../grpc-java') if 'go' in languages: From cbca2ff03f436db4f22bb130dde0fe793e55a369 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 14 Aug 2018 12:14:59 -0700 Subject: [PATCH 115/546] Match parameter name in definition to declaration --- src/core/lib/surface/completion_queue.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 3ded712b70e..0769d9e4f63 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -497,9 +497,9 @@ grpc_completion_queue* grpc_completion_queue_create_internal( return cq; } -static void cq_init_next(void* ptr, +static void cq_init_next(void* data, grpc_core::CQCallbackInterface* shutdown_callback) { - cq_next_data* cqd = static_cast(ptr); + cq_next_data* cqd = static_cast(data); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); cqd->shutdown_called = false; @@ -507,15 +507,15 @@ static void cq_init_next(void* ptr, cq_event_queue_init(&cqd->queue); } -static void cq_destroy_next(void* ptr) { - cq_next_data* cqd = static_cast(ptr); +static void cq_destroy_next(void* data) { + cq_next_data* cqd = static_cast(data); GPR_ASSERT(cq_event_queue_num_items(&cqd->queue) == 0); cq_event_queue_destroy(&cqd->queue); } -static void cq_init_pluck(void* ptr, +static void cq_init_pluck(void* data, grpc_core::CQCallbackInterface* shutdown_callback) { - cq_pluck_data* cqd = static_cast(ptr); + cq_pluck_data* cqd = static_cast(data); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); cqd->completed_tail = &cqd->completed_head; @@ -526,14 +526,14 @@ static void cq_init_pluck(void* ptr, gpr_atm_no_barrier_store(&cqd->things_queued_ever, 0); } -static void cq_destroy_pluck(void* ptr) { - cq_pluck_data* cqd = static_cast(ptr); +static void cq_destroy_pluck(void* data) { + cq_pluck_data* cqd = static_cast(data); GPR_ASSERT(cqd->completed_head.next == (uintptr_t)&cqd->completed_head); } static void cq_init_callback( - void* ptr, grpc_core::CQCallbackInterface* shutdown_callback) { - cq_callback_data* cqd = static_cast(ptr); + void* data, grpc_core::CQCallbackInterface* shutdown_callback) { + cq_callback_data* cqd = static_cast(data); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); cqd->shutdown_called = false; @@ -541,7 +541,7 @@ static void cq_init_callback( cqd->shutdown_callback = shutdown_callback; } -static void cq_destroy_callback(void* ptr) {} +static void cq_destroy_callback(void* data) {} grpc_cq_completion_type grpc_get_cq_completion_type(grpc_completion_queue* cq) { return cq->vtable->cq_completion_type; From f025b6ed899822bcec9b1c8a2e748ccda5f45551 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 14 Aug 2018 14:42:00 -0700 Subject: [PATCH 116/546] Change thread default to INT_MAX --- src/cpp/server/server_cc.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index d32d6b49043..4cd7ebda93a 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -48,10 +48,11 @@ namespace grpc { namespace { // The default value for maximum number of threads that can be created in the -// sync server. This value of 500 is empirically chosen. To increase the max -// number of threads in a sync server, pass a custom ResourceQuota object (with -// the desired number of max-threads set) to the server builder -#define DEFAULT_MAX_SYNC_SERVER_THREADS 500 +// sync server. This value of INT_MAX is chose to match the default behavior if +// no ResourceQuota is set. To modify the max number of threads in a sync +// server, pass a custom ResourceQuota object (with the desired number of +// max-threads set) to the server builder. +#define DEFAULT_MAX_SYNC_SERVER_THREADS INT_MAX class DefaultGlobalCallbacks final : public Server::GlobalCallbacks { public: From 6321a53e4a31973a80d5198bb1a4298a96d6212c Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 14 Aug 2018 15:01:28 -0700 Subject: [PATCH 117/546] fix typo --- src/cpp/server/server_cc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 4cd7ebda93a..9d9cc7de625 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -48,7 +48,7 @@ namespace grpc { namespace { // The default value for maximum number of threads that can be created in the -// sync server. This value of INT_MAX is chose to match the default behavior if +// sync server. This value of INT_MAX is chosen to match the default behavior if // no ResourceQuota is set. To modify the max number of threads in a sync // server, pass a custom ResourceQuota object (with the desired number of // max-threads set) to the server builder. From 1a10a9b9bf8f3ebc096b0349ccadf8f8b047251f Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 14 Aug 2018 15:05:18 -0700 Subject: [PATCH 118/546] Fix dns_resolver_cooldown_test and fake_resolver_test. --- .../resolvers/dns_resolver_cooldown_test.cc | 114 ++++++------------ .../resolvers/fake_resolver_test.cc | 58 +++------ 2 files changed, 48 insertions(+), 124 deletions(-) diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc index b1f3a1c08aa..27de7cac958 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -28,12 +28,14 @@ #include "src/core/lib/iomgr/sockaddr_utils.h" #include "test/core/util/test_config.h" +constexpr int kMinResolutionPeriodMs = 1000; + extern grpc_address_resolver_vtable* grpc_resolve_address_impl; static grpc_address_resolver_vtable* default_resolve_address; static grpc_combiner* g_combiner; -grpc_ares_request* (*g_default_dns_lookup_ares_locked)( +static grpc_ares_request* (*g_default_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, @@ -43,7 +45,7 @@ grpc_ares_request* (*g_default_dns_lookup_ares_locked)( // times a system-level resolution has happened. static int g_resolution_count; -struct iomgr_args { +static struct iomgr_args { gpr_event ev; gpr_atm done_atm; gpr_mu* mu; @@ -61,6 +63,16 @@ static void test_resolve_address_impl(const char* name, default_resolve_address->resolve_address( name, default_port, g_iomgr_args.pollset_set, on_done, addrs); ++g_resolution_count; + static grpc_millis last_resolution_time = 0; + if (last_resolution_time == 0) { + last_resolution_time = + grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); + } else { + grpc_millis now = + grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); + GPR_ASSERT(now - last_resolution_time >= kMinResolutionPeriodMs); + last_resolution_time = now; + } } static grpc_error* test_blocking_resolve_address_impl( @@ -73,7 +85,7 @@ static grpc_error* test_blocking_resolve_address_impl( static grpc_address_resolver_vtable test_resolver = { test_resolve_address_impl, test_blocking_resolve_address_impl}; -grpc_ares_request* test_dns_lookup_ares_locked( +static grpc_ares_request* test_dns_lookup_ares_locked( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, @@ -82,6 +94,15 @@ grpc_ares_request* test_dns_lookup_ares_locked( dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, addrs, check_grpclb, service_config_json, combiner); ++g_resolution_count; + static grpc_millis last_resolution_time = 0; + if (last_resolution_time == 0) { + grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); + } else { + grpc_millis now = + grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); + GPR_ASSERT(now - last_resolution_time >= kMinResolutionPeriodMs); + last_resolution_time = now; + } return result; } @@ -91,7 +112,7 @@ static gpr_timespec test_deadline(void) { static void do_nothing(void* arg, grpc_error* error) {} -void iomgr_args_init(iomgr_args* args) { +static void iomgr_args_init(iomgr_args* args) { gpr_event_init(&args->ev); args->pollset = static_cast(gpr_zalloc(grpc_pollset_size())); grpc_pollset_init(args->pollset, &args->mu); @@ -100,7 +121,7 @@ void iomgr_args_init(iomgr_args* args) { gpr_atm_rel_store(&args->done_atm, 0); } -void iomgr_args_finish(iomgr_args* args) { +static void iomgr_args_finish(iomgr_args* args) { GPR_ASSERT(gpr_event_wait(&args->ev, test_deadline())); grpc_pollset_set_del_pollset(args->pollset_set, args->pollset); grpc_pollset_set_destroy(args->pollset_set); @@ -146,29 +167,19 @@ struct OnResolutionCallbackArg { const char* uri_str = nullptr; grpc_core::OrphanablePtr resolver; grpc_channel_args* result = nullptr; - grpc_millis delay_before_second_resolution = 0; }; -// Counter for the number of times a resolution notification callback has been -// invoked. -static int g_on_resolution_invocations_count; - // Set to true by the last callback in the resolution chain. -bool g_all_callbacks_invoked; +static bool g_all_callbacks_invoked; -void on_fourth_resolution(void* arg, grpc_error* error) { +static void on_second_resolution(void* arg, grpc_error* error) { OnResolutionCallbackArg* cb_arg = static_cast(arg); grpc_channel_args_destroy(cb_arg->result); GPR_ASSERT(error == GRPC_ERROR_NONE); - ++g_on_resolution_invocations_count; - gpr_log(GPR_INFO, - "4th: g_on_resolution_invocations_count: %d, g_resolution_count: %d", - g_on_resolution_invocations_count, g_resolution_count); - // In this case we expect to have incurred in another system-level resolution - // because on_third_resolution slept for longer than the min resolution - // period. - GPR_ASSERT(g_on_resolution_invocations_count == 4); - GPR_ASSERT(g_resolution_count == 3); + gpr_log(GPR_INFO, "2nd: g_resolution_count: %d", g_resolution_count); + // The resolution callback was not invoked until new data was + // available, which was delayed until after the cooldown period. + GPR_ASSERT(g_resolution_count == 2); cb_arg->resolver.reset(); gpr_atm_rel_store(&g_iomgr_args.done_atm, 1); gpr_mu_lock(g_iomgr_args.mu); @@ -179,67 +190,13 @@ void on_fourth_resolution(void* arg, grpc_error* error) { g_all_callbacks_invoked = true; } -void on_third_resolution(void* arg, grpc_error* error) { - OnResolutionCallbackArg* cb_arg = static_cast(arg); - grpc_channel_args_destroy(cb_arg->result); - GPR_ASSERT(error == GRPC_ERROR_NONE); - ++g_on_resolution_invocations_count; - gpr_log(GPR_INFO, - "3rd: g_on_resolution_invocations_count: %d, g_resolution_count: %d", - g_on_resolution_invocations_count, g_resolution_count); - // The timer set because of the previous re-resolution request fires, so a new - // system-level resolution happened. - GPR_ASSERT(g_on_resolution_invocations_count == 3); - GPR_ASSERT(g_resolution_count == 2); - grpc_core::ExecCtx::Get()->TestOnlySetNow( - cb_arg->delay_before_second_resolution * 2); - cb_arg->resolver->NextLocked( - &cb_arg->result, - GRPC_CLOSURE_CREATE(on_fourth_resolution, arg, - grpc_combiner_scheduler(g_combiner))); - cb_arg->resolver->RequestReresolutionLocked(); - gpr_mu_lock(g_iomgr_args.mu); - GRPC_LOG_IF_ERROR("pollset_kick", - grpc_pollset_kick(g_iomgr_args.pollset, nullptr)); - gpr_mu_unlock(g_iomgr_args.mu); -} - -void on_second_resolution(void* arg, grpc_error* error) { - OnResolutionCallbackArg* cb_arg = static_cast(arg); - grpc_channel_args_destroy(cb_arg->result); - GPR_ASSERT(error == GRPC_ERROR_NONE); - ++g_on_resolution_invocations_count; - gpr_log(GPR_INFO, - "2nd: g_on_resolution_invocations_count: %d, g_resolution_count: %d", - g_on_resolution_invocations_count, g_resolution_count); - // The resolution request for which this function is the callback happened - // before the min resolution period. Therefore, no new system-level - // resolutions happened, as indicated by g_resolution_count. But a resolution - // timer was set to fire when the cooldown finishes. - GPR_ASSERT(g_on_resolution_invocations_count == 2); - GPR_ASSERT(g_resolution_count == 1); - // Register a new callback to capture the timer firing. - cb_arg->resolver->NextLocked( - &cb_arg->result, - GRPC_CLOSURE_CREATE(on_third_resolution, arg, - grpc_combiner_scheduler(g_combiner))); - gpr_mu_lock(g_iomgr_args.mu); - GRPC_LOG_IF_ERROR("pollset_kick", - grpc_pollset_kick(g_iomgr_args.pollset, nullptr)); - gpr_mu_unlock(g_iomgr_args.mu); -} - -void on_first_resolution(void* arg, grpc_error* error) { +static void on_first_resolution(void* arg, grpc_error* error) { OnResolutionCallbackArg* cb_arg = static_cast(arg); grpc_channel_args_destroy(cb_arg->result); GPR_ASSERT(error == GRPC_ERROR_NONE); - ++g_on_resolution_invocations_count; - gpr_log(GPR_INFO, - "1st: g_on_resolution_invocations_count: %d, g_resolution_count: %d", - g_on_resolution_invocations_count, g_resolution_count); + gpr_log(GPR_INFO, "1st: g_resolution_count: %d", g_resolution_count); // There's one initial system-level resolution and one invocation of a // notification callback (the current function). - GPR_ASSERT(g_on_resolution_invocations_count == 1); GPR_ASSERT(g_resolution_count == 1); cb_arg->resolver->NextLocked( &cb_arg->result, @@ -265,9 +222,7 @@ static void start_test_under_combiner(void* arg, grpc_error* error) { grpc_core::ResolverArgs args; args.uri = uri; args.combiner = g_combiner; - g_on_resolution_invocations_count = 0; g_resolution_count = 0; - constexpr int kMinResolutionPeriodMs = 1000; grpc_arg cooldown_arg; cooldown_arg.key = @@ -280,7 +235,6 @@ static void start_test_under_combiner(void* arg, grpc_error* error) { res_cb_arg->resolver = factory->CreateResolver(args); grpc_channel_args_destroy(cooldown_channel_args); GPR_ASSERT(res_cb_arg->resolver != nullptr); - res_cb_arg->delay_before_second_resolution = kMinResolutionPeriodMs; // First resolution, would incur in system-level resolution. res_cb_arg->resolver->NextLocked( &res_cb_arg->result, diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc index 14caa3ea5df..f6696bf1278 100644 --- a/test/core/client_channel/resolvers/fake_resolver_test.cc +++ b/test/core/client_channel/resolvers/fake_resolver_test.cc @@ -124,8 +124,8 @@ static void test_fake_resolver() { build_fake_resolver(combiner, response_generator.get()); GPR_ASSERT(resolver.get() != nullptr); // Test 1: normal resolution. - // next_results != NULL, reresolution_results == NULL, last_used_results == - // NULL. Expected response is next_results. + // next_results != NULL, reresolution_results == NULL. + // Expected response is next_results. grpc_channel_args* results = create_new_resolver_result(); on_resolution_arg on_res_arg = create_on_resolution_arg(results); grpc_closure* on_resolution = GRPC_CLOSURE_CREATE( @@ -137,10 +137,9 @@ static void test_fake_resolver() { GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, grpc_timeout_seconds_to_deadline(5)) != nullptr); // Test 2: update resolution. - // next_results != NULL, reresolution_results == NULL, last_used_results != - // NULL. Expected response is next_results. + // next_results != NULL, reresolution_results == NULL. + // Expected response is next_results. results = create_new_resolver_result(); - grpc_channel_args* last_used_results = grpc_channel_args_copy(results); on_res_arg = create_on_resolution_arg(results); on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, grpc_combiner_scheduler(combiner)); @@ -150,21 +149,9 @@ static void test_fake_resolver() { grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, grpc_timeout_seconds_to_deadline(5)) != nullptr); - // Test 3: fallback re-resolution. - // next_results == NULL, reresolution_results == NULL, last_used_results != - // NULL. Expected response is last_used_results. - on_res_arg = create_on_resolution_arg(last_used_results); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, - grpc_combiner_scheduler(combiner)); - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); - // Trigger a re-resolution. - resolver->RequestReresolutionLocked(); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_seconds_to_deadline(5)) != nullptr); - // Test 4: normal re-resolution. - // next_results == NULL, reresolution_results != NULL, last_used_results != - // NULL. Expected response is reresolution_results. + // Test 3: normal re-resolution. + // next_results == NULL, reresolution_results != NULL. + // Expected response is reresolution_results. grpc_channel_args* reresolution_results = create_new_resolver_result(); on_res_arg = create_on_resolution_arg(grpc_channel_args_copy(reresolution_results)); @@ -180,9 +167,9 @@ static void test_fake_resolver() { grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, grpc_timeout_seconds_to_deadline(5)) != nullptr); - // Test 5: repeat re-resolution. - // next_results == NULL, reresolution_results != NULL, last_used_results != - // NULL. Expected response is reresolution_results. + // Test 4: repeat re-resolution. + // next_results == NULL, reresolution_results != NULL. + // Expected response is reresolution_results. on_res_arg = create_on_resolution_arg(reresolution_results); on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, grpc_combiner_scheduler(combiner)); @@ -192,11 +179,10 @@ static void test_fake_resolver() { grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, grpc_timeout_seconds_to_deadline(5)) != nullptr); - // Test 6: normal resolution. - // next_results != NULL, reresolution_results != NULL, last_used_results != - // NULL. Expected response is next_results. + // Test 5: normal resolution. + // next_results != NULL, reresolution_results != NULL. + // Expected response is next_results. results = create_new_resolver_result(); - last_used_results = grpc_channel_args_copy(results); on_res_arg = create_on_resolution_arg(results); on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, grpc_combiner_scheduler(combiner)); @@ -206,23 +192,7 @@ static void test_fake_resolver() { grpc_core::ExecCtx::Get()->Flush(); GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, grpc_timeout_seconds_to_deadline(5)) != nullptr); - // Test 7: fallback re-resolution. - // next_results == NULL, reresolution_results == NULL, last_used_results != - // NULL. Expected response is last_used_results. - on_res_arg = create_on_resolution_arg(last_used_results); - on_resolution = GRPC_CLOSURE_CREATE(on_resolution_cb, &on_res_arg, - grpc_combiner_scheduler(combiner)); - resolver->NextLocked(&on_res_arg.resolver_result, on_resolution); - // Reset reresolution_results. - response_generator->SetReresolutionResponse(nullptr); - // Flush here to guarantee that reresolution_results has been reset. - grpc_core::ExecCtx::Get()->Flush(); - // Trigger a re-resolution. - resolver->RequestReresolutionLocked(); - grpc_core::ExecCtx::Get()->Flush(); - GPR_ASSERT(gpr_event_wait(&on_res_arg.ev, - grpc_timeout_seconds_to_deadline(5)) != nullptr); - // Test 8: no-op. + // Test 6: no-op. // Requesting a new resolution without setting the response shouldn't trigger // the resolution callback. memset(&on_res_arg, 0, sizeof(on_res_arg)); From 14ad82a76de99de39460d901cf44767308859ae0 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 14 Aug 2018 15:04:35 -0700 Subject: [PATCH 119/546] Create a new method handler for resource exhaustion and tie into thread mgr --- include/grpcpp/impl/codegen/byte_buffer.h | 4 + .../grpcpp/impl/codegen/completion_queue.h | 6 +- .../grpcpp/impl/codegen/method_handler_impl.h | 17 ++- include/grpcpp/impl/codegen/server_context.h | 6 +- include/grpcpp/server.h | 3 + src/cpp/server/server_cc.cc | 22 +++- src/cpp/thread_manager/thread_manager.cc | 35 ++++-- src/cpp/thread_manager/thread_manager.h | 2 +- test/cpp/end2end/thread_stress_test.cc | 113 ++++++++---------- .../cpp/thread_manager/thread_manager_test.cc | 4 +- 10 files changed, 125 insertions(+), 87 deletions(-) diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h index 86c047ebe7a..8cc51581152 100644 --- a/include/grpcpp/impl/codegen/byte_buffer.h +++ b/include/grpcpp/impl/codegen/byte_buffer.h @@ -45,6 +45,8 @@ template class RpcMethodHandler; template class ServerStreamingHandler; +template +class ErrorMethodHandler; template class DeserializeFuncType; class GrpcByteBufferPeer; @@ -144,6 +146,8 @@ class ByteBuffer final { friend class internal::RpcMethodHandler; template friend class internal::ServerStreamingHandler; + template + friend class internal::ErrorMethodHandler; template friend class internal::DeserializeFuncType; friend class ProtoBufferReader; diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 272575dac28..3f7d4fb765f 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -78,9 +78,10 @@ template class ServerStreamingHandler; template class BidiStreamingHandler; -class UnknownMethodHandler; template class TemplatedBidiStreamingHandler; +template +class ErrorMethodHandler; template class BlockingUnaryCallImpl; } // namespace internal @@ -265,7 +266,8 @@ class CompletionQueue : private GrpcLibraryCodegen { friend class ::grpc::internal::ServerStreamingHandler; template friend class ::grpc::internal::TemplatedBidiStreamingHandler; - friend class ::grpc::internal::UnknownMethodHandler; + template + friend class ::grpc::internal::ErrorMethodHandler; friend class ::grpc::Server; friend class ::grpc::ServerContext; friend class ::grpc::ServerInterface; diff --git a/include/grpcpp/impl/codegen/method_handler_impl.h b/include/grpcpp/impl/codegen/method_handler_impl.h index 851aa2a024b..53117f941b4 100644 --- a/include/grpcpp/impl/codegen/method_handler_impl.h +++ b/include/grpcpp/impl/codegen/method_handler_impl.h @@ -272,12 +272,14 @@ class SplitServerStreamingHandler ServerSplitStreamer, false>(func) {} }; -/// Handle unknown method by returning UNIMPLEMENTED error. -class UnknownMethodHandler : public MethodHandler { +/// General method handler class for errors that prevent real method use +/// e.g., handle unknown method by returning UNIMPLEMENTED error. +template +class ErrorMethodHandler : public MethodHandler { public: template static void FillOps(ServerContext* context, T* ops) { - Status status(StatusCode::UNIMPLEMENTED, ""); + Status status(code, ""); if (!context->sent_initial_metadata_) { ops->SendInitialMetadata(context->initial_metadata_, context->initial_metadata_flags()); @@ -294,9 +296,18 @@ class UnknownMethodHandler : public MethodHandler { FillOps(param.server_context, &ops); param.call->PerformOps(&ops); param.call->cq()->Pluck(&ops); + // We also have to destroy any request payload in the handler parameter + ByteBuffer* payload = param.request.bbuf_ptr(); + if (payload != nullptr) { + payload->Clear(); + } } }; +typedef ErrorMethodHandler UnknownMethodHandler; +typedef ErrorMethodHandler + ResourceExhaustedHandler; + } // namespace internal } // namespace grpc diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index 153b404d9e1..10372de1299 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -63,9 +63,10 @@ template class ServerStreamingHandler; template class BidiStreamingHandler; -class UnknownMethodHandler; template class TemplatedBidiStreamingHandler; +template +class ErrorMethodHandler; class Call; } // namespace internal @@ -262,7 +263,8 @@ class ServerContext { friend class ::grpc::internal::ServerStreamingHandler; template friend class ::grpc::internal::TemplatedBidiStreamingHandler; - friend class ::grpc::internal::UnknownMethodHandler; + template + friend class internal::ErrorMethodHandler; friend class ::grpc::ClientContext; /// Prevent copying. diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 189d8bec224..72544c0f0bc 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -223,6 +223,9 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { std::unique_ptr health_check_service_; bool health_check_service_disabled_; + + // A special handler for resource exhausted in sync case + std::unique_ptr resource_exhausted_handler_; }; } // namespace grpc diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index d32d6b49043..66d432c9107 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -210,8 +210,10 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { call_(mrd->call_, server, &cq_, server->max_receive_message_size()), ctx_(mrd->deadline_, &mrd->request_metadata_), has_request_payload_(mrd->has_request_payload_), - request_payload_(mrd->request_payload_), - method_(mrd->method_) { + request_payload_(has_request_payload_ ? mrd->request_payload_ + : nullptr), + method_(mrd->method_), + server_(server) { ctx_.set_call(mrd->call_); ctx_.cq_ = &cq_; GPR_ASSERT(mrd->in_flight_); @@ -225,10 +227,13 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { } } - void Run(const std::shared_ptr& global_callbacks) { + void Run(const std::shared_ptr& global_callbacks, + bool resources) { ctx_.BeginCompletionOp(&call_); global_callbacks->PreSynchronousRequest(&ctx_); - method_->handler()->RunHandler(internal::MethodHandler::HandlerParameter( + auto* handler = resources ? method_->handler() + : server_->resource_exhausted_handler_.get(); + handler->RunHandler(internal::MethodHandler::HandlerParameter( &call_, &ctx_, request_payload_)); global_callbacks->PostSynchronousRequest(&ctx_); request_payload_ = nullptr; @@ -250,6 +255,7 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { const bool has_request_payload_; grpc_byte_buffer* request_payload_; internal::RpcServiceMethod* const method_; + Server* server_; }; private: @@ -300,7 +306,7 @@ class Server::SyncRequestThreadManager : public ThreadManager { GPR_UNREACHABLE_CODE(return TIMEOUT); } - void DoWork(void* tag, bool ok) override { + void DoWork(void* tag, bool ok, bool resources) override { SyncRequest* sync_req = static_cast(tag); if (!sync_req) { @@ -320,7 +326,7 @@ class Server::SyncRequestThreadManager : public ThreadManager { } GPR_TIMER_SCOPE("cd.Run()", 0); - cd.Run(global_callbacks_); + cd.Run(global_callbacks_, resources); } // TODO (sreek) If ok is false here (which it isn't in case of // grpc_request_registered_call), we should still re-queue the request @@ -578,6 +584,10 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { } } + if (!sync_server_cqs_->empty()) { + resource_exhausted_handler_.reset(new internal::ResourceExhaustedHandler); + } + for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { (*it)->Start(); } diff --git a/src/cpp/thread_manager/thread_manager.cc b/src/cpp/thread_manager/thread_manager.cc index fa9eec5f9ba..e48bf951ea4 100644 --- a/src/cpp/thread_manager/thread_manager.cc +++ b/src/cpp/thread_manager/thread_manager.cc @@ -166,22 +166,37 @@ void ThreadManager::MainWorkLoop() { case WORK_FOUND: // If we got work and there are now insufficient pollers and there is // quota available to create a new thread, start a new poller thread - if (!shutdown_ && num_pollers_ < min_pollers_ && - grpc_resource_user_allocate_threads(resource_user_, 1)) { - num_pollers_++; - num_threads_++; - if (num_threads_ > max_active_threads_sofar_) { - max_active_threads_sofar_ = num_threads_; + bool got_thread; + if (!shutdown_ && num_pollers_ < min_pollers_) { + if (grpc_resource_user_allocate_threads(resource_user_, 1)) { + num_pollers_++; + num_threads_++; + if (num_threads_ > max_active_threads_sofar_) { + max_active_threads_sofar_ = num_threads_; + } + // Drop lock before spawning thread to avoid contention + lock.unlock(); + new WorkerThread(this); + got_thread = true; + } else if (num_pollers_ > 0) { + // There is still at least some thread polling, so we can go on + // even though we couldn't allocate a new thread + lock.unlock(); + got_thread = true; + } else { + // There are no pollers to spare and we couldn't allocate + // a new thread, so resources are exhausted! + lock.unlock(); + got_thread = false; } - // Drop lock before spawning thread to avoid contention - lock.unlock(); - new WorkerThread(this); } else { // Drop lock for consistency with above branch lock.unlock(); + got_thread = true; } // Lock is always released at this point - do the application work - DoWork(tag, ok); + // or return resource exhausted + DoWork(tag, ok, got_thread); // Take the lock again to check post conditions lock.lock(); // If we're shutdown, we should finish at this point. diff --git a/src/cpp/thread_manager/thread_manager.h b/src/cpp/thread_manager/thread_manager.h index 01043edb31e..352f80baf4c 100644 --- a/src/cpp/thread_manager/thread_manager.h +++ b/src/cpp/thread_manager/thread_manager.h @@ -72,7 +72,7 @@ class ThreadManager { // The implementation of DoWork() should also do any setup needed to ensure // that the next call to PollForWork() (not necessarily by the current thread) // actually finds some work - virtual void DoWork(void* tag, bool ok) = 0; + virtual void DoWork(void* tag, bool ok, bool resources) = 0; // Mark the ThreadManager as shutdown and begin draining the work. This is a // non-blocking call and the caller should call Wait(), a blocking call which diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index ccf8400a872..94ad684fe7d 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -16,6 +16,7 @@ * */ +#include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -51,63 +53,13 @@ namespace testing { class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { public: - TestServiceImpl() : signal_client_(false) {} + TestServiceImpl() {} Status Echo(ServerContext* context, const EchoRequest* request, EchoResponse* response) override { response->set_message(request->message()); return Status::OK; } - - // Unimplemented is left unimplemented to test the returned error. - - Status RequestStream(ServerContext* context, - ServerReader* reader, - EchoResponse* response) override { - EchoRequest request; - response->set_message(""); - while (reader->Read(&request)) { - response->mutable_message()->append(request.message()); - } - return Status::OK; - } - - // Return 3 messages. - // TODO(yangg) make it generic by adding a parameter into EchoRequest - Status ResponseStream(ServerContext* context, const EchoRequest* request, - ServerWriter* writer) override { - EchoResponse response; - response.set_message(request->message() + "0"); - writer->Write(response); - response.set_message(request->message() + "1"); - writer->Write(response); - response.set_message(request->message() + "2"); - writer->Write(response); - - return Status::OK; - } - - Status BidiStream( - ServerContext* context, - ServerReaderWriter* stream) override { - EchoRequest request; - EchoResponse response; - while (stream->Read(&request)) { - gpr_log(GPR_INFO, "recv msg %s", request.message().c_str()); - response.set_message(request.message()); - stream->Write(response); - } - return Status::OK; - } - - bool signal_client() { - std::unique_lock lock(mu_); - return signal_client_; - } - - private: - bool signal_client_; - std::mutex mu_; }; template @@ -118,6 +70,7 @@ class CommonStressTest { virtual void SetUp() = 0; virtual void TearDown() = 0; virtual void ResetStub() = 0; + virtual bool AllowExhaustion() = 0; grpc::testing::EchoTestService::Stub* GetStub() { return stub_.get(); } protected: @@ -146,6 +99,7 @@ class CommonStressTestInsecure : public CommonStressTest { CreateChannel(server_address_.str(), InsecureChannelCredentials()); this->stub_ = grpc::testing::EchoTestService::NewStub(channel); } + bool AllowExhaustion() override { return false; } protected: void SetUpStart(ServerBuilder* builder, Service* service) override { @@ -161,7 +115,7 @@ class CommonStressTestInsecure : public CommonStressTest { std::ostringstream server_address_; }; -template +template class CommonStressTestInproc : public CommonStressTest { public: void ResetStub() override { @@ -169,6 +123,7 @@ class CommonStressTestInproc : public CommonStressTest { std::shared_ptr channel = this->server_->InProcessChannel(args); this->stub_ = grpc::testing::EchoTestService::NewStub(channel); } + bool AllowExhaustion() override { return allow_resource_exhaustion; } protected: void SetUpStart(ServerBuilder* builder, Service* service) override { @@ -193,6 +148,26 @@ class CommonStressTestSyncServer : public BaseClass { TestServiceImpl service_; }; +template +class CommonStressTestSyncServerLowThreadCount : public BaseClass { + public: + void SetUp() override { + ServerBuilder builder; + ResourceQuota quota; + this->SetUpStart(&builder, &service_); + quota.SetMaxThreads(4); + builder.SetResourceQuota(quota); + this->SetUpEnd(&builder); + } + void TearDown() override { + this->TearDownStart(); + this->TearDownEnd(); + } + + private: + TestServiceImpl service_; +}; + template class CommonStressTestAsyncServer : public BaseClass { public: @@ -293,7 +268,8 @@ class End2endTest : public ::testing::Test { Common common_; }; -static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs) { +static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs, + bool allow_exhaustion, gpr_atm* errors) { EchoRequest request; EchoResponse response; request.set_message("Hello"); @@ -301,34 +277,49 @@ static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs) { for (int i = 0; i < num_rpcs; ++i) { ClientContext context; Status s = stub->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok() || (allow_exhaustion && + s.error_code() == StatusCode::RESOURCE_EXHAUSTED)); if (!s.ok()) { - gpr_log(GPR_ERROR, "RPC error: %d: %s", s.error_code(), - s.error_message().c_str()); + if (!(allow_exhaustion && + s.error_code() == StatusCode::RESOURCE_EXHAUSTED)) { + gpr_log(GPR_ERROR, "RPC error: %d: %s", s.error_code(), + s.error_message().c_str()); + } + gpr_atm_no_barrier_fetch_add(errors, static_cast(1)); + } else { + EXPECT_EQ(response.message(), request.message()); } - ASSERT_TRUE(s.ok()); } } typedef ::testing::Types< CommonStressTestSyncServer>, - CommonStressTestSyncServer>, + CommonStressTestSyncServer>, + CommonStressTestSyncServerLowThreadCount< + CommonStressTestInproc>, CommonStressTestAsyncServer< CommonStressTestInsecure>, - CommonStressTestAsyncServer< - CommonStressTestInproc>> + CommonStressTestAsyncServer>> CommonTypes; TYPED_TEST_CASE(End2endTest, CommonTypes); TYPED_TEST(End2endTest, ThreadStress) { this->common_.ResetStub(); std::vector threads; + gpr_atm errors; + gpr_atm_rel_store(&errors, static_cast(0)); threads.reserve(kNumThreads); for (int i = 0; i < kNumThreads; ++i) { - threads.emplace_back(SendRpc, this->common_.GetStub(), kNumRpcs); + threads.emplace_back(SendRpc, this->common_.GetStub(), kNumRpcs, + this->common_.AllowExhaustion(), &errors); } for (int i = 0; i < kNumThreads; ++i) { threads[i].join(); } + uint64_t error_cnt = static_cast(gpr_atm_no_barrier_load(&errors)); + if (error_cnt != 0) { + gpr_log(GPR_INFO, "RPC error count: %" PRIu64, error_cnt); + } } template diff --git a/test/cpp/thread_manager/thread_manager_test.cc b/test/cpp/thread_manager/thread_manager_test.cc index 838f5f72adb..99de5a3e010 100644 --- a/test/cpp/thread_manager/thread_manager_test.cc +++ b/test/cpp/thread_manager/thread_manager_test.cc @@ -55,7 +55,7 @@ class ThreadManagerTest final : public grpc::ThreadManager { num_work_found_(0) {} grpc::ThreadManager::WorkStatus PollForWork(void** tag, bool* ok) override; - void DoWork(void* tag, bool ok) override; + void DoWork(void* tag, bool ok, bool resources) override; // Get number of times PollForWork() returned WORK_FOUND int GetNumWorkFound(); @@ -102,7 +102,7 @@ grpc::ThreadManager::WorkStatus ThreadManagerTest::PollForWork(void** tag, return WORK_FOUND; } -void ThreadManagerTest::DoWork(void* tag, bool ok) { +void ThreadManagerTest::DoWork(void* tag, bool ok, bool resources) { gpr_atm_no_barrier_fetch_add(&num_do_work_, 1); SleepForMs(settings_.work_duration_ms); // Simulate work by sleeping } From 3aa987a29a02f59116f3e7d07cfa6a4835c211b4 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 13 Aug 2018 23:43:48 -0700 Subject: [PATCH 120/546] Add channelz server support --- include/grpc/grpc.h | 3 + src/core/lib/channel/channelz.cc | 41 ++++++++++ src/core/lib/channel/channelz.h | 28 ++++++- src/core/lib/channel/channelz_registry.cc | 40 +++++++++ src/core/lib/channel/channelz_registry.h | 7 ++ src/core/lib/surface/call.cc | 54 ++++++++----- src/core/lib/surface/call.h | 1 + src/core/lib/surface/channel.cc | 7 +- src/core/lib/surface/server.cc | 24 ++++++ src/core/lib/surface/server.h | 4 + test/core/channel/channelz_test.cc | 90 ++++++++++++++++++++- test/core/end2end/tests/channelz.cc | 67 ++++++++++----- test/cpp/util/channel_trace_proto_helper.cc | 9 +++ test/cpp/util/channel_trace_proto_helper.h | 2 + 14 files changed, 331 insertions(+), 46 deletions(-) diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 412778f7f73..cb32808c562 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -483,6 +483,9 @@ GRPCAPI const grpc_arg_pointer_vtable* grpc_resource_quota_arg_vtable(void); The returned string is allocated and must be freed by the application. */ GRPCAPI char* grpc_channelz_get_top_channels(intptr_t start_channel_id); +/* Gets all servers that exist in the process. */ +GRPCAPI char* grpc_channelz_get_servers(intptr_t start_channel_id); + /* Returns a single Channel, or else a NOT_FOUND code. The returned string is allocated and must be freed by the application. */ GRPCAPI char* grpc_channelz_get_channel(intptr_t channel_id); diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 9f548500025..bb790056544 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -48,6 +48,7 @@ BaseNode::~BaseNode() { ChannelzRegistry::Unregister(uuid_); } char* BaseNode::RenderJsonString() { grpc_json* json = RenderJson(); + GPR_ASSERT(json != nullptr); char* json_str = grpc_json_dump_to_string(json, 0); grpc_json_destroy(json); return json_str; @@ -146,5 +147,45 @@ RefCountedPtr ChannelNode::MakeChannelNode( channel, channel_tracer_max_nodes, is_top_level_channel); } +ServerNode::ServerNode(size_t channel_tracer_max_nodes) + : BaseNode(EntityType::kServer), trace_(channel_tracer_max_nodes) {} + +ServerNode::~ServerNode() {} + +grpc_json* ServerNode::RenderJson() { + // We need to track these three json objects to build our object + grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); + grpc_json* json = top_level_json; + grpc_json* json_iterator = nullptr; + // create and fill the ref child + json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr, + GRPC_JSON_OBJECT, false); + json = json_iterator; + json_iterator = nullptr; + json_iterator = grpc_json_add_number_string_child(json, json_iterator, + "serverId", uuid()); + // reset json iterators to top level object + json = top_level_json; + json_iterator = nullptr; + // create and fill the data child. + grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr, + GRPC_JSON_OBJECT, false); + json = data; + json_iterator = nullptr; + // fill in the channel trace if applicable + grpc_json* trace_json = trace_.RenderJson(); + if (trace_json != nullptr) { + trace_json->key = "trace"; // this object is named trace in channelz.proto + grpc_json_link_child(json, trace_json, nullptr); + } + // ask CallCountingHelper to populate trace and call count data. + call_counter_.PopulateCallCounts(json); + json = top_level_json; + // template method. Child classes may override this to add their specific + // functionality. + PopulateSockets(json); + return top_level_json; +} + } // namespace channelz } // namespace grpc_core diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index bd2735929c8..9a448d3b389 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -167,12 +167,32 @@ class ChannelNode : public BaseNode { }; // Handles channelz bookkeeping for servers -// TODO(ncteisen): implement in subsequent PR. class ServerNode : public BaseNode { public: - explicit ServerNode(size_t channel_tracer_max_nodes) - : BaseNode(EntityType::kServer) {} - ~ServerNode() override {} + explicit ServerNode(size_t channel_tracer_max_nodes); + ~ServerNode() override; + + grpc_json* RenderJson() override; + + void PopulateSockets(grpc_json* json) {} + + // proxy methods to composed classes. + void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { + trace_.AddTraceEvent(severity, data); + } + void AddTraceEventWithReference(ChannelTrace::Severity severity, + grpc_slice data, + RefCountedPtr referenced_channel) { + trace_.AddTraceEventWithReference(severity, data, + std::move(referenced_channel)); + } + void RecordCallStarted() { call_counter_.RecordCallStarted(); } + void RecordCallFailed() { call_counter_.RecordCallFailed(); } + void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } + + private: + CallCountingHelper call_counter_; + ChannelTrace trace_; }; // Handles channelz bookkeeping for sockets diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index d2c403cc1bb..285f641ba9c 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -111,6 +111,42 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { return json_str; } +char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) { + grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); + grpc_json* json = top_level_json; + grpc_json* json_iterator = nullptr; + InlinedVector servers; + // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is + // reserved). However, we want to support requests coming in with + // start_server_id=0, which signifies "give me everything." + size_t start_idx = start_server_id == 0 ? 0 : start_server_id - 1; + for (size_t i = start_idx; i < entities_.size(); ++i) { + if (entities_[i] != nullptr && + entities_[i]->type() == + grpc_core::channelz::BaseNode::EntityType::kServer) { + servers.push_back(entities_[i]); + } + } + if (!servers.empty()) { + // create list of servers + grpc_json* array_parent = grpc_json_create_child( + nullptr, json, "server", nullptr, GRPC_JSON_ARRAY, false); + for (size_t i = 0; i < servers.size(); ++i) { + grpc_json* server_json = servers[i]->RenderJson(); + json_iterator = + grpc_json_link_child(array_parent, server_json, json_iterator); + } + } + // For now we do not have any pagination rules. In the future we could + // pick a constant for max_channels_sent for a GetServers request. + // Tracking: https://github.com/grpc/grpc/issues/16019. + json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, + GRPC_JSON_TRUE, false); + char* json_str = grpc_json_dump_to_string(top_level_json, 0); + grpc_json_destroy(top_level_json); + return json_str; +} + } // namespace channelz } // namespace grpc_core @@ -119,6 +155,10 @@ char* grpc_channelz_get_top_channels(intptr_t start_channel_id) { start_channel_id); } +char* grpc_channelz_get_servers(intptr_t start_server_id) { + return grpc_core::channelz::ChannelzRegistry::GetServers(start_server_id); +} + char* grpc_channelz_get_channel(intptr_t channel_id) { grpc_core::channelz::BaseNode* channel_node = grpc_core::channelz::ChannelzRegistry::Get(channel_id); diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h index 142c039220d..d0d660600d9 100644 --- a/src/core/lib/channel/channelz_registry.h +++ b/src/core/lib/channel/channelz_registry.h @@ -52,6 +52,12 @@ class ChannelzRegistry { return Default()->InternalGetTopChannels(start_channel_id); } + // Returns the allocated JSON string that represents the proto + // GetServersResponse as per channelz.proto. + static char* GetServers(intptr_t start_server_id) { + return Default()->InternalGetServers(start_server_id); + } + private: GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE @@ -74,6 +80,7 @@ class ChannelzRegistry { BaseNode* InternalGet(intptr_t uuid); char* InternalGetTopChannels(intptr_t start_channel_id); + char* InternalGetServers(intptr_t start_server_id); // protects entities_ and uuid_ gpr_mu mu_; diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index d81e33054a2..d32281e076c 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -48,6 +48,7 @@ #include "src/core/lib/surface/call_test_only.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/completion_queue.h" +#include "src/core/lib/surface/server.h" #include "src/core/lib/surface/validate_metadata.h" #include "src/core/lib/transport/error_utils.h" #include "src/core/lib/transport/metadata.h" @@ -166,6 +167,8 @@ struct grpc_call { grpc_completion_queue* cq; grpc_polling_entity pollent; grpc_channel* channel; + // backpointer to owning server if this is a server side call. + grpc_server* server; gpr_timespec start_time; /* parent_call* */ gpr_atm parent_call_atm; child_call* child; @@ -362,14 +365,11 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, /* Always support no compression */ GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_MESSAGE_COMPRESS_NONE); call->is_client = args->server_transport_data == nullptr; - if (call->is_client) { - GRPC_STATS_INC_CLIENT_CALLS_CREATED(); - } else { - GRPC_STATS_INC_SERVER_CALLS_CREATED(); - } call->stream_op_payload.context = call->context; grpc_slice path = grpc_empty_slice(); if (call->is_client) { + GRPC_STATS_INC_CLIENT_CALLS_CREATED(); + call->server = nullptr; GPR_ASSERT(args->add_initial_metadata_count < MAX_SEND_EXTRA_METADATA_COUNT); for (i = 0; i < args->add_initial_metadata_count; i++) { @@ -383,6 +383,8 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, call->send_extra_metadata_count = static_cast(args->add_initial_metadata_count); } else { + GRPC_STATS_INC_SERVER_CALLS_CREATED(); + call->server = args->server; GPR_ASSERT(args->add_initial_metadata_count == 0); call->send_extra_metadata_count = 0; } @@ -486,10 +488,18 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, &call->pollent); } - grpc_core::channelz::ChannelNode* channelz_channel = - grpc_channel_get_channelz_node(call->channel); - if (channelz_channel != nullptr) { - channelz_channel->RecordCallStarted(); + if (call->is_client) { + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(call->channel); + if (channelz_channel != nullptr) { + channelz_channel->RecordCallStarted(); + } + } else { + grpc_core::channelz::ServerNode* channelz_server = + grpc_server_get_channelz_node(call->server); + if (channelz_server != nullptr) { + channelz_server->RecordCallStarted(); + } } grpc_slice_unref_internal(path); @@ -1263,18 +1273,26 @@ static void post_batch_completion(batch_control* bctl) { call->final_op.client.status, call->final_op.client.status_details, call->final_op.client.error_string); + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(call->channel); + if (channelz_channel != nullptr) { + if (*call->final_op.client.status != GRPC_STATUS_OK) { + channelz_channel->RecordCallFailed(); + } else { + channelz_channel->RecordCallSucceeded(); + } + } } else { get_final_status(call, set_cancelled_value, call->final_op.server.cancelled, nullptr, nullptr); - } - // Record channelz data for the channel. - grpc_core::channelz::ChannelNode* channelz_channel = - grpc_channel_get_channelz_node(call->channel); - if (channelz_channel != nullptr) { - if (*call->final_op.client.status != GRPC_STATUS_OK) { - channelz_channel->RecordCallFailed(); - } else { - channelz_channel->RecordCallSucceeded(); + grpc_core::channelz::ServerNode* channelz_server = + grpc_server_get_channelz_node(call->server); + if (channelz_server != nullptr) { + if (*call->final_op.server.cancelled) { + channelz_server->RecordCallFailed(); + } else { + channelz_server->RecordCallSucceeded(); + } } } GRPC_ERROR_UNREF(error); diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index b3b06059d4d..b34260505ae 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -33,6 +33,7 @@ typedef void (*grpc_ioreq_completion_func)(grpc_call* call, int success, typedef struct grpc_call_create_args { grpc_channel* channel; + grpc_server* server; grpc_call* parent; uint32_t propagation_mask; diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index 10d90e1406c..815d302577a 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -166,10 +166,11 @@ grpc_channel* grpc_channel_create_with_builder( } grpc_channel_args_destroy(args); - if (channelz_enabled) { - bool is_top_level_channel = channel->is_client && !internal_channel; + // only track client channels since server channels are held in the + // grpc_server channel. + if (channelz_enabled && channel->is_client) { channel->channelz_channel = channel_node_create_func( - channel, channel_tracer_max_nodes, is_top_level_channel); + channel, channel_tracer_max_nodes, !internal_channel); channel->channelz_channel->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Channel created")); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index cb34def7403..8e9d8ec98cc 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -219,6 +219,8 @@ struct grpc_server { /** when did we print the last shutdown progress message */ gpr_timespec last_shutdown_message_time; + + grpc_core::RefCountedPtr channelz_server; }; #define SERVER_FROM_CALL_ELEM(elem) \ @@ -364,6 +366,7 @@ static void server_ref(grpc_server* server) { static void server_delete(grpc_server* server) { registered_method* rm; size_t i; + server->channelz_server.reset(); grpc_channel_args_destroy(server->channel_args); gpr_mu_destroy(&server->mu_global); gpr_mu_destroy(&server->mu_call); @@ -779,6 +782,7 @@ static void accept_stream(void* cd, grpc_transport* transport, args.channel = chand->channel; args.server_transport_data = transport_server_data; args.send_deadline = GRPC_MILLIS_INF_FUTURE; + args.server = chand->server; grpc_call* call; grpc_error* error = grpc_call_create(&args, &call); grpc_call_element* elem = @@ -941,6 +945,7 @@ void grpc_server_register_completion_queue(grpc_server* server, } grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) { + grpc_core::ExecCtx exec_ctx; GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved)); grpc_server* server = @@ -957,6 +962,20 @@ grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) { server->channel_args = grpc_channel_args_copy(args); + const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_ENABLE_CHANNELZ); + if (grpc_channel_arg_get_bool(arg, false)) { + arg = grpc_channel_args_find(args, + GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); + size_t trace_events_per_node = + grpc_channel_arg_get_integer(arg, {0, 0, INT_MAX}); + server->channelz_server = + grpc_core::MakeRefCounted( + trace_events_per_node); + server->channelz_server->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string("Server created")); + } + return server; } @@ -1459,3 +1478,8 @@ int grpc_server_has_open_connections(grpc_server* server) { gpr_mu_unlock(&server->mu_global); return r; } + +grpc_core::channelz::ServerNode* grpc_server_get_channelz_node( + grpc_server* server) { + return server->channelz_server.get(); +} diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h index c617cc223e0..0196743ff9d 100644 --- a/src/core/lib/surface/server.h +++ b/src/core/lib/surface/server.h @@ -23,6 +23,7 @@ #include #include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/channel/channelz.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/transport/transport.h" @@ -46,6 +47,9 @@ void grpc_server_setup_transport(grpc_server* server, grpc_transport* transport, grpc_pollset* accepting_pollset, const grpc_channel_args* args); +grpc_core::channelz::ServerNode* grpc_server_get_channelz_node( + grpc_server* server); + const grpc_channel_args* grpc_server_get_channel_args(grpc_server* server); int grpc_server_has_open_connections(grpc_server* server); diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index 8fa46a18dae..f947617d0fd 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -31,6 +31,7 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/json/json.h" #include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" #include "test/core/util/test_config.h" #include "test/cpp/util/channel_trace_proto_helper.h" @@ -102,6 +103,25 @@ void ValidateGetTopChannels(size_t expected_channels) { gpr_free(core_api_json_str); } +void ValidateGetServers(size_t expected_servers) { + char* json_str = ChannelzRegistry::GetServers(0); + grpc::testing::ValidateGetServersResponseProtoJsonTranslation(json_str); + grpc_json* parsed_json = grpc_json_parse_string(json_str); + // This check will naturally have to change when we support pagination. + // tracked: https://github.com/grpc/grpc/issues/16019. + ValidateJsonArraySize(parsed_json, "server", expected_servers); + grpc_json* end = GetJsonChild(parsed_json, "end"); + ASSERT_NE(end, nullptr); + EXPECT_EQ(end->type, GRPC_JSON_TRUE); + grpc_json_destroy(parsed_json); + gpr_free(json_str); + // also check that the core API formats this correctly + char* core_api_json_str = grpc_channelz_get_servers(0); + grpc::testing::ValidateGetServersResponseProtoJsonTranslation( + core_api_json_str); + gpr_free(core_api_json_str); +} + class ChannelFixture { public: ChannelFixture(int max_trace_nodes = 0) { @@ -124,6 +144,27 @@ class ChannelFixture { grpc_channel* channel_; }; +class ServerFixture { + public: + ServerFixture(int max_trace_nodes = 0) { + grpc_arg server_a[2]; + server_a[0] = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE), + max_trace_nodes); + server_a[1] = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ENABLE_CHANNELZ), true); + grpc_channel_args server_args = {GPR_ARRAY_SIZE(server_a), server_a}; + server_ = grpc_server_create(&server_args, nullptr); + } + + ~ServerFixture() { grpc_server_destroy(server_); } + + grpc_server* server() { return server_; } + + private: + grpc_server* server_; +}; + struct validate_channel_data_args { int64_t calls_started; int64_t calls_failed; @@ -163,6 +204,13 @@ void ValidateChannel(ChannelNode* channel, validate_channel_data_args args) { gpr_free(core_api_json_str); } +void ValidateServer(ServerNode* server, validate_channel_data_args args) { + char* json_str = server->RenderJsonString(); + grpc::testing::ValidateServerProtoJsonTranslation(json_str); + ValidateCounters(json_str, args); + gpr_free(json_str); +} + grpc_millis GetLastCallStartedMillis(CallCountingHelper* channel) { CallCountingHelperPeer peer(channel); return peer.last_call_started_millis(); @@ -237,7 +285,7 @@ TEST_P(ChannelzChannelTest, LastCallStartedMillis) { EXPECT_NE(millis1, millis4); } -TEST(ChannelzGetTopChannelsTest, BasicTest) { +TEST(ChannelzGetTopChannelsTest, BasicGetTopChannelsTest) { grpc_core::ExecCtx exec_ctx; ChannelFixture channel; ValidateGetTopChannels(1); @@ -273,9 +321,49 @@ TEST(ChannelzGetTopChannelsTest, InternalChannelTest) { grpc_channel_destroy(internal_channel); } +class ChannelzServerTest : public ::testing::TestWithParam {}; + +TEST_P(ChannelzServerTest, BasicServerAPIFunctionality) { + grpc_core::ExecCtx exec_ctx; + ServerFixture server(10); + ServerNode* channelz_server = grpc_server_get_channelz_node(server.server()); + channelz_server->RecordCallStarted(); + channelz_server->RecordCallFailed(); + channelz_server->RecordCallSucceeded(); + ValidateServer(channelz_server, {1, 1, 1}); + channelz_server->RecordCallStarted(); + channelz_server->RecordCallFailed(); + channelz_server->RecordCallSucceeded(); + channelz_server->RecordCallStarted(); + channelz_server->RecordCallFailed(); + channelz_server->RecordCallSucceeded(); + ValidateServer(channelz_server, {3, 3, 3}); +} + +TEST(ChannelzGetServersTest, BasicGetServersTest) { + grpc_core::ExecCtx exec_ctx; + ServerFixture server; + ValidateGetServers(1); +} + +TEST(ChannelzGetServersTest, NoServersTest) { + grpc_core::ExecCtx exec_ctx; + ValidateGetServers(0); +} + +TEST(ChannelzGetServersTest, ManyServersTest) { + grpc_core::ExecCtx exec_ctx; + ServerFixture servers[10]; + (void)servers; // suppress unused variable error + ValidateGetServers(10); +} + INSTANTIATE_TEST_CASE_P(ChannelzChannelTestSweep, ChannelzChannelTest, ::testing::Values(0, 1, 2, 6, 10, 15)); +INSTANTIATE_TEST_CASE_P(ChannelzServerTestSweep, ChannelzServerTest, + ::testing::Values(0, 1, 2, 6, 10, 15)); + } // namespace testing } // namespace channelz } // namespace grpc_core diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 533703a2bec..f96c430b69f 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -22,6 +22,7 @@ #include #include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" #include #include @@ -198,17 +199,21 @@ static void run_one_request(grpc_end2end_test_config config, static void test_channelz(grpc_end2end_test_config config) { grpc_end2end_test_fixture f; - grpc_arg client_a; - client_a.type = GRPC_ARG_INTEGER; - client_a.key = const_cast(GRPC_ARG_ENABLE_CHANNELZ); - client_a.value.integer = true; - grpc_channel_args client_args = {1, &client_a}; + grpc_arg arg; + arg.type = GRPC_ARG_INTEGER; + arg.key = const_cast(GRPC_ARG_ENABLE_CHANNELZ); + arg.value.integer = true; + grpc_channel_args args = {1, &arg}; - f = begin_test(config, "test_channelz", &client_args, nullptr); + f = begin_test(config, "test_channelz", &args, &args); grpc_core::channelz::ChannelNode* channelz_channel = grpc_channel_get_channelz_node(f.client); - GPR_ASSERT(channelz_channel != nullptr); + + grpc_core::channelz::ServerNode* channelz_server = + grpc_server_get_channelz_node(f.server); + GPR_ASSERT(channelz_server != nullptr); + char* json = channelz_channel->RenderJsonString(); GPR_ASSERT(json != nullptr); // nothing is present yet @@ -241,6 +246,18 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); gpr_free(json); + json = channelz_server->RenderJsonString(); + GPR_ASSERT(json != nullptr); + gpr_log(GPR_INFO, "%s", json); + GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"2\"")); + GPR_ASSERT(nullptr != strstr(json, "\"callsFailed\":\"1\"")); + GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"1\"")); + // channel tracing is not enables, so these should not be preset. + GPR_ASSERT(nullptr == strstr(json, "\"trace\"")); + GPR_ASSERT(nullptr == strstr(json, "\"description\":\"Channel created\"")); + GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); + gpr_free(json); + end_test(&f); config.tear_down_data(&f); } @@ -248,22 +265,24 @@ static void test_channelz(grpc_end2end_test_config config) { static void test_channelz_with_channel_trace(grpc_end2end_test_config config) { grpc_end2end_test_fixture f; - grpc_arg client_a[2]; - client_a[0].type = GRPC_ARG_INTEGER; - client_a[0].key = - const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); - client_a[0].value.integer = 5; - client_a[1].type = GRPC_ARG_INTEGER; - client_a[1].key = const_cast(GRPC_ARG_ENABLE_CHANNELZ); - client_a[1].value.integer = true; - grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a}; - - f = begin_test(config, "test_channelz_with_channel_trace", &client_args, - nullptr); + grpc_arg arg[2]; + arg[0].type = GRPC_ARG_INTEGER; + arg[0].key = const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); + arg[0].value.integer = 5; + arg[1].type = GRPC_ARG_INTEGER; + arg[1].key = const_cast(GRPC_ARG_ENABLE_CHANNELZ); + arg[1].value.integer = true; + grpc_channel_args args = {GPR_ARRAY_SIZE(arg), arg}; + + f = begin_test(config, "test_channelz_with_channel_trace", &args, &args); grpc_core::channelz::ChannelNode* channelz_channel = grpc_channel_get_channelz_node(f.client); - GPR_ASSERT(channelz_channel != nullptr); + + grpc_core::channelz::ServerNode* channelz_server = + grpc_server_get_channelz_node(f.server); + GPR_ASSERT(channelz_server != nullptr); + char* json = channelz_channel->RenderJsonString(); GPR_ASSERT(json != nullptr); gpr_log(GPR_INFO, "%s", json); @@ -272,6 +291,14 @@ static void test_channelz_with_channel_trace(grpc_end2end_test_config config) { GPR_ASSERT(nullptr != strstr(json, "\"severity\":\"CT_INFO\"")); gpr_free(json); + json = channelz_server->RenderJsonString(); + GPR_ASSERT(json != nullptr); + gpr_log(GPR_INFO, "%s", json); + GPR_ASSERT(nullptr != strstr(json, "\"trace\"")); + GPR_ASSERT(nullptr != strstr(json, "\"description\":\"Server created\"")); + GPR_ASSERT(nullptr != strstr(json, "\"severity\":\"CT_INFO\"")); + gpr_free(json); + end_test(&f); config.tear_down_data(&f); } diff --git a/test/cpp/util/channel_trace_proto_helper.cc b/test/cpp/util/channel_trace_proto_helper.cc index e416a0375f0..42a436d49ba 100644 --- a/test/cpp/util/channel_trace_proto_helper.cc +++ b/test/cpp/util/channel_trace_proto_helper.cc @@ -86,5 +86,14 @@ void ValidateSubchannelProtoJsonTranslation(char* json_c_str) { VaidateProtoJsonTranslation(json_c_str); } +void ValidateServerProtoJsonTranslation(char* json_c_str) { + VaidateProtoJsonTranslation(json_c_str); +} + +void ValidateGetServersResponseProtoJsonTranslation(char* json_c_str) { + VaidateProtoJsonTranslation( + json_c_str); +} + } // namespace testing } // namespace grpc diff --git a/test/cpp/util/channel_trace_proto_helper.h b/test/cpp/util/channel_trace_proto_helper.h index a1ebbcd1100..67c363e89bf 100644 --- a/test/cpp/util/channel_trace_proto_helper.h +++ b/test/cpp/util/channel_trace_proto_helper.h @@ -27,6 +27,8 @@ void ValidateChannelProtoJsonTranslation(char* json_c_str); void ValidateGetTopChannelsResponseProtoJsonTranslation(char* json_c_str); void ValidateGetChannelResponseProtoJsonTranslation(char* json_c_str); void ValidateSubchannelProtoJsonTranslation(char* json_c_str); +void ValidateServerProtoJsonTranslation(char* json_c_str); +void ValidateGetServersResponseProtoJsonTranslation(char* json_c_str); } // namespace testing } // namespace grpc From 8e354419f478898c957aed82e8ea2c07057259db Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 14 Aug 2018 18:03:17 -0700 Subject: [PATCH 121/546] Fix LR test --- .../lb_policy/pick_first/pick_first.cc | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) 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 1cd5ef065de..ab33d933981 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 @@ -285,11 +285,11 @@ bool PickFirst::PickLocked(PickState* pick, grpc_error** error) { "No pick result available but synchronous result required."); return true; } + pick->next = pending_picks_; + pending_picks_ = pick; if (!started_picking_) { StartPickingLocked(); } - pick->next = pending_picks_; - pending_picks_ = pick; return false; } @@ -570,15 +570,6 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { PickFirst* p = static_cast(subchannel_list()->policy()); - if (p->selected_ == this) { - if (grpc_lb_pick_first_trace.enabled()) { - gpr_log(GPR_ERROR, - "Pick First %p calling ProcessUnselectedReadyLocked() on " - "selected subchannel %p", - p, subchannel()); - } - return; - } // If we get here, there are two possible cases: // 1. We do not currently have a selected subchannel, and the update is // for a subchannel in p->subchannel_list_ that we're trying to From d9781df47461e10ec364290955313773cd1876e1 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 15 Aug 2018 10:13:22 -0700 Subject: [PATCH 122/546] Address reviewer comments --- src/cpp/server/server_cc.cc | 3 +++ src/cpp/thread_manager/thread_manager.cc | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 66d432c9107..92f3f925cb5 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -584,6 +584,9 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { } } + // If this server has any support for synchronous methods (has any sync + // server CQs), make sure that we have a ResourceExhausted handler + // to deal with the case of thread exhaustion if (!sync_server_cqs_->empty()) { resource_exhausted_handler_.reset(new internal::ResourceExhaustedHandler); } diff --git a/src/cpp/thread_manager/thread_manager.cc b/src/cpp/thread_manager/thread_manager.cc index e48bf951ea4..3e8606a76fd 100644 --- a/src/cpp/thread_manager/thread_manager.cc +++ b/src/cpp/thread_manager/thread_manager.cc @@ -166,9 +166,10 @@ void ThreadManager::MainWorkLoop() { case WORK_FOUND: // If we got work and there are now insufficient pollers and there is // quota available to create a new thread, start a new poller thread - bool got_thread; + bool resource_exhausted = false; if (!shutdown_ && num_pollers_ < min_pollers_) { if (grpc_resource_user_allocate_threads(resource_user_, 1)) { + // We can allocate a new poller thread num_pollers_++; num_threads_++; if (num_threads_ > max_active_threads_sofar_) { @@ -177,26 +178,26 @@ void ThreadManager::MainWorkLoop() { // Drop lock before spawning thread to avoid contention lock.unlock(); new WorkerThread(this); - got_thread = true; } else if (num_pollers_ > 0) { // There is still at least some thread polling, so we can go on - // even though we couldn't allocate a new thread + // even though we are below the number of pollers that we would + // like to have (min_pollers_) lock.unlock(); - got_thread = true; } else { // There are no pollers to spare and we couldn't allocate // a new thread, so resources are exhausted! lock.unlock(); - got_thread = false; + resource_exhausted = true; } } else { - // Drop lock for consistency with above branch + // There are a sufficient number of pollers available so we can do + // the work and continue polling with our existing poller threads lock.unlock(); - got_thread = true; } // Lock is always released at this point - do the application work - // or return resource exhausted - DoWork(tag, ok, got_thread); + // or return resource exhausted if there is new work but we couldn't + // get a thread in which to do it. + DoWork(tag, ok, !resource_exhausted); // Take the lock again to check post conditions lock.lock(); // If we're shutdown, we should finish at this point. From f3c600f33547f23c9ff5b6686757a82c071119eb Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 15 Aug 2018 10:56:32 -0700 Subject: [PATCH 123/546] Fix up C++ test to be more stable --- src/cpp/server/channelz/channelz_service.cc | 6 +++ test/cpp/end2end/channelz_service_test.cc | 49 +++++++++++++-------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc index 77c175e5b8f..8365745201e 100644 --- a/src/cpp/server/channelz/channelz_service.cc +++ b/src/cpp/server/channelz/channelz_service.cc @@ -32,6 +32,9 @@ Status ChannelzService::GetTopChannels( ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request, channelz::v1::GetTopChannelsResponse* response) { char* json_str = grpc_channelz_get_top_channels(request->start_channel_id()); + if (json_str == nullptr) { + return Status(INTERNAL, "grpc_channelz_get_top_channels returned null"); + } google::protobuf::util::Status s = google::protobuf::util::JsonStringToMessage(json_str, response); gpr_free(json_str); @@ -45,6 +48,9 @@ Status ChannelzService::GetChannel( ServerContext* unused, const channelz::v1::GetChannelRequest* request, channelz::v1::GetChannelResponse* response) { char* json_str = grpc_channelz_get_channel(request->channel_id()); + if (json_str == nullptr) { + return Status(NOT_FOUND, "No object found for that ChannelId"); + } google::protobuf::util::Status s = google::protobuf::util::JsonStringToMessage(json_str, response); gpr_free(json_str); diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index 933e4a1ff67..ce1b7547119 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -140,7 +140,7 @@ class ChannelzServerTest : public ::testing::Test { ClientContext context; Status s = echo_stub_->Echo(&context, request, &response); EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); } void SendFailedEcho(int channel_idx) { @@ -156,6 +156,19 @@ class ChannelzServerTest : public ::testing::Test { EXPECT_FALSE(s.ok()); } + // Uses GetTopChannels to return the channel_id of a particular channel, + // so that the unit tests may test GetChannel call. + intptr_t GetChannelId(int channel_idx) { + GetTopChannelsRequest request; + GetTopChannelsResponse response; + request.set_start_channel_id(0); + ClientContext context; + Status s = channelz_stub_->GetTopChannels(&context, request, &response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + EXPECT_GT(response.channel_size(), channel_idx); + return response.channel(channel_idx).ref().channel_id(); + } + static string to_string(const int number) { std::stringstream strs; strs << number; @@ -190,7 +203,7 @@ TEST_F(ChannelzServerTest, BasicTest) { request.set_start_channel_id(0); ClientContext context; Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); EXPECT_EQ(response.channel_size(), 1); } @@ -202,7 +215,7 @@ TEST_F(ChannelzServerTest, HighStartId) { request.set_start_channel_id(10000); ClientContext context; Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); EXPECT_EQ(response.channel_size(), 0); } @@ -212,10 +225,10 @@ TEST_F(ChannelzServerTest, SuccessfulRequestTest) { SendSuccessfulEcho(0); GetChannelRequest request; GetChannelResponse response; - request.set_channel_id(1); + request.set_channel_id(GetChannelId(0)); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), 1); EXPECT_EQ(response.channel().data().calls_succeeded(), 1); EXPECT_EQ(response.channel().data().calls_failed(), 0); @@ -227,10 +240,10 @@ TEST_F(ChannelzServerTest, FailedRequestTest) { SendFailedEcho(0); GetChannelRequest request; GetChannelResponse response; - request.set_channel_id(1); + request.set_channel_id(GetChannelId(0)); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), 1); EXPECT_EQ(response.channel().data().calls_succeeded(), 0); EXPECT_EQ(response.channel().data().calls_failed(), 1); @@ -250,10 +263,10 @@ TEST_F(ChannelzServerTest, ManyRequestsTest) { } GetChannelRequest request; GetChannelResponse response; - request.set_channel_id(1); + request.set_channel_id(GetChannelId(0)); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess + kNumFailed); EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); @@ -269,7 +282,7 @@ TEST_F(ChannelzServerTest, ManyChannels) { request.set_start_channel_id(0); ClientContext context; Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); EXPECT_EQ(response.channel_size(), kNumChannels); } @@ -292,10 +305,10 @@ TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { { GetChannelRequest request; GetChannelResponse response; - request.set_channel_id(1); + request.set_channel_id(GetChannelId(0)); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess); EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); EXPECT_EQ(response.channel().data().calls_failed(), 0); @@ -305,10 +318,10 @@ TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { { GetChannelRequest request; GetChannelResponse response; - request.set_channel_id(2); + request.set_channel_id(GetChannelId(1)); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), kNumFailed); EXPECT_EQ(response.channel().data().calls_succeeded(), 0); EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed); @@ -318,10 +331,10 @@ TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { { GetChannelRequest request; GetChannelResponse response; - request.set_channel_id(3); + request.set_channel_id(GetChannelId(2)); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess + kNumFailed); EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); @@ -332,10 +345,10 @@ TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { { GetChannelRequest request; GetChannelResponse response; - request.set_channel_id(4); + request.set_channel_id(GetChannelId(3)); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), 0); EXPECT_EQ(response.channel().data().calls_succeeded(), 0); EXPECT_EQ(response.channel().data().calls_failed(), 0); From 632b58cb82111629c9ac59c195a56029540ae8e7 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 15 Aug 2018 11:13:41 -0700 Subject: [PATCH 124/546] regenerate projects --- grpc.def | 1 + src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 ++ src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 +++ test/core/surface/public_headers_must_be_c89.c | 1 + 4 files changed, 7 insertions(+) diff --git a/grpc.def b/grpc.def index 356137f80aa..e23610993ae 100644 --- a/grpc.def +++ b/grpc.def @@ -71,6 +71,7 @@ EXPORTS grpc_resource_quota_resize grpc_resource_quota_arg_vtable grpc_channelz_get_top_channels + grpc_channelz_get_servers grpc_channelz_get_channel grpc_channelz_get_subchannel grpc_insecure_channel_create_from_fd diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 0d5dcbc5433..8a9acc69445 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -94,6 +94,7 @@ grpc_resource_quota_unref_type grpc_resource_quota_unref_import; grpc_resource_quota_resize_type grpc_resource_quota_resize_import; grpc_resource_quota_arg_vtable_type grpc_resource_quota_arg_vtable_import; grpc_channelz_get_top_channels_type grpc_channelz_get_top_channels_import; +grpc_channelz_get_servers_type grpc_channelz_get_servers_import; grpc_channelz_get_channel_type grpc_channelz_get_channel_import; grpc_channelz_get_subchannel_type grpc_channelz_get_subchannel_import; grpc_insecure_channel_create_from_fd_type grpc_insecure_channel_create_from_fd_import; @@ -346,6 +347,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_resource_quota_resize_import = (grpc_resource_quota_resize_type) GetProcAddress(library, "grpc_resource_quota_resize"); grpc_resource_quota_arg_vtable_import = (grpc_resource_quota_arg_vtable_type) GetProcAddress(library, "grpc_resource_quota_arg_vtable"); grpc_channelz_get_top_channels_import = (grpc_channelz_get_top_channels_type) GetProcAddress(library, "grpc_channelz_get_top_channels"); + grpc_channelz_get_servers_import = (grpc_channelz_get_servers_type) GetProcAddress(library, "grpc_channelz_get_servers"); grpc_channelz_get_channel_import = (grpc_channelz_get_channel_type) GetProcAddress(library, "grpc_channelz_get_channel"); grpc_channelz_get_subchannel_import = (grpc_channelz_get_subchannel_type) GetProcAddress(library, "grpc_channelz_get_subchannel"); grpc_insecure_channel_create_from_fd_import = (grpc_insecure_channel_create_from_fd_type) GetProcAddress(library, "grpc_insecure_channel_create_from_fd"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index e8e1df72ad3..b540f869eff 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -257,6 +257,9 @@ extern grpc_resource_quota_arg_vtable_type grpc_resource_quota_arg_vtable_import typedef char*(*grpc_channelz_get_top_channels_type)(intptr_t start_channel_id); extern grpc_channelz_get_top_channels_type grpc_channelz_get_top_channels_import; #define grpc_channelz_get_top_channels grpc_channelz_get_top_channels_import +typedef char*(*grpc_channelz_get_servers_type)(intptr_t start_channel_id); +extern grpc_channelz_get_servers_type grpc_channelz_get_servers_import; +#define grpc_channelz_get_servers grpc_channelz_get_servers_import typedef char*(*grpc_channelz_get_channel_type)(intptr_t channel_id); extern grpc_channelz_get_channel_type grpc_channelz_get_channel_import; #define grpc_channelz_get_channel grpc_channelz_get_channel_import diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 429497df82f..4d0e960ba29 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -133,6 +133,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_resource_quota_resize); printf("%lx", (unsigned long) grpc_resource_quota_arg_vtable); printf("%lx", (unsigned long) grpc_channelz_get_top_channels); + printf("%lx", (unsigned long) grpc_channelz_get_servers); printf("%lx", (unsigned long) grpc_channelz_get_channel); printf("%lx", (unsigned long) grpc_channelz_get_subchannel); printf("%lx", (unsigned long) grpc_auth_property_iterator_next); From 70ef911343c88d6058e383ab775d8fb47506241c Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 15 Aug 2018 12:05:58 -0700 Subject: [PATCH 125/546] Add C++ support for GetServers --- src/cpp/server/channelz/channelz_service.cc | 16 ++++++++ src/cpp/server/channelz/channelz_service.h | 4 ++ test/cpp/end2end/channelz_service_test.cc | 41 +++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc index 0666986a39f..e096c1f421d 100644 --- a/src/cpp/server/channelz/channelz_service.cc +++ b/src/cpp/server/channelz/channelz_service.cc @@ -44,6 +44,22 @@ Status ChannelzService::GetTopChannels( return Status::OK; } +Status ChannelzService::GetServers( + ServerContext* unused, const channelz::v1::GetServersRequest* request, + channelz::v1::GetServersResponse* response) { + char* json_str = grpc_channelz_get_servers(request->start_server_id()); + if (json_str == nullptr) { + return Status(INTERNAL, "grpc_channelz_get_servers returned null"); + } + google::protobuf::util::Status s = + google::protobuf::util::JsonStringToMessage(json_str, response); + gpr_free(json_str); + if (s != google::protobuf::util::Status::OK) { + return Status(INTERNAL, s.ToString()); + } + return Status::OK; +} + Status ChannelzService::GetChannel( ServerContext* unused, const channelz::v1::GetChannelRequest* request, channelz::v1::GetChannelResponse* response) { diff --git a/src/cpp/server/channelz/channelz_service.h b/src/cpp/server/channelz/channelz_service.h index 95d6f47cff1..9e0b5b6eadb 100644 --- a/src/cpp/server/channelz/channelz_service.h +++ b/src/cpp/server/channelz/channelz_service.h @@ -32,6 +32,10 @@ class ChannelzService final : public channelz::v1::Channelz::Service { Status GetTopChannels( ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request, channelz::v1::GetTopChannelsResponse* response) override; + // implementation of GetServers rpc + Status GetServers(ServerContext* unused, + const channelz::v1::GetServersRequest* request, + channelz::v1::GetServersResponse* response) override; // implementation of GetChannel rpc Status GetChannel(ServerContext* unused, const channelz::v1::GetChannelRequest* request, diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index 53aebf24599..f219740a536 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -41,6 +41,8 @@ using grpc::channelz::v1::GetChannelRequest; using grpc::channelz::v1::GetChannelResponse; +using grpc::channelz::v1::GetServersRequest; +using grpc::channelz::v1::GetServersResponse; using grpc::channelz::v1::GetSubchannelRequest; using grpc::channelz::v1::GetSubchannelResponse; using grpc::channelz::v1::GetTopChannelsRequest; @@ -415,6 +417,45 @@ TEST_F(ChannelzServerTest, ManySubchannels) { } } +TEST_F(ChannelzServerTest, BasicServerTest) { + ResetStubs(); + ConfigureProxy(1); + GetServersRequest request; + GetServersResponse response; + request.set_start_server_id(0); + ClientContext context; + Status s = channelz_stub_->GetServers(&context, request, &response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + EXPECT_EQ(response.server_size(), 1); +} + +TEST_F(ChannelzServerTest, ServerCallTest) { + ResetStubs(); + ConfigureProxy(1); + const int kNumSuccess = 10; + const int kNumFailed = 11; + for (int i = 0; i < kNumSuccess; ++i) { + SendSuccessfulEcho(0); + } + for (int i = 0; i < kNumFailed; ++i) { + SendFailedEcho(0); + } + GetServersRequest request; + GetServersResponse response; + request.set_start_server_id(0); + ClientContext context; + Status s = channelz_stub_->GetServers(&context, request, &response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + EXPECT_EQ(response.server_size(), 1); + EXPECT_EQ(response.server(0).data().calls_succeeded(), kNumSuccess); + EXPECT_EQ(response.server(0).data().calls_failed(), kNumFailed); + // This is success+failure+1 because the call that retrieved this information + // will be counted as started. It will not track success/failure until after + // it has returned, so that is not included in the response. + EXPECT_EQ(response.server(0).data().calls_started(), + kNumSuccess + kNumFailed + 1); +} + } // namespace testing } // namespace grpc From d08ea3025b653d63652b65d52fa58517bcfa94e5 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Wed, 15 Aug 2018 13:43:15 -0700 Subject: [PATCH 126/546] Fixed ordering in adding pending picks to PF --- .../lb_policy/pick_first/pick_first.cc | 4 ++-- test/cpp/end2end/client_lb_end2end_test.cc | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) 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 2b6a9ba8c53..bc51903ef56 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 @@ -279,11 +279,11 @@ bool PickFirst::PickLocked(PickState* pick, grpc_error** error) { "No pick result available but synchronous result required."); return true; } + pick->next = pending_picks_; + pending_picks_ = pick; if (!started_picking_) { StartPickingLocked(); } - pick->next = pending_picks_; - pending_picks_ = pick; return false; } diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 7fe0da8aaec..26c241b74a2 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -353,6 +353,23 @@ TEST_F(ClientLbEnd2endTest, PickFirst) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } +TEST_F(ClientLbEnd2endTest, PickFirstProcessPending) { + StartServers(1); // Single server + auto channel = BuildChannel(""); // test that pick first is the default. + auto stub = BuildStub(channel); + SetNextResolution({servers_[0]->port_}); + WaitForServer(stub, 0, DEBUG_LOCATION); + // Create a new channel and its corresponding PF LB policy, which will pick + // the subchannels in READY state from the previous RPC against the same + // target (even if it happened over a different channel, because subchannels + // are globally reused). Progress should happen without any transition from + // this READY state. + auto second_channel = BuildChannel(""); + auto second_stub = BuildStub(second_channel); + SetNextResolution({servers_[0]->port_}); + CheckRpcSendOk(second_stub, DEBUG_LOCATION); +} + TEST_F(ClientLbEnd2endTest, PickFirstBackOffInitialReconnect) { ChannelArguments args; constexpr int kInitialBackOffMs = 100; From 9c32dab63dc031e71412bdb90865eafbc1f18746 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 15 Aug 2018 14:46:51 -0700 Subject: [PATCH 127/546] Expand comment based on reviewer feedback --- src/cpp/thread_manager/thread_manager.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpp/thread_manager/thread_manager.h b/src/cpp/thread_manager/thread_manager.h index 352f80baf4c..6f0bd17c5fe 100644 --- a/src/cpp/thread_manager/thread_manager.h +++ b/src/cpp/thread_manager/thread_manager.h @@ -67,7 +67,9 @@ class ThreadManager { // The implementation of DoWork() is supposed to perform the work found by // PollForWork(). The tag and ok parameters are the same as returned by - // PollForWork() + // PollForWork(). The resources parameter indicates that the call actually + // has the resources available for performing the RPC's work. If it doesn't, + // the implementation should fail it appropriately. // // The implementation of DoWork() should also do any setup needed to ensure // that the next call to PollForWork() (not necessarily by the current thread) From 3f002567c4c1f8cc7542aeee2d60d6d0c4c5dd54 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 15 Aug 2018 15:26:54 -0700 Subject: [PATCH 128/546] Add error checking for server args in PHP --- src/php/ext/grpc/server.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c index cb7b188b0e4..8c7eaee203f 100644 --- a/src/php/ext/grpc/server.c +++ b/src/php/ext/grpc/server.c @@ -75,7 +75,10 @@ PHP_METHOD(Server, __construct) { if (args_array == NULL) { server->wrapped = grpc_server_create(NULL, NULL); } else { - php_grpc_read_args_array(args_array, &args TSRMLS_CC); + if (php_grpc_read_args_array(args_array, &args TSRMLS_CC) == FAILURE) { + efree(args.args); + return; + } server->wrapped = grpc_server_create(&args, NULL); efree(args.args); } From befcfee767956659517266d32d262c4c83fdcbab Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 15 Aug 2018 15:26:54 -0700 Subject: [PATCH 129/546] Add error checking for server args in PHP --- src/php/ext/grpc/server.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c index cb7b188b0e4..8c7eaee203f 100644 --- a/src/php/ext/grpc/server.c +++ b/src/php/ext/grpc/server.c @@ -75,7 +75,10 @@ PHP_METHOD(Server, __construct) { if (args_array == NULL) { server->wrapped = grpc_server_create(NULL, NULL); } else { - php_grpc_read_args_array(args_array, &args TSRMLS_CC); + if (php_grpc_read_args_array(args_array, &args TSRMLS_CC) == FAILURE) { + efree(args.args); + return; + } server->wrapped = grpc_server_create(&args, NULL); efree(args.args); } From 16f738359db28c5c2293c05d91038192345f75e1 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 15 Aug 2018 16:30:59 -0700 Subject: [PATCH 130/546] Make sure that we actually saw some resource exhaustion if applicable --- test/cpp/end2end/thread_stress_test.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index 94ad684fe7d..1a5ed28a2cc 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -320,6 +320,10 @@ TYPED_TEST(End2endTest, ThreadStress) { if (error_cnt != 0) { gpr_log(GPR_INFO, "RPC error count: %" PRIu64, error_cnt); } + // If this test allows resource exhaustion, expect that it actually sees some + if (this->common_.AllowExhaustion()) { + EXPECT_GT(error_cnt, static_cast(0)); + } } template From 33e5c0d0912900ed9c1fab8c144f5fca67120378 Mon Sep 17 00:00:00 2001 From: Paul Petit Date: Thu, 16 Aug 2018 11:35:30 +0200 Subject: [PATCH 131/546] Replace is by == for a status comparison This worked fine with CPython, but the condition was always evaluated to False with Pypy, causing bugs down the road. Tested with Pypy 6.0. --- src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index d2c0389ca6a..0a25218e19e 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -48,7 +48,7 @@ cdef int _get_metadata( cdef size_t metadata_count cdef grpc_metadata *c_metadata def callback(metadata, grpc_status_code status, bytes error_details): - if status is StatusCode.ok: + if status == StatusCode.ok: _store_c_metadata(metadata, &c_metadata, &metadata_count) cb(user_data, c_metadata, metadata_count, status, NULL) _release_c_metadata(c_metadata, metadata_count) From 8a80364a9fde058d2d1126a8ec2acf3da1cbea5b Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Thu, 16 Aug 2018 06:50:10 -0700 Subject: [PATCH 132/546] Cleaned up BUILD file, which fixed a dependency problem with protobuf. --- test/cpp/util/BUILD | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index c3bfeb76156..477862a0ee1 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -269,27 +269,15 @@ grpc_cc_test( grpc_cc_binary( name = "grpc_cli", srcs = [ - "cli_call.cc", - "cli_call.h", - "cli_credentials.cc", - "cli_credentials.h", - "config_grpc_cli.h", "grpc_cli.cc", - "grpc_tool.cc", - "grpc_tool.h", - "proto_file_parser.cc", - "proto_file_parser.h", - "proto_reflection_descriptor_database.cc", - "proto_reflection_descriptor_database.h", - "service_describer.cc", - "service_describer.h", - "test_config.h", - "test_config_cc.cc", ], external_deps = [ "gflags", ], deps = [ + ":grpc_cli_libs", + ":grpc++_proto_reflection_desc_db", + ":test_config", "//:grpc++", "//src/proto/grpc/reflection/v1alpha:reflection_proto", ], From 26d3e774df8d601c5ce9c5fb181f846b1fe07049 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 16 Aug 2018 13:13:30 +0200 Subject: [PATCH 133/546] new C# serialization API --- .../Grpc.Core/DeserializationContext.cs | 49 ++++++++ src/csharp/Grpc.Core/Marshaller.cs | 110 ++++++++++++++++-- src/csharp/Grpc.Core/SerializationContext.cs | 34 ++++++ 3 files changed, 181 insertions(+), 12 deletions(-) create mode 100644 src/csharp/Grpc.Core/DeserializationContext.cs create mode 100644 src/csharp/Grpc.Core/SerializationContext.cs diff --git a/src/csharp/Grpc.Core/DeserializationContext.cs b/src/csharp/Grpc.Core/DeserializationContext.cs new file mode 100644 index 00000000000..17f0ba2805c --- /dev/null +++ b/src/csharp/Grpc.Core/DeserializationContext.cs @@ -0,0 +1,49 @@ +#region Copyright notice and license + +// Copyright 2018 The 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 + +namespace Grpc.Core +{ + /// + /// Provides access to the payload being deserialized when deserializing messages. + /// + public abstract class DeserializationContext + { + /// + /// Returns true if there is a payload to deserialize (= payload is not null), false otherwise. + /// + public virtual bool HasPayload => PayloadLength.HasValue; + + /// + /// Get the total length of the payload in bytes or null if the payload is null. + /// + public abstract int? PayloadLength { get; } + + /// + /// Gets the entire payload as a newly allocated byte array. + /// Once the byte array is returned, the byte array becomes owned by the caller and won't be ever accessed or reused by gRPC again. + /// NOTE: Obtaining the buffer as a newly allocated byte array is the simplest way of accessing the payload, + /// but it can have important consequences in high-performance scenarios. + /// In particular, using this method usually requires copying of the entire buffer one extra time. + /// Also, allocating a new buffer each time can put excessive pressure on GC, especially if + /// the payload is more than 86700 bytes large (which means the newly allocated buffer will be placed in LOH, + /// and LOH object can only be garbage collected via a full ("stop the world") GC run). + /// + /// byte array containing the entire payload or null if there is no payload. + public abstract byte[] PayloadAsNewBuffer(); + } +} diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core/Marshaller.cs index 1d758ca935d..df59cbd8d3a 100644 --- a/src/csharp/Grpc.Core/Marshaller.cs +++ b/src/csharp/Grpc.Core/Marshaller.cs @@ -29,36 +29,122 @@ namespace Grpc.Core readonly Func serializer; readonly Func deserializer; + readonly Action contextualSerializer; + readonly Func contextualDeserializer; + /// - /// Initializes a new marshaller. + /// Initializes a new marshaller from simple serialize/deserialize functions. /// /// Function that will be used to serialize messages. /// Function that will be used to deserialize messages. public Marshaller(Func serializer, Func deserializer) { - this.serializer = GrpcPreconditions.CheckNotNull(serializer, "serializer"); - this.deserializer = GrpcPreconditions.CheckNotNull(deserializer, "deserializer"); + this.serializer = GrpcPreconditions.CheckNotNull(serializer, nameof(serializer)); + this.deserializer = GrpcPreconditions.CheckNotNull(deserializer, nameof(deserializer)); + this.contextualSerializer = EmulateContextualSerializer; + this.contextualDeserializer = EmulateContextualDeserializer; } /// - /// Gets the serializer function. + /// Initializes a new marshaller from serialize/deserialize fuctions that can access serialization and deserialization + /// context. Compared to the simple serializer/deserializer functions, using the contextual version provides more + /// flexibility and can lead to increased efficiency (and better performance). + /// Note: This constructor is part of an experimental API that can change or be removed without any prior notice. /// - public Func Serializer + /// Function that will be used to serialize messages. + /// Function that will be used to deserialize messages. + public Marshaller(Action serializer, Func deserializer) { - get - { - return this.serializer; - } + this.contextualSerializer = GrpcPreconditions.CheckNotNull(serializer, nameof(serializer)); + this.contextualDeserializer = GrpcPreconditions.CheckNotNull(deserializer, nameof(deserializer)); + this.serializer = EmulateSimpleSerializer; + this.deserializer = EmulateSimpleDeserializer; } + /// + /// Gets the serializer function. + /// + public Func Serializer => this.serializer; + /// /// Gets the deserializer function. /// - public Func Deserializer + public Func Deserializer => this.deserializer; + + /// + /// Gets the serializer function. + /// Note: experimental API that can change or be removed without any prior notice. + /// + public Action ContextualSerializer => this.contextualSerializer; + + /// + /// Gets the serializer function. + /// Note: experimental API that can change or be removed without any prior notice. + /// + public Func ContextualDeserializer => this.contextualDeserializer; + + // for backward compatibility, emulate the simple serializer using the contextual one + private byte[] EmulateSimpleSerializer(T msg) { - get + // TODO(jtattermusch): avoid the allocation by passing a thread-local instance + var context = new EmulatedSerializationContext(); + this.contextualSerializer(msg, context); + return context.GetPayload(); + } + + // for backward compatibility, emulate the simple deserializer using the contextual one + private T EmulateSimpleDeserializer(byte[] payload) + { + // TODO(jtattermusch): avoid the allocation by passing a thread-local instance + var context = new EmulatedDeserializationContext(payload); + return this.contextualDeserializer(context); + } + + // for backward compatibility, emulate the contextual serializer using the simple one + private void EmulateContextualSerializer(T message, SerializationContext context) + { + var payload = this.serializer(message); + context.Complete(payload); + } + + // for backward compatibility, emulate the contextual deserializer using the simple one + private T EmulateContextualDeserializer(DeserializationContext context) + { + return this.deserializer(context.PayloadAsNewBuffer()); + } + + internal class EmulatedSerializationContext : SerializationContext + { + bool isComplete; + byte[] payload; + + public override void Complete(byte[] payload) + { + GrpcPreconditions.CheckState(!isComplete); + this.isComplete = true; + this.payload = payload; + } + + internal byte[] GetPayload() + { + return this.payload; + } + } + + internal class EmulatedDeserializationContext : DeserializationContext + { + readonly byte[] payload; + + public EmulatedDeserializationContext(byte[] payload) + { + this.payload = payload; + } + + public override int? PayloadLength => payload?.Length; + + public override byte[] PayloadAsNewBuffer() { - return this.deserializer; + return payload; } } } diff --git a/src/csharp/Grpc.Core/SerializationContext.cs b/src/csharp/Grpc.Core/SerializationContext.cs new file mode 100644 index 00000000000..cf4d1595da2 --- /dev/null +++ b/src/csharp/Grpc.Core/SerializationContext.cs @@ -0,0 +1,34 @@ +#region Copyright notice and license + +// Copyright 2018 The 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 + +namespace Grpc.Core +{ + /// + /// Provides storage for payload when serializing a message. + /// + public abstract class SerializationContext + { + /// + /// Use the byte array as serialized form of current message and mark serialization process as complete. + /// Complete() can only be called once. By calling this method the caller gives up the ownership of the + /// payload which must not be accessed afterwards. + /// + /// the serialized form of current message + public abstract void Complete(byte[] payload); + } +} From b840d5e45c03d7a3a5d371d0358b673a07f0dc65 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Thu, 16 Aug 2018 08:58:26 -0700 Subject: [PATCH 134/546] Revert "Add more filter priority levels" --- .../client_channel/client_channel_plugin.cc | 2 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 2 +- .../ext/filters/deadline/deadline_filter.cc | 4 +-- .../filters/http/client_authority_filter.cc | 12 ++++---- .../ext/filters/http/http_filters_plugin.cc | 27 +++++++++--------- .../server_load_reporting_filter.cc | 3 +- .../ext/filters/max_age/max_age_filter.cc | 2 +- .../message_size/message_size_filter.cc | 6 ++-- src/core/lib/channel/connected_channel.cc | 4 +-- src/core/lib/channel/connected_channel.h | 4 +-- src/core/lib/surface/channel_init.h | 28 +------------------ src/core/lib/surface/init.cc | 26 +++++++++-------- src/core/lib/surface/init_secure.cc | 11 +++----- src/cpp/common/channel_filter.cc | 9 ++---- src/cpp/common/channel_filter.h | 7 +---- src/cpp/ext/filters/census/grpc_plugin.cc | 6 ++-- .../channel/minimal_stack_is_minimal_test.cc | 16 +++++------ .../end2end/tests/filter_call_init_fails.cc | 15 +++++----- .../core/end2end/tests/filter_causes_close.cc | 5 ++-- test/core/end2end/tests/filter_latency.cc | 19 +++++++------ test/core/end2end/tests/filter_status_code.cc | 19 +++++++------ test/cpp/common/channel_filter_test.cc | 3 +- test/cpp/end2end/filter_end2end_test.cc | 3 +- 23 files changed, 96 insertions(+), 137 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc index 71da6486604..e0784b7e5c1 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -56,7 +56,7 @@ void grpc_client_channel_init(void) { grpc_register_http_proxy_mapper(); grpc_subchannel_index_init(); grpc_channel_init_register_stage( - GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_MAX, append_filter, + GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, append_filter, (void*)&grpc_client_channel_filter); grpc_http_connect_register_handshaker_factory(); } 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 6581385ff91..cf029ef4c18 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 @@ -1890,7 +1890,7 @@ void grpc_lb_policy_grpclb_init() { grpc_core::UniquePtr( grpc_core::New())); grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_LOW, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_client_load_reporting_filter, (void*)&grpc_client_load_reporting_filter); } diff --git a/src/core/ext/filters/deadline/deadline_filter.cc b/src/core/ext/filters/deadline/deadline_filter.cc index 3bd30593122..d23ad67ad51 100644 --- a/src/core/ext/filters/deadline/deadline_filter.cc +++ b/src/core/ext/filters/deadline/deadline_filter.cc @@ -379,10 +379,10 @@ static bool maybe_add_deadline_filter(grpc_channel_stack_builder* builder, void grpc_deadline_filter_init(void) { grpc_channel_init_register_stage( - GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_VERY_HIGH, + GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_deadline_filter, (void*)&grpc_client_deadline_filter); grpc_channel_init_register_stage( - GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_VERY_HIGH, + GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_deadline_filter, (void*)&grpc_server_deadline_filter); } diff --git a/src/core/ext/filters/http/client_authority_filter.cc b/src/core/ext/filters/http/client_authority_filter.cc index 3c0ae47e8d5..ddc939ed121 100644 --- a/src/core/ext/filters/http/client_authority_filter.cc +++ b/src/core/ext/filters/http/client_authority_filter.cc @@ -146,12 +146,12 @@ static bool add_client_authority_filter(grpc_channel_stack_builder* builder, } void grpc_client_authority_filter_init(void) { - grpc_channel_init_register_stage( - GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_PRIORITY_HIGH, - add_client_authority_filter, (void*)&grpc_client_authority_filter); - grpc_channel_init_register_stage( - GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_HIGH, - add_client_authority_filter, (void*)&grpc_client_authority_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX, + add_client_authority_filter, + (void*)&grpc_client_authority_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, + add_client_authority_filter, + (void*)&grpc_client_authority_filter); } void grpc_client_authority_filter_shutdown(void) {} diff --git a/src/core/ext/filters/http/http_filters_plugin.cc b/src/core/ext/filters/http/http_filters_plugin.cc index 38757710f39..f03fa0141df 100644 --- a/src/core/ext/filters/http/http_filters_plugin.cc +++ b/src/core/ext/filters/http/http_filters_plugin.cc @@ -18,7 +18,6 @@ #include -#include #include #include "src/core/ext/filters/http/client/http_client_filter.h" @@ -52,15 +51,15 @@ static bool maybe_add_optional_filter(grpc_channel_stack_builder* builder, bool enable = grpc_channel_arg_get_bool( grpc_channel_args_find(channel_args, filtarg->control_channel_arg), !grpc_channel_args_want_minimal_stack(channel_args)); - return enable ? grpc_channel_stack_builder_append_filter( + return enable ? grpc_channel_stack_builder_prepend_filter( builder, filtarg->filter, nullptr, nullptr) : true; } -static bool maybe_append_required_filter(grpc_channel_stack_builder* builder, - void* arg) { +static bool maybe_add_required_filter(grpc_channel_stack_builder* builder, + void* arg) { return is_building_http_like_transport(builder) - ? grpc_channel_stack_builder_append_filter( + ? grpc_channel_stack_builder_prepend_filter( builder, static_cast(arg), nullptr, nullptr) : true; @@ -68,23 +67,23 @@ static bool maybe_append_required_filter(grpc_channel_stack_builder* builder, void grpc_http_filters_init(void) { grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_HIGH, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_optional_filter, &compress_filter); grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_HIGH, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_optional_filter, &compress_filter); grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_HIGH, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_optional_filter, &compress_filter); grpc_channel_init_register_stage( - GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_PRIORITY_HIGH, - maybe_append_required_filter, (void*)&grpc_http_client_filter); + GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + maybe_add_required_filter, (void*)&grpc_http_client_filter); grpc_channel_init_register_stage( - GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_HIGH, - maybe_append_required_filter, (void*)&grpc_http_client_filter); + GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + maybe_add_required_filter, (void*)&grpc_http_client_filter); grpc_channel_init_register_stage( - GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_HIGH, - maybe_append_required_filter, (void*)&grpc_http_server_filter); + GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + maybe_add_required_filter, (void*)&grpc_http_server_filter); } void grpc_http_filters_shutdown(void) {} 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 0c4ffea27bf..6529046a5e7 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 @@ -345,8 +345,7 @@ struct ServerLoadReportingFilterStaticRegistrar { if (registered) return; RegisterChannelFilter( - "server_load_reporting", GRPC_SERVER_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_LOW, true, + "server_load_reporting", GRPC_SERVER_CHANNEL, INT_MAX, MaybeAddServerLoadReportingFilter); // Access measures to ensure they are initialized. Otherwise, we can't // create any valid view before the first RPC. 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 7db30d5b488..1fe8288bd0a 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -536,7 +536,7 @@ static bool maybe_add_max_age_filter(grpc_channel_stack_builder* builder, void grpc_max_age_filter_init(void) { grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_LOW, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_max_age_filter, nullptr); } 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 1bd9cf1426b..c7fc3f2e627 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -311,13 +311,13 @@ static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, void grpc_message_size_filter_init(void) { grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_LOW, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_message_size_filter, nullptr); grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_LOW, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_message_size_filter, nullptr); grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_LOW, + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_message_size_filter, nullptr); } diff --git a/src/core/lib/channel/connected_channel.cc b/src/core/lib/channel/connected_channel.cc index c78849a29b6..e2ea334dedf 100644 --- a/src/core/lib/channel/connected_channel.cc +++ b/src/core/lib/channel/connected_channel.cc @@ -228,8 +228,8 @@ static void bind_transport(grpc_channel_stack* channel_stack, grpc_transport_stream_size(static_cast(t)); } -bool grpc_append_connected_filter(grpc_channel_stack_builder* builder, - void* arg_must_be_null) { +bool grpc_add_connected_filter(grpc_channel_stack_builder* builder, + void* arg_must_be_null) { GPR_ASSERT(arg_must_be_null == nullptr); grpc_transport* t = grpc_channel_stack_builder_get_transport(builder); GPR_ASSERT(t != nullptr); diff --git a/src/core/lib/channel/connected_channel.h b/src/core/lib/channel/connected_channel.h index 280daf040da..faa1c73a21f 100644 --- a/src/core/lib/channel/connected_channel.h +++ b/src/core/lib/channel/connected_channel.h @@ -25,8 +25,8 @@ extern const grpc_channel_filter grpc_connected_filter; -bool grpc_append_connected_filter(grpc_channel_stack_builder* builder, - void* arg_must_be_null); +bool grpc_add_connected_filter(grpc_channel_stack_builder* builder, + void* arg_must_be_null); /* Debug helper to dig the transport stream out of a call element */ grpc_stream* grpc_connected_channel_get_stream(grpc_call_element* elem); diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index 6543796b4c8..f01852473ba 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -21,37 +21,11 @@ #include -#include - #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" -// Priority for channel registration functions to be used in -// grpc_channel_init_register_stage(). The priority dictates the -// order in which the registration functions run. -// -// When used to register a filter, the filter can either be appended or -// prepended, thus dictating whether the filter goes at the top or bottom of -// the stack. Higher priority functions can get closer to the top or bottom -// of the stack than lower priority functions. -enum { - // Default level. Most of filters should use this level if their location in - // the stack does not matter. - GRPC_CHANNEL_INIT_PRIORITY_LOW = 0, - // For filters that should be added after the group of filters with default - // priority, such as auth filters. - GRPC_CHANNEL_INIT_PRIORITY_MED = 10000, - // For filters that need to be close to top or bottom, such as protocol-level - // filters (client_authority, http-client, http-server). - GRPC_CHANNEL_INIT_PRIORITY_HIGH = 20000, - // For filters that need to be very close to the wire or surface, such as - // stats filters (census). - GRPC_CHANNEL_INIT_PRIORITY_VERY_HIGH = 30000, - // For things that have to happen last, such as connected channel filter or - // surface server filter. Consider as reserved for gRPC internals. - GRPC_CHANNEL_INIT_PRIORITY_MAX = INT_MAX -}; +#define GRPC_CHANNEL_INIT_BUILTIN_PRIORITY 10000 /// This module provides a way for plugins (and the grpc core library itself) /// to register mutators for channel stacks. diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 7807b261d40..0ad82fed99e 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -70,6 +70,11 @@ static void do_basic_init(void) { g_initializations = 0; } +static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { + return grpc_channel_stack_builder_append_filter( + builder, static_cast(arg), nullptr, nullptr); +} + static bool prepend_filter(grpc_channel_stack_builder* builder, void* arg) { return grpc_channel_stack_builder_prepend_filter( builder, static_cast(arg), nullptr, nullptr); @@ -77,20 +82,19 @@ static bool prepend_filter(grpc_channel_stack_builder* builder, void* arg) { static void register_builtin_channel_init() { grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_MAX, - grpc_append_connected_filter, nullptr); + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + grpc_add_connected_filter, nullptr); grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_MAX, - grpc_append_connected_filter, nullptr); + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + grpc_add_connected_filter, nullptr); grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_MAX, - grpc_append_connected_filter, nullptr); + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + grpc_add_connected_filter, nullptr); grpc_channel_init_register_stage(GRPC_CLIENT_LAME_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_MAX, - prepend_filter, (void*)&grpc_lame_filter); - grpc_channel_init_register_stage( - GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_MAX, prepend_filter, - (void*)&grpc_server_top_filter); + GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + append_filter, (void*)&grpc_lame_filter); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter, + (void*)&grpc_server_top_filter); } typedef struct grpc_plugin { diff --git a/src/core/lib/surface/init_secure.cc b/src/core/lib/surface/init_secure.cc index 8058aaa804d..28c6f7b121f 100644 --- a/src/core/lib/surface/init_secure.cc +++ b/src/core/lib/surface/init_secure.cc @@ -67,17 +67,14 @@ static bool maybe_prepend_server_auth_filter( } void grpc_register_security_filters(void) { - // Register the auth client with a medium priority to allow the authority + // Register the auth client with a priority < INT_MAX to allow the authority // filter -on which the auth filter depends- to be higher on the channel // stack. - grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_MED, + grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX - 1, maybe_prepend_client_auth_filter, nullptr); - grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_MED, + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX - 1, maybe_prepend_client_auth_filter, nullptr); - grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_MED, + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, maybe_prepend_server_auth_filter, nullptr); } diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc index 0634b0416fd..422e7bb65ee 100644 --- a/src/cpp/common/channel_filter.cc +++ b/src/cpp/common/channel_filter.cc @@ -78,13 +78,8 @@ bool MaybeAddFilter(grpc_channel_stack_builder* builder, void* arg) { grpc_channel_stack_builder_get_channel_arguments(builder); if (!filter.include_filter(*args)) return true; } - if (filter.prepend) { - return grpc_channel_stack_builder_prepend_filter(builder, &filter.filter, - nullptr, nullptr); - } else { - return grpc_channel_stack_builder_append_filter(builder, &filter.filter, - nullptr, nullptr); - } + return grpc_channel_stack_builder_prepend_filter(builder, &filter.filter, + nullptr, nullptr); } } // namespace diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h index 359c72737c2..5e569c97e68 100644 --- a/src/cpp/common/channel_filter.h +++ b/src/cpp/common/channel_filter.h @@ -36,8 +36,7 @@ /// \c ChannelData. Then register the filter using something like this: /// \code{.cpp} /// RegisterChannelFilter( -/// "name-of-filter", GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_LOW, -/// true, nullptr); +/// "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); /// \endcode namespace grpc { @@ -352,7 +351,6 @@ class ChannelFilter final { struct FilterRecord { grpc_channel_stack_type stack_type; int priority; - bool prepend; std::function include_filter; grpc_channel_filter filter; }; @@ -365,14 +363,12 @@ void ChannelFilterPluginShutdown(); /// Registers a new filter. /// Must be called by only one thread at a time. -/// The \a prepend argument decides whether to prepend or append the filter. /// The \a include_filter argument specifies a function that will be called /// to determine at run-time whether or not to add the filter. If the /// value is nullptr, the filter will be added unconditionally. template void RegisterChannelFilter( const char* name, grpc_channel_stack_type stack_type, int priority, - bool prepend, std::function include_filter) { // If we haven't been called before, initialize channel_filters and // call grpc_register_plugin(). @@ -387,7 +383,6 @@ void RegisterChannelFilter( internal::FilterRecord filter_record = { stack_type, priority, - prepend, include_filter, {FilterType::StartTransportStreamOpBatch, FilterType::StartTransportOp, FilterType::call_data_size, FilterType::InitCallElement, diff --git a/src/cpp/ext/filters/census/grpc_plugin.cc b/src/cpp/ext/filters/census/grpc_plugin.cc index f79e0e0e960..f978ed3bf51 100644 --- a/src/cpp/ext/filters/census/grpc_plugin.cc +++ b/src/cpp/ext/filters/census/grpc_plugin.cc @@ -32,12 +32,10 @@ namespace grpc { void RegisterOpenCensusPlugin() { RegisterChannelFilter( - "opencensus_client", GRPC_CLIENT_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_VERY_HIGH, true /* prepend */, + "opencensus_client", GRPC_CLIENT_CHANNEL, INT_MAX /* priority */, nullptr /* condition function */); RegisterChannelFilter( - "opencensus_server", GRPC_SERVER_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_VERY_HIGH, true /* prepend */, + "opencensus_server", GRPC_SERVER_CHANNEL, INT_MAX /* priority */, nullptr /* condition function */); // Access measures to ensure they are initialized. Otherwise, creating a view diff --git a/test/core/channel/minimal_stack_is_minimal_test.cc b/test/core/channel/minimal_stack_is_minimal_test.cc index 5b651ed39b7..e5953acedcf 100644 --- a/test/core/channel/minimal_stack_is_minimal_test.cc +++ b/test/core/channel/minimal_stack_is_minimal_test.cc @@ -85,21 +85,21 @@ int main(int argc, char** argv) { // tests with a default stack errors += - CHECK_STACK("unknown", nullptr, GRPC_CLIENT_DIRECT_CHANNEL, "deadline", - "authority", "message_size", "connected", NULL); + CHECK_STACK("unknown", nullptr, GRPC_CLIENT_DIRECT_CHANNEL, "authority", + "message_size", "deadline", "connected", NULL); errors += CHECK_STACK("unknown", nullptr, GRPC_CLIENT_SUBCHANNEL, "authority", "message_size", "connected", NULL); errors += CHECK_STACK("unknown", nullptr, GRPC_SERVER_CHANNEL, "server", - "deadline", "message_size", "connected", NULL); + "message_size", "deadline", "connected", NULL); errors += CHECK_STACK("chttp2", nullptr, GRPC_CLIENT_DIRECT_CHANNEL, - "deadline", "authority", "message_size", - "message_compress", "http-client", "connected", NULL); + "authority", "message_size", "deadline", "http-client", + "message_compress", "connected", NULL); errors += CHECK_STACK("chttp2", nullptr, GRPC_CLIENT_SUBCHANNEL, "authority", - "message_size", "message_compress", "http-client", + "message_size", "http-client", "message_compress", "connected", NULL); errors += CHECK_STACK("chttp2", nullptr, GRPC_SERVER_CHANNEL, "server", - "deadline", "message_size", "message_compress", - "http-server", "connected", NULL); + "message_size", "deadline", "http-server", + "message_compress", "connected", NULL); errors += CHECK_STACK(nullptr, nullptr, GRPC_CLIENT_CHANNEL, "client-channel", NULL); diff --git a/test/core/end2end/tests/filter_call_init_fails.cc b/test/core/end2end/tests/filter_call_init_fails.cc index 07e14214461..ab96879fe44 100644 --- a/test/core/end2end/tests/filter_call_init_fails.cc +++ b/test/core/end2end/tests/filter_call_init_fails.cc @@ -438,6 +438,7 @@ static bool maybe_add_server_channel_filter(grpc_channel_stack_builder* builder, // must be the last one. So we add it right before the last one. grpc_channel_stack_builder_iterator* it = grpc_channel_stack_builder_create_iterator_at_last(builder); + GPR_ASSERT(grpc_channel_stack_builder_move_prev(it)); const bool retval = grpc_channel_stack_builder_add_filter_before( it, &test_filter, nullptr, nullptr); grpc_channel_stack_builder_iterator_destroy(it); @@ -456,6 +457,7 @@ static bool maybe_add_client_channel_filter(grpc_channel_stack_builder* builder, // must be the last one. So we add it right before the last one. grpc_channel_stack_builder_iterator* it = grpc_channel_stack_builder_create_iterator_at_last(builder); + GPR_ASSERT(grpc_channel_stack_builder_move_prev(it)); const bool retval = grpc_channel_stack_builder_add_filter_before( it, &test_filter, nullptr, nullptr); grpc_channel_stack_builder_iterator_destroy(it); @@ -474,6 +476,7 @@ static bool maybe_add_client_subchannel_filter( // must be the last one. So we add it right before the last one. grpc_channel_stack_builder_iterator* it = grpc_channel_stack_builder_create_iterator_at_last(builder); + GPR_ASSERT(grpc_channel_stack_builder_move_prev(it)); const bool retval = grpc_channel_stack_builder_add_filter_before( it, &test_filter, nullptr, nullptr); grpc_channel_stack_builder_iterator_destroy(it); @@ -484,17 +487,13 @@ static bool maybe_add_client_subchannel_filter( } static void init_plugin(void) { - grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_MAX, + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, maybe_add_server_channel_filter, nullptr); - grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_MAX, + grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, maybe_add_client_channel_filter, nullptr); - grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_MAX, + grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX, maybe_add_client_subchannel_filter, nullptr); - grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_MAX, + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, maybe_add_client_channel_filter, nullptr); } diff --git a/test/core/end2end/tests/filter_causes_close.cc b/test/core/end2end/tests/filter_causes_close.cc index 891c1b8c1fb..a7f4268803f 100644 --- a/test/core/end2end/tests/filter_causes_close.cc +++ b/test/core/end2end/tests/filter_causes_close.cc @@ -261,9 +261,8 @@ static bool maybe_add_filter(grpc_channel_stack_builder* builder, void* arg) { } static void init_plugin(void) { - grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, - GRPC_CHANNEL_INIT_PRIORITY_HIGH, - maybe_add_filter, nullptr); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, 0, maybe_add_filter, + nullptr); } static void destroy_plugin(void) {} diff --git a/test/core/end2end/tests/filter_latency.cc b/test/core/end2end/tests/filter_latency.cc index 02a4d079277..a89db7b094b 100644 --- a/test/core/end2end/tests/filter_latency.cc +++ b/test/core/end2end/tests/filter_latency.cc @@ -314,6 +314,7 @@ static bool maybe_add_filter(grpc_channel_stack_builder* builder, void* arg) { // must be the last one. So we add it right before the last one. grpc_channel_stack_builder_iterator* it = grpc_channel_stack_builder_create_iterator_at_last(builder); + GPR_ASSERT(grpc_channel_stack_builder_move_prev(it)); const bool retval = grpc_channel_stack_builder_add_filter_before( it, filter, nullptr, nullptr); grpc_channel_stack_builder_iterator_destroy(it); @@ -325,15 +326,15 @@ static bool maybe_add_filter(grpc_channel_stack_builder* builder, void* arg) { static void init_plugin(void) { gpr_mu_init(&g_mu); - grpc_channel_init_register_stage( - GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_MAX, maybe_add_filter, - (void*)&test_client_filter); - grpc_channel_init_register_stage( - GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_MAX, - maybe_add_filter, (void*)&test_client_filter); - grpc_channel_init_register_stage( - GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_MAX, maybe_add_filter, - (void*)&test_server_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, + maybe_add_filter, + (void*)&test_client_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, + maybe_add_filter, + (void*)&test_client_filter); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, + maybe_add_filter, + (void*)&test_server_filter); } static void destroy_plugin(void) { gpr_mu_destroy(&g_mu); } diff --git a/test/core/end2end/tests/filter_status_code.cc b/test/core/end2end/tests/filter_status_code.cc index 6ed1de15c62..ba3cbfa6d11 100644 --- a/test/core/end2end/tests/filter_status_code.cc +++ b/test/core/end2end/tests/filter_status_code.cc @@ -333,6 +333,7 @@ static bool maybe_add_filter(grpc_channel_stack_builder* builder, void* arg) { // So we add it right before the last one. grpc_channel_stack_builder_iterator* it = grpc_channel_stack_builder_create_iterator_at_last(builder); + GPR_ASSERT(grpc_channel_stack_builder_move_prev(it)); const bool retval = grpc_channel_stack_builder_add_filter_before( it, filter, nullptr, nullptr); grpc_channel_stack_builder_iterator_destroy(it); @@ -349,15 +350,15 @@ static void init_plugin(void) { g_client_code_recv = false; g_server_code_recv = false; - grpc_channel_init_register_stage( - GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_MAX, maybe_add_filter, - (void*)&test_client_filter); - grpc_channel_init_register_stage( - GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_MAX, - maybe_add_filter, (void*)&test_client_filter); - grpc_channel_init_register_stage( - GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_MAX, maybe_add_filter, - (void*)&test_server_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, + maybe_add_filter, + (void*)&test_client_filter); + grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX, + maybe_add_filter, + (void*)&test_client_filter); + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, + maybe_add_filter, + (void*)&test_server_filter); } static void destroy_plugin(void) { diff --git a/test/cpp/common/channel_filter_test.cc b/test/cpp/common/channel_filter_test.cc index 9b603ca5b48..7bdd53f9e7a 100644 --- a/test/cpp/common/channel_filter_test.cc +++ b/test/cpp/common/channel_filter_test.cc @@ -50,8 +50,7 @@ class MyCallData : public CallData { // C-core, we don't accidentally break the C++ filter API. TEST(ChannelFilterTest, RegisterChannelFilter) { grpc::RegisterChannelFilter( - "myfilter", GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_LOW, true, - nullptr); + "myfilter", GRPC_CLIENT_CHANNEL, INT_MAX, nullptr); } // TODO(roth): When we have time, add tests for all methods of the diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index a8022823b10..88f8f380c3a 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -323,8 +323,7 @@ TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { void RegisterFilter() { grpc::RegisterChannelFilter( - "test-filter", GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_PRIORITY_LOW, true, - nullptr); + "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); } } // namespace From 052beefdec5d84ddd329e702ccb06fc0139a17b2 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 16 Aug 2018 11:08:00 -0700 Subject: [PATCH 135/546] Add further comments --- src/core/lib/iomgr/tcp_posix.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 6d4c0962176..8a479d2cccb 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -120,7 +120,7 @@ struct grpc_tcp { * requirement from the TCP endpoint layer is that this arg should be non-null * if the user wants timestamps for the write. */ void* outgoing_buffer_arg; - /* Current TCP relative sequence number as defined in RFC 793. Used for + /* Current TCP (relative) sequence number which starts out at zero. Used for * timestamping traced buffers. */ int bytes_counter; bool socket_ts_enabled; /* True if timestamping options are set on the socket @@ -576,6 +576,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, } tcp->socket_ts_enabled = true; } + /* Set control message to indicate that you want timestamps. */ union { char cmsg_buf[CMSG_SPACE(sizeof(uint32_t))]; struct cmsghdr align; @@ -594,6 +595,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, GRPC_STATS_INC_SYSCALL_WRITE(); length = sendmsg(tcp->fd, msg, SENDMSG_FLAGS); } while (length < 0 && errno == EINTR); + /* If there was an error on sendmsg the logic in tcp_flush will handle it. */ *sent_length = length; /* Only save timestamps if all the bytes were taken by sendmsg. */ if (sending_length == static_cast(length)) { From 981f19bed286b8eb8e1a51a077d3b4aad4503398 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Thu, 16 Aug 2018 11:07:31 -0700 Subject: [PATCH 136/546] Remove protobuf js_embed hack --- ...otobuf_generated_well_known_types_embed.cc | 328 ------------------ tools/distrib/python/grpcio_tools/setup.py | 24 +- 2 files changed, 1 insertion(+), 351 deletions(-) delete mode 100644 tools/distrib/python/grpcio_tools/grpc_tools/protobuf_generated_well_known_types_embed.cc diff --git a/tools/distrib/python/grpcio_tools/grpc_tools/protobuf_generated_well_known_types_embed.cc b/tools/distrib/python/grpcio_tools/grpc_tools/protobuf_generated_well_known_types_embed.cc deleted file mode 100644 index ba93621e4ff..00000000000 --- a/tools/distrib/python/grpcio_tools/grpc_tools/protobuf_generated_well_known_types_embed.cc +++ /dev/null @@ -1,328 +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. - -// HACK: Embed the generated well_known_types_js.cc to make -// grpc-tools python package compilation easy. -#include -struct FileToc well_known_types_js[] = { -{"any.js", - "// Protocol Buffers - Google's data interchange format\n" - "// Copyright 2008 Google Inc. All rights reserved.\n" - "// https://developers.google.com/protocol-buffers/\n" - "//\n" - "// Redistribution and use in source and binary forms, with or without\n" - "// modification, are permitted provided that the following conditions are\n" - "// met:\n" - "//\n" - "// * Redistributions of source code must retain the above copyright\n" - "// notice, this list of conditions and the following disclaimer.\n" - "// * Redistributions in binary form must reproduce the above\n" - "// copyright notice, this list of conditions and the following disclaimer\n" - "// in the documentation and/or other materials provided with the\n" - "// distribution.\n" - "// * Neither the name of Google Inc. nor the names of its\n" - "// contributors may be used to endorse or promote products derived from\n" - "// this software without specific prior written permission.\n" - "//\n" - "// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n" - "// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n" - "// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n" - "// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n" - "// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" - "// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" - "// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n" - "// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" - "// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" - "// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" - "// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" - "\n" - "/* This code will be inserted into generated code for\n" - " * google/protobuf/any.proto. */\n" - "\n" - "/**\n" - " * Returns the type name contained in this instance, if any.\n" - " * @return {string|undefined}\n" - " */\n" - "proto.google.protobuf.Any.prototype.getTypeName = function() {\n" - " return this.getTypeUrl().split('/').pop();\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Packs the given message instance into this Any.\n" - " * @param {!Uint8Array} serialized The serialized data to pack.\n" - " * @param {string} name The type name of this message object.\n" - " * @param {string=} opt_typeUrlPrefix the type URL prefix.\n" - " */\n" - "proto.google.protobuf.Any.prototype.pack = function(serialized, name,\n" - " opt_typeUrlPrefix) {\n" - " if (!opt_typeUrlPrefix) {\n" - " opt_typeUrlPrefix = 'type.googleapis.com/';\n" - " }\n" - "\n" - " if (opt_typeUrlPrefix.substr(-1) != '/') {\n" - " this.setTypeUrl(opt_typeUrlPrefix + '/' + name);\n" - " } else {\n" - " this.setTypeUrl(opt_typeUrlPrefix + name);\n" - " }\n" - "\n" - " this.setValue(serialized);\n" - "};\n" - "\n" - "\n" - "/**\n" - " * @template T\n" - " * Unpacks this Any into the given message object.\n" - " * @param {function(Uint8Array):T} deserialize Function that will deserialize\n" - " * the binary data properly.\n" - " * @param {string} name The expected type name of this message object.\n" - " * @return {?T} If the name matched the expected name, returns the deserialized\n" - " * object, otherwise returns undefined.\n" - " */\n" - "proto.google.protobuf.Any.prototype.unpack = function(deserialize, name) {\n" - " if (this.getTypeName() == name) {\n" - " return deserialize(this.getValue_asU8());\n" - " } else {\n" - " return null;\n" - " }\n" - "};\n" -}, -{"struct.js", - "// Protocol Buffers - Google's data interchange format\n" - "// Copyright 2008 Google Inc. All rights reserved.\n" - "// https://developers.google.com/protocol-buffers/\n" - "//\n" - "// Redistribution and use in source and binary forms, with or without\n" - "// modification, are permitted provided that the following conditions are\n" - "// met:\n" - "//\n" - "// * Redistributions of source code must retain the above copyright\n" - "// notice, this list of conditions and the following disclaimer.\n" - "// * Redistributions in binary form must reproduce the above\n" - "// copyright notice, this list of conditions and the following disclaimer\n" - "// in the documentation and/or other materials provided with the\n" - "// distribution.\n" - "// * Neither the name of Google Inc. nor the names of its\n" - "// contributors may be used to endorse or promote products derived from\n" - "// this software without specific prior written permission.\n" - "//\n" - "// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n" - "// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n" - "// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n" - "// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n" - "// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" - "// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" - "// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n" - "// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" - "// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" - "// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" - "// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" - "\n" - "/* This code will be inserted into generated code for\n" - " * google/protobuf/struct.proto. */\n" - "\n" - "/**\n" - " * Typedef representing plain JavaScript values that can go into a\n" - " * Struct.\n" - " * @typedef {null|number|string|boolean|Array|Object}\n" - " */\n" - "proto.google.protobuf.JavaScriptValue;\n" - "\n" - "\n" - "/**\n" - " * Converts this Value object to a plain JavaScript value.\n" - " * @return {?proto.google.protobuf.JavaScriptValue} a plain JavaScript\n" - " * value representing this Struct.\n" - " */\n" - "proto.google.protobuf.Value.prototype.toJavaScript = function() {\n" - " var kindCase = proto.google.protobuf.Value.KindCase;\n" - " switch (this.getKindCase()) {\n" - " case kindCase.NULL_VALUE:\n" - " return null;\n" - " case kindCase.NUMBER_VALUE:\n" - " return this.getNumberValue();\n" - " case kindCase.STRING_VALUE:\n" - " return this.getStringValue();\n" - " case kindCase.BOOL_VALUE:\n" - " return this.getBoolValue();\n" - " case kindCase.STRUCT_VALUE:\n" - " return this.getStructValue().toJavaScript();\n" - " case kindCase.LIST_VALUE:\n" - " return this.getListValue().toJavaScript();\n" - " default:\n" - " throw new Error('Unexpected struct type');\n" - " }\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Converts this JavaScript value to a new Value proto.\n" - " * @param {!proto.google.protobuf.JavaScriptValue} value The value to\n" - " * convert.\n" - " * @return {!proto.google.protobuf.Value} The newly constructed value.\n" - " */\n" - "proto.google.protobuf.Value.fromJavaScript = function(value) {\n" - " var ret = new proto.google.protobuf.Value();\n" - " switch (goog.typeOf(value)) {\n" - " case 'string':\n" - " ret.setStringValue(/** @type {string} */ (value));\n" - " break;\n" - " case 'number':\n" - " ret.setNumberValue(/** @type {number} */ (value));\n" - " break;\n" - " case 'boolean':\n" - " ret.setBoolValue(/** @type {boolean} */ (value));\n" - " break;\n" - " case 'null':\n" - " ret.setNullValue(proto.google.protobuf.NullValue.NULL_VALUE);\n" - " break;\n" - " case 'array':\n" - " ret.setListValue(proto.google.protobuf.ListValue.fromJavaScript(\n" - " /** @type{!Array} */ (value)));\n" - " break;\n" - " case 'object':\n" - " ret.setStructValue(proto.google.protobuf.Struct.fromJavaScript(\n" - " /** @type{!Object} */ (value)));\n" - " break;\n" - " default:\n" - " throw new Error('Unexpected struct type.');\n" - " }\n" - "\n" - " return ret;\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Converts this ListValue object to a plain JavaScript array.\n" - " * @return {!Array} a plain JavaScript array representing this List.\n" - " */\n" - "proto.google.protobuf.ListValue.prototype.toJavaScript = function() {\n" - " var ret = [];\n" - " var values = this.getValuesList();\n" - "\n" - " for (var i = 0; i < values.length; i++) {\n" - " ret[i] = values[i].toJavaScript();\n" - " }\n" - "\n" - " return ret;\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Constructs a ListValue protobuf from this plain JavaScript array.\n" - " * @param {!Array} array a plain JavaScript array\n" - " * @return {proto.google.protobuf.ListValue} a new ListValue object\n" - " */\n" - "proto.google.protobuf.ListValue.fromJavaScript = function(array) {\n" - " var ret = new proto.google.protobuf.ListValue();\n" - "\n" - " for (var i = 0; i < array.length; i++) {\n" - " ret.addValues(proto.google.protobuf.Value.fromJavaScript(array[i]));\n" - " }\n" - "\n" - " return ret;\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Converts this Struct object to a plain JavaScript object.\n" - " * @return {!Object} a plain\n" - " * JavaScript object representing this Struct.\n" - " */\n" - "proto.google.protobuf.Struct.prototype.toJavaScript = function() {\n" - " var ret = {};\n" - "\n" - " this.getFieldsMap().forEach(function(value, key) {\n" - " ret[key] = value.toJavaScript();\n" - " });\n" - "\n" - " return ret;\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Constructs a Struct protobuf from this plain JavaScript object.\n" - " * @param {!Object} obj a plain JavaScript object\n" - " * @return {proto.google.protobuf.Struct} a new Struct object\n" - " */\n" - "proto.google.protobuf.Struct.fromJavaScript = function(obj) {\n" - " var ret = new proto.google.protobuf.Struct();\n" - " var map = ret.getFieldsMap();\n" - "\n" - " for (var property in obj) {\n" - " var val = obj[property];\n" - " map.set(property, proto.google.protobuf.Value.fromJavaScript(val));\n" - " }\n" - "\n" - " return ret;\n" - "};\n" -}, -{"timestamp.js", - "// Protocol Buffers - Google's data interchange format\n" - "// Copyright 2008 Google Inc. All rights reserved.\n" - "// https://developers.google.com/protocol-buffers/\n" - "//\n" - "// Redistribution and use in source and binary forms, with or without\n" - "// modification, are permitted provided that the following conditions are\n" - "// met:\n" - "//\n" - "// * Redistributions of source code must retain the above copyright\n" - "// notice, this list of conditions and the following disclaimer.\n" - "// * Redistributions in binary form must reproduce the above\n" - "// copyright notice, this list of conditions and the following disclaimer\n" - "// in the documentation and/or other materials provided with the\n" - "// distribution.\n" - "// * Neither the name of Google Inc. nor the names of its\n" - "// contributors may be used to endorse or promote products derived from\n" - "// this software without specific prior written permission.\n" - "//\n" - "// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n" - "// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n" - "// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n" - "// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n" - "// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" - "// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" - "// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n" - "// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" - "// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" - "// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" - "// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" - "\n" - "/* This code will be inserted into generated code for\n" - " * google/protobuf/timestamp.proto. */\n" - "\n" - "/**\n" - " * Returns a JavaScript 'Date' object corresponding to this Timestamp.\n" - " * @return {!Date}\n" - " */\n" - "proto.google.protobuf.Timestamp.prototype.toDate = function() {\n" - " var seconds = this.getSeconds();\n" - " var nanos = this.getNanos();\n" - "\n" - " return new Date((seconds * 1000) + (nanos / 1000000));\n" - "};\n" - "\n" - "\n" - "/**\n" - " * Sets the value of this Timestamp object to be the given Date.\n" - " * @param {!Date} value The value to set.\n" - " */\n" - "proto.google.protobuf.Timestamp.prototype.fromDate = function(value) {\n" - " var millis = value.getTime();\n" - " this.setSeconds(Math.floor(value.getTime() / 1000));\n" - " this.setNanos(value.getMilliseconds() * 1000000);\n" - "};\n" -}, - {NULL, NULL} // Terminate the list. -}; diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py index c6bcee497f0..c13dfe9ade5 100644 --- a/tools/distrib/python/grpcio_tools/setup.py +++ b/tools/distrib/python/grpcio_tools/setup.py @@ -160,29 +160,7 @@ def extension_modules(): plugin_sources += [ os.path.join('grpc_tools', 'main.cc'), os.path.join('grpc_root', 'src', 'compiler', 'python_generator.cc') - ] - - #HACK: Substitute the embed.cc, which is a JS to C++ - # preprocessor with the generated code. - # The generated code should not be material - # to the parts of protoc we use (it affects - # the JavaScript code generator, supposedly), - # but we need to be cautious about it. - cc_files_clone = list(CC_FILES) - embed_cc_file = os.path.normpath('google/protobuf/compiler/js/embed.cc') - well_known_types_file = os.path.normpath( - 'google/protobuf/compiler/js/well_known_types_embed.cc') - if embed_cc_file in cc_files_clone: - cc_files_clone.remove(embed_cc_file) - if well_known_types_file in cc_files_clone: - cc_files_clone.remove(well_known_types_file) - plugin_sources += [ - os.path.join('grpc_tools', - 'protobuf_generated_well_known_types_embed.cc') - ] - plugin_sources += [ - os.path.join(CC_INCLUDE, cc_file) for cc_file in cc_files_clone - ] + ] + [os.path.join(CC_INCLUDE, cc_file) for cc_file in CC_FILES] plugin_ext = extension.Extension( name='grpc_tools._protoc_compiler', From 7a7e4f56529c4da16ec6a3035e7b3bdf9dfb6f67 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 16 Aug 2018 12:04:24 -0700 Subject: [PATCH 137/546] Move C++ mu_guard class out of C-core public headers and fix style. --- BUILD | 1 + build.yaml | 1 + gRPC-C++.podspec | 2 + gRPC-Core.podspec | 2 + grpc.gemspec | 1 + include/grpc/support/sync.h | 16 ------- package.xml | 1 + .../client_channel/lb_policy/grpclb/grpclb.cc | 3 +- .../lb_policy/pick_first/pick_first.cc | 5 ++- .../lb_policy/round_robin/round_robin.cc | 5 ++- src/core/lib/channel/channelz_registry.cc | 7 ++-- src/core/lib/gprpp/mutex_lock.h | 42 +++++++++++++++++++ src/core/lib/iomgr/ev_epollex_linux.cc | 3 +- .../ssl/session_cache/ssl_session_cache.cc | 10 ++--- tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core.internal | 1 + .../generated/sources_and_headers.json | 2 + 17 files changed, 73 insertions(+), 30 deletions(-) create mode 100644 src/core/lib/gprpp/mutex_lock.h diff --git a/BUILD b/BUILD index 35cf86288d6..7835e8ea25f 100644 --- a/BUILD +++ b/BUILD @@ -560,6 +560,7 @@ grpc_cc_library( "src/core/lib/gprpp/fork.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/memory.h", + "src/core/lib/gprpp/mutex_lock.h", "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h", ], diff --git a/build.yaml b/build.yaml index bd9c4237a11..bb72c41a8cf 100644 --- a/build.yaml +++ b/build.yaml @@ -196,6 +196,7 @@ filegroups: - src/core/lib/gprpp/fork.h - src/core/lib/gprpp/manual_constructor.h - src/core/lib/gprpp/memory.h + - src/core/lib/gprpp/mutex_lock.h - src/core/lib/gprpp/thd.h - src/core/lib/profiling/timers.h uses: diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 1d3cedb16be..ae3bd4b312f 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -236,6 +236,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/fork.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/memory.h', + 'src/core/lib/gprpp/mutex_lock.h', 'src/core/lib/gprpp/thd.h', 'src/core/lib/profiling/timers.h', 'src/core/ext/transport/chttp2/transport/bin_decoder.h', @@ -534,6 +535,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/fork.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/memory.h', + 'src/core/lib/gprpp/mutex_lock.h', 'src/core/lib/gprpp/thd.h', 'src/core/lib/profiling/timers.h', 'src/core/lib/avl/avl.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 1998bc8b4c5..146e5cc1ed8 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -208,6 +208,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/fork.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/memory.h', + 'src/core/lib/gprpp/mutex_lock.h', 'src/core/lib/gprpp/thd.h', 'src/core/lib/profiling/timers.h', 'src/core/lib/gpr/alloc.cc', @@ -844,6 +845,7 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/fork.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/memory.h', + 'src/core/lib/gprpp/mutex_lock.h', 'src/core/lib/gprpp/thd.h', 'src/core/lib/profiling/timers.h', 'src/core/ext/transport/chttp2/transport/bin_decoder.h', diff --git a/grpc.gemspec b/grpc.gemspec index 55d53cb71db..a5252b06fd1 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -105,6 +105,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/fork.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/mutex_lock.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 ) diff --git a/include/grpc/support/sync.h b/include/grpc/support/sync.h index 91d1fa79b5d..da820dece5e 100644 --- a/include/grpc/support/sync.h +++ b/include/grpc/support/sync.h @@ -277,22 +277,6 @@ GPRAPI intptr_t gpr_stats_read(const gpr_stats_counter* c); #ifdef __cplusplus } // extern "C" - -namespace grpc_core { - -class mu_guard { - public: - mu_guard(gpr_mu* mu) : mu_(mu) { gpr_mu_lock(mu); } - ~mu_guard() { gpr_mu_unlock(mu_); } - - mu_guard(const mu_guard&) = delete; - mu_guard& operator=(const mu_guard&) = delete; - - private: - gpr_mu* const mu_; -}; - -} // namespace grpc_core #endif #endif /* GRPC_SUPPORT_SYNC_H */ diff --git a/package.xml b/package.xml index 76bdd5ac8f6..c89d490b00c 100644 --- a/package.xml +++ b/package.xml @@ -110,6 +110,7 @@ + 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 6581385ff91..a624850f4ba 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 @@ -92,6 +92,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/combiner.h" @@ -1259,7 +1260,7 @@ void GrpcLb::FillChildRefsForChannelz(ChildRefsList* child_subchannels, ChildRefsList* child_channels) { // delegate to the RoundRobin to fill the children subchannels. rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels); - mu_guard guard(&lb_channel_mu_); + MutexLock lock(&lb_channel_mu_); if (lb_channel_ != nullptr) { grpc_core::channelz::ChannelNode* channel_node = grpc_channel_get_channelz_node(lb_channel_); 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 2b6a9ba8c53..0f5041ff51b 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 @@ -27,6 +27,7 @@ #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/transport/connectivity_state.h" @@ -308,7 +309,7 @@ void PickFirst::NotifyOnStateChangeLocked(grpc_connectivity_state* current, void PickFirst::FillChildRefsForChannelz( ChildRefsList* child_subchannels_to_fill, ChildRefsList* ignored) { - mu_guard guard(&child_refs_mu_); + MutexLock lock(&child_refs_mu_); for (size_t i = 0; i < child_subchannels_.size(); ++i) { // TODO(ncteisen): implement a de dup loop that is not O(n^2). Might // have to implement lightweight set. For now, we don't care about @@ -335,7 +336,7 @@ void PickFirst::UpdateChildRefsLocked() { latest_pending_subchannel_list_->PopulateChildRefsList(&cs); } // atomically update the data that channelz will actually be looking at. - mu_guard guard(&child_refs_mu_); + MutexLock lock(&child_refs_mu_); child_subchannels_ = std::move(cs); } 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 fea84331d80..c730b3bd2b1 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 @@ -36,6 +36,7 @@ #include "src/core/ext/filters/client_channel/subchannel_index.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/combiner.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -400,7 +401,7 @@ bool RoundRobin::PickLocked(PickState* pick, grpc_error** error) { void RoundRobin::FillChildRefsForChannelz( ChildRefsList* child_subchannels_to_fill, ChildRefsList* ignored) { - mu_guard guard(&child_refs_mu_); + MutexLock lock(&child_refs_mu_); for (size_t i = 0; i < child_subchannels_.size(); ++i) { // TODO(ncteisen): implement a de dup loop that is not O(n^2). Might // have to implement lightweight set. For now, we don't care about @@ -427,7 +428,7 @@ void RoundRobin::UpdateChildRefsLocked() { latest_pending_subchannel_list_->PopulateChildRefsList(&cs); } // atomically update the data that channelz will actually be looking at. - mu_guard guard(&child_refs_mu_); + MutexLock lock(&child_refs_mu_); child_subchannels_ = std::move(cs); } diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index 38496b3d78c..f79d2f0c177 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -23,6 +23,7 @@ #include "src/core/lib/channel/channelz_registry.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/mutex_lock.h" #include #include @@ -53,7 +54,7 @@ ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); } ChannelzRegistry::~ChannelzRegistry() { gpr_mu_destroy(&mu_); } intptr_t ChannelzRegistry::InternalRegisterEntry(const RegistryEntry& entry) { - mu_guard guard(&mu_); + MutexLock lock(&mu_); entities_.push_back(entry); intptr_t uuid = entities_.size(); return uuid; @@ -61,7 +62,7 @@ intptr_t ChannelzRegistry::InternalRegisterEntry(const RegistryEntry& entry) { void ChannelzRegistry::InternalUnregisterEntry(intptr_t uuid, EntityType type) { GPR_ASSERT(uuid >= 1); - mu_guard guard(&mu_); + MutexLock lock(&mu_); GPR_ASSERT(static_cast(uuid) <= entities_.size()); GPR_ASSERT(entities_[uuid - 1].type == type); entities_[uuid - 1].object = nullptr; @@ -69,7 +70,7 @@ void ChannelzRegistry::InternalUnregisterEntry(intptr_t uuid, EntityType type) { } void* ChannelzRegistry::InternalGetEntry(intptr_t uuid, EntityType type) { - mu_guard guard(&mu_); + MutexLock lock(&mu_); if (uuid < 1 || uuid > static_cast(entities_.size())) { return nullptr; } diff --git a/src/core/lib/gprpp/mutex_lock.h b/src/core/lib/gprpp/mutex_lock.h new file mode 100644 index 00000000000..54751d5fe46 --- /dev/null +++ b/src/core/lib/gprpp/mutex_lock.h @@ -0,0 +1,42 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_GPRPP_MUTEX_LOCK_H +#define GRPC_CORE_LIB_GPRPP_MUTEX_LOCK_H + +#include + +#include + +namespace grpc_core { + +class MutexLock { + public: + explicit MutexLock(gpr_mu* mu) : mu_(mu) { gpr_mu_lock(mu); } + ~MutexLock() { gpr_mu_unlock(mu_); } + + MutexLock(const MutexLock&) = delete; + MutexLock& operator=(const MutexLock&) = delete; + + private: + gpr_mu* const mu_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_GPRPP_MUTEX_LOCK_H */ diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index 96eae303451..b082634af11 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -46,6 +46,7 @@ #include "src/core/lib/gpr/tls.h" #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/iomgr/block_annotate.h" #include "src/core/lib/iomgr/iomgr_internal.h" #include "src/core/lib/iomgr/is_epollexclusive_available.h" @@ -735,7 +736,7 @@ static void pollset_maybe_finish_shutdown(grpc_pollset* pollset) { static grpc_error* kick_one_worker(grpc_pollset_worker* specific_worker) { GPR_TIMER_SCOPE("kick_one_worker", 0); pollable* p = specific_worker->pollable_obj; - grpc_core::mu_guard lock(&p->mu); + grpc_core::MutexLock lock(&p->mu); GPR_ASSERT(specific_worker != nullptr); if (specific_worker->kicked) { if (grpc_polling_trace.enabled()) { diff --git a/src/core/tsi/ssl/session_cache/ssl_session_cache.cc b/src/core/tsi/ssl/session_cache/ssl_session_cache.cc index fe4f83a13de..ce74fde3434 100644 --- a/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +++ b/src/core/tsi/ssl/session_cache/ssl_session_cache.cc @@ -18,9 +18,9 @@ #include -#include "src/core/tsi/ssl/session_cache/ssl_session_cache.h" - +#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/tsi/ssl/session_cache/ssl_session.h" +#include "src/core/tsi/ssl/session_cache/ssl_session_cache.h" #include #include @@ -97,7 +97,7 @@ SslSessionLRUCache::~SslSessionLRUCache() { } size_t SslSessionLRUCache::Size() { - grpc_core::mu_guard guard(&lock_); + grpc_core::MutexLock lock(&lock_); return use_order_list_size_; } @@ -117,7 +117,7 @@ SslSessionLRUCache::Node* SslSessionLRUCache::FindLocked( } void SslSessionLRUCache::Put(const char* key, SslSessionPtr session) { - grpc_core::mu_guard guard(&lock_); + grpc_core::MutexLock lock(&lock_); Node* node = FindLocked(grpc_slice_from_static_string(key)); if (node != nullptr) { node->SetSession(std::move(session)); @@ -140,7 +140,7 @@ void SslSessionLRUCache::Put(const char* key, SslSessionPtr session) { } SslSessionPtr SslSessionLRUCache::Get(const char* key) { - grpc_core::mu_guard guard(&lock_); + grpc_core::MutexLock lock(&lock_); // Key is only used for lookups. grpc_slice key_slice = grpc_slice_from_static_string(key); Node* node = FindLocked(key_slice); diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 592b0b20e65..43ebf8cad95 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1058,6 +1058,7 @@ src/core/lib/gprpp/fork.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/memory.h \ +src/core/lib/gprpp/mutex_lock.h \ src/core/lib/gprpp/orphanable.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index fa2ad93a456..0f5047a305c 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1142,6 +1142,7 @@ src/core/lib/gprpp/fork.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/memory.h \ +src/core/lib/gprpp/mutex_lock.h \ src/core/lib/gprpp/orphanable.h \ src/core/lib/gprpp/ref_counted.h \ src/core/lib/gprpp/ref_counted_ptr.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 34e23f09c2d..f81f3bb6770 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9306,6 +9306,7 @@ "src/core/lib/gprpp/fork.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/memory.h", + "src/core/lib/gprpp/mutex_lock.h", "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h" ], @@ -9353,6 +9354,7 @@ "src/core/lib/gprpp/fork.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/memory.h", + "src/core/lib/gprpp/mutex_lock.h", "src/core/lib/gprpp/thd.h", "src/core/lib/profiling/timers.h" ], From 381bcab8bde911a0aa03d2148f2b291c1c846481 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 16 Aug 2018 15:44:19 -0700 Subject: [PATCH 138/546] Move a file from src/cpp to src/core since core depends on it --- BUILD | 6 +++--- CMakeLists.txt | 6 +++--- Makefile | 6 +++--- build.yaml | 2 +- config.m4 | 4 ++-- config.w32 | 7 ++----- gRPC-Core.podspec | 2 +- grpc.gemspec | 2 +- grpc.gyp | 4 ++-- package.xml | 2 +- src/{cpp => core}/ext/filters/census/grpc_context.cc | 0 src/python/grpcio/grpc_core_dependencies.py | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- tools/run_tests/generated/sources_and_headers.json | 2 +- 14 files changed, 22 insertions(+), 25 deletions(-) rename src/{cpp => core}/ext/filters/census/grpc_context.cc (100%) diff --git a/BUILD b/BUILD index c1b573f9cf9..76d5026f6c9 100644 --- a/BUILD +++ b/BUILD @@ -485,7 +485,7 @@ grpc_cc_library( grpc_cc_library( name = "census", srcs = [ - "src/cpp/ext/filters/census/grpc_context.cc", + "src/core/ext/filters/census/grpc_context.cc", ], language = "c++", public_hdrs = [ @@ -1436,9 +1436,9 @@ grpc_cc_library( "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", ], hdrs = [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", @@ -1885,8 +1885,8 @@ grpc_cc_library( "src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h", "src/core/tsi/alts/handshaker/alts_tsi_utils.h", "src/core/tsi/alts_transport_security.h", - "src/core/tsi/local_transport_security.h", "src/core/tsi/fake_transport_security.h", + "src/core/tsi/local_transport_security.h", "src/core/tsi/ssl/session_cache/ssl_session.h", "src/core/tsi/ssl/session_cache/ssl_session_cache.h", "src/core/tsi/ssl_transport_security.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index c4526d2af5d..32d7a9b94d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1239,7 +1239,7 @@ add_library(grpc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc - src/cpp/ext/filters/census/grpc_context.cc + src/core/ext/filters/census/grpc_context.cc src/core/ext/filters/max_age/max_age_filter.cc src/core/ext/filters/message_size/message_size_filter.cc src/core/ext/filters/http/client_authority_filter.cc @@ -2560,7 +2560,7 @@ add_library(grpc_unsecure third_party/nanopb/pb_encode.c src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc - src/cpp/ext/filters/census/grpc_context.cc + src/core/ext/filters/census/grpc_context.cc src/core/ext/filters/max_age/max_age_filter.cc src/core/ext/filters/message_size/message_size_filter.cc src/core/ext/filters/http/client_authority_filter.cc @@ -3348,7 +3348,7 @@ add_library(grpc++_cronet src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc src/core/ext/transport/chttp2/server/chttp2_server.cc - src/cpp/ext/filters/census/grpc_context.cc + src/core/ext/filters/census/grpc_context.cc ) if(WIN32 AND MSVC) diff --git a/Makefile b/Makefile index aa6f8d076b1..3454ef85870 100644 --- a/Makefile +++ b/Makefile @@ -3737,7 +3737,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ - src/cpp/ext/filters/census/grpc_context.cc \ + src/core/ext/filters/census/grpc_context.cc \ src/core/ext/filters/max_age/max_age_filter.cc \ src/core/ext/filters/message_size/message_size_filter.cc \ src/core/ext/filters/http/client_authority_filter.cc \ @@ -5024,7 +5024,7 @@ LIBGRPC_UNSECURE_SRC = \ third_party/nanopb/pb_encode.c \ src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \ src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \ - src/cpp/ext/filters/census/grpc_context.cc \ + src/core/ext/filters/census/grpc_context.cc \ src/core/ext/filters/max_age/max_age_filter.cc \ src/core/ext/filters/message_size/message_size_filter.cc \ src/core/ext/filters/http/client_authority_filter.cc \ @@ -5800,7 +5800,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc \ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc \ src/core/ext/transport/chttp2/server/chttp2_server.cc \ - src/cpp/ext/filters/census/grpc_context.cc \ + src/core/ext/filters/census/grpc_context.cc \ PUBLIC_HEADERS_CXX += \ include/grpc++/alarm.h \ diff --git a/build.yaml b/build.yaml index 2cb349510a4..e3539bc0fc0 100644 --- a/build.yaml +++ b/build.yaml @@ -100,7 +100,7 @@ filegroups: public_headers: - include/grpc/census.h src: - - src/cpp/ext/filters/census/grpc_context.cc + - src/core/ext/filters/census/grpc_context.cc uses: - grpc_base - name: cmdline diff --git a/config.m4 b/config.m4 index a46b076fe92..7825274eea9 100644 --- a/config.m4 +++ b/config.m4 @@ -389,7 +389,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ - src/cpp/ext/filters/census/grpc_context.cc \ + src/core/ext/filters/census/grpc_context.cc \ src/core/ext/filters/max_age/max_age_filter.cc \ src/core/ext/filters/message_size/message_size_filter.cc \ src/core/ext/filters/http/client_authority_filter.cc \ @@ -660,6 +660,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc) PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/census) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1) @@ -723,7 +724,6 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/tsi/alts/handshaker) PHP_ADD_BUILD_DIR($ext_builddir/src/core/tsi/alts/zero_copy_frame_protector) PHP_ADD_BUILD_DIR($ext_builddir/src/core/tsi/ssl/session_cache) - PHP_ADD_BUILD_DIR($ext_builddir/src/cpp/ext/filters/census) PHP_ADD_BUILD_DIR($ext_builddir/third_party/address_sorting) PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto) PHP_ADD_BUILD_DIR($ext_builddir/third_party/boringssl/crypto/asn1) diff --git a/config.w32 b/config.w32 index 3aea5fa7f20..a9d1e6c9d01 100644 --- a/config.w32 +++ b/config.w32 @@ -364,7 +364,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.cc " + - "src\\cpp\\ext\\filters\\census\\grpc_context.cc " + + "src\\core\\ext\\filters\\census\\grpc_context.cc " + "src\\core\\ext\\filters\\max_age\\max_age_filter.cc " + "src\\core\\ext\\filters\\message_size\\message_size_filter.cc " + "src\\core\\ext\\filters\\http\\client_authority_filter.cc " + @@ -665,6 +665,7 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\census"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb"); @@ -741,10 +742,6 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\tsi\\alts\\zero_copy_frame_protector"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\tsi\\ssl"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\tsi\\ssl\\session_cache"); - FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\cpp"); - FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\cpp\\ext"); - FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\cpp\\ext\\filters"); - FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\cpp\\ext\\filters\\census"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php\\ext"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\php\\ext\\grpc"); diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f828185752a..6f51d21c5e9 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -813,7 +813,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', - 'src/cpp/ext/filters/census/grpc_context.cc', + 'src/core/ext/filters/census/grpc_context.cc', 'src/core/ext/filters/max_age/max_age_filter.cc', 'src/core/ext/filters/message_size/message_size_filter.cc', 'src/core/ext/filters/http/client_authority_filter.cc', diff --git a/grpc.gemspec b/grpc.gemspec index 55d53cb71db..cbb380fceac 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -753,7 +753,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc ) - s.files += %w( src/cpp/ext/filters/census/grpc_context.cc ) + s.files += %w( src/core/ext/filters/census/grpc_context.cc ) s.files += %w( src/core/ext/filters/max_age/max_age_filter.cc ) s.files += %w( src/core/ext/filters/message_size/message_size_filter.cc ) s.files += %w( src/core/ext/filters/http/client_authority_filter.cc ) diff --git a/grpc.gyp b/grpc.gyp index ba4e8185c61..a36998bcb3b 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -581,7 +581,7 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', - 'src/cpp/ext/filters/census/grpc_context.cc', + 'src/core/ext/filters/census/grpc_context.cc', 'src/core/ext/filters/max_age/max_age_filter.cc', 'src/core/ext/filters/message_size/message_size_filter.cc', 'src/core/ext/filters/http/client_authority_filter.cc', @@ -1313,7 +1313,7 @@ 'third_party/nanopb/pb_encode.c', 'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc', 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', - 'src/cpp/ext/filters/census/grpc_context.cc', + 'src/core/ext/filters/census/grpc_context.cc', 'src/core/ext/filters/max_age/max_age_filter.cc', 'src/core/ext/filters/message_size/message_size_filter.cc', 'src/core/ext/filters/http/client_authority_filter.cc', diff --git a/package.xml b/package.xml index 76bdd5ac8f6..02e41bee56b 100644 --- a/package.xml +++ b/package.xml @@ -758,7 +758,7 @@ - + diff --git a/src/cpp/ext/filters/census/grpc_context.cc b/src/core/ext/filters/census/grpc_context.cc similarity index 100% rename from src/cpp/ext/filters/census/grpc_context.cc rename to src/core/ext/filters/census/grpc_context.cc diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index a8158311fb0..6e6d756eec7 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -363,7 +363,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', - 'src/cpp/ext/filters/census/grpc_context.cc', + 'src/core/ext/filters/census/grpc_context.cc', 'src/core/ext/filters/max_age/max_age_filter.cc', 'src/core/ext/filters/message_size/message_size_filter.cc', 'src/core/ext/filters/http/client_authority_filter.cc', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index fa2ad93a456..d91cf094651 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -868,6 +868,7 @@ include/grpc/support/time.h \ include/grpc/support/workaround_list.h \ src/core/README.md \ src/core/ext/README.md \ +src/core/ext/filters/census/grpc_context.cc \ src/core/ext/filters/client_channel/README.md \ src/core/ext/filters/client_channel/backup_poller.cc \ src/core/ext/filters/client_channel/backup_poller.h \ @@ -1521,7 +1522,6 @@ src/core/tsi/transport_security.h \ src/core/tsi/transport_security_grpc.cc \ src/core/tsi/transport_security_grpc.h \ src/core/tsi/transport_security_interface.h \ -src/cpp/ext/filters/census/grpc_context.cc \ third_party/nanopb/pb.h \ third_party/nanopb/pb_common.c \ third_party/nanopb/pb_common.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a9327bded12..886c8517c3e 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9187,7 +9187,7 @@ "name": "census", "src": [ "include/grpc/census.h", - "src/cpp/ext/filters/census/grpc_context.cc" + "src/core/ext/filters/census/grpc_context.cc" ], "third_party": false, "type": "filegroup" From 79851428e9d46b7e830d60e5150f9dd788a6332f Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 16 Aug 2018 15:55:53 -0700 Subject: [PATCH 139/546] Add a sanity check to avoid reintroducing dependence on cpp by core --- .../sanity/{check_unsecure.sh => check_bad_dependencies.sh} | 4 ++++ tools/run_tests/sanity/sanity_tests.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) rename tools/run_tests/sanity/{check_unsecure.sh => check_bad_dependencies.sh} (87%) diff --git a/tools/run_tests/sanity/check_unsecure.sh b/tools/run_tests/sanity/check_bad_dependencies.sh similarity index 87% rename from tools/run_tests/sanity/check_unsecure.sh rename to tools/run_tests/sanity/check_bad_dependencies.sh index cca1235479e..5ae0e02c81d 100755 --- a/tools/run_tests/sanity/check_unsecure.sh +++ b/tools/run_tests/sanity/check_bad_dependencies.sh @@ -23,5 +23,9 @@ test "$(bazel query 'somepath("//:grpc++_unsecure", "//external:libssl")' 2>/dev test "$(bazel query 'somepath("//:grpc++_codegen_proto", "//external:libssl")' 2>/dev/null | wc -l)" -eq 0 || exit 1 test "$(bazel query 'somepath("//test/cpp/microbenchmarks:helpers", "//external:libssl")' 2>/dev/null | wc -l)" -eq 0 || exit 1 +# Make sure that core doesn't depend on anything in C++ library + +test "$(bazel query 'deps("//:grpc")' 2>/dev/null | egrep 'src/cpp|include/grpcpp' | wc -l)" -eq 0 || exit 1 + exit 0 diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml index ac0d4c70e5d..91b53eb38d4 100644 --- a/tools/run_tests/sanity/sanity_tests.yaml +++ b/tools/run_tests/sanity/sanity_tests.yaml @@ -1,4 +1,5 @@ # a set of tests that are run in parallel for sanity tests +- script: tools/run_tests/sanity/check_bad_dependencies.sh - script: tools/run_tests/sanity/check_bazel_workspace.py - script: tools/run_tests/sanity/check_cache_mk.sh - script: tools/run_tests/sanity/check_owners.sh @@ -6,7 +7,6 @@ - script: tools/run_tests/sanity/check_submodules.sh - script: tools/run_tests/sanity/check_test_filtering.py - script: tools/run_tests/sanity/check_tracer_sanity.py -- script: tools/run_tests/sanity/check_unsecure.sh - script: tools/run_tests/sanity/core_banned_functions.py - script: tools/run_tests/sanity/core_untyped_structs.sh - script: tools/run_tests/sanity/check_deprecated_grpc++.py From ccc4771630d04000c5a4998b3dc27bcb7dc8c834 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 16 Aug 2018 16:11:51 -0700 Subject: [PATCH 140/546] Fix Bazel BUILD --- BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD b/BUILD index 76d5026f6c9..46063008c44 100644 --- a/BUILD +++ b/BUILD @@ -2129,7 +2129,7 @@ grpc_cc_library( "src/cpp/ext/filters/census/channel_filter.cc", "src/cpp/ext/filters/census/client_filter.cc", "src/cpp/ext/filters/census/context.cc", - "src/cpp/ext/filters/census/grpc_context.cc", + "src/core/ext/filters/census/grpc_context.cc", "src/cpp/ext/filters/census/grpc_plugin.cc", "src/cpp/ext/filters/census/measures.cc", "src/cpp/ext/filters/census/rpc_encoding.cc", From d9f4c7635612f0868aea70902b085bbad9abe163 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 16 Aug 2018 16:26:42 -0700 Subject: [PATCH 141/546] Add a nullptr check --- src/cpp/server/server_cc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 46872c85a18..67f3f177ae4 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -588,7 +588,7 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { // If this server has any support for synchronous methods (has any sync // server CQs), make sure that we have a ResourceExhausted handler // to deal with the case of thread exhaustion - if (!sync_server_cqs_->empty()) { + if (sync_server_cqs != nullptr && !sync_server_cqs_->empty()) { resource_exhausted_handler_.reset(new internal::ResourceExhaustedHandler); } From d19fd1c689b1d60cf329331da7fab5d1ca6063cc Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 16 Aug 2018 17:54:27 -0700 Subject: [PATCH 142/546] PF: Check connectivity state before watching --- .../lb_policy/pick_first/pick_first.cc | 112 ++++++++++++------ test/cpp/end2end/client_lb_end2end_test.cc | 55 +++++++++ 2 files changed, 128 insertions(+), 39 deletions(-) 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 bc51903ef56..ab33d933981 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 @@ -80,6 +80,11 @@ class PickFirst : public LoadBalancingPolicy { void ProcessConnectivityChangeLocked( grpc_connectivity_state connectivity_state, grpc_error* error) override; + + // Processes the connectivity change to READY for an unselected subchannel. + void ProcessUnselectedReadyLocked(); + + void CheckConnectivityStateAndStartWatchingLocked(); }; class PickFirstSubchannelList @@ -247,7 +252,8 @@ void PickFirst::StartPickingLocked() { if (subchannel_list_ != nullptr) { for (size_t i = 0; i < subchannel_list_->num_subchannels(); ++i) { if (subchannel_list_->subchannel(i)->subchannel() != nullptr) { - subchannel_list_->subchannel(i)->StartConnectivityWatchLocked(); + subchannel_list_->subchannel(i) + ->CheckConnectivityStateAndStartWatchingLocked(); break; } } @@ -386,7 +392,8 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) { // If we've started picking, start trying to connect to the first // subchannel in the new list. if (started_picking_) { - subchannel_list_->subchannel(0)->StartConnectivityWatchLocked(); + subchannel_list_->subchannel(0) + ->CheckConnectivityStateAndStartWatchingLocked(); } } else { // We do have a selected subchannel. @@ -440,7 +447,7 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) { // subchannel in the new list. if (started_picking_) { latest_pending_subchannel_list_->subchannel(0) - ->StartConnectivityWatchLocked(); + ->CheckConnectivityStateAndStartWatchingLocked(); } } } @@ -519,41 +526,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( // select in place of the current one. switch (connectivity_state) { case GRPC_CHANNEL_READY: { - // Case 2. Promote p->latest_pending_subchannel_list_ to - // p->subchannel_list_. - if (subchannel_list() == p->latest_pending_subchannel_list_.get()) { - if (grpc_lb_pick_first_trace.enabled()) { - gpr_log(GPR_INFO, - "Pick First %p promoting pending subchannel list %p to " - "replace %p", - p, p->latest_pending_subchannel_list_.get(), - p->subchannel_list_.get()); - } - p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); - } - // Cases 1 and 2. - grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY, - GRPC_ERROR_NONE, "connecting_ready"); - p->selected_ = this; - if (grpc_lb_pick_first_trace.enabled()) { - gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, - subchannel()); - } - // Drop all other subchannels, since we are now connected. - p->DestroyUnselectedSubchannelsLocked(); - // Update any calls that were waiting for a pick. - PickState* pick; - while ((pick = p->pending_picks_)) { - p->pending_picks_ = pick->next; - pick->connected_subchannel = - p->selected_->connected_subchannel()->Ref(); - if (grpc_lb_pick_first_trace.enabled()) { - gpr_log(GPR_INFO, - "Servicing pending pick with selected subchannel %p", - p->selected_->subchannel()); - } - GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); - } + ProcessUnselectedReadyLocked(); // Renew notification. RenewConnectivityWatchLocked(); break; @@ -574,7 +547,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), "exhausted_subchannels"); } - sd->StartConnectivityWatchLocked(); + sd->CheckConnectivityStateAndStartWatchingLocked(); break; } case GRPC_CHANNEL_CONNECTING: @@ -595,6 +568,67 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked( GRPC_ERROR_UNREF(error); } +void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() { + PickFirst* p = static_cast(subchannel_list()->policy()); + // If we get here, there are two possible cases: + // 1. We do not currently have a selected subchannel, and the update is + // for a subchannel in p->subchannel_list_ that we're trying to + // connect to. The goal here is to find a subchannel that we can + // select. + // 2. We do currently have a selected subchannel, and the update is + // for a subchannel in p->latest_pending_subchannel_list_. The + // goal here is to find a subchannel from the update that we can + // select in place of the current one. + GPR_ASSERT(subchannel_list() == p->subchannel_list_.get() || + subchannel_list() == p->latest_pending_subchannel_list_.get()); + // Case 2. Promote p->latest_pending_subchannel_list_ to p->subchannel_list_. + if (subchannel_list() == p->latest_pending_subchannel_list_.get()) { + if (grpc_lb_pick_first_trace.enabled()) { + gpr_log(GPR_INFO, + "Pick First %p promoting pending subchannel list %p to " + "replace %p", + p, p->latest_pending_subchannel_list_.get(), + p->subchannel_list_.get()); + } + p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_); + } + // Cases 1 and 2. + grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY, + GRPC_ERROR_NONE, "subchannel_ready"); + p->selected_ = this; + if (grpc_lb_pick_first_trace.enabled()) { + gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel()); + } + // Drop all other subchannels, since we are now connected. + p->DestroyUnselectedSubchannelsLocked(); + // Update any calls that were waiting for a pick. + PickState* pick; + while ((pick = p->pending_picks_)) { + p->pending_picks_ = pick->next; + pick->connected_subchannel = p->selected_->connected_subchannel()->Ref(); + if (grpc_lb_pick_first_trace.enabled()) { + gpr_log(GPR_INFO, "Servicing pending pick with selected subchannel %p", + p->selected_->subchannel()); + } + GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); + } +} + +void PickFirst::PickFirstSubchannelData:: + CheckConnectivityStateAndStartWatchingLocked() { + PickFirst* p = static_cast(subchannel_list()->policy()); + grpc_error* error = GRPC_ERROR_NONE; + if (p->selected_ != this && + CheckConnectivityStateLocked(&error) == GRPC_CHANNEL_READY) { + // We must process the READY subchannel before we start watching it. + // Otherwise, we won't know it's READY because we will be waiting for its + // connectivity state to change from READY. + ProcessUnselectedReadyLocked(); + } + GRPC_ERROR_UNREF(error); + StartConnectivityWatchLocked(); +} + // // factory // diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 26c241b74a2..68219c16dcb 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -291,6 +291,17 @@ class ClientLbEnd2endTest : public ::testing::Test { ResetCounters(); } + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + bool SeenAllServers() { for (const auto& server : servers_) { if (server->service_.request_count() == 0) return false; @@ -590,6 +601,50 @@ TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } +TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) { + std::vector ports = {grpc_pick_unused_port_or_die()}; + StartServers(1, ports); + auto channel_1 = BuildChannel("pick_first"); + auto stub_1 = BuildStub(channel_1); + SetNextResolution(ports); + gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 1 *******"); + WaitForServer(stub_1, 0, DEBUG_LOCATION); + gpr_log(GPR_INFO, "****** CHANNEL 1 CONNECTED *******"); + servers_[0]->Shutdown(); + // Channel 1 will receive a re-resolution containing the same server. It will + // create a new subchannel and hold a ref to it. + servers_.clear(); + StartServers(1, ports); + gpr_log(GPR_INFO, "****** SERVER RESTARTED *******"); + auto channel_2 = BuildChannel("pick_first"); + auto stub_2 = BuildStub(channel_2); + // TODO(juanlishen): This resolution result will only be visible to channel 2 + // since the response generator is only associated with channel 2 now. We + // should change the response generator to be able to deliver updates to + // multiple channels at once. + SetNextResolution(ports); + gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 2 *******"); + WaitForServer(stub_2, 0, DEBUG_LOCATION, true); + gpr_log(GPR_INFO, "****** CHANNEL 2 CONNECTED *******"); + servers_[0]->Shutdown(); + // Wait until the disconnection has triggered the connectivity notification. + // Otherwise, the subchannel may be picked for next call but will fail soon. + EXPECT_TRUE(WaitForChannelNotReady(channel_2.get())); + // Channel 2 will also receive a re-resolution containing the same server. + // Both channels will ref the same subchannel that failed. + servers_.clear(); + StartServers(1, ports); + gpr_log(GPR_INFO, "****** SERVER RESTARTED AGAIN *******"); + gpr_log(GPR_INFO, "****** CHANNEL 2 STARTING A CALL *******"); + // The first call after the server restart will succeed. + CheckRpcSendOk(stub_2, DEBUG_LOCATION); + gpr_log(GPR_INFO, "****** CHANNEL 2 FINISHED A CALL *******"); + // Check LB policy name for the channel. + EXPECT_EQ("pick_first", channel_1->GetLoadBalancingPolicyName()); + // Check LB policy name for the channel. + EXPECT_EQ("pick_first", channel_2->GetLoadBalancingPolicyName()); +} + TEST_F(ClientLbEnd2endTest, RoundRobin) { // Start servers and send one RPC per server. const int kNumServers = 3; From b22c3009d4e0dcabb6228e321c39ae77989a1cd7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 16 Aug 2018 18:15:26 -0700 Subject: [PATCH 143/546] Fix typo --- src/cpp/server/server_cc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 67f3f177ae4..36c709eb45b 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -588,7 +588,7 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { // If this server has any support for synchronous methods (has any sync // server CQs), make sure that we have a ResourceExhausted handler // to deal with the case of thread exhaustion - if (sync_server_cqs != nullptr && !sync_server_cqs_->empty()) { + if (sync_server_cqs_ != nullptr && !sync_server_cqs_->empty()) { resource_exhausted_handler_.reset(new internal::ResourceExhaustedHandler); } From a20e2073c1c53cbdd81a4fb750982a0b13e0c24e Mon Sep 17 00:00:00 2001 From: Naresh Date: Fri, 17 Aug 2018 12:24:58 +0000 Subject: [PATCH 144/546] Configure module level loggers with basicConfig() Module level loggers were introduced to gRPC Python in 06e1683, but missed configuring these, leading to 'No handler found for module' errors. Using the root logger implicitly calls basicConfig() which does the basic configuration for the logging system by creating a StreamHandler with a default Formatter and adding it to the logger. But this is not the case for module level loggers. Fix this issue by explicitly calling logging.basicConfig(). --- src/python/grpcio/grpc/_channel.py | 1 + src/python/grpcio/grpc/_common.py | 1 + src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi | 1 + src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi | 1 + src/python/grpcio/grpc/_plugin_wrapping.py | 1 + src/python/grpcio/grpc/_server.py | 1 + src/python/grpcio/grpc/framework/foundation/callable_util.py | 1 + src/python/grpcio/grpc/framework/foundation/logging_pool.py | 1 + src/python/grpcio/grpc/framework/foundation/stream_util.py | 1 + src/python/grpcio_testing/grpc_testing/_channel/_invocation.py | 1 + src/python/grpcio_testing/grpc_testing/_server/_rpc.py | 1 + src/python/grpcio_testing/grpc_testing/_time.py | 1 + src/python/grpcio_tests/tests/interop/server.py | 1 + 13 files changed, 13 insertions(+) diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index e9246991df1..c7dc1949f63 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -24,6 +24,7 @@ from grpc import _grpcio_metadata from grpc._cython import cygrpc from grpc.framework.foundation import callable_util +logging.basicConfig() _LOGGER = logging.getLogger(__name__) _USER_AGENT = 'grpc-python/{}'.format(_grpcio_metadata.__version__) diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py index 8358cbec5b3..3805c7e82a7 100644 --- a/src/python/grpcio/grpc/_common.py +++ b/src/python/grpcio/grpc/_common.py @@ -20,6 +20,7 @@ import six import grpc from grpc._cython import cygrpc +logging.basicConfig() _LOGGER = logging.getLogger(__name__) CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = { diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi index 00a1b23a67b..334e561baad 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi @@ -14,6 +14,7 @@ import logging +logging.basicConfig() _LOGGER = logging.getLogger(__name__) # This function will ascii encode unicode string inputs if neccesary. diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index da3dd212441..8cece46437a 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -18,6 +18,7 @@ import logging import time import grpc +logging.basicConfig() _LOGGER = logging.getLogger(__name__) cdef grpc_ssl_certificate_config_reload_status _server_cert_config_fetcher_wrapper( diff --git a/src/python/grpcio/grpc/_plugin_wrapping.py b/src/python/grpcio/grpc/_plugin_wrapping.py index 916ee080b60..88ab4d8371f 100644 --- a/src/python/grpcio/grpc/_plugin_wrapping.py +++ b/src/python/grpcio/grpc/_plugin_wrapping.py @@ -20,6 +20,7 @@ import grpc from grpc import _common from grpc._cython import cygrpc +logging.basicConfig() _LOGGER = logging.getLogger(__name__) diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py index 7276a7fd90e..daa000a6e1b 100644 --- a/src/python/grpcio/grpc/_server.py +++ b/src/python/grpcio/grpc/_server.py @@ -27,6 +27,7 @@ from grpc import _interceptor from grpc._cython import cygrpc from grpc.framework.foundation import callable_util +logging.basicConfig() _LOGGER = logging.getLogger(__name__) _SHUTDOWN_TAG = 'shutdown' diff --git a/src/python/grpcio/grpc/framework/foundation/callable_util.py b/src/python/grpcio/grpc/framework/foundation/callable_util.py index 24daf3406f8..fb8d5f7c1e3 100644 --- a/src/python/grpcio/grpc/framework/foundation/callable_util.py +++ b/src/python/grpcio/grpc/framework/foundation/callable_util.py @@ -21,6 +21,7 @@ import logging import six +logging.basicConfig() _LOGGER = logging.getLogger(__name__) diff --git a/src/python/grpcio/grpc/framework/foundation/logging_pool.py b/src/python/grpcio/grpc/framework/foundation/logging_pool.py index 216e3990db0..7702d1785f9 100644 --- a/src/python/grpcio/grpc/framework/foundation/logging_pool.py +++ b/src/python/grpcio/grpc/framework/foundation/logging_pool.py @@ -17,6 +17,7 @@ import logging from concurrent import futures +logging.basicConfig() _LOGGER = logging.getLogger(__name__) diff --git a/src/python/grpcio/grpc/framework/foundation/stream_util.py b/src/python/grpcio/grpc/framework/foundation/stream_util.py index 1faaf29bd7e..9184f958737 100644 --- a/src/python/grpcio/grpc/framework/foundation/stream_util.py +++ b/src/python/grpcio/grpc/framework/foundation/stream_util.py @@ -19,6 +19,7 @@ import threading from grpc.framework.foundation import stream _NO_VALUE = object() +logging.basicConfig() _LOGGER = logging.getLogger(__name__) diff --git a/src/python/grpcio_testing/grpc_testing/_channel/_invocation.py b/src/python/grpcio_testing/grpc_testing/_channel/_invocation.py index 191b1c17264..d7205ca5793 100644 --- a/src/python/grpcio_testing/grpc_testing/_channel/_invocation.py +++ b/src/python/grpcio_testing/grpc_testing/_channel/_invocation.py @@ -18,6 +18,7 @@ import threading import grpc _NOT_YET_OBSERVED = object() +logging.basicConfig() _LOGGER = logging.getLogger(__name__) diff --git a/src/python/grpcio_testing/grpc_testing/_server/_rpc.py b/src/python/grpcio_testing/grpc_testing/_server/_rpc.py index b856da100f0..736b714dc6d 100644 --- a/src/python/grpcio_testing/grpc_testing/_server/_rpc.py +++ b/src/python/grpcio_testing/grpc_testing/_server/_rpc.py @@ -18,6 +18,7 @@ import threading import grpc from grpc_testing import _common +logging.basicConfig() _LOGGER = logging.getLogger(__name__) diff --git a/src/python/grpcio_testing/grpc_testing/_time.py b/src/python/grpcio_testing/grpc_testing/_time.py index 75e6db34586..9692c34e6f3 100644 --- a/src/python/grpcio_testing/grpc_testing/_time.py +++ b/src/python/grpcio_testing/grpc_testing/_time.py @@ -21,6 +21,7 @@ import time as _time import grpc import grpc_testing +logging.basicConfig() _LOGGER = logging.getLogger(__name__) diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py index fd28d498a18..768cdaf468d 100644 --- a/src/python/grpcio_tests/tests/interop/server.py +++ b/src/python/grpcio_tests/tests/interop/server.py @@ -25,6 +25,7 @@ from tests.interop import methods from tests.interop import resources from tests.unit import test_common +logging.basicConfig() _ONE_DAY_IN_SECONDS = 60 * 60 * 24 _LOGGER = logging.getLogger(__name__) From 4d6f002780e936290ddc629a6eb04a95567f5f8a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 17 Aug 2018 08:09:32 -0700 Subject: [PATCH 145/546] Code review changes and fix threading bug in test. --- .../client_channel/lb_policy/pick_first/pick_first.cc | 11 +++-------- .../client_channel/resolver/fake/fake_resolver.cc | 2 +- test/cpp/end2end/client_lb_end2end_test.cc | 7 ++++--- 3 files changed, 8 insertions(+), 12 deletions(-) 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 fa39d9eb93c..464e3fc2166 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 @@ -248,14 +248,9 @@ void PickFirst::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask, void PickFirst::StartPickingLocked() { started_picking_ = true; - if (subchannel_list_ != nullptr) { - for (size_t i = 0; i < subchannel_list_->num_subchannels(); ++i) { - if (subchannel_list_->subchannel(i)->subchannel() != nullptr) { - subchannel_list_->subchannel(i) - ->CheckConnectivityStateAndStartWatchingLocked(); - break; - } - } + if (subchannel_list_ != nullptr && subchannel_list_->num_subchannels() > 0) { + subchannel_list_->subchannel(0) + ->CheckConnectivityStateAndStartWatchingLocked(); } } 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 d090545d0c0..144ac24a56a 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 @@ -103,8 +103,8 @@ void FakeResolver::NextLocked(grpc_channel_args** target_result, } void FakeResolver::RequestReresolutionLocked() { - grpc_channel_args_destroy(next_results_); if (reresolution_results_ != nullptr) { + grpc_channel_args_destroy(next_results_); next_results_ = grpc_channel_args_copy(reresolution_results_); MaybeFinishNextLocked(); } diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 8e0ee7bd76a..d0b7e796545 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -131,6 +131,7 @@ class ClientLbEnd2endTest : public ::testing::Test { void CreateServers(size_t num_servers, std::vector ports = std::vector()) { + servers_.clear(); for (size_t i = 0; i < num_servers; ++i) { int port = 0; if (ports.size() == num_servers) port = ports[i]; @@ -144,7 +145,7 @@ class ClientLbEnd2endTest : public ::testing::Test { void StartServers(size_t num_servers, std::vector ports = std::vector()) { - if (servers_.empty()) CreateServers(num_servers, ports); + CreateServers(num_servers, ports); for (size_t i = 0; i < num_servers; ++i) { StartServer(i); } @@ -630,7 +631,7 @@ TEST_F(ClientLbEnd2endTest, gpr_log(GPR_INFO, "****** STOPPING SERVER ******"); servers_[1]->Shutdown(); EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - gpr_log(GPR_INFO, "****** STARTING SERVER 0 ******"); + gpr_log(GPR_INFO, "****** STARTING BOTH SERVERS ******"); servers_.clear(); StartServers(2, ports); WaitForServer(stub, 0, DEBUG_LOCATION); @@ -895,7 +896,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) { // Kill all servers gpr_log(GPR_INFO, "****** ABOUT TO KILL SERVERS *******"); for (size_t i = 0; i < servers_.size(); ++i) { - servers_[i]->Shutdown(false); + servers_[i]->Shutdown(true); } gpr_log(GPR_INFO, "****** SERVERS KILLED *******"); gpr_log(GPR_INFO, "****** SENDING DOOMED REQUESTS *******"); From aad7884233fbe037fdf7f37dd7e526a0219faa4c Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 17 Aug 2018 11:24:54 -0700 Subject: [PATCH 146/546] Code review changes. --- test/cpp/end2end/client_lb_end2end_test.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 2dbf9fc6b65..6ccf16aaa13 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -629,7 +629,6 @@ TEST_F(ClientLbEnd2endTest, PickFirstReconnectWithoutNewResolverResult) { servers_[0]->Shutdown(); EXPECT_TRUE(WaitForChannelNotReady(channel.get())); gpr_log(GPR_INFO, "****** RESTARTING SERVER ******"); - servers_.clear(); StartServers(1, ports); WaitForServer(stub, 0, DEBUG_LOCATION); } @@ -649,7 +648,6 @@ TEST_F(ClientLbEnd2endTest, servers_[1]->Shutdown(); EXPECT_TRUE(WaitForChannelNotReady(channel.get())); gpr_log(GPR_INFO, "****** STARTING BOTH SERVERS ******"); - servers_.clear(); StartServers(2, ports); WaitForServer(stub, 0, DEBUG_LOCATION); } @@ -666,7 +664,6 @@ TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) { servers_[0]->Shutdown(); // Channel 1 will receive a re-resolution containing the same server. It will // create a new subchannel and hold a ref to it. - servers_.clear(); StartServers(1, ports); gpr_log(GPR_INFO, "****** SERVER RESTARTED *******"); auto channel_2 = BuildChannel("pick_first"); @@ -685,7 +682,6 @@ TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) { EXPECT_TRUE(WaitForChannelNotReady(channel_2.get())); // Channel 2 will also receive a re-resolution containing the same server. // Both channels will ref the same subchannel that failed. - servers_.clear(); StartServers(1, ports); gpr_log(GPR_INFO, "****** SERVER RESTARTED AGAIN *******"); gpr_log(GPR_INFO, "****** CHANNEL 2 STARTING A CALL *******"); From 25f7d0f6f4a40dc969685192b45257d8c000a58d Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 17 Aug 2018 13:25:15 -0700 Subject: [PATCH 147/546] Revert to TRANSIENT_FAILURE during backoff --- .../ext/filters/client_channel/subchannel.cc | 9 ++------- test/cpp/end2end/grpclb_end2end_test.cc | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 48c6030c895..0e40f42e189 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -404,6 +404,8 @@ static void continue_connect_locked(grpc_subchannel* c) { c->next_attempt_deadline = c->backoff->NextAttemptTime(); args.deadline = std::max(c->next_attempt_deadline, min_deadline); args.channel_args = c->args; + grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING, + GRPC_ERROR_NONE, "connecting"); grpc_connector_connect(c->connector, &args, &c->connecting_result, &c->on_connected); } @@ -478,8 +480,6 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) { GRPC_SUBCHANNEL_WEAK_REF(c, "connecting"); if (!c->backoff_begun) { c->backoff_begun = true; - grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING, - GRPC_ERROR_NONE, "connecting"); continue_connect_locked(c); } else { GPR_ASSERT(!c->have_alarm); @@ -494,11 +494,6 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) { } GRPC_CLOSURE_INIT(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx); grpc_timer_init(&c->alarm, c->next_attempt_deadline, &c->on_alarm); - // During backoff, we prefer the connectivity state of CONNECTING instead of - // TRANSIENT_FAILURE in order to prevent triggering re-resolution - // continuously in pick_first. - grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING, - GRPC_ERROR_NONE, "backoff"); } } diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 28f9ae6f40a..b69b861fcf4 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -734,6 +734,25 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) { EXPECT_EQ(2U, balancer_servers_[0].service_->response_count()); } +TEST_F(SingleBalancerTest, AllServersUnreachableFailFast) { + SetNextResolutionAllBalancers(); + const size_t kNumUnreachableServers = 5; + std::vector ports; + for (size_t i = 0; i < kNumUnreachableServers; ++i) { + ports.push_back(grpc_pick_unused_port_or_die()); + } + ScheduleResponseForBalancer( + 0, BalancerServiceImpl::BuildResponseForBackends(ports, {}), 0); + const Status status = SendRpc(); + // The error shouldn't be DEADLINE_EXCEEDED. + EXPECT_EQ(StatusCode::UNAVAILABLE, status.error_code()); + 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()); +} + TEST_F(SingleBalancerTest, Fallback) { SetNextResolutionAllBalancers(); const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); From 616b5d798a818d976b0bbb2ab2b1ce8c4fa6ac0e Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 17 Aug 2018 13:38:48 -0700 Subject: [PATCH 148/546] Cast an index to size_t to avoid sign-conversion warning --- doc/cpp/pending_api_cleanups.md | 3 ++ include/grpcpp/impl/codegen/service_type.h | 37 ++++++++++++++-------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/doc/cpp/pending_api_cleanups.md b/doc/cpp/pending_api_cleanups.md index fa19b52002f..5c231eda2c8 100644 --- a/doc/cpp/pending_api_cleanups.md +++ b/doc/cpp/pending_api_cleanups.md @@ -17,3 +17,6 @@ number: `include/grpc++/impl/codegen/client_context.h` (commit `9477724`) - remove directory `include/grpc++` and all headers in it (commit `eb06572`) +- make all `Request` and `Mark` methods in `grpc::Service` take a + `size_t` argument for `index` rather than `int` (since that is only + used as a vector index) diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h index a0bbd659e28..9f1a0521689 100644 --- a/include/grpcpp/impl/codegen/service_type.h +++ b/include/grpcpp/impl/codegen/service_type.h @@ -93,14 +93,19 @@ class Service { internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) { - server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq, + // Typecast the index to size_t for indexing into a vector + // while preserving the API that existed before a compiler + // warning was first seen (grpc/grpc#11664) + size_t idx = static_cast(index); + server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag, request); } void RequestAsyncClientStreaming( int index, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) { - server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq, + size_t idx = static_cast(index); + server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag); } template @@ -108,14 +113,16 @@ class Service { int index, ServerContext* context, Message* request, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) { - server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq, + size_t idx = static_cast(index); + server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag, request); } void RequestAsyncBidiStreaming( int index, ServerContext* context, internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, ServerCompletionQueue* notification_cq, void* tag) { - server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq, + size_t idx = static_cast(index); + server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, notification_cq, tag); } @@ -126,46 +133,50 @@ class Service { void MarkMethodAsync(int index) { // This does not have to be a hard error, however no one has approached us // with a use case yet. Please file an issue if you believe you have one. + size_t idx = static_cast(index); GPR_CODEGEN_ASSERT( - methods_[index].get() != nullptr && + methods_[idx].get() != nullptr && "Cannot mark the method as 'async' because it has already been " "marked as 'generic'."); - methods_[index]->SetServerAsyncType( + methods_[idx]->SetServerAsyncType( internal::RpcServiceMethod::AsyncType::ASYNC); } void MarkMethodRaw(int index) { // This does not have to be a hard error, however no one has approached us // with a use case yet. Please file an issue if you believe you have one. - GPR_CODEGEN_ASSERT(methods_[index].get() != nullptr && + size_t idx = static_cast(index); + GPR_CODEGEN_ASSERT(methods_[idx].get() != nullptr && "Cannot mark the method as 'raw' because it has already " "been marked as 'generic'."); - methods_[index]->SetServerAsyncType( + methods_[idx]->SetServerAsyncType( internal::RpcServiceMethod::AsyncType::RAW); } void MarkMethodGeneric(int index) { // This does not have to be a hard error, however no one has approached us // with a use case yet. Please file an issue if you believe you have one. + size_t idx = static_cast(index); GPR_CODEGEN_ASSERT( - methods_[index]->handler() != nullptr && + methods_[idx]->handler() != nullptr && "Cannot mark the method as 'generic' because it has already been " "marked as 'async' or 'raw'."); - methods_[index].reset(); + methods_[idx].reset(); } void MarkMethodStreamed(int index, internal::MethodHandler* streamed_method) { // This does not have to be a hard error, however no one has approached us // with a use case yet. Please file an issue if you believe you have one. - GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() && + size_t idx = static_cast(index); + GPR_CODEGEN_ASSERT(methods_[idx] && methods_[idx]->handler() && "Cannot mark an async or generic method Streamed"); - methods_[index]->SetHandler(streamed_method); + methods_[idx]->SetHandler(streamed_method); // From the server's point of view, streamed unary is a special // case of BIDI_STREAMING that has 1 read and 1 write, in that order, // and split server-side streaming is BIDI_STREAMING with 1 read and // any number of writes, in that order. - methods_[index]->SetMethodType(internal::RpcMethod::BIDI_STREAMING); + methods_[idx]->SetMethodType(internal::RpcMethod::BIDI_STREAMING); } private: From 356fff684a63f9503c4ff4d7b22ef7bd20f3aa12 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 17 Aug 2018 14:55:05 -0700 Subject: [PATCH 149/546] Improve documentation on lifetime of message and status --- include/grpcpp/impl/codegen/async_stream.h | 43 +++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index b2134590c3c..cd433e48696 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -64,7 +64,7 @@ class ClientAsyncStreamingInterface { /// earlier call to \a AsyncReaderInterface::Read that yielded a failed /// result, e.g. cq->Next(&read_tag, &ok) filled in 'ok' with 'false'). /// - /// This function will return when either: + /// The tag will be returned when either: /// - all incoming messages have been read and the server has returned /// a status. /// - the server has returned a non-OK status. @@ -112,6 +112,8 @@ class AsyncWriterInterface { /// Only one write may be outstanding at any given time. This means that /// after calling Write, one must wait to receive \a tag from the completion /// queue BEFORE calling Write again. + /// GRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// to deallocate once Write returns. /// This is thread-safe with respect to \a AsyncReaderInterface::Read /// /// \param[in] msg The message to be written. @@ -124,6 +126,8 @@ class AsyncWriterInterface { /// Only one write may be outstanding at any given time. This means that /// after calling Write, one must wait to receive \a tag from the completion /// queue BEFORE calling Write again. + /// GRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// to deallocate once Write returns. /// WriteOptions \a options is used to set the write options of this message. /// This is thread-safe with respect to \a AsyncReaderInterface::Read /// @@ -143,6 +147,8 @@ class AsyncWriterInterface { /// and write is initiated. Note that WriteLast can only buffer \a msg up to /// the flow control window size. If \a msg size is larger than the window /// size, it will be sent on wire without buffering. + /// GRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// to deallocate once Write returns. /// /// \param[in] msg The message to be written. /// \param[in] options The WriteOptions to be used to write this message. @@ -629,6 +635,8 @@ class ServerAsyncReaderInterface /// This operation will end when the server has finished sending out initial /// metadata (if not sent already), response message, and status, or if /// some failure occurred when trying to do so. + /// GRPC doesn't take ownership or a reference to \a msg or \a status, so it + /// is safe to to deallocate once Finish returns. /// /// \param[in] tag Tag identifying this request. /// \param[in] status To be sent to the client as the result of this call. @@ -650,6 +658,9 @@ class ServerAsyncReaderInterface /// metadata (if not sent already), and status, or if some failure occurred /// when trying to do so. /// + /// GRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once FinishWithError returns. + /// /// \param[in] tag Tag identifying this request. /// \param[in] status To be sent to the client as the result of this call. /// - Note: \a status must have a non-OK code. @@ -697,6 +708,9 @@ class ServerAsyncReader final : public ServerAsyncReaderInterface { /// initial and trailing metadata. /// /// Note: \a msg is not sent if \a status has a non-OK code. + /// + /// GRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to to deallocate once Finish returns. void Finish(const W& msg, const Status& status, void* tag) override { finish_ops_.set_output_tag(tag); if (!ctx_->sent_initial_metadata_) { @@ -723,6 +737,9 @@ class ServerAsyncReader final : public ServerAsyncReaderInterface { /// - also sends initial metadata if not alreay sent. /// - uses the \a ServerContext associated with this call to send possible /// initial and trailing metadata. + /// + /// GRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once FinishWithError returns. void FinishWithError(const Status& status, void* tag) override { GPR_CODEGEN_ASSERT(!status.ok()); finish_ops_.set_output_tag(tag); @@ -773,6 +790,9 @@ class ServerAsyncWriterInterface /// metadata (if not sent already), response message, and status, or if /// some failure occurred when trying to do so. /// + /// GRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once Finish returns. + /// /// \param[in] tag Tag identifying this request. /// \param[in] status To be sent to the client as the result of this call. virtual void Finish(const Status& status, void* tag) = 0; @@ -784,6 +804,9 @@ class ServerAsyncWriterInterface /// WriteAndFinish is equivalent of performing WriteLast and Finish /// in a single step. /// + /// GRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to to deallocate once WriteAndFinish returns. + /// /// \param[in] msg The message to be written. /// \param[in] options The WriteOptions to be used to write this message. /// \param[in] status The Status that server returns to client. @@ -847,6 +870,9 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface { /// for sending trailing (and initial) metadata to the client. /// /// Note: \a status must have an OK code. + /// + /// GRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to to deallocate once WriteAndFinish returns. void WriteAndFinish(const W& msg, WriteOptions options, const Status& status, void* tag) override { write_ops_.set_output_tag(tag); @@ -865,6 +891,9 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface { /// /// Note: there are no restrictions are the code of /// \a status,it may be non-OK + /// + /// GRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once Finish returns. void Finish(const Status& status, void* tag) override { finish_ops_.set_output_tag(tag); EnsureInitialMetadataSent(&finish_ops_); @@ -924,6 +953,9 @@ class ServerAsyncReaderWriterInterface /// metadata (if not sent already), response message, and status, or if some /// failure occurred when trying to do so. /// + /// GRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once Finish returns. + /// /// \param[in] tag Tag identifying this request. /// \param[in] status To be sent to the client as the result of this call. virtual void Finish(const Status& status, void* tag) = 0; @@ -935,6 +967,9 @@ class ServerAsyncReaderWriterInterface /// WriteAndFinish is equivalent of performing WriteLast and Finish in a /// single step. /// + /// GRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to to deallocate once WriteAndFinish returns. + /// /// \param[in] msg The message to be written. /// \param[in] options The WriteOptions to be used to write this message. /// \param[in] status The Status that server returns to client. @@ -1006,6 +1041,9 @@ class ServerAsyncReaderWriter final /// for sending trailing (and initial) metadata to the client. /// /// Note: \a status must have an OK code. + // + /// GRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// is safe to to deallocate once WriteAndFinish returns. void WriteAndFinish(const W& msg, WriteOptions options, const Status& status, void* tag) override { write_ops_.set_output_tag(tag); @@ -1024,6 +1062,9 @@ class ServerAsyncReaderWriter final /// /// Note: there are no restrictions are the code of \a status, /// it may be non-OK + // + /// GRPC doesn't take ownership or a reference to \a status, so it is safe to + /// to deallocate once Finish returns. void Finish(const Status& status, void* tag) override { finish_ops_.set_output_tag(tag); EnsureInitialMetadataSent(&finish_ops_); From f80af5a7c753f18f0f15ab6b377949fc4b06d69f Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 17 Aug 2018 14:58:01 -0700 Subject: [PATCH 150/546] Formatting --- include/grpcpp/impl/codegen/async_stream.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index cd433e48696..5df849f610a 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -112,9 +112,10 @@ class AsyncWriterInterface { /// Only one write may be outstanding at any given time. This means that /// after calling Write, one must wait to receive \a tag from the completion /// queue BEFORE calling Write again. + /// This is thread-safe with respect to \a AsyncReaderInterface::Read + /// /// GRPC doesn't take ownership or a reference to \a msg, so it is safe to /// to deallocate once Write returns. - /// This is thread-safe with respect to \a AsyncReaderInterface::Read /// /// \param[in] msg The message to be written. /// \param[in] tag The tag identifying the operation. @@ -126,11 +127,12 @@ class AsyncWriterInterface { /// Only one write may be outstanding at any given time. This means that /// after calling Write, one must wait to receive \a tag from the completion /// queue BEFORE calling Write again. - /// GRPC doesn't take ownership or a reference to \a msg, so it is safe to - /// to deallocate once Write returns. /// WriteOptions \a options is used to set the write options of this message. /// This is thread-safe with respect to \a AsyncReaderInterface::Read /// + /// GRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// to deallocate once Write returns. + /// /// \param[in] msg The message to be written. /// \param[in] options The WriteOptions to be used to write this message. /// \param[in] tag The tag identifying the operation. @@ -147,6 +149,7 @@ class AsyncWriterInterface { /// and write is initiated. Note that WriteLast can only buffer \a msg up to /// the flow control window size. If \a msg size is larger than the window /// size, it will be sent on wire without buffering. + /// /// GRPC doesn't take ownership or a reference to \a msg, so it is safe to /// to deallocate once Write returns. /// @@ -635,6 +638,7 @@ class ServerAsyncReaderInterface /// This operation will end when the server has finished sending out initial /// metadata (if not sent already), response message, and status, or if /// some failure occurred when trying to do so. + /// /// GRPC doesn't take ownership or a reference to \a msg or \a status, so it /// is safe to to deallocate once Finish returns. /// From 66a4efc5a863f40feb3574fcea59172779b81bff Mon Sep 17 00:00:00 2001 From: ZhouyihaiDing Date: Fri, 17 Aug 2018 18:09:13 -0700 Subject: [PATCH 151/546] PHP: fix failed test 16392 --- .../PersistentChannelTest.php | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/php/tests/unit_tests/PersistentChannelTests/PersistentChannelTest.php b/src/php/tests/unit_tests/PersistentChannelTests/PersistentChannelTest.php index 2bb5c4bb852..7515a012334 100644 --- a/src/php/tests/unit_tests/PersistentChannelTests/PersistentChannelTest.php +++ b/src/php/tests/unit_tests/PersistentChannelTests/PersistentChannelTest.php @@ -174,12 +174,12 @@ class PersistentListTest extends PHPUnit_Framework_TestCase public function testPersistentChannelSharedChannelClose() { // same underlying channel - $this->channel1 = new Grpc\Channel('localhost:10010', [ + $this->channel1 = new Grpc\Channel('localhost:10001', [ "grpc_target_persist_bound" => 2, ]); - $this->channel2 = new Grpc\Channel('localhost:10010', []); + $this->channel2 = new Grpc\Channel('localhost:10001', []); $this->server = new Grpc\Server([]); - $this->port = $this->server->addHttp2Port('localhost:10010'); + $this->port = $this->server->addHttp2Port('localhost:10001'); // channel2 can still be use $state = $this->channel2->getConnectivityState(); @@ -216,7 +216,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase public function testPersistentChannelTargetDefaultUpperBound() { - $this->channel1 = new Grpc\Channel('localhost:10011', []); + $this->channel1 = new Grpc\Channel('localhost:10002', []); $channel1_info = $this->channel1->getChannelInfo(); $this->assertEquals($channel1_info['target_upper_bound'], 1); $this->assertEquals($channel1_info['target_current_size'], 1); @@ -224,7 +224,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase public function testPersistentChannelTargetUpperBoundZero() { - $this->channel1 = new Grpc\Channel('localhost:10011', [ + $this->channel1 = new Grpc\Channel('localhost:10002', [ "grpc_target_persist_bound" => 0, ]); // channel1 will not be persisted. @@ -237,7 +237,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase public function testPersistentChannelTargetUpperBoundNotZero() { - $this->channel1 = new Grpc\Channel('localhost:10011', [ + $this->channel1 = new Grpc\Channel('localhost:10003', [ "grpc_target_persist_bound" => 3, ]); $channel1_info = $this->channel1->getChannelInfo(); @@ -245,7 +245,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase $this->assertEquals($channel1_info['target_current_size'], 1); // The upper bound should not be changed - $this->channel2 = new Grpc\Channel('localhost:10011', []); + $this->channel2 = new Grpc\Channel('localhost:10003', []); $channel2_info = $this->channel2->getChannelInfo(); $this->assertEquals($channel2_info['target_upper_bound'], 3); $this->assertEquals($channel2_info['target_current_size'], 1); @@ -253,14 +253,14 @@ class PersistentListTest extends PHPUnit_Framework_TestCase // The upper bound should not be changed $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); - $this->channel3 = new Grpc\Channel('localhost:10011', + $this->channel3 = new Grpc\Channel('localhost:10003', ['credentials' => $channel_credentials]); $channel3_info = $this->channel3->getChannelInfo(); $this->assertEquals($channel3_info['target_upper_bound'], 3); $this->assertEquals($channel3_info['target_current_size'], 2); // The upper bound should not be changed - $this->channel4 = new Grpc\Channel('localhost:10011', [ + $this->channel4 = new Grpc\Channel('localhost:10003', [ "grpc_target_persist_bound" => 5, ]); $channel4_info = $this->channel4->getChannelInfo(); @@ -393,14 +393,14 @@ class PersistentListTest extends PHPUnit_Framework_TestCase public function testPersistentChannelTwoUpperBoundOutBound2() { - $this->channel1 = new Grpc\Channel('localhost:10011', [ + $this->channel1 = new Grpc\Channel('localhost:10012', [ "grpc_target_persist_bound" => 2, ]); $channel1_info = $this->channel1->getChannelInfo(); $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); - $this->channel2 = new Grpc\Channel('localhost:10011', + $this->channel2 = new Grpc\Channel('localhost:10012', ['credentials' => $channel_credentials]); $channel2_info = $this->channel2->getChannelInfo(); @@ -409,7 +409,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase $channel_credentials = Grpc\ChannelCredentials::createSsl("a", null, null); - $this->channel3 = new Grpc\Channel('localhost:10011', + $this->channel3 = new Grpc\Channel('localhost:10012', ['credentials' => $channel_credentials]); $channel3_info = $this->channel3->getChannelInfo(); @@ -422,14 +422,14 @@ class PersistentListTest extends PHPUnit_Framework_TestCase public function testPersistentChannelTwoUpperBoundOutBound3() { - $this->channel1 = new Grpc\Channel('localhost:10011', [ + $this->channel1 = new Grpc\Channel('localhost:10013', [ "grpc_target_persist_bound" => 2, ]); $channel1_info = $this->channel1->getChannelInfo(); $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); - $this->channel2 = new Grpc\Channel('localhost:10011', + $this->channel2 = new Grpc\Channel('localhost:10013', ['credentials' => $channel_credentials]); $this->channel2->getConnectivityState(true); $this->waitUntilNotIdle($this->channel2); @@ -442,7 +442,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase $channel_credentials = Grpc\ChannelCredentials::createSsl("a", null, null); - $this->channel3 = new Grpc\Channel('localhost:10011', + $this->channel3 = new Grpc\Channel('localhost:10013', ['credentials' => $channel_credentials]); $channel3_info = $this->channel3->getChannelInfo(); @@ -456,7 +456,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase public function testPersistentChannelTwoUpperBoundOutBound4() { - $this->channel1 = new Grpc\Channel('localhost:10011', [ + $this->channel1 = new Grpc\Channel('localhost:10014', [ "grpc_target_persist_bound" => 2, ]); $this->channel1->getConnectivityState(true); @@ -466,7 +466,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); - $this->channel2 = new Grpc\Channel('localhost:10011', + $this->channel2 = new Grpc\Channel('localhost:10014', ['credentials' => $channel_credentials]); $this->channel2->getConnectivityState(true); $this->waitUntilNotIdle($this->channel2); @@ -475,7 +475,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase $channel_credentials = Grpc\ChannelCredentials::createSsl("a", null, null); - $this->channel3 = new Grpc\Channel('localhost:10011', + $this->channel3 = new Grpc\Channel('localhost:10014', ['credentials' => $channel_credentials]); $channel3_info = $this->channel3->getChannelInfo(); From 49e74c087e6a6261709ce8fe7fca6b7d90a1d096 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 17 Aug 2018 20:41:16 -0700 Subject: [PATCH 152/546] Simplify call arena size growth --- src/core/lib/gpr/arena.cc | 82 ++++++++++++++------------------------- 1 file changed, 29 insertions(+), 53 deletions(-) diff --git a/src/core/lib/gpr/arena.cc b/src/core/lib/gpr/arena.cc index e30b297aeab..4e7094d9bb2 100644 --- a/src/core/lib/gpr/arena.cc +++ b/src/core/lib/gpr/arena.cc @@ -77,16 +77,15 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) { // would allow us to use the alignment actually needed by the caller. typedef struct zone { - size_t size_begin; // All the space we have set aside for allocations up - // until this zone. - size_t size_end; // size_end = size_begin plus all the space we set aside for - // allocations in zone z itself. zone* next; } zone; struct gpr_arena { - gpr_atm size_so_far; + gpr_atm total_used; + gpr_atm initial_zone_used; + size_t initial_zone_size; zone initial_zone; + zone* last_zone; gpr_mu arena_growth_mutex; }; @@ -100,14 +99,15 @@ gpr_arena* gpr_arena_create(size_t initial_size) { initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size); gpr_arena* a = static_cast(zalloc_aligned( GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size)); - a->initial_zone.size_end = initial_size; + a->initial_zone_size = initial_size; + a->last_zone = &a->initial_zone; gpr_mu_init(&a->arena_growth_mutex); return a; } size_t gpr_arena_destroy(gpr_arena* arena) { gpr_mu_destroy(&arena->arena_growth_mutex); - gpr_atm size = gpr_atm_no_barrier_load(&arena->size_so_far); + gpr_atm size = gpr_atm_no_barrier_load(&arena->total_used); zone* z = arena->initial_zone.next; gpr_free_aligned(arena); while (z) { @@ -120,55 +120,31 @@ size_t gpr_arena_destroy(gpr_arena* arena) { void* gpr_arena_alloc(gpr_arena* arena, size_t size) { size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size); - size_t previous_size_of_arena_allocations = static_cast( - gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size)); - size_t updated_size_of_arena_allocations = - previous_size_of_arena_allocations + size; - zone* z = &arena->initial_zone; - // Check to see if the allocation isn't able to end in the initial zone. - // This statement is true only in the uncommon case because of our arena - // sizing historesis (that is, most calls should have a large enough initial - // zone and will not need to grow the arena). - if (updated_size_of_arena_allocations > z->size_end) { - // Find a zone to fit this allocation + // Update the total used size to estimate next call's size. + gpr_atm_no_barrier_fetch_add(&arena->total_used, size); + // Try to allocate in the initial zone. + size_t initial_zone_alloc_begin = static_cast( + gpr_atm_no_barrier_fetch_add(&arena->initial_zone_used, size)); + size_t initial_zone_alloc_end = initial_zone_alloc_begin + size; + if (initial_zone_alloc_end <= arena->initial_zone_size) { + return reinterpret_cast(arena) + + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + + initial_zone_alloc_begin; + } else { + // If the allocation isn't able to end in the initial zone, create a new + // zone for this allocation, and any unused space in the initial zone is + // wasted. This overflowing and wasting is uncommon because of our arena + // sizing historesis (that is, most calls should have a large enough initial + // zone and will not need to grow the arena). gpr_mu_lock(&arena->arena_growth_mutex); - while (updated_size_of_arena_allocations > z->size_end) { - if (z->next == nullptr) { - // Note that we do an extra increment of size_so_far to prevent multiple - // simultaneous callers from stepping on each other. However, this extra - // increment means some space in the arena is wasted. - // So whenever we need to allocate x bytes and there are x - n (where - // n > 0) remaining in the current zone, we will waste x bytes (x - n - // in the current zone and n in the new zone). - previous_size_of_arena_allocations = static_cast( - gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size)); - updated_size_of_arena_allocations = - previous_size_of_arena_allocations + size; - size_t next_z_size = updated_size_of_arena_allocations; - z->next = static_cast(zalloc_aligned( - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + next_z_size)); - z->next->size_begin = z->size_end; - z->next->size_end = z->size_end + next_z_size; - } - z = z->next; - } + zone* z = static_cast( + zalloc_aligned(GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + size)); + arena->last_zone->next = z; + arena->last_zone = z; gpr_mu_unlock(&arena->arena_growth_mutex); + return reinterpret_cast(z) + + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)); } - GPR_ASSERT(previous_size_of_arena_allocations >= z->size_begin); - GPR_ASSERT(updated_size_of_arena_allocations <= z->size_end); - // Skip the first part of the zone, which just contains tracking information. - // For the initial zone, this is the gpr_arena struct and for any other zone, - // it's the zone struct. - char* start_of_allocation_space = - (z == &arena->initial_zone) - ? reinterpret_cast(arena) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) - : reinterpret_cast(z) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)); - // previous_size_of_arena_allocations - size_begin is how many bytes have been - // allocated into the current zone - return start_of_allocation_space + previous_size_of_arena_allocations - - z->size_begin; } #endif // SIMPLE_ARENA_FOR_DEBUGGING From add72762a7a7fb8e72a95bf5e573f2e909371ce5 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 20 Aug 2018 07:08:59 -0700 Subject: [PATCH 153/546] Fix round_robin to avoid negative size_t value. --- .../client_channel/lb_policy/round_robin/round_robin.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 fea84331d80..960780a27a5 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 @@ -138,7 +138,8 @@ class RoundRobin : public LoadBalancingPolicy { grpc_client_channel_factory* client_channel_factory, const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, - client_channel_factory, args) { + client_channel_factory, args), + last_ready_index_(num_subchannels() - 1) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' // pollset_sets will include the LB policy's pollset_set. @@ -179,7 +180,7 @@ class RoundRobin : public LoadBalancingPolicy { size_t num_connecting_ = 0; size_t num_transient_failure_ = 0; grpc_error* last_transient_failure_error_ = GRPC_ERROR_NONE; - size_t last_ready_index_ = -1; // Index into list of last pick. + size_t last_ready_index_; // Index into list of last pick. }; // Helper class to ensure that any function that modifies the child refs From c818320a3d0534a95055dba521b59553b6c7d6c3 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Aug 2018 17:26:22 +0200 Subject: [PATCH 154/546] upgrade dotnet examples to grpc1.14.1 and protobuf 3.6.1 --- examples/csharp/Helloworld/Greeter/Greeter.csproj | 8 ++++---- examples/csharp/Helloworld/generate_protos.bat | 5 +++-- examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj | 8 ++++---- examples/csharp/RouteGuide/generate_protos.bat | 6 ++++-- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/examples/csharp/Helloworld/Greeter/Greeter.csproj b/examples/csharp/Helloworld/Greeter/Greeter.csproj index 3d4be5da6b4..1ca821320cd 100644 --- a/examples/csharp/Helloworld/Greeter/Greeter.csproj +++ b/examples/csharp/Helloworld/Greeter/Greeter.csproj @@ -9,10 +9,10 @@ - - - - + + + + diff --git a/examples/csharp/Helloworld/generate_protos.bat b/examples/csharp/Helloworld/generate_protos.bat index dcf60848f77..ab0c0eb46a4 100644 --- a/examples/csharp/Helloworld/generate_protos.bat +++ b/examples/csharp/Helloworld/generate_protos.bat @@ -19,8 +19,9 @@ setlocal @rem enter this directory cd /d %~dp0 -set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.5.0\tools\windows_x64\protoc.exe -set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.8.0\tools\windows_x64\grpc_csharp_plugin.exe +@rem packages will be available in nuget cache directory once the project is built or after "dotnet restore" +set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.6.1\tools\windows_x64\protoc.exe +set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.14.1\tools\windows_x64\grpc_csharp_plugin.exe %PROTOC% -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%PLUGIN% diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj index 7419f1a277d..e1c44ecf3c4 100644 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj +++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj @@ -9,10 +9,10 @@ - - - - + + + + diff --git a/examples/csharp/RouteGuide/generate_protos.bat b/examples/csharp/RouteGuide/generate_protos.bat index a8c9cb505a1..f3a4382cf19 100644 --- a/examples/csharp/RouteGuide/generate_protos.bat +++ b/examples/csharp/RouteGuide/generate_protos.bat @@ -19,8 +19,10 @@ setlocal @rem enter this directory cd /d %~dp0 -set TOOLS_PATH=packages\Grpc.Tools.1.8.0\tools\windows_x86 +@rem packages will be available in nuget cache directory once the project is built or after "dotnet restore" +set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.6.1\tools\windows_x64\protoc.exe +set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.14.1\tools\windows_x64\grpc_csharp_plugin.exe -%TOOLS_PATH%\protoc.exe -I../../protos --csharp_out RouteGuide ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe +%PROTOC% -I../../protos --csharp_out RouteGuide ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%PLUGIN% endlocal From 5be131147202fc210752548e73bcce3f15955c0e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Aug 2018 17:32:30 +0200 Subject: [PATCH 155/546] upgrade HelloworldLegacyCsproj to grpc1.14.1 and protobuf 3.6.1 --- .../Greeter/Greeter.csproj | 19 ++++++++++++------- .../Greeter/packages.config | 8 ++++---- .../GreeterClient/GreeterClient.csproj | 19 ++++++++++++------- .../GreeterClient/packages.config | 6 +++--- .../GreeterServer/GreeterServer.csproj | 19 ++++++++++++------- .../GreeterServer/packages.config | 6 +++--- .../generate_protos.bat | 2 +- 7 files changed, 47 insertions(+), 32 deletions(-) diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj b/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj index ab584c86d3e..197a9fb6257 100644 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj +++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj @@ -32,18 +32,17 @@ false - - ..\packages\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll - True + + ..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll + + + ..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll True - - ..\packages\Grpc.Core.1.13.1\lib\net45\Grpc.Core.dll - @@ -62,5 +61,11 @@ - + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config b/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config index 8e61429a8ea..23857be22fa 100644 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config +++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config @@ -1,8 +1,8 @@  - - - - + + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj index 2d2961d1289..3bb7ff1ee13 100644 --- a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj +++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj @@ -32,18 +32,17 @@ true - - ..\packages\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll - True + + ..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll + + + ..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll True - - ..\packages\Grpc.Core.1.13.1\lib\net45\Grpc.Core.dll - @@ -60,5 +59,11 @@ - + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config index da7dbcd8cb5..df4df8282c4 100644 --- a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config +++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config @@ -1,7 +1,7 @@  - - - + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj index 1d47d705955..4396b04efeb 100644 --- a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj +++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj @@ -32,18 +32,17 @@ true - - ..\packages\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll - True + + ..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll + + + ..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll ..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll True - - ..\packages\Grpc.Core.1.13.1\lib\net45\Grpc.Core.dll - @@ -60,5 +59,11 @@ - + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config index da7dbcd8cb5..df4df8282c4 100644 --- a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config +++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config @@ -1,7 +1,7 @@  - - - + + + \ No newline at end of file diff --git a/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat b/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat index 45b097e837e..d1e7160f91e 100644 --- a/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat +++ b/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat @@ -19,7 +19,7 @@ setlocal @rem enter this directory cd /d %~dp0 -set TOOLS_PATH=packages\Grpc.Tools.1.8.0\tools\windows_x86 +set TOOLS_PATH=packages\Grpc.Tools.1.14.1\tools\windows_x86 %TOOLS_PATH%\protoc.exe -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe From a554a5cd709346cb1e2d23247715e82cb17b273d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Aug 2018 17:34:04 +0200 Subject: [PATCH 156/546] regenerate protos for C# examples --- .../csharp/Helloworld/Greeter/Helloworld.cs | 38 ++++++-- .../Helloworld/Greeter/HelloworldGrpc.cs | 23 +++-- .../Greeter/Helloworld.cs | 38 ++++++-- .../Greeter/HelloworldGrpc.cs | 23 +++-- .../RouteGuide/RouteGuide/RouteGuide.cs | 94 +++++++++++++++---- .../RouteGuide/RouteGuide/RouteGuideGrpc.cs | 47 +++++----- 6 files changed, 187 insertions(+), 76 deletions(-) diff --git a/examples/csharp/Helloworld/Greeter/Helloworld.cs b/examples/csharp/Helloworld/Greeter/Helloworld.cs index ecfc8e131cb..e008ec27e54 100644 --- a/examples/csharp/Helloworld/Greeter/Helloworld.cs +++ b/examples/csharp/Helloworld/Greeter/Helloworld.cs @@ -1,5 +1,7 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +// #pragma warning disable 1591, 0612, 3021 #region Designer generated code @@ -44,6 +46,7 @@ namespace Helloworld { /// public sealed partial class HelloRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloRequest()); + private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -67,6 +70,7 @@ namespace Helloworld { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HelloRequest(HelloRequest other) : this() { name_ = other.name_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -99,13 +103,16 @@ namespace Helloworld { return true; } if (Name != other.Name) return false; - return true; + return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Name.Length != 0) hash ^= Name.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } return hash; } @@ -120,6 +127,9 @@ namespace Helloworld { output.WriteRawTag(10); output.WriteString(Name); } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -128,6 +138,9 @@ namespace Helloworld { if (Name.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } return size; } @@ -139,6 +152,7 @@ namespace Helloworld { if (other.Name.Length != 0) { Name = other.Name; } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -147,7 +161,7 @@ namespace Helloworld { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - input.SkipLastField(); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { Name = input.ReadString(); @@ -164,6 +178,7 @@ namespace Helloworld { /// public sealed partial class HelloReply : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloReply()); + private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -187,6 +202,7 @@ namespace Helloworld { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HelloReply(HelloReply other) : this() { message_ = other.message_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -219,13 +235,16 @@ namespace Helloworld { return true; } if (Message != other.Message) return false; - return true; + return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Message.Length != 0) hash ^= Message.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } return hash; } @@ -240,6 +259,9 @@ namespace Helloworld { output.WriteRawTag(10); output.WriteString(Message); } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -248,6 +270,9 @@ namespace Helloworld { if (Message.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } return size; } @@ -259,6 +284,7 @@ namespace Helloworld { if (other.Message.Length != 0) { Message = other.Message; } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -267,7 +293,7 @@ namespace Helloworld { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - input.SkipLastField(); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { Message = input.ReadString(); diff --git a/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs b/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs index c808884e579..d6b959adc64 100644 --- a/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs +++ b/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs @@ -1,5 +1,7 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +// // Original file comments: // Copyright 2015 gRPC authors. // @@ -15,12 +17,9 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#pragma warning disable 1591 +#pragma warning disable 0414, 1591 #region Designer generated code -using System; -using System.Threading; -using System.Threading.Tasks; using grpc = global::Grpc.Core; namespace Helloworld { @@ -31,15 +30,15 @@ namespace Helloworld { { static readonly string __ServiceName = "helloworld.Greeter"; - static readonly grpc::Marshaller __Marshaller_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_helloworld_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); static readonly grpc::Method __Method_SayHello = new grpc::Method( grpc::MethodType.Unary, __ServiceName, "SayHello", - __Marshaller_HelloRequest, - __Marshaller_HelloReply); + __Marshaller_helloworld_HelloRequest, + __Marshaller_helloworld_HelloReply); /// Service descriptor public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor @@ -94,7 +93,7 @@ namespace Helloworld { /// An optional deadline for the call. The call will be cancelled if deadline is hit. /// An optional token for canceling the call. /// The response received from the server. - public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken)); } @@ -116,7 +115,7 @@ namespace Helloworld { /// An optional deadline for the call. The call will be cancelled if deadline is hit. /// An optional token for canceling the call. /// The call object. - public virtual grpc::AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual grpc::AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken)); } diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs b/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs index ecfc8e131cb..e008ec27e54 100644 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs +++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs @@ -1,5 +1,7 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +// #pragma warning disable 1591, 0612, 3021 #region Designer generated code @@ -44,6 +46,7 @@ namespace Helloworld { /// public sealed partial class HelloRequest : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloRequest()); + private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -67,6 +70,7 @@ namespace Helloworld { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HelloRequest(HelloRequest other) : this() { name_ = other.name_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -99,13 +103,16 @@ namespace Helloworld { return true; } if (Name != other.Name) return false; - return true; + return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Name.Length != 0) hash ^= Name.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } return hash; } @@ -120,6 +127,9 @@ namespace Helloworld { output.WriteRawTag(10); output.WriteString(Name); } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -128,6 +138,9 @@ namespace Helloworld { if (Name.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } return size; } @@ -139,6 +152,7 @@ namespace Helloworld { if (other.Name.Length != 0) { Name = other.Name; } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -147,7 +161,7 @@ namespace Helloworld { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - input.SkipLastField(); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { Name = input.ReadString(); @@ -164,6 +178,7 @@ namespace Helloworld { /// public sealed partial class HelloReply : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloReply()); + private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -187,6 +202,7 @@ namespace Helloworld { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public HelloReply(HelloReply other) : this() { message_ = other.message_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -219,13 +235,16 @@ namespace Helloworld { return true; } if (Message != other.Message) return false; - return true; + return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; if (Message.Length != 0) hash ^= Message.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } return hash; } @@ -240,6 +259,9 @@ namespace Helloworld { output.WriteRawTag(10); output.WriteString(Message); } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -248,6 +270,9 @@ namespace Helloworld { if (Message.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } return size; } @@ -259,6 +284,7 @@ namespace Helloworld { if (other.Message.Length != 0) { Message = other.Message; } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -267,7 +293,7 @@ namespace Helloworld { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - input.SkipLastField(); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { Message = input.ReadString(); diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs b/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs index c808884e579..d6b959adc64 100644 --- a/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs +++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs @@ -1,5 +1,7 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: helloworld.proto +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +// // Original file comments: // Copyright 2015 gRPC authors. // @@ -15,12 +17,9 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#pragma warning disable 1591 +#pragma warning disable 0414, 1591 #region Designer generated code -using System; -using System.Threading; -using System.Threading.Tasks; using grpc = global::Grpc.Core; namespace Helloworld { @@ -31,15 +30,15 @@ namespace Helloworld { { static readonly string __ServiceName = "helloworld.Greeter"; - static readonly grpc::Marshaller __Marshaller_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_helloworld_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); static readonly grpc::Method __Method_SayHello = new grpc::Method( grpc::MethodType.Unary, __ServiceName, "SayHello", - __Marshaller_HelloRequest, - __Marshaller_HelloReply); + __Marshaller_helloworld_HelloRequest, + __Marshaller_helloworld_HelloReply); /// Service descriptor public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor @@ -94,7 +93,7 @@ namespace Helloworld { /// An optional deadline for the call. The call will be cancelled if deadline is hit. /// An optional token for canceling the call. /// The response received from the server. - public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken)); } @@ -116,7 +115,7 @@ namespace Helloworld { /// An optional deadline for the call. The call will be cancelled if deadline is hit. /// An optional token for canceling the call. /// The call object. - public virtual grpc::AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual grpc::AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken)); } diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs index 603809ee76f..10c9aec5f80 100644 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs +++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs @@ -1,5 +1,7 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: route_guide.proto +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: route_guide.proto +// #pragma warning disable 1591, 0612, 3021 #region Designer generated code @@ -60,6 +62,7 @@ namespace Routeguide { /// public sealed partial class Point : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Point()); + private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -84,6 +87,7 @@ namespace Routeguide { public Point(Point other) : this() { latitude_ = other.latitude_; longitude_ = other.longitude_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -128,7 +132,7 @@ namespace Routeguide { } if (Latitude != other.Latitude) return false; if (Longitude != other.Longitude) return false; - return true; + return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -136,6 +140,9 @@ namespace Routeguide { int hash = 1; if (Latitude != 0) hash ^= Latitude.GetHashCode(); if (Longitude != 0) hash ^= Longitude.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } return hash; } @@ -154,6 +161,9 @@ namespace Routeguide { output.WriteRawTag(16); output.WriteInt32(Longitude); } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -165,6 +175,9 @@ namespace Routeguide { if (Longitude != 0) { size += 1 + pb::CodedOutputStream.ComputeInt32Size(Longitude); } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } return size; } @@ -179,6 +192,7 @@ namespace Routeguide { if (other.Longitude != 0) { Longitude = other.Longitude; } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -187,7 +201,7 @@ namespace Routeguide { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - input.SkipLastField(); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 8: { Latitude = input.ReadInt32(); @@ -209,6 +223,7 @@ namespace Routeguide { /// public sealed partial class Rectangle : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Rectangle()); + private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -231,8 +246,9 @@ namespace Routeguide { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Rectangle(Rectangle other) : this() { - Lo = other.lo_ != null ? other.Lo.Clone() : null; - Hi = other.hi_ != null ? other.Hi.Clone() : null; + lo_ = other.lo_ != null ? other.lo_.Clone() : null; + hi_ = other.hi_ != null ? other.hi_.Clone() : null; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -283,7 +299,7 @@ namespace Routeguide { } if (!object.Equals(Lo, other.Lo)) return false; if (!object.Equals(Hi, other.Hi)) return false; - return true; + return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -291,6 +307,9 @@ namespace Routeguide { int hash = 1; if (lo_ != null) hash ^= Lo.GetHashCode(); if (hi_ != null) hash ^= Hi.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } return hash; } @@ -309,6 +328,9 @@ namespace Routeguide { output.WriteRawTag(18); output.WriteMessage(Hi); } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -320,6 +342,9 @@ namespace Routeguide { if (hi_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Hi); } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } return size; } @@ -340,6 +365,7 @@ namespace Routeguide { } Hi.MergeFrom(other.Hi); } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -348,7 +374,7 @@ namespace Routeguide { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - input.SkipLastField(); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { if (lo_ == null) { @@ -377,6 +403,7 @@ namespace Routeguide { /// public sealed partial class Feature : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Feature()); + private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -400,7 +427,8 @@ namespace Routeguide { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Feature(Feature other) : this() { name_ = other.name_; - Location = other.location_ != null ? other.Location.Clone() : null; + location_ = other.location_ != null ? other.location_.Clone() : null; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -451,7 +479,7 @@ namespace Routeguide { } if (Name != other.Name) return false; if (!object.Equals(Location, other.Location)) return false; - return true; + return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -459,6 +487,9 @@ namespace Routeguide { int hash = 1; if (Name.Length != 0) hash ^= Name.GetHashCode(); if (location_ != null) hash ^= Location.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } return hash; } @@ -477,6 +508,9 @@ namespace Routeguide { output.WriteRawTag(18); output.WriteMessage(Location); } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -488,6 +522,9 @@ namespace Routeguide { if (location_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Location); } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } return size; } @@ -505,6 +542,7 @@ namespace Routeguide { } Location.MergeFrom(other.Location); } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -513,7 +551,7 @@ namespace Routeguide { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - input.SkipLastField(); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { Name = input.ReadString(); @@ -537,6 +575,7 @@ namespace Routeguide { /// public sealed partial class RouteNote : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new RouteNote()); + private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -559,8 +598,9 @@ namespace Routeguide { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public RouteNote(RouteNote other) : this() { - Location = other.location_ != null ? other.Location.Clone() : null; + location_ = other.location_ != null ? other.location_.Clone() : null; message_ = other.message_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -611,7 +651,7 @@ namespace Routeguide { } if (!object.Equals(Location, other.Location)) return false; if (Message != other.Message) return false; - return true; + return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -619,6 +659,9 @@ namespace Routeguide { int hash = 1; if (location_ != null) hash ^= Location.GetHashCode(); if (Message.Length != 0) hash ^= Message.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } return hash; } @@ -637,6 +680,9 @@ namespace Routeguide { output.WriteRawTag(18); output.WriteString(Message); } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -648,6 +694,9 @@ namespace Routeguide { if (Message.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } return size; } @@ -665,6 +714,7 @@ namespace Routeguide { if (other.Message.Length != 0) { Message = other.Message; } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -673,7 +723,7 @@ namespace Routeguide { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - input.SkipLastField(); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { if (location_ == null) { @@ -701,6 +751,7 @@ namespace Routeguide { /// public sealed partial class RouteSummary : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new RouteSummary()); + private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -727,6 +778,7 @@ namespace Routeguide { featureCount_ = other.featureCount_; distance_ = other.distance_; elapsedTime_ = other.elapsedTime_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -807,7 +859,7 @@ namespace Routeguide { if (FeatureCount != other.FeatureCount) return false; if (Distance != other.Distance) return false; if (ElapsedTime != other.ElapsedTime) return false; - return true; + return Equals(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -817,6 +869,9 @@ namespace Routeguide { if (FeatureCount != 0) hash ^= FeatureCount.GetHashCode(); if (Distance != 0) hash ^= Distance.GetHashCode(); if (ElapsedTime != 0) hash ^= ElapsedTime.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } return hash; } @@ -843,6 +898,9 @@ namespace Routeguide { output.WriteRawTag(32); output.WriteInt32(ElapsedTime); } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -860,6 +918,9 @@ namespace Routeguide { if (ElapsedTime != 0) { size += 1 + pb::CodedOutputStream.ComputeInt32Size(ElapsedTime); } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } return size; } @@ -880,6 +941,7 @@ namespace Routeguide { if (other.ElapsedTime != 0) { ElapsedTime = other.ElapsedTime; } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -888,7 +950,7 @@ namespace Routeguide { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - input.SkipLastField(); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 8: { PointCount = input.ReadInt32(); diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs index 765d5d520bc..445708e4469 100644 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs +++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs @@ -1,5 +1,7 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: route_guide.proto +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: route_guide.proto +// // Original file comments: // Copyright 2015 gRPC authors. // @@ -15,12 +17,9 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#pragma warning disable 1591 +#pragma warning disable 0414, 1591 #region Designer generated code -using System; -using System.Threading; -using System.Threading.Tasks; using grpc = global::Grpc.Core; namespace Routeguide { @@ -31,39 +30,39 @@ namespace Routeguide { { static readonly string __ServiceName = "routeguide.RouteGuide"; - static readonly grpc::Marshaller __Marshaller_Point = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Point.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_Feature = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Feature.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_Rectangle = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Rectangle.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_RouteSummary = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteSummary.Parser.ParseFrom); - static readonly grpc::Marshaller __Marshaller_RouteNote = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteNote.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_routeguide_Point = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Point.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_routeguide_Feature = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Feature.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_routeguide_Rectangle = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Rectangle.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_routeguide_RouteSummary = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteSummary.Parser.ParseFrom); + static readonly grpc::Marshaller __Marshaller_routeguide_RouteNote = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteNote.Parser.ParseFrom); static readonly grpc::Method __Method_GetFeature = new grpc::Method( grpc::MethodType.Unary, __ServiceName, "GetFeature", - __Marshaller_Point, - __Marshaller_Feature); + __Marshaller_routeguide_Point, + __Marshaller_routeguide_Feature); static readonly grpc::Method __Method_ListFeatures = new grpc::Method( grpc::MethodType.ServerStreaming, __ServiceName, "ListFeatures", - __Marshaller_Rectangle, - __Marshaller_Feature); + __Marshaller_routeguide_Rectangle, + __Marshaller_routeguide_Feature); static readonly grpc::Method __Method_RecordRoute = new grpc::Method( grpc::MethodType.ClientStreaming, __ServiceName, "RecordRoute", - __Marshaller_Point, - __Marshaller_RouteSummary); + __Marshaller_routeguide_Point, + __Marshaller_routeguide_RouteSummary); static readonly grpc::Method __Method_RouteChat = new grpc::Method( grpc::MethodType.DuplexStreaming, __ServiceName, "RouteChat", - __Marshaller_RouteNote, - __Marshaller_RouteNote); + __Marshaller_routeguide_RouteNote, + __Marshaller_routeguide_RouteNote); /// Service descriptor public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor @@ -174,7 +173,7 @@ namespace Routeguide { /// An optional deadline for the call. The call will be cancelled if deadline is hit. /// An optional token for canceling the call. /// The response received from the server. - public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { return GetFeature(request, new grpc::CallOptions(headers, deadline, cancellationToken)); } @@ -206,7 +205,7 @@ namespace Routeguide { /// An optional deadline for the call. The call will be cancelled if deadline is hit. /// An optional token for canceling the call. /// The call object. - public virtual grpc::AsyncUnaryCall GetFeatureAsync(global::Routeguide.Point request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual grpc::AsyncUnaryCall GetFeatureAsync(global::Routeguide.Point request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { return GetFeatureAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken)); } @@ -238,7 +237,7 @@ namespace Routeguide { /// An optional deadline for the call. The call will be cancelled if deadline is hit. /// An optional token for canceling the call. /// The call object. - public virtual grpc::AsyncServerStreamingCall ListFeatures(global::Routeguide.Rectangle request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual grpc::AsyncServerStreamingCall ListFeatures(global::Routeguide.Rectangle request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { return ListFeatures(request, new grpc::CallOptions(headers, deadline, cancellationToken)); } @@ -267,7 +266,7 @@ namespace Routeguide { /// An optional deadline for the call. The call will be cancelled if deadline is hit. /// An optional token for canceling the call. /// The call object. - public virtual grpc::AsyncClientStreamingCall RecordRoute(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual grpc::AsyncClientStreamingCall RecordRoute(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { return RecordRoute(new grpc::CallOptions(headers, deadline, cancellationToken)); } @@ -293,7 +292,7 @@ namespace Routeguide { /// An optional deadline for the call. The call will be cancelled if deadline is hit. /// An optional token for canceling the call. /// The call object. - public virtual grpc::AsyncDuplexStreamingCall RouteChat(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + public virtual grpc::AsyncDuplexStreamingCall RouteChat(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken)) { return RouteChat(new grpc::CallOptions(headers, deadline, cancellationToken)); } From 0a69991080e0aa153d4b27df5654f699b5e12323 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Mon, 20 Aug 2018 09:32:30 -0700 Subject: [PATCH 157/546] Fix sort issue in package build page --- tools/package_hosting/build-201807.xsl | 116 ++++++++++++------------- 1 file changed, 57 insertions(+), 59 deletions(-) diff --git a/tools/package_hosting/build-201807.xsl b/tools/package_hosting/build-201807.xsl index 69a190446fa..f7571d178e7 100644 --- a/tools/package_hosting/build-201807.xsl +++ b/tools/package_hosting/build-201807.xsl @@ -1,75 +1,74 @@ - + - - - Artifacts for gRPC Build <xsl:value-of select="@id"/> - - - - - - - - - + + + Artifacts for gRPC Build <xsl:value-of select="@id"/> + + + + + + + + + + + + + + +
+ Artifacts for gRPC Build +
+
+
+ Build: + [invocation]
+ Timestamp: +
+ Branch: + + +
+ Commit: + +
+
+ +
+
- - - - - -
- Artifacts for gRPC Build -
-
-
- Build: - [invocation]
- Timestamp: -
- Branch: - - -
- Commit: - -
-
- -
-
- -

gRPC is a Cloud Native Computing Foundation project. Privacy Policy.

-

- Copyright ©  The gRPC Authors

-
-
-
- - +

gRPC is a Cloud Native Computing Foundation project. Privacy Policy.

+

+ Copyright ©  The gRPC Authors

+
+
+
+ +

gRPC protoc Plugins

- - + +

C#

- - + +

PHP

- - + +
@@ -87,24 +86,23 @@ document.write("

" + - +

Ruby

- - + +
-
- - + + From 373c5b31db9ce8dbe200ad5abbcfce70dec6a048 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 20 Aug 2018 10:55:49 -0700 Subject: [PATCH 158/546] added qps tests on bazel --- test/cpp/qps/BUILD | 43 +++--- test/cpp/qps/gen_build_yaml.py | 123 +++++++++--------- .../qps/json_run_localhost_scenario_gen.py | 34 +++++ test/cpp/qps/qps_json_driver_scenario_gen.py | 34 +++++ 4 files changed, 159 insertions(+), 75 deletions(-) create mode 100755 test/cpp/qps/json_run_localhost_scenario_gen.py create mode 100755 test/cpp/qps/qps_json_driver_scenario_gen.py diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index b958c75fc7c..988385bba5c 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -22,8 +22,8 @@ grpc_cc_library( name = "parse_json", srcs = ["parse_json.cc"], hdrs = ["parse_json.h"], - deps = ["//:grpc++"], external_deps = ["protobuf"], + deps = ["//:grpc++"], ) grpc_cc_library( @@ -31,16 +31,19 @@ grpc_cc_library( srcs = [ "client_async.cc", "client_sync.cc", + "qps_server_builder.cc", "qps_worker.cc", "server_async.cc", "server_sync.cc", - "qps_server_builder.cc", ], hdrs = [ "client.h", + "qps_server_builder.h", "qps_worker.h", "server.h", - "qps_server_builder.h", + ], + external_deps = [ + "gflags", ], deps = [ ":histogram", @@ -56,11 +59,8 @@ grpc_cc_library( "//test/core/end2end:ssl_test_data", "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", - "//test/cpp/util:test_util", "//test/cpp/util:test_config", - ], - external_deps = [ - "gflags", + "//test/cpp/util:test_util", ], ) @@ -97,15 +97,15 @@ grpc_cc_library( hdrs = [ "benchmark_config.h", ], + external_deps = [ + "gflags", + ], deps = [ ":driver_impl", ":histogram", "//:grpc++", "//src/proto/grpc/testing:control_proto", ], - external_deps = [ - "gflags", - ], ) grpc_cc_library( @@ -135,9 +135,14 @@ grpc_cc_library( deps = ["//:grpc++"], ) -grpc_cc_binary( +grpc_cc_test( name = "json_run_localhost", srcs = ["json_run_localhost.cc"], + args = [ + "--scenarios_json", + """'{"scenarios": [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_75Kqps_600channel_60Krpcs_300Breq_50Bresp", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 16, "threads_per_cq": 1, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"poisson": {"offered_load": 37500}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 50, "req_size": 300}}, "client_channels": 300, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_75Kqps_600channel_60Krpcs_300Breq_50Bresp", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 16, "threads_per_cq": 1, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"poisson": {"offered_load": 37500}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 50, "req_size": 300}}, "client_channels": 300, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}' +""", + ], deps = [ "//:gpr", "//test/core/util:gpr_test_util", @@ -157,9 +162,18 @@ grpc_cc_test( ], ) -grpc_cc_binary( +grpc_cc_test( name = "qps_json_driver", srcs = ["qps_json_driver.cc"], + args = [ + "--run_inproc", + "--scenarios_json", + """'{"scenarios": [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}' +""", + ], + external_deps = [ + "gflags", + ], deps = [ ":benchmark_config", ":driver_impl", @@ -167,14 +181,12 @@ grpc_cc_binary( "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], - external_deps = [ - "gflags", - ], ) grpc_cc_test( name = "qps_openloop_test", srcs = ["qps_openloop_test.cc"], + data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"], deps = [ ":benchmark_config", ":driver_impl", @@ -182,7 +194,6 @@ grpc_cc_test( "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], - data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"], ) grpc_cc_test( diff --git a/test/cpp/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py index 776283c25a8..fb2caf5486a 100755 --- a/test/cpp/qps/gen_build_yaml.py +++ b/test/cpp/qps/gen_build_yaml.py @@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import print_function import json import pipes import shutil @@ -68,62 +69,66 @@ def maybe_exclude_gcov(scenario_json): return ['gcov'] return [] -print yaml.dump({ - 'tests': [ - { - 'name': 'json_run_localhost', - 'shortname': 'json_run_localhost:%s' % scenario_json['name'], - 'args': ['--scenarios_json', _scenario_json_string(scenario_json, False)], - 'ci_platforms': ['linux'], - 'platforms': ['linux'], - 'flaky': False, - 'language': 'c++', - 'boringssl': True, - 'defaults': 'boringssl', - 'cpu_cost': guess_cpu(scenario_json, False), - 'exclude_configs': ['tsan', 'asan'] + maybe_exclude_gcov(scenario_json), - 'timeout_seconds': 2*60, - 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []), - 'auto_timeout_scaling': False - } - for scenario_json in scenario_config.CXXLanguage().scenarios() - if 'scalable' in scenario_json.get('CATEGORIES', []) - ] + [ - { - 'name': 'qps_json_driver', - 'shortname': 'qps_json_driver:inproc_%s' % scenario_json['name'], - 'args': ['--run_inproc', '--scenarios_json', _scenario_json_string(scenario_json, False)], - 'ci_platforms': ['linux'], - 'platforms': ['linux'], - 'flaky': False, - 'language': 'c++', - 'boringssl': True, - 'defaults': 'boringssl', - 'cpu_cost': guess_cpu(scenario_json, False), - 'exclude_configs': ['tsan', 'asan'], - 'timeout_seconds': 6*60, - 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []) - } - for scenario_json in scenario_config.CXXLanguage().scenarios() - if 'inproc' in scenario_json.get('CATEGORIES', []) - ] + [ - { - 'name': 'json_run_localhost', - 'shortname': 'json_run_localhost:%s_low_thread_count' % scenario_json['name'], - 'args': ['--scenarios_json', _scenario_json_string(scenario_json, True)], - 'ci_platforms': ['linux'], - 'platforms': ['linux'], - 'flaky': False, - 'language': 'c++', - 'boringssl': True, - 'defaults': 'boringssl', - 'cpu_cost': guess_cpu(scenario_json, True), - 'exclude_configs': sorted(c for c in configs_from_yaml if c not in ('tsan', 'asan')), - 'timeout_seconds': 10*60, - 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []), - 'auto_timeout_scaling': False - } - for scenario_json in scenario_config.CXXLanguage().scenarios() - if 'scalable' in scenario_json.get('CATEGORIES', []) - ] -}) +def generate_yaml(): + return { + 'tests': [ + { + 'name': 'json_run_localhost', + 'shortname': 'json_run_localhost:%s' % scenario_json['name'], + 'args': ['--scenarios_json', _scenario_json_string(scenario_json, False)], + 'ci_platforms': ['linux'], + 'platforms': ['linux'], + 'flaky': False, + 'language': 'c++', + 'boringssl': True, + 'defaults': 'boringssl', + 'cpu_cost': guess_cpu(scenario_json, False), + 'exclude_configs': ['tsan', 'asan'] + maybe_exclude_gcov(scenario_json), + 'timeout_seconds': 2*60, + 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []), + 'auto_timeout_scaling': False + } + for scenario_json in scenario_config.CXXLanguage().scenarios() + if 'scalable' in scenario_json.get('CATEGORIES', []) + ] + [ + { + 'name': 'qps_json_driver', + 'shortname': 'qps_json_driver:inproc_%s' % scenario_json['name'], + 'args': ['--run_inproc', '--scenarios_json', _scenario_json_string(scenario_json, False)], + 'ci_platforms': ['linux'], + 'platforms': ['linux'], + 'flaky': False, + 'language': 'c++', + 'boringssl': True, + 'defaults': 'boringssl', + 'cpu_cost': guess_cpu(scenario_json, False), + 'exclude_configs': ['tsan', 'asan'], + 'timeout_seconds': 6*60, + 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []) + } + for scenario_json in scenario_config.CXXLanguage().scenarios() + if 'inproc' in scenario_json.get('CATEGORIES', []) + ] + [ + { + 'name': 'json_run_localhost', + 'shortname': 'json_run_localhost:%s_low_thread_count' % scenario_json['name'], + 'args': ['--scenarios_json', _scenario_json_string(scenario_json, True)], + 'ci_platforms': ['linux'], + 'platforms': ['linux'], + 'flaky': False, + 'language': 'c++', + 'boringssl': True, + 'defaults': 'boringssl', + 'cpu_cost': guess_cpu(scenario_json, True), + 'exclude_configs': sorted(c for c in configs_from_yaml if c not in ('tsan', 'asan')), + 'timeout_seconds': 10*60, + 'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []), + 'auto_timeout_scaling': False + } + for scenario_json in scenario_config.CXXLanguage().scenarios() + if 'scalable' in scenario_json.get('CATEGORIES', []) + ] + } + + +print(yaml.dump(generate_yaml())) \ No newline at end of file diff --git a/test/cpp/qps/json_run_localhost_scenario_gen.py b/test/cpp/qps/json_run_localhost_scenario_gen.py new file mode 100755 index 00000000000..82b2932f3f1 --- /dev/null +++ b/test/cpp/qps/json_run_localhost_scenario_gen.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python2.7 + +# 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. + +import gen_build_yaml as gen +import json + +def generate_args(): + all_scenario_set = gen.generate_yaml() + all_scenario_set = all_scenario_set['tests'] + qps_json_driver_scenario_set = \ + [item for item in all_scenario_set if item['name'] == 'json_run_localhost'] + qps_json_driver_arg_set = \ + [item['args'][1] for item in qps_json_driver_scenario_set \ + if 'args' in item and len(item['args']) > 1] + deserialized_scenarios = [json.loads(item)['scenarios'][0] \ + for item in qps_json_driver_arg_set] + all_scenarios = {'scenarios': deserialized_scenarios} + print('\'' + json.dumps(all_scenarios) + '\'') + + +generate_args() diff --git a/test/cpp/qps/qps_json_driver_scenario_gen.py b/test/cpp/qps/qps_json_driver_scenario_gen.py new file mode 100755 index 00000000000..99bc3828f84 --- /dev/null +++ b/test/cpp/qps/qps_json_driver_scenario_gen.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python2.7 + +# 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. + +import gen_build_yaml as gen +import json + +def generate_args(): + all_scenario_set = gen.generate_yaml() + all_scenario_set = all_scenario_set['tests'] + qps_json_driver_scenario_set = \ + [item for item in all_scenario_set if item['name'] == 'qps_json_driver'] + qps_json_driver_arg_set = \ + [item['args'][2] for item in qps_json_driver_scenario_set \ + if 'args' in item and len(item['args']) > 2] + deserialized_scenarios = [json.loads(item)['scenarios'][0] \ + for item in qps_json_driver_arg_set] + all_scenarios = {'scenarios': deserialized_scenarios} + print('\'' + json.dumps(all_scenarios) + '\'') + + +generate_args() From ba4f66e705d149a4f30993befb4d6d5825b13841 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 20 Aug 2018 12:30:28 -0700 Subject: [PATCH 159/546] Allow more timing slack in dns cooldown test. --- .../client_channel/resolvers/dns_resolver_cooldown_test.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc index 27de7cac958..1a7db40f598 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -29,6 +29,8 @@ #include "test/core/util/test_config.h" constexpr int kMinResolutionPeriodMs = 1000; +// Provide some slack when checking intervals, to allow for test timing issues. +constexpr int kMinResolutionPeriodForCheckMs = 900; extern grpc_address_resolver_vtable* grpc_resolve_address_impl; static grpc_address_resolver_vtable* default_resolve_address; @@ -70,7 +72,7 @@ static void test_resolve_address_impl(const char* name, } else { grpc_millis now = grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); - GPR_ASSERT(now - last_resolution_time >= kMinResolutionPeriodMs); + GPR_ASSERT(now - last_resolution_time >= kMinResolutionPeriodForCheckMs); last_resolution_time = now; } } @@ -96,11 +98,12 @@ static grpc_ares_request* test_dns_lookup_ares_locked( ++g_resolution_count; static grpc_millis last_resolution_time = 0; if (last_resolution_time == 0) { + last_resolution_time = grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); } else { grpc_millis now = grpc_timespec_to_millis_round_up(gpr_now(GPR_CLOCK_MONOTONIC)); - GPR_ASSERT(now - last_resolution_time >= kMinResolutionPeriodMs); + GPR_ASSERT(now - last_resolution_time >= kMinResolutionPeriodForCheckMs); last_resolution_time = now; } return result; From 4312d1217ec6cb4ab5b7104ebd9a43f404b17462 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 20 Aug 2018 13:10:22 -0700 Subject: [PATCH 160/546] clang-format --- test/cpp/end2end/client_lb_end2end_test.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 6ccf16aaa13..e5d6132012a 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -139,9 +139,7 @@ class ClientLbEnd2endTest : public ::testing::Test { } } - void StartServer(size_t index) { - servers_[index]->Start(server_host_); - } + void StartServer(size_t index) { servers_[index]->Start(server_host_); } void StartServers(size_t num_servers, std::vector ports = std::vector()) { From 461c910a8ca883d5cabc4f9879f51840a9c99c3c Mon Sep 17 00:00:00 2001 From: ZhouyihaiDing Date: Mon, 20 Aug 2018 16:28:17 -0700 Subject: [PATCH 161/546] PHP: fix failed test 16392 --- .../PersistentChannelTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/php/tests/unit_tests/PersistentChannelTests/PersistentChannelTest.php b/src/php/tests/unit_tests/PersistentChannelTests/PersistentChannelTest.php index 7515a012334..5423368cdf5 100644 --- a/src/php/tests/unit_tests/PersistentChannelTests/PersistentChannelTest.php +++ b/src/php/tests/unit_tests/PersistentChannelTests/PersistentChannelTest.php @@ -270,7 +270,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase public function testPersistentChannelDefaultOutBound1() { - $this->channel1 = new Grpc\Channel('localhost:10011', []); + $this->channel1 = new Grpc\Channel('localhost:10004', []); // Make channel1 not IDLE. $this->channel1->getConnectivityState(true); $this->waitUntilNotIdle($this->channel1); @@ -280,7 +280,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase // Since channel1 is CONNECTING, channel 2 will not be persisted $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); - $this->channel2 = new Grpc\Channel('localhost:10011', + $this->channel2 = new Grpc\Channel('localhost:10004', ['credentials' => $channel_credentials]); $channel2_info = $this->channel2->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel2_info['connectivity_status']); @@ -295,7 +295,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase public function testPersistentChannelDefaultOutBound2() { - $this->channel1 = new Grpc\Channel('localhost:10011', []); + $this->channel1 = new Grpc\Channel('localhost:10005', []); $channel1_info = $this->channel1->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel1_info['connectivity_status']); @@ -303,7 +303,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase // gRPC channel. channel2 will not be persisted $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); - $this->channel2 = new Grpc\Channel('localhost:10011', + $this->channel2 = new Grpc\Channel('localhost:10005', ['credentials' => $channel_credentials]); $channel2_info = $this->channel2->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel2_info['connectivity_status']); @@ -318,7 +318,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase public function testPersistentChannelDefaultOutBound3() { - $this->channel1 = new Grpc\Channel('localhost:10011', []); + $this->channel1 = new Grpc\Channel('localhost:10006', []); $channel1_info = $this->channel1->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel1_info['connectivity_status']); @@ -327,7 +327,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase // channel2 can be persisted. $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); - $this->channel2 = new Grpc\Channel('localhost:10011', + $this->channel2 = new Grpc\Channel('localhost:10006', ['credentials' => $channel_credentials]); $channel2_info = $this->channel2->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel2_info['connectivity_status']); @@ -342,7 +342,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase public function testPersistentChannelTwoUpperBound() { - $this->channel1 = new Grpc\Channel('localhost:10011', [ + $this->channel1 = new Grpc\Channel('localhost:10007', [ "grpc_target_persist_bound" => 2, ]); $channel1_info = $this->channel1->getChannelInfo(); @@ -351,7 +351,7 @@ class PersistentListTest extends PHPUnit_Framework_TestCase // Since channel1 is IDLE, channel 1 will be deleted $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, null); - $this->channel2 = new Grpc\Channel('localhost:10011', + $this->channel2 = new Grpc\Channel('localhost:10007', ['credentials' => $channel_credentials]); $channel2_info = $this->channel2->getChannelInfo(); $this->assertEquals(GRPC\CHANNEL_IDLE, $channel2_info['connectivity_status']); From 22d8e60bdb7a9410023b019c277dcf5b2ee42651 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 21 Aug 2018 13:59:31 +0200 Subject: [PATCH 162/546] improve BUILDING.md --- BUILDING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/BUILDING.md b/BUILDING.md index e408402a766..81edb68e435 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -103,6 +103,9 @@ repository at the latest stable version. In the C++ world, there's no "standard" build system that would work for in all supported use cases and on all supported platforms. Therefore, gRPC supports several major build systems, which should satisfy most users. +Note that this section only covers the build of gRPC itself, not the installation. See the [How to use](https://github.com/grpc/grpc/tree/master/src/cpp#to-start-using-grpc-c) instructions +for guidance on how to add gRPC as a dependency to a C++ application (there are several ways and system wide installation is often not the best choice). + ## make (on UNIX systems) From the grpc repository root From 9e515951ac422faec2699fd8c7d75e7dfed6e377 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 17 Aug 2018 15:47:03 -0700 Subject: [PATCH 163/546] size_t shouldn't have the value -1; switch to int --- src/core/lib/transport/service_config.cc | 4 ++-- src/core/lib/transport/service_config.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/lib/transport/service_config.cc b/src/core/lib/transport/service_config.cc index e1a55d98ab7..405e3360287 100644 --- a/src/core/lib/transport/service_config.cc +++ b/src/core/lib/transport/service_config.cc @@ -65,8 +65,8 @@ const char* ServiceConfig::GetLoadBalancingPolicyName() const { return lb_policy_name; } -size_t ServiceConfig::CountNamesInMethodConfig(grpc_json* json) { - size_t num_names = 0; +int ServiceConfig::CountNamesInMethodConfig(grpc_json* json) { + int num_names = 0; for (grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key != nullptr && strcmp(field->key, "name") == 0) { if (field->type != GRPC_JSON_ARRAY) return -1; diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h index a65b267d461..2c0dd758453 100644 --- a/src/core/lib/transport/service_config.h +++ b/src/core/lib/transport/service_config.h @@ -103,7 +103,7 @@ class ServiceConfig { ServiceConfig(UniquePtr 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); + static int CountNamesInMethodConfig(grpc_json* json); // Returns a path string for the JSON name object specified by \a json. // Returns null on error. @@ -188,9 +188,9 @@ ServiceConfig::CreateMethodConfigTable(CreateValue create_value) { // Find number of entries. for (grpc_json* method = field->child; method != nullptr; method = method->next) { - size_t count = CountNamesInMethodConfig(method); + int count = CountNamesInMethodConfig(method); if (count <= 0) return nullptr; - num_entries += count; + num_entries += static_cast(count); } // Populate method config table entries. entries = static_cast>::Entry*>( From 72695b886e3064cc846e3fe391d63e4fc21f5623 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 21 Aug 2018 08:51:19 -0700 Subject: [PATCH 164/546] Add an inproc-based non-polling test of core callback API --- CMakeLists.txt | 30 ++ Makefile | 36 ++ build.yaml | 13 + test/core/end2end/BUILD | 13 + test/core/end2end/inproc_callback_test.cc | 462 ++++++++++++++++++ .../generated/sources_and_headers.json | 20 + tools/run_tests/generated/tests.json | 24 + 7 files changed, 598 insertions(+) create mode 100644 test/core/end2end/inproc_callback_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 32d7a9b94d3..a330fefc272 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,6 +331,7 @@ if(_gRPC_PLATFORM_LINUX) add_dependencies(buildtests_c httpscli_test) endif() add_dependencies(buildtests_c init_test) +add_dependencies(buildtests_c inproc_callback_test) add_dependencies(buildtests_c invalid_call_argument_test) add_dependencies(buildtests_c json_rewrite) add_dependencies(buildtests_c json_rewrite_test) @@ -7893,6 +7894,35 @@ target_link_libraries(init_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(inproc_callback_test + test/core/end2end/inproc_callback_test.cc +) + + +target_include_directories(inproc_callback_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 ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(inproc_callback_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr_test_util + gpr +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(invalid_call_argument_test test/core/end2end/invalid_call_argument_test.cc ) diff --git a/Makefile b/Makefile index 3454ef85870..e9a9486a3cc 100644 --- a/Makefile +++ b/Makefile @@ -1053,6 +1053,7 @@ httpcli_format_request_test: $(BINDIR)/$(CONFIG)/httpcli_format_request_test httpcli_test: $(BINDIR)/$(CONFIG)/httpcli_test httpscli_test: $(BINDIR)/$(CONFIG)/httpscli_test init_test: $(BINDIR)/$(CONFIG)/init_test +inproc_callback_test: $(BINDIR)/$(CONFIG)/inproc_callback_test invalid_call_argument_test: $(BINDIR)/$(CONFIG)/invalid_call_argument_test json_fuzzer_test: $(BINDIR)/$(CONFIG)/json_fuzzer_test json_rewrite: $(BINDIR)/$(CONFIG)/json_rewrite @@ -1500,6 +1501,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/httpcli_test \ $(BINDIR)/$(CONFIG)/httpscli_test \ $(BINDIR)/$(CONFIG)/init_test \ + $(BINDIR)/$(CONFIG)/inproc_callback_test \ $(BINDIR)/$(CONFIG)/invalid_call_argument_test \ $(BINDIR)/$(CONFIG)/json_rewrite \ $(BINDIR)/$(CONFIG)/json_rewrite_test \ @@ -2076,6 +2078,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/httpscli_test || ( echo test httpscli_test failed ; exit 1 ) $(E) "[RUN] Testing init_test" $(Q) $(BINDIR)/$(CONFIG)/init_test || ( echo test init_test failed ; exit 1 ) + $(E) "[RUN] Testing inproc_callback_test" + $(Q) $(BINDIR)/$(CONFIG)/inproc_callback_test || ( echo test inproc_callback_test failed ; exit 1 ) $(E) "[RUN] Testing invalid_call_argument_test" $(Q) $(BINDIR)/$(CONFIG)/invalid_call_argument_test || ( echo test invalid_call_argument_test failed ; exit 1 ) $(E) "[RUN] Testing json_rewrite_test" @@ -13115,6 +13119,38 @@ endif endif +INPROC_CALLBACK_TEST_SRC = \ + test/core/end2end/inproc_callback_test.cc \ + +INPROC_CALLBACK_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INPROC_CALLBACK_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/inproc_callback_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/inproc_callback_test: $(INPROC_CALLBACK_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) $(INPROC_CALLBACK_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)/inproc_callback_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/end2end/inproc_callback_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_inproc_callback_test: $(INPROC_CALLBACK_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(INPROC_CALLBACK_TEST_OBJS:.o=.dep) +endif +endif + + INVALID_CALL_ARGUMENT_TEST_SRC = \ test/core/end2end/invalid_call_argument_test.cc \ diff --git a/build.yaml b/build.yaml index 34bec009336..bf119cd71b2 100644 --- a/build.yaml +++ b/build.yaml @@ -3016,6 +3016,19 @@ targets: - gpr_test_util - gpr uses_polling: false +- name: inproc_callback_test + build: test + language: c + headers: + - test/core/end2end/end2end_tests.h + src: + - test/core/end2end/inproc_callback_test.cc + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr + uses_polling: false - name: invalid_call_argument_test cpu_cost: 0.1 build: test diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index dd16694204a..37999a98d1e 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -123,6 +123,19 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "inproc_callback_test", + srcs = ["inproc_callback_test.cc"], + language = "C++", + deps = [ + ':end2end_tests', + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "invalid_call_argument_test", srcs = ["invalid_call_argument_test.cc"], diff --git a/test/core/end2end/inproc_callback_test.cc b/test/core/end2end/inproc_callback_test.cc new file mode 100644 index 00000000000..05257dd4bf5 --- /dev/null +++ b/test/core/end2end/inproc_callback_test.cc @@ -0,0 +1,462 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include + +#include +#include +#include + +#include "src/core/ext/transport/inproc/inproc_transport.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/completion_queue.h" +#include "src/core/lib/surface/server.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +typedef struct inproc_fixture_data { + bool dummy; // reserved for future expansion. Struct can't be empty +} inproc_fixture_data; + +namespace { +template +class CQDeletingCallback : public grpc_core::CQCallbackInterface { + public: + explicit CQDeletingCallback(F f) : func_(f) {} + ~CQDeletingCallback() override {} + void Run(bool ok) override { + func_(ok); + grpc_core::Delete(this); + } + + private: + F func_; +}; + +template +grpc_core::CQCallbackInterface* NewDeletingCallback(F f) { + return grpc_core::New>(f); +} + +class ShutdownCallback : public grpc_core::CQCallbackInterface { + public: + ShutdownCallback() : done_(false) { + gpr_mu_init(&mu_); + gpr_cv_init(&cv_); + } + ~ShutdownCallback() override {} + void Run(bool ok) override { + gpr_log(GPR_DEBUG, "CQ shutdown notification invoked"); + gpr_mu_lock(&mu_); + done_ = true; + gpr_cv_broadcast(&cv_); + gpr_mu_unlock(&mu_); + } + void Wait(gpr_timespec deadline) { + gpr_mu_lock(&mu_); + while (!done_ && !gpr_cv_wait(&cv_, &mu_, deadline)) { + } + gpr_mu_unlock(&mu_); + } + + private: + bool done_; + gpr_mu mu_; + gpr_cv cv_; +}; + +ShutdownCallback* g_shutdown_callback; +} // namespace + +static gpr_mu tags_mu; +static gpr_cv tags_cv; +const size_t kAvailableTags = 4; +bool tags[kAvailableTags]; +bool tags_valid[kAvailableTags]; +bool tags_expected[kAvailableTags]; +bool tags_needed[kAvailableTags]; + +static void expect_tag(intptr_t tag, bool ok) { + size_t idx = static_cast(tag); + GPR_ASSERT(idx < kAvailableTags); + tags_needed[idx] = true; + tags_expected[idx] = ok; +} + +static void verify_tags(gpr_timespec deadline) { + bool done = false; + + gpr_mu_lock(&tags_mu); + while (!done) { + done = gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), deadline) > 0; + for (size_t i = 0; i < kAvailableTags; i++) { + if (tags_needed[i]) { + if (tags_valid[i]) { + gpr_log(GPR_DEBUG, "Verifying tag %d", static_cast(i)); + if (tags[i] != tags_expected[i]) { + gpr_log(GPR_ERROR, "Got wrong result (%d instead of %d) for tag %d", + tags[i], tags_expected[i], static_cast(i)); + } + tags_valid[i] = false; + tags_needed[i] = false; + } else if (done) { + gpr_log(GPR_ERROR, "Didn't get tag %d", static_cast(i)); + } + } + } + bool empty = true; + for (size_t i = 0; i < kAvailableTags; i++) { + if (tags_needed[i]) { + empty = false; + } + } + done = done || empty; + if (done) { + for (size_t i = 0; i < kAvailableTags; i++) { + if (tags_valid[i]) { + gpr_log(GPR_ERROR, "Got unexpected tag %d and result %d", + static_cast(i), tags[i]); + } + tags_valid[i] = false; + } + } else { + gpr_cv_wait(&tags_cv, &tags_mu, deadline); + } + } + gpr_mu_unlock(&tags_mu); +} + +static grpc_end2end_test_fixture inproc_create_fixture( + grpc_channel_args* client_args, grpc_channel_args* server_args) { + grpc_end2end_test_fixture f; + inproc_fixture_data* ffd = static_cast( + gpr_malloc(sizeof(inproc_fixture_data))); + memset(&f, 0, sizeof(f)); + + f.fixture_data = ffd; + g_shutdown_callback = grpc_core::New(); + f.cq = + grpc_completion_queue_create_for_callback(g_shutdown_callback, nullptr); + f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); + + return f; +} + +void inproc_init_client(grpc_end2end_test_fixture* f, + grpc_channel_args* client_args) { + f->client = grpc_inproc_channel_create(f->server, client_args, nullptr); + GPR_ASSERT(f->client); +} + +void inproc_init_server(grpc_end2end_test_fixture* f, + grpc_channel_args* server_args) { + if (f->server) { + grpc_server_destroy(f->server); + } + f->server = grpc_server_create(server_args, nullptr); + grpc_server_register_completion_queue(f->server, f->cq, nullptr); + grpc_server_start(f->server); +} + +void inproc_tear_down(grpc_end2end_test_fixture* f) { + inproc_fixture_data* ffd = static_cast(f->fixture_data); + gpr_free(ffd); +} + +static grpc_core::CQCallbackInterface* tag(intptr_t t) { + auto func = [t](bool ok) { + gpr_mu_lock(&tags_mu); + gpr_log(GPR_DEBUG, "Completing operation %" PRIdPTR, t); + bool was_empty = true; + for (size_t i = 0; i < kAvailableTags; i++) { + if (tags_valid[i]) { + was_empty = false; + } + } + size_t idx = static_cast(t); + tags[idx] = ok; + tags_valid[idx] = true; + if (was_empty) { + gpr_cv_signal(&tags_cv); + } + gpr_mu_unlock(&tags_mu); + }; + auto cb = NewDeletingCallback(func); + return cb; +} + +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() { return n_seconds_from_now(5); } + +static void drain_cq(grpc_completion_queue* cq) { + g_shutdown_callback->Wait(five_seconds_from_now()); + gpr_log(GPR_DEBUG, "CQ shutdown wait complete"); + grpc_core::Delete(g_shutdown_callback); +} + +static void shutdown_server(grpc_end2end_test_fixture* f) { + if (!f->server) return; + grpc_server_shutdown_and_notify( + f->server, f->shutdown_cq, + reinterpret_cast(static_cast(1000))); + GPR_ASSERT( + grpc_completion_queue_pluck(f->shutdown_cq, (void*)((intptr_t)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); +} + +static void simple_request_body(grpc_end2end_test_config config, + grpc_end2end_test_fixture f) { + 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_status_code status; + const char* error_string; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + char* peer; + 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("/foo"), nullptr, + 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); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->data.recv_status_on_client.error_string = &error_string; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast(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(2)); + GPR_ASSERT(GRPC_CALL_OK == error); + expect_tag(2, true); + verify_tags(deadline); + + 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->flags = 0; + op->reserved = nullptr; + 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_UNIMPLEMENTED; + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + op->data.send_status_from_server.status_details = &status_details; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(3), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + expect_tag(3, true); + expect_tag(1, true); + verify_tags(deadline); + + GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); + // the following sanity check makes sure that the requested error string is + // correctly populated by the core. It looks for certain substrings that are + // not likely to change much. Some parts of the error, like time created, + // obviously are not checked. + GPR_ASSERT(nullptr != strstr(error_string, "xyz")); + GPR_ASSERT(nullptr != strstr(error_string, "description")); + GPR_ASSERT(nullptr != strstr(error_string, "Error received from peer")); + GPR_ASSERT(nullptr != strstr(error_string, "grpc_message")); + GPR_ASSERT(nullptr != strstr(error_string, "grpc_status")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + grpc_slice_unref(details); + gpr_free(static_cast(const_cast(error_string))); + 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_call_unref(c); + grpc_call_unref(s); + + int expected_calls = 1; + if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) { + expected_calls *= 2; + } +} + +static void test_invoke_simple_request(grpc_end2end_test_config config) { + grpc_end2end_test_fixture f; + + f = begin_test(config, "test_invoke_simple_request", nullptr, nullptr); + simple_request_body(config, f); + end_test(&f); + config.tear_down_data(&f); +} + +static void test_invoke_10_simple_requests(grpc_end2end_test_config config) { + int i; + grpc_end2end_test_fixture f = + begin_test(config, "test_invoke_10_simple_requests", nullptr, nullptr); + for (i = 0; i < 10; i++) { + simple_request_body(config, f); + gpr_log(GPR_INFO, "Running test: Passed simple request %d", i); + } + end_test(&f); + config.tear_down_data(&f); +} + +static void test_invoke_many_simple_requests(grpc_end2end_test_config config) { + int i; + const int many = 1000; + grpc_end2end_test_fixture f = + begin_test(config, "test_invoke_many_simple_requests", nullptr, nullptr); + gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); + for (i = 0; i < many; i++) { + simple_request_body(config, f); + } + double us = + gpr_timespec_to_micros(gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), t1)) / + many; + gpr_log(GPR_INFO, "Time per ping %f us", us); + end_test(&f); + config.tear_down_data(&f); +} + +static void simple_request(grpc_end2end_test_config config) { + int i; + for (i = 0; i < 10; i++) { + test_invoke_simple_request(config); + } + test_invoke_10_simple_requests(config); + test_invoke_many_simple_requests(config); +} + +static void simple_request_pre_init() { + gpr_mu_init(&tags_mu); + gpr_cv_init(&tags_cv); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"inproc-callback", FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, nullptr, + inproc_create_fixture, inproc_init_client, inproc_init_server, + inproc_tear_down}, +}; + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + + simple_request_pre_init(); + simple_request(configs[0]); + + grpc_shutdown(); + + return 0; +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index bff045f7860..3a7db7d1077 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -1410,6 +1410,26 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [ + "test/core/end2end/end2end_tests.h" + ], + "is_filegroup": false, + "language": "c", + "name": "inproc_callback_test", + "src": [ + "test/core/end2end/end2end_tests.h", + "test/core/end2end/inproc_callback_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index a51be28ad51..51c7b57d8ae 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -1697,6 +1697,30 @@ ], "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": "inproc_callback_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, From 7132cd7164198855347ae21332e104b8f4e15700 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 21 Aug 2018 18:01:53 +0200 Subject: [PATCH 165/546] cmake: disable assembly optimizations only when necessary --- cmake/ssl.cmake | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake index 83f642a6754..19a7d779b35 100644 --- a/cmake/ssl.cmake +++ b/cmake/ssl.cmake @@ -17,7 +17,14 @@ if("${gRPC_SSL_PROVIDER}" STREQUAL "module") set(BORINGSSL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/boringssl) endif() if(EXISTS "${BORINGSSL_ROOT_DIR}/CMakeLists.txt") - set(OPENSSL_NO_ASM ON) # make boringssl buildable with Visual Studio + if (MSVC AND NOT CMAKE_GENERATOR STREQUAL "Ninja") + # Visual Studio build with assembly optimizations is broken, + # but it works with Ninja generator. + # This will get eventually fixed in cmake, but until then + # we need to disable assembly optimizations. + # See https://github.com/grpc/grpc/issues/16376 + set(OPENSSL_NO_ASM ON) + endif() add_subdirectory(${BORINGSSL_ROOT_DIR} third_party/boringssl) if(TARGET ssl) set(_gRPC_SSL_LIBRARIES ssl) From 1096fa81a41c58d40e88a29e4ca20613a4276e6b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 21 Aug 2018 18:28:07 +0200 Subject: [PATCH 166/546] update ssl-performance.md --- doc/ssl-performance.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/ssl-performance.md b/doc/ssl-performance.md index 176c8d8f247..711b9dff095 100644 --- a/doc/ssl-performance.md +++ b/doc/ssl-performance.md @@ -14,7 +14,9 @@ Makefile | all other cases | all | :x: Bazel | | Linux | :heavy_check_mark: Bazel | | MacOS | :heavy_check_mark: Bazel | | Windows | :x: -CMake | boringssl from submodule (default) | all | :x: +CMake | boringssl from submodule (default) | Linux or MacOS | :heavy_check_mark: +CMake | boringssl from submodule (default), generator=Ninja | Windows | :heavy_check_mark: +CMake | boringssl from submodule (default), generator=Visual Studio | Windows | :x: CMake | pre-installed OpenSSL 1.0.2+ (`gRPC_SSL_PROVIDER=package`) | all | :heavy_check_mark: ## Other Languages: Binary/Source Packages From 91cb48ad1aef109633365cd156e8482011c74b51 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 26 Jul 2018 11:06:24 -0700 Subject: [PATCH 167/546] Add timer tests for long running services --- src/core/lib/iomgr/exec_ctx.cc | 6 ++ src/core/lib/iomgr/exec_ctx.h | 2 + src/core/lib/iomgr/timer.h | 5 +- test/core/iomgr/timer_list_test.cc | 111 ++++++++++++++++++++++++++--- 4 files changed, 113 insertions(+), 11 deletions(-) diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc index 5d5c355ff98..d68fa0714bf 100644 --- a/src/core/lib/iomgr/exec_ctx.cc +++ b/src/core/lib/iomgr/exec_ctx.cc @@ -109,6 +109,12 @@ grpc_closure_scheduler* grpc_schedule_on_exec_ctx = &exec_ctx_scheduler; namespace grpc_core { GPR_TLS_CLASS_DEF(ExecCtx::exec_ctx_); +// WARNING: for testing purposes only! +void ExecCtx::TestOnlyGlobalInit(gpr_timespec new_val) { + g_start_time = new_val; + gpr_tls_init(&exec_ctx_); +} + void ExecCtx::GlobalInit(void) { g_start_time = gpr_now(GPR_CLOCK_MONOTONIC); gpr_tls_init(&exec_ctx_); diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index 8ddab0d3810..f3528d527ac 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -192,6 +192,8 @@ class ExecCtx { now_is_valid_ = true; } + static void TestOnlyGlobalInit(gpr_timespec new_val); + /** Global initialization for ExecCtx. Called by iomgr. */ static void GlobalInit(void); diff --git a/src/core/lib/iomgr/timer.h b/src/core/lib/iomgr/timer.h index 7f534476df2..17e933b8658 100644 --- a/src/core/lib/iomgr/timer.h +++ b/src/core/lib/iomgr/timer.h @@ -61,10 +61,11 @@ typedef struct grpc_timer_vtable { /* Initialize *timer. When expired or canceled, closure will be called with error set to indicate if it expired (GRPC_ERROR_NONE) or was canceled - (GRPC_ERROR_CANCELLED). timer_cb is guaranteed to be called exactly once, and + (GRPC_ERROR_CANCELLED). *closure is guaranteed to be called exactly once, and application code should check the error to determine how it was invoked. The application callback is also responsible for maintaining information about - when to free up any user-level state. */ + when to free up any user-level state. Behavior is undefined for a deadline of + GRPC_MILLIS_INF_FUTURE. */ void grpc_timer_init(grpc_timer* timer, grpc_millis deadline, grpc_closure* closure); diff --git a/test/core/iomgr/timer_list_test.cc b/test/core/iomgr/timer_list_test.cc index b1d919b292f..fd65d1abf1f 100644 --- a/test/core/iomgr/timer_list_test.cc +++ b/test/core/iomgr/timer_list_test.cc @@ -38,6 +38,8 @@ extern grpc_core::TraceFlag grpc_timer_trace; extern grpc_core::TraceFlag grpc_timer_check_trace; static int cb_called[MAX_CB][2]; +static const int64_t kMillisIn25Days = 2160000000; +static const int64_t kHoursIn25Days = 600; static void cb(void* arg, grpc_error* error) { cb_called[(intptr_t)arg][error == GRPC_ERROR_NONE]++; @@ -151,17 +153,108 @@ void destruction_test(void) { GPR_ASSERT(1 == cb_called[2][0]); } -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - grpc_core::ExecCtx::GlobalInit(); +/* Cleans up a list with pending timers that simulate long-running-services. + This test does the following: + 1) Simulates grpc server start time to 25 days in the past (completed in + `main` using TestOnlyGlobalInit()) + 2) Creates 4 timers - one with a deadline 25 days in the future, one just + 3 milliseconds in future, one way out in the future, and one using the + grpc_timespec_to_millis_round_up function to compute a deadline of 25 + days in the future + 3) Simulates 4 milliseconds of elapsed time by changing `now` (cached at + step 1) to `now+4` + 4) Shuts down the timer list + https://github.com/grpc/grpc/issues/15904 */ +void long_running_service_cleanup_test(void) { + grpc_timer timers[4]; grpc_core::ExecCtx exec_ctx; - grpc_determine_iomgr_platform(); - grpc_iomgr_platform_init(); - gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); - add_test(); - destruction_test(); - grpc_iomgr_platform_shutdown(); + + gpr_log(GPR_INFO, "long_running_service_cleanup_test"); + + grpc_millis now = grpc_core::ExecCtx::Get()->Now(); + GPR_ASSERT(now >= kMillisIn25Days); + grpc_timer_list_init(); + grpc_core::testing::grpc_tracer_enable_flag(&grpc_timer_trace); + grpc_core::testing::grpc_tracer_enable_flag(&grpc_timer_check_trace); + memset(cb_called, 0, sizeof(cb_called)); + + grpc_timer_init( + &timers[0], now + kMillisIn25Days, + GRPC_CLOSURE_CREATE(cb, (void*)(intptr_t)0, grpc_schedule_on_exec_ctx)); + grpc_timer_init( + &timers[1], now + 3, + GRPC_CLOSURE_CREATE(cb, (void*)(intptr_t)1, grpc_schedule_on_exec_ctx)); + grpc_timer_init( + &timers[2], GRPC_MILLIS_INF_FUTURE - 1, + GRPC_CLOSURE_CREATE(cb, (void*)(intptr_t)2, grpc_schedule_on_exec_ctx)); + + gpr_timespec deadline_spec = grpc_millis_to_timespec( + now + kMillisIn25Days, gpr_clock_type::GPR_CLOCK_MONOTONIC); + + /* grpc_timespec_to_millis_round_up is how users usually compute a millisecond + input value into grpc_timer_init, so we mimic that behavior here */ + grpc_timer_init( + &timers[3], grpc_timespec_to_millis_round_up(deadline_spec), + GRPC_CLOSURE_CREATE(cb, (void*)(intptr_t)3, grpc_schedule_on_exec_ctx)); + + grpc_core::ExecCtx::Get()->TestOnlySetNow(now + 4); + GPR_ASSERT(grpc_timer_check(nullptr) == GRPC_TIMERS_FIRED); + grpc_core::ExecCtx::Get()->Flush(); + GPR_ASSERT(0 == cb_called[0][0]); // Timer 0 not called + GPR_ASSERT(0 == cb_called[0][1]); + GPR_ASSERT(0 == cb_called[1][0]); + GPR_ASSERT(1 == cb_called[1][1]); // Timer 1 fired + GPR_ASSERT(0 == cb_called[2][0]); // Timer 2 not called + GPR_ASSERT(0 == cb_called[2][1]); + GPR_ASSERT(0 == cb_called[3][0]); // Timer 3 not called + GPR_ASSERT(0 == cb_called[3][1]); + + grpc_timer_list_shutdown(); + grpc_core::ExecCtx::Get()->Flush(); + /* Timers 0, 2, and 3 were fired with an error during cleanup */ + GPR_ASSERT(1 == cb_called[0][0]); + GPR_ASSERT(0 == cb_called[1][0]); + GPR_ASSERT(1 == cb_called[2][0]); + GPR_ASSERT(1 == cb_called[3][0]); +} + +int main(int argc, char** argv) { + /* Tests with default g_start_time */ + { + grpc_test_init(argc, argv); + grpc_core::ExecCtx::GlobalInit(); + grpc_core::ExecCtx exec_ctx; + grpc_determine_iomgr_platform(); + grpc_iomgr_platform_init(); + gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); + add_test(); + destruction_test(); + grpc_iomgr_platform_shutdown(); + } grpc_core::ExecCtx::GlobalShutdown(); + + /* Begin long running service tests */ + { + grpc_test_init(argc, argv); + /* Set g_start_time back 25 days. */ + /* We set g_start_time here in case there are any initialization + dependencies that use g_start_time. */ + gpr_timespec new_start = + gpr_time_sub(gpr_now(gpr_clock_type::GPR_CLOCK_MONOTONIC), + gpr_time_from_hours(kHoursIn25Days, + gpr_clock_type::GPR_CLOCK_MONOTONIC)); + grpc_core::ExecCtx::TestOnlyGlobalInit(new_start); + grpc_core::ExecCtx exec_ctx; + grpc_determine_iomgr_platform(); + grpc_iomgr_platform_init(); + gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); + long_running_service_cleanup_test(); + add_test(); + destruction_test(); + grpc_iomgr_platform_shutdown(); + } + grpc_core::ExecCtx::GlobalShutdown(); + return 0; } From 85ff14dd16524b408bd30eb76d790be126aebb90 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 21 Aug 2018 10:11:53 -0700 Subject: [PATCH 168/546] Modify existing error child manipulation --- .../filters/http/client/http_client_filter.cc | 9 ++------- .../filters/http/server/http_server_filter.cc | 5 +++-- .../filters/message_size/message_size_filter.cc | 3 ++- src/core/lib/iomgr/error.cc | 16 ++++++---------- src/core/lib/iomgr/error.h | 6 ------ .../lib/security/transport/server_auth_filter.cc | 2 +- src/core/lib/surface/call.cc | 4 +--- src/core/lib/surface/server.cc | 2 +- 8 files changed, 16 insertions(+), 31 deletions(-) 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 04ac4ac947c..f44dc032a7e 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -164,13 +164,8 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { } else { GRPC_ERROR_REF(error); } - if (calld->recv_initial_metadata_error != GRPC_ERROR_NONE) { - if (error == GRPC_ERROR_NONE) { - error = GRPC_ERROR_REF(calld->recv_initial_metadata_error); - } else if (error != calld->recv_initial_metadata_error) { - error = grpc_error_add_child(error, calld->recv_initial_metadata_error); - } - } + error = grpc_error_add_child( + error, GRPC_ERROR_REF(calld->recv_initial_metadata_error)); GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, error); } 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 c66f531a891..926afeec84f 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -321,8 +321,9 @@ static void hs_recv_message_ready(void* user_data, grpc_error* err) { static void hs_recv_trailing_metadata_ready(void* user_data, grpc_error* err) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); - err = - grpc_error_maybe_add_child(err, calld->recv_initial_metadata_ready_error); + err = grpc_error_add_child( + GRPC_ERROR_REF(err), + GRPC_ERROR_REF(calld->recv_initial_metadata_ready_error)); GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); } 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 b5ca1be804f..a5f5f8e2ff9 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -155,7 +155,8 @@ static void recv_message_ready(void* user_data, grpc_error* error) { static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); - error = grpc_error_maybe_add_child(error, calld->error); + error = + grpc_error_add_child(GRPC_ERROR_REF(error), GRPC_ERROR_REF(calld->error)); // Invoke the next callback. GRPC_CLOSURE_RUN(calld->next_recv_trailing_metadata_ready, error); } diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index 226b44c46d1..dfd063a6959 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -513,22 +513,18 @@ bool grpc_error_get_str(grpc_error* err, grpc_error_strs which, grpc_error* grpc_error_add_child(grpc_error* src, grpc_error* child) { GPR_TIMER_SCOPE("grpc_error_add_child", 0); - grpc_error* new_err = copy_error_and_unref(src); - internal_add_error(&new_err, child); - return new_err; -} - -grpc_error* grpc_error_maybe_add_child(grpc_error* src, grpc_error* child) { if (src != GRPC_ERROR_NONE) { if (child == GRPC_ERROR_NONE) { - return GRPC_ERROR_REF(src); + return src; } else if (child != src) { - return grpc_error_add_child(src, GRPC_ERROR_REF(child)); + grpc_error* new_err = copy_error_and_unref(src); + internal_add_error(&new_err, child); + return new_err; } else { - return GRPC_ERROR_REF(src); + return src; } } else { - return GRPC_ERROR_REF(child); + return child; } } diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index 4f65c447fdb..e5369695c9f 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -187,12 +187,6 @@ bool grpc_error_get_str(grpc_error* error, grpc_error_strs which, /// child error. grpc_error* grpc_error_add_child(grpc_error* src, grpc_error* child) GRPC_MUST_USE_RESULT; -/// Produce an error that is a combination of both src and child. -// If src or child, is GRPC_ERROR_NONE, a new reference to the other error is -// returned. Otherwise, a new error with src as the parent and child as the -// child is returned. -grpc_error* grpc_error_maybe_add_child(grpc_error* src, - grpc_error* child) GRPC_MUST_USE_RESULT; grpc_error* grpc_os_error(const char* file, int line, int err, const char* call_name) GRPC_MUST_USE_RESULT; diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc index 5f2ad261d28..552e70130ad 100644 --- a/src/core/lib/security/transport/server_auth_filter.cc +++ b/src/core/lib/security/transport/server_auth_filter.cc @@ -191,7 +191,7 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { static void recv_trailing_metadata_ready(void* user_data, grpc_error* err) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); - err = grpc_error_maybe_add_child(err, calld->error); + err = grpc_error_add_child(GRPC_ERROR_REF(err), GRPC_ERROR_REF(calld->error)); GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); } diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 56c45629529..d2c14571d32 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -686,6 +686,7 @@ static void cancel_with_status(grpc_call* c, grpc_status_code status, } static void set_final_status(grpc_call* call, grpc_error* error) { + gpr_log(GPR_INFO, "set final status"); if (grpc_call_error_trace.enabled()) { gpr_log(GPR_DEBUG, "set_final_status %s", call->is_client ? "CLI" : "SVR"); gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); @@ -1650,9 +1651,6 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, grpc_slice_ref_internal( *op->data.send_status_from_server.status_details)); call->send_extra_metadata_count++; - char* msg = grpc_slice_to_c_string( - GRPC_MDVALUE(call->send_extra_metadata[1].md)); - gpr_free(msg); } grpc_error* status_error = op->data.send_status_from_server.status == GRPC_STATUS_OK diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 4403caf044c..521825ca698 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -737,7 +737,7 @@ static void server_recv_trailing_metadata_ready(void* user_data, grpc_error* err) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); - err = grpc_error_maybe_add_child(err, calld->error); + err = grpc_error_add_child(GRPC_ERROR_REF(err), GRPC_ERROR_REF(calld->error)); GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); } From 97ceb5962cc5317b262aa60b8863c7df7799f640 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 21 Aug 2018 10:42:22 -0700 Subject: [PATCH 169/546] Remove unwanted logs and also add status details to status error --- src/core/lib/surface/call.cc | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index d2c14571d32..d0f418220b5 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -686,7 +686,6 @@ static void cancel_with_status(grpc_call* c, grpc_status_code status, } static void set_final_status(grpc_call* call, grpc_error* error) { - gpr_log(GPR_INFO, "set final status"); if (grpc_call_error_trace.enabled()) { gpr_log(GPR_DEBUG, "set_final_status %s", call->is_client ? "CLI" : "SVR"); gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); @@ -1645,13 +1644,6 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, call->send_extra_metadata_count = 1; call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem( call->channel, op->data.send_status_from_server.status); - if (op->data.send_status_from_server.status_details != nullptr) { - call->send_extra_metadata[1].md = grpc_mdelem_from_slices( - GRPC_MDSTR_GRPC_MESSAGE, - grpc_slice_ref_internal( - *op->data.send_status_from_server.status_details)); - call->send_extra_metadata_count++; - } grpc_error* status_error = op->data.send_status_from_server.status == GRPC_STATUS_OK ? GRPC_ERROR_NONE @@ -1661,6 +1653,22 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, GRPC_ERROR_INT_GRPC_STATUS, static_cast( op->data.send_status_from_server.status)); + if (op->data.send_status_from_server.status_details != nullptr) { + call->send_extra_metadata[1].md = grpc_mdelem_from_slices( + GRPC_MDSTR_GRPC_MESSAGE, + grpc_slice_ref_internal( + *op->data.send_status_from_server.status_details)); + call->send_extra_metadata_count++; + if (status_error != GRPC_ERROR_NONE) { + char* msg = grpc_slice_to_c_string( + GRPC_MDVALUE(call->send_extra_metadata[1].md)); + status_error = + grpc_error_set_str(status_error, GRPC_ERROR_STR_GRPC_MESSAGE, + grpc_slice_from_copied_string(msg)); + gpr_free(msg); + } + } + call->status_error = status_error; if (!prepare_application_metadata( call, From 087bbb2f4eddc654011ce18acbb4a0e2a243ce1d Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 21 Aug 2018 09:52:53 -0700 Subject: [PATCH 170/546] Disable test on windows --- test/core/iomgr/timer_list_test.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/core/iomgr/timer_list_test.cc b/test/core/iomgr/timer_list_test.cc index fd65d1abf1f..feedf3f1493 100644 --- a/test/core/iomgr/timer_list_test.cc +++ b/test/core/iomgr/timer_list_test.cc @@ -248,7 +248,11 @@ int main(int argc, char** argv) { grpc_determine_iomgr_platform(); grpc_iomgr_platform_init(); gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); +#ifndef GPR_WINDOWS + /* Skip this test on Windows until we figure out why it fails */ + /* https://github.com/grpc/grpc/issues/16417 */ long_running_service_cleanup_test(); +#endif // GPR_WINDOWS add_test(); destruction_test(); grpc_iomgr_platform_shutdown(); From 2f8e60a7737293a3e44f555ac9de92267785e91f Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 21 Aug 2018 11:59:24 -0700 Subject: [PATCH 171/546] Set TCP_USER_TIMEOUT socket option --- .../lib/iomgr/socket_utils_common_posix.cc | 24 +++++++++++++++++++ src/core/lib/iomgr/socket_utils_posix.h | 3 +++ src/core/lib/iomgr/tcp_client_posix.cc | 3 +++ .../iomgr/tcp_server_utils_posix_common.cc | 2 ++ 4 files changed, 32 insertions(+) diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc index c4b991c94d8..8b8e303ef75 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.cc +++ b/src/core/lib/iomgr/socket_utils_common_posix.cc @@ -222,6 +222,30 @@ grpc_error* grpc_set_socket_low_latency(int fd, int low_latency) { return GRPC_ERROR_NONE; } +#define DEFAULT_TCP_USER_TIMEOUT 20000 /* 20 seconds */ + +/* Set TCP_USER_TIMEOUT */ +grpc_error* grpc_set_socket_tcp_user_timeout(int fd, int val) { +#ifdef GPR_LINUX + int newval; + socklen_t len; + if (val == 0) { + val = DEFAULT_TCP_USER_TIMEOUT; + } + if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &val, sizeof(val))) { + return GRPC_OS_ERROR(errno, "setsockopt(TCP_USER_TIMEOUT)"); + } + if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len)) { + return GRPC_OS_ERROR(errno, "getsockopt(TCP_USER_TIMEOUT)"); + } + if (newval != val) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Failed to set TCP_USER_TIMEOUT"); + } +#endif /* GPR_LINUX */ + return GRPC_ERROR_NONE; +} + /* set a socket using a grpc_socket_mutator */ grpc_error* grpc_set_socket_with_mutator(int fd, grpc_socket_mutator* mutator) { GPR_ASSERT(mutator); diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h index b3fd58a5302..8550bd1324d 100644 --- a/src/core/lib/iomgr/socket_utils_posix.h +++ b/src/core/lib/iomgr/socket_utils_posix.h @@ -53,6 +53,9 @@ grpc_error* grpc_set_socket_low_latency(int fd, int low_latency); /* set SO_REUSEPORT */ grpc_error* grpc_set_socket_reuse_port(int fd, int reuse); +/* Set TCP_USER_TIMEOUT to val, or the default value if val is 0. */ +grpc_error* grpc_set_socket_tcp_user_timeout(int fd, int val); + /* Returns true if this system can create AF_INET6 sockets bound to ::1. The value is probed once, and cached for the life of the process. diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc index 296ee74311a..518b0b2b3b6 100644 --- a/src/core/lib/iomgr/tcp_client_posix.cc +++ b/src/core/lib/iomgr/tcp_client_posix.cc @@ -76,8 +76,11 @@ static grpc_error* prepare_socket(const grpc_resolved_address* addr, int fd, if (!grpc_is_unix_socket(addr)) { err = grpc_set_socket_low_latency(fd, 1); if (err != GRPC_ERROR_NONE) goto error; + err = grpc_set_socket_tcp_user_timeout(fd, 0 /* set to gRPC default */); + if (err != GRPC_ERROR_NONE) goto error; } err = grpc_set_socket_no_sigpipe_if_possible(fd); + if (err != GRPC_ERROR_NONE) goto error; if (channel_args) { for (size_t i = 0; i < channel_args->num_args; i++) { 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 b9f81455729..2cb28f2e033 100644 --- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc @@ -166,6 +166,8 @@ grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server* s, int fd, if (err != GRPC_ERROR_NONE) goto error; err = grpc_set_socket_reuse_addr(fd, 1); if (err != GRPC_ERROR_NONE) goto error; + err = grpc_set_socket_tcp_user_timeout(fd, 0); + if (err != GRPC_ERROR_NONE) goto error; } err = grpc_set_socket_no_sigpipe_if_possible(fd); if (err != GRPC_ERROR_NONE) goto error; From f94d98833b6975a0f067cb29bd679a36c4151e3e Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 21 Aug 2018 13:20:59 -0700 Subject: [PATCH 172/546] Remove unnecessary atm --- src/core/lib/gpr/arena.cc | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/core/lib/gpr/arena.cc b/src/core/lib/gpr/arena.cc index 4e7094d9bb2..77f9357146d 100644 --- a/src/core/lib/gpr/arena.cc +++ b/src/core/lib/gpr/arena.cc @@ -81,8 +81,9 @@ typedef struct zone { } zone; struct gpr_arena { + // Keep track of the total used size. We use this in our call sizing + // historesis. gpr_atm total_used; - gpr_atm initial_zone_used; size_t initial_zone_size; zone initial_zone; zone* last_zone; @@ -120,16 +121,10 @@ size_t gpr_arena_destroy(gpr_arena* arena) { void* gpr_arena_alloc(gpr_arena* arena, size_t size) { size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size); - // Update the total used size to estimate next call's size. - gpr_atm_no_barrier_fetch_add(&arena->total_used, size); - // Try to allocate in the initial zone. - size_t initial_zone_alloc_begin = static_cast( - gpr_atm_no_barrier_fetch_add(&arena->initial_zone_used, size)); - size_t initial_zone_alloc_end = initial_zone_alloc_begin + size; - if (initial_zone_alloc_end <= arena->initial_zone_size) { + size_t begin = gpr_atm_no_barrier_fetch_add(&arena->total_used, size); + if (begin + size <= arena->initial_zone_size) { return reinterpret_cast(arena) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + - initial_zone_alloc_begin; + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + begin; } else { // If the allocation isn't able to end in the initial zone, create a new // zone for this allocation, and any unused space in the initial zone is From 147826a909cc60d963c34b919417ce7a888e29ce Mon Sep 17 00:00:00 2001 From: Nathan Herring Date: Tue, 21 Aug 2018 23:16:22 +0200 Subject: [PATCH 173/546] Use grpc_slice_unref_internal --- test/cpp/util/cli_credentials.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/util/cli_credentials.cc b/test/cpp/util/cli_credentials.cc index a78027e5aa5..7e05ac2d535 100644 --- a/test/cpp/util/cli_credentials.cc +++ b/test/cpp/util/cli_credentials.cc @@ -86,7 +86,7 @@ CliCredentials::GetChannelCredentials() const { grpc_load_file(FLAGS_ssl_client_cert.c_str(), 1, &cert_slice)); ssl_creds_options.pem_cert_chain = grpc::StringFromCopiedSlice(cert_slice); - grpc_slice_unref(cert_slice); + grpc_slice_unref_internal(cert_slice); } if (!FLAGS_ssl_client_key.empty()) { grpc_slice key_slice = grpc_empty_slice(); @@ -95,7 +95,7 @@ CliCredentials::GetChannelCredentials() const { grpc_load_file(FLAGS_ssl_client_key.c_str(), 1, &key_slice)); ssl_creds_options.pem_private_key = grpc::StringFromCopiedSlice(key_slice); - grpc_slice_unref(key_slice); + grpc_slice_unref_internal(key_slice); } return grpc::SslCredentials(ssl_creds_options); } else if (FLAGS_channel_creds_type.compare("gdc") == 0) { From 234fdc6fbf68aa6c29990db7c7ddcface3355cb5 Mon Sep 17 00:00:00 2001 From: Nathan Herring Date: Tue, 21 Aug 2018 23:28:45 +0200 Subject: [PATCH 174/546] Missing #include --- test/cpp/util/cli_credentials.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cpp/util/cli_credentials.cc b/test/cpp/util/cli_credentials.cc index 7e05ac2d535..73ecc78d5c3 100644 --- a/test/cpp/util/cli_credentials.cc +++ b/test/cpp/util/cli_credentials.cc @@ -24,6 +24,7 @@ #include #include "src/core/lib/iomgr/load_file.h" +#include "src/core/lib/slice/slice_internal.h" DEFINE_bool( enable_ssl, false, From 1cfd81a604699d6ab8095c90e7da5fc588bb3048 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 21 Aug 2018 16:25:40 -0700 Subject: [PATCH 175/546] Explain the newer semantics of grpc_error_add_child --- src/core/lib/iomgr/error.cc | 5 +++++ src/core/lib/iomgr/error.h | 7 +++++++ test/core/iomgr/error_test.cc | 11 ----------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index dfd063a6959..13bc69ffb60 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -515,15 +515,20 @@ grpc_error* grpc_error_add_child(grpc_error* src, grpc_error* child) { GPR_TIMER_SCOPE("grpc_error_add_child", 0); if (src != GRPC_ERROR_NONE) { if (child == GRPC_ERROR_NONE) { + /* \a child is empty. Simply return the ref to \a src */ return src; } else if (child != src) { grpc_error* new_err = copy_error_and_unref(src); internal_add_error(&new_err, child); return new_err; } else { + /* \a src and \a child are the same. Drop one of the references and return + * the other */ + GRPC_ERROR_UNREF(child); return src; } } else { + /* \a src is empty. Simply return the ref to \a child */ return child; } } diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index e5369695c9f..49f4029bc22 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -185,6 +185,13 @@ bool grpc_error_get_str(grpc_error* error, grpc_error_strs which, /// error occurring. Allows root causing high level errors from lower level /// errors that contributed to them. The src error takes ownership of the /// child error. +/// +/// Edge Conditions - +/// 1) If either of \a src or \a child is GRPC_ERROR_NONE, returns a reference +/// to the other argument. 2) If both \a src and \a child are GRPC_ERROR_NONE, +/// returns GRPC_ERROR_NONE. 3) If \a src and \a child point to the same error, +/// returns a single reference. (Note that, 2 references should have been +/// received to the error in this case.) grpc_error* grpc_error_add_child(grpc_error* src, grpc_error* child) GRPC_MUST_USE_RESULT; diff --git a/test/core/iomgr/error_test.cc b/test/core/iomgr/error_test.cc index a1628a1f717..d78a8c2af39 100644 --- a/test/core/iomgr/error_test.cc +++ b/test/core/iomgr/error_test.cc @@ -187,16 +187,6 @@ static void test_os_error() { GRPC_ERROR_UNREF(error); } -static void test_special() { - grpc_error* error = GRPC_ERROR_NONE; - error = grpc_error_add_child( - error, GRPC_ERROR_CREATE_FROM_STATIC_STRING("test child")); - intptr_t i; - GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &i)); - GPR_ASSERT(i == GRPC_STATUS_OK); - GRPC_ERROR_UNREF(error); -} - static void test_overflow() { grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Overflow"); @@ -235,7 +225,6 @@ int main(int argc, char** argv) { test_os_error(); test_create_referencing(); test_create_referencing_many(); - test_special(); test_overflow(); grpc_shutdown(); From ecee4ac703e909b4edd789e137e3b0b736dfe37a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 21 Aug 2018 17:07:33 -0700 Subject: [PATCH 176/546] Use linux kernel version 2.6.37 to decide whether to use TCP_USER_TIMEOUT or not --- src/core/lib/iomgr/port.h | 6 ++++++ src/core/lib/iomgr/socket_utils_common_posix.cc | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 066417b93cc..bc58ed13c07 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -77,6 +77,12 @@ #define GRPC_LINUX_SOCKETUTILS 1 #endif #endif +#include +#ifdef LINUX_VERSION_CODE +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) +#define GRPC_HAVE_TCP_USER_TIMEOUT +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) */ +#endif /* LINUX_VERSION_CODE */ #ifndef __GLIBC__ #define GRPC_LINUX_EPOLL 1 #define GRPC_LINUX_EPOLL_CREATE1 1 diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc index 8b8e303ef75..5dc8fcb427b 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.cc +++ b/src/core/lib/iomgr/socket_utils_common_posix.cc @@ -226,7 +226,7 @@ grpc_error* grpc_set_socket_low_latency(int fd, int low_latency) { /* Set TCP_USER_TIMEOUT */ grpc_error* grpc_set_socket_tcp_user_timeout(int fd, int val) { -#ifdef GPR_LINUX +#ifdef GRPC_HAVE_TCP_USER_TIMEOUT int newval; socklen_t len; if (val == 0) { @@ -242,7 +242,7 @@ grpc_error* grpc_set_socket_tcp_user_timeout(int fd, int val) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Failed to set TCP_USER_TIMEOUT"); } -#endif /* GPR_LINUX */ +#endif /* GRPC_HAVE_TCP_USER_TIMEOUT */ return GRPC_ERROR_NONE; } From dfe377eddc38faae3e4f604c7e27cec0c9a7d31c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 21 Aug 2018 17:16:28 -0700 Subject: [PATCH 177/546] Did not initialize len earlier --- src/core/lib/iomgr/socket_utils_common_posix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc index 5dc8fcb427b..9b32089a928 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.cc +++ b/src/core/lib/iomgr/socket_utils_common_posix.cc @@ -228,7 +228,7 @@ grpc_error* grpc_set_socket_low_latency(int fd, int low_latency) { grpc_error* grpc_set_socket_tcp_user_timeout(int fd, int val) { #ifdef GRPC_HAVE_TCP_USER_TIMEOUT int newval; - socklen_t len; + socklen_t len = sizeof(newval); if (val == 0) { val = DEFAULT_TCP_USER_TIMEOUT; } From 622f1a893466b1cef9e73a9616a5493c90d6ba01 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 21 Aug 2018 17:23:45 -0700 Subject: [PATCH 178/546] Reviewer comment --- src/core/ext/filters/message_size/message_size_filter.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 a5f5f8e2ff9..c17df86f3da 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -107,7 +107,7 @@ struct call_data { // Original recv_message_ready callback, invoked after our own. grpc_closure* next_recv_message_ready; // Original recv_trailing_metadata callback, invoked after our own. - grpc_closure* next_recv_trailing_metadata_ready; + grpc_closure* original_recv_trailing_metadata_ready; }; struct channel_data { @@ -158,7 +158,7 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { error = grpc_error_add_child(GRPC_ERROR_REF(error), GRPC_ERROR_REF(calld->error)); // Invoke the next callback. - GRPC_CLOSURE_RUN(calld->next_recv_trailing_metadata_ready, error); + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, error); } // Start transport stream op. @@ -191,7 +191,7 @@ static void start_transport_stream_op_batch( } // Inject callback for receiving trailing metadata. if (op->recv_trailing_metadata) { - calld->next_recv_trailing_metadata_ready = + calld->original_recv_trailing_metadata_ready = op->payload->recv_trailing_metadata.recv_trailing_metadata_ready; op->payload->recv_trailing_metadata.recv_trailing_metadata_ready = &calld->recv_trailing_metadata_ready; @@ -207,7 +207,7 @@ static grpc_error* init_call_elem(grpc_call_element* elem, call_data* calld = static_cast(elem->call_data); calld->call_combiner = args->call_combiner; calld->next_recv_message_ready = nullptr; - calld->next_recv_trailing_metadata_ready = nullptr; + calld->original_recv_trailing_metadata_ready = nullptr; calld->error = GRPC_ERROR_NONE; GRPC_CLOSURE_INIT(&calld->recv_message_ready, recv_message_ready, elem, grpc_schedule_on_exec_ctx); From 0aa1bd2ed481f12b1d6348b4bf0a19093eafc7fb Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Tue, 21 Aug 2018 17:03:48 -0700 Subject: [PATCH 179/546] Ensure thread_pool is not None for grpc.Server --- src/python/grpcio_tests/tests/unit/_channel_args_test.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio_tests/tests/unit/_channel_args_test.py b/src/python/grpcio_tests/tests/unit/_channel_args_test.py index 1a2d2c01179..869c2f4d2f4 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_args_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_args_test.py @@ -13,6 +13,7 @@ # limitations under the License. """Tests of Channel Args on client/server side.""" +from concurrent import futures import unittest import grpc @@ -39,7 +40,9 @@ class ChannelArgsTest(unittest.TestCase): grpc.insecure_channel('localhost:8080', options=TEST_CHANNEL_ARGS) def test_server(self): - grpc.server(None, options=TEST_CHANNEL_ARGS) + grpc.server( + futures.ThreadPoolExecutor(max_workers=1), + options=TEST_CHANNEL_ARGS) if __name__ == '__main__': From 986fa0ed58661e13b71e04fd9c6a62f9d84493f3 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 21 Aug 2018 18:55:05 -0700 Subject: [PATCH 180/546] reviewer comments --- src/core/lib/surface/call.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index d0f418220b5..fb3161aeaab 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -693,12 +693,10 @@ static void set_final_status(grpc_call* call, grpc_error* error) { grpc_core::channelz::ChannelNode* channelz_channel = grpc_channel_get_channelz_node(call->channel); if (call->is_client) { - const char** error_string = call->final_op.client.error_string; - grpc_status_code code; grpc_slice slice = grpc_empty_slice(); - grpc_error_get_status(error, call->send_deadline, &code, &slice, nullptr, - error_string); - *call->final_op.client.status = code; + grpc_error_get_status(error, call->send_deadline, + call->final_op.client.status, &slice, nullptr, + call->final_op.client.error_string); *call->final_op.client.status_details = grpc_slice_ref_internal(slice); call->status_error = error; if (channelz_channel != nullptr) { From fba18d8551dcd515b8f6b85b03a9dbda1c2e0272 Mon Sep 17 00:00:00 2001 From: Chris Lamb Date: Wed, 22 Aug 2018 16:52:46 +0100 Subject: [PATCH 181/546] Fix a number of spelling errors. --- doc/core/grpc-error.md | 8 ++++---- src/core/ext/filters/client_channel/client_channel.cc | 2 +- src/core/ext/filters/http/client_authority_filter.cc | 2 +- src/core/lib/iomgr/socket_mutator.cc | 2 +- src/core/lib/iomgr/socket_mutator.h | 2 +- .../lib/security/credentials/oauth2/oauth2_credentials.cc | 2 +- src/core/lib/surface/call.cc | 2 +- src/core/tsi/ssl_transport_security.cc | 2 +- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 2 +- src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs | 2 +- src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs | 4 ++-- .../Grpc.Core/Internal/RequestCallContextSafeHandle.cs | 2 +- src/python/grpcio_tests/tests/stress/test_runner.py | 2 +- src/ruby/pb/test/client.rb | 6 +++--- src/ruby/spec/generic/client_stub_spec.rb | 6 +++--- test/core/security/credentials_test.cc | 4 ++-- 16 files changed, 25 insertions(+), 25 deletions(-) diff --git a/doc/core/grpc-error.md b/doc/core/grpc-error.md index 49a95b353cf..105a6482845 100644 --- a/doc/core/grpc-error.md +++ b/doc/core/grpc-error.md @@ -56,7 +56,7 @@ For example, in the following code block, error1 and error2 are owned by the current function. ```C -grpc_error* error1 = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured"); +grpc_error* error1 = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occurred"); grpc_error* error2 = some_operation_that_might_fail(...); ``` @@ -87,7 +87,7 @@ callbacks with `GRPC_CLOSURE_RUN` and `GRPC_CLOSURE_SCHED`. These functions are not callbacks, so they will take ownership of the error passed to them. ```C -grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured"); +grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occurred"); GRPC_CLOSURE_RUN(exec_ctx, cb, error); // current function no longer has ownership of the error ``` @@ -96,7 +96,7 @@ If you schedule or run a closure, but still need ownership of the error, then you must explicitly take a reference. ```C -grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured"); +grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occurred"); GRPC_CLOSURE_RUN(exec_ctx, cb, GRPC_ERROR_REF(error)); // do some other things with the error GRPC_ERROR_UNREF(error); @@ -128,7 +128,7 @@ void on_some_action(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { Take the following example: ```C -grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured"); +grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occurred"); // do some things some_function(error); // can't use error anymore! might be gone. diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index b06f09d8c7b..d2bf4f388d3 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -3101,7 +3101,7 @@ static void cc_start_transport_stream_op_batch( // For all other batches, release the call combiner. if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, - "chand=%p calld=%p: saved batch, yeilding call combiner", chand, + "chand=%p calld=%p: saved batch, yielding call combiner", chand, calld); } GRPC_CALL_COMBINER_STOP(calld->call_combiner, diff --git a/src/core/ext/filters/http/client_authority_filter.cc b/src/core/ext/filters/http/client_authority_filter.cc index ddc939ed121..1ca20ebb26d 100644 --- a/src/core/ext/filters/http/client_authority_filter.cc +++ b/src/core/ext/filters/http/client_authority_filter.cc @@ -94,7 +94,7 @@ grpc_error* init_channel_elem(grpc_channel_element* elem, if (default_authority_arg == nullptr) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "GRPC_ARG_DEFAULT_AUTHORITY channel arg. not found. Note that direct " - "channels must explicity specify a value for this argument."); + "channels must explicitly specify a value for this argument."); } const char* default_authority_str = grpc_channel_arg_get_string(default_authority_arg); diff --git a/src/core/lib/iomgr/socket_mutator.cc b/src/core/lib/iomgr/socket_mutator.cc index b9b8eaf4ad2..a448c9f61c3 100644 --- a/src/core/lib/iomgr/socket_mutator.cc +++ b/src/core/lib/iomgr/socket_mutator.cc @@ -57,7 +57,7 @@ int grpc_socket_mutator_compare(grpc_socket_mutator* a, void grpc_socket_mutator_unref(grpc_socket_mutator* mutator) { if (gpr_unref(&mutator->refcount)) { - mutator->vtable->destory(mutator); + mutator->vtable->destroy(mutator); } } diff --git a/src/core/lib/iomgr/socket_mutator.h b/src/core/lib/iomgr/socket_mutator.h index 6c7781c51d5..8742a3ba613 100644 --- a/src/core/lib/iomgr/socket_mutator.h +++ b/src/core/lib/iomgr/socket_mutator.h @@ -33,7 +33,7 @@ typedef struct { /** Compare socket mutator \a a and \a b */ int (*compare)(grpc_socket_mutator* a, grpc_socket_mutator* b); /** Destroys the socket mutator instance */ - void (*destory)(grpc_socket_mutator* mutator); + void (*destroy)(grpc_socket_mutator* mutator); } grpc_socket_mutator_vtable; /** The Socket Mutator interface allows changes on socket options */ diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc index 43dd68e8747..44b093557f3 100644 --- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc @@ -235,7 +235,7 @@ static void on_oauth2_token_fetcher_http_response(void* user_data, access_token_md); } else { error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Error occured when fetching oauth2 token.", &error, 1); + "Error occurred when fetching oauth2 token.", &error, 1); } GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, error); grpc_polling_entity_del_from_pollset_set( diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 52053e686b9..2923a86646a 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -1951,7 +1951,7 @@ done: return error; done_with_error: - /* reverse any mutations that occured */ + /* reverse any mutations that occurred */ if (stream_op->send_initial_metadata) { call->sent_initial_metadata = false; grpc_metadata_batch_clear(&call->metadata_batch[0][0]); diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index e66fc9ba034..44bad0d19a0 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -216,7 +216,7 @@ static void ssl_log_where_info(const SSL* ssl, int where, int flag, /* Used for debugging. TODO(jboeuf): Remove when code is mature enough. */ static void ssl_info_callback(const SSL* ssl, int where, int ret) { if (ret == 0) { - gpr_log(GPR_ERROR, "ssl_info_callback: error occured.\n"); + gpr_log(GPR_ERROR, "ssl_info_callback: error occurred.\n"); return; } diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 9946d1a6cf9..3c9e090ba44 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -108,7 +108,7 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Logger.Error(e, "Exception occured while invoking completion delegate."); + Logger.Error(e, "Exception occurred while invoking completion delegate."); } } finally diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs index 53a859d18f7..085e7faf595 100644 --- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs @@ -144,7 +144,7 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Logger.Error(e, "Exception occured while invoking batch completion delegate."); + Logger.Error(e, "Exception occurred while invoking batch completion delegate."); } finally { diff --git a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs index 8ddda9be5cd..622cfde9e70 100644 --- a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs +++ b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs @@ -189,7 +189,7 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Logger.Error(e, "Exception occured while extracting event from completion registry."); + Logger.Error(e, "Exception occurred while extracting event from completion registry."); } } } @@ -233,7 +233,7 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Logger.Error(e, "Exception occured while invoking completion delegate"); + Logger.Error(e, "Exception occurred while invoking completion delegate"); } finally { diff --git a/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs index ebc2d6d8d65..24fde75e5a4 100644 --- a/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs @@ -112,7 +112,7 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Logger.Error(e, "Exception occured while invoking request call completion delegate."); + Logger.Error(e, "Exception occurred while invoking request call completion delegate."); } finally { diff --git a/src/python/grpcio_tests/tests/stress/test_runner.py b/src/python/grpcio_tests/tests/stress/test_runner.py index 764cda17fbb..e66eda64a80 100644 --- a/src/python/grpcio_tests/tests/stress/test_runner.py +++ b/src/python/grpcio_tests/tests/stress/test_runner.py @@ -53,5 +53,5 @@ class TestRunner(threading.Thread): except Exception as e: # pylint: disable=broad-except traceback.print_exc() self._exception_queue.put( - Exception("An exception occured during test {}" + Exception("An exception occurred during test {}" .format(test_case), e)) diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb index 1b9d7cbbe61..cfed7ca12a9 100755 --- a/src/ruby/pb/test/client.rb +++ b/src/ruby/pb/test/client.rb @@ -681,13 +681,13 @@ class NamedTests # Send probing message for compressed request on the server, to see # if it's implemented. def send_probe_for_compressed_request_support(&send_probe) - bad_status_occured = false + bad_status_occurred = false begin send_probe.call rescue GRPC::BadStatus => e if e.code == GRPC::Core::StatusCodes::INVALID_ARGUMENT - bad_status_occured = true + bad_status_occurred = true else fail AssertionError, "Bad status received but code is #{e.code}" end @@ -696,7 +696,7 @@ class NamedTests end assert('CompressedRequest probe failed') do - bad_status_occured + bad_status_occurred end end diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb index fbf594a6553..fc50362ca5f 100644 --- a/src/ruby/spec/generic/client_stub_spec.rb +++ b/src/ruby/spec/generic/client_stub_spec.rb @@ -265,14 +265,14 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength end creds = GRPC::Core::CallCredentials.new(failing_auth) - unavailable_error_occured = false + unavailable_error_occurred = false begin get_response(stub, credentials: creds) rescue GRPC::Unavailable => e - unavailable_error_occured = true + unavailable_error_occurred = true expect(e.details.include?(error_message)).to be true end - expect(unavailable_error_occured).to eq(true) + expect(unavailable_error_occurred).to eq(true) @server.shutdown_and_notify(Time.now + 3) th.join diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index 8a793e4bb29..97156761bdf 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -610,7 +610,7 @@ static void test_compute_engine_creds_failure(void) { grpc_core::ExecCtx exec_ctx; request_metadata_state* state = make_request_metadata_state( GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Error occured when fetching oauth2 token."), + "Error occurred when fetching oauth2 token."), nullptr, 0); grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, nullptr, nullptr}; @@ -699,7 +699,7 @@ static void test_refresh_token_creds_failure(void) { grpc_core::ExecCtx exec_ctx; request_metadata_state* state = make_request_metadata_state( GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Error occured when fetching oauth2 token."), + "Error occurred when fetching oauth2 token."), nullptr, 0); grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method, nullptr, nullptr}; From 2c37c51dd9518b74444ed2c93f521849169f7694 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 22 Aug 2018 10:19:43 -0700 Subject: [PATCH 182/546] Add logging for tcp_user_timeout not supported --- src/core/lib/iomgr/socket_utils_common_posix.cc | 2 ++ src/core/lib/iomgr/tcp_server_utils_posix_common.cc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc index 9b32089a928..b7fc833608b 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.cc +++ b/src/core/lib/iomgr/socket_utils_common_posix.cc @@ -242,6 +242,8 @@ grpc_error* grpc_set_socket_tcp_user_timeout(int fd, int val) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Failed to set TCP_USER_TIMEOUT"); } +#else + gpr_log(GPR_INFO, "TCP_USER_TIMEOUT not supported for this platform"); #endif /* GRPC_HAVE_TCP_USER_TIMEOUT */ return GRPC_ERROR_NONE; } 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 2cb28f2e033..20b9037c68f 100644 --- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc @@ -166,7 +166,7 @@ grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server* s, int fd, if (err != GRPC_ERROR_NONE) goto error; err = grpc_set_socket_reuse_addr(fd, 1); if (err != GRPC_ERROR_NONE) goto error; - err = grpc_set_socket_tcp_user_timeout(fd, 0); + err = grpc_set_socket_tcp_user_timeout(fd, 0 /* set to gRPC default */); if (err != GRPC_ERROR_NONE) goto error; } err = grpc_set_socket_no_sigpipe_if_possible(fd); From 39e53c13bf1f62fdfe7e05fbfe5427f5ad3b1a90 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 22 Aug 2018 10:20:59 -0700 Subject: [PATCH 183/546] remove extra blank line --- src/core/lib/iomgr/tcp_client_posix.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc index 518b0b2b3b6..c2a08922116 100644 --- a/src/core/lib/iomgr/tcp_client_posix.cc +++ b/src/core/lib/iomgr/tcp_client_posix.cc @@ -80,7 +80,6 @@ static grpc_error* prepare_socket(const grpc_resolved_address* addr, int fd, if (err != GRPC_ERROR_NONE) goto error; } err = grpc_set_socket_no_sigpipe_if_possible(fd); - if (err != GRPC_ERROR_NONE) goto error; if (channel_args) { for (size_t i = 0; i < channel_args->num_args; i++) { From f8cf7ee56d4150ae870f44298a406f7b2ca038c0 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 25 Jun 2018 10:25:28 -0700 Subject: [PATCH 184/546] Support gRPC Python client-side fork with epoll1 A process may fork after invoking grpc_init() and use gRPC in the child if and only if the child process first destroys all gRPC resources inherited from the parent process and invokes grpc_shutdown(). Subsequent to this, the child will be able to re-initialize and use gRPC. After fork, the parent process will be able to continue to use existing gRPC resources such as channels and calls without interference from the child process. To facilitate gRPC Python applications meeting the above constraints, gRPC Python will automatically destroy and shutdown all gRPC Core resources in the child's post-fork handler, including cancelling in-flight calls (see detailed design below). From the client's perspective, the child process is now free to create new channels and use gRPC. --- .pylintrc-tests | 2 + src/core/lib/gprpp/fork.cc | 73 +-- src/core/lib/gprpp/fork.h | 17 +- src/core/lib/iomgr/ev_epoll1_linux.cc | 72 +++ src/core/lib/iomgr/fork_posix.cc | 5 + src/python/grpcio/grpc/_channel.py | 59 ++- .../grpcio/grpc/_cython/_cygrpc/call.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/channel.pxd.pxi | 1 + .../grpc/_cython/_cygrpc/channel.pyx.pxi | 63 ++- .../_cython/_cygrpc/completion_queue.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/credentials.pyx.pxi | 8 +- .../grpc/_cython/_cygrpc/fork_posix.pxd.pxi | 29 ++ .../grpc/_cython/_cygrpc/fork_posix.pyx.pxi | 203 ++++++++ .../grpc/_cython/_cygrpc/fork_windows.pyx.pxi | 63 +++ .../grpc/_cython/_cygrpc/records.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/server.pyx.pxi | 2 +- src/python/grpcio/grpc/_cython/cygrpc.pxd | 3 + src/python/grpcio/grpc/_cython/cygrpc.pyx | 5 + src/python/grpcio_tests/commands.py | 25 + src/python/grpcio_tests/setup.py | 1 + .../grpcio_tests/tests/fork/__init__.py | 13 + src/python/grpcio_tests/tests/fork/client.py | 76 +++ src/python/grpcio_tests/tests/fork/methods.py | 445 ++++++++++++++++++ src/python/grpcio_tests/tests/tests.json | 2 + .../tests/unit/_cython/_fork_test.py | 68 +++ 25 files changed, 1167 insertions(+), 74 deletions(-) create mode 100644 src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pxd.pxi create mode 100644 src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi create mode 100644 src/python/grpcio/grpc/_cython/_cygrpc/fork_windows.pyx.pxi create mode 100644 src/python/grpcio_tests/tests/fork/__init__.py create mode 100644 src/python/grpcio_tests/tests/fork/client.py create mode 100644 src/python/grpcio_tests/tests/fork/methods.py create mode 100644 src/python/grpcio_tests/tests/unit/_cython/_fork_test.py diff --git a/.pylintrc-tests b/.pylintrc-tests index ebe9d507cdd..e68755c674e 100644 --- a/.pylintrc-tests +++ b/.pylintrc-tests @@ -20,6 +20,8 @@ notes=FIXME,XXX [MESSAGES CONTROL] +extension-pkg-whitelist=grpc._cython.cygrpc + disable= # These suppressions are specific to tests: # diff --git a/src/core/lib/gprpp/fork.cc b/src/core/lib/gprpp/fork.cc index f6d9a87d2c1..0288c396808 100644 --- a/src/core/lib/gprpp/fork.cc +++ b/src/core/lib/gprpp/fork.cc @@ -157,11 +157,11 @@ class ThreadState { } // namespace void Fork::GlobalInit() { - if (!overrideEnabled_) { + if (!override_enabled_) { #ifdef GRPC_ENABLE_FORK_SUPPORT - supportEnabled_ = true; + support_enabled_ = true; #else - supportEnabled_ = false; + support_enabled_ = false; #endif bool env_var_set = false; char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT"); @@ -172,7 +172,7 @@ void Fork::GlobalInit() { "False", "FALSE", "0"}; for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) { if (0 == strcmp(env, truthy[i])) { - supportEnabled_ = true; + support_enabled_ = true; env_var_set = true; break; } @@ -180,7 +180,7 @@ void Fork::GlobalInit() { if (!env_var_set) { for (size_t i = 0; i < GPR_ARRAY_SIZE(falsey); i++) { if (0 == strcmp(env, falsey[i])) { - supportEnabled_ = false; + support_enabled_ = false; env_var_set = true; break; } @@ -189,72 +189,79 @@ void Fork::GlobalInit() { gpr_free(env); } } - if (supportEnabled_) { - execCtxState_ = grpc_core::New(); - threadState_ = grpc_core::New(); + if (support_enabled_) { + exec_ctx_state_ = grpc_core::New(); + thread_state_ = grpc_core::New(); } } void Fork::GlobalShutdown() { - if (supportEnabled_) { - grpc_core::Delete(execCtxState_); - grpc_core::Delete(threadState_); + if (support_enabled_) { + grpc_core::Delete(exec_ctx_state_); + grpc_core::Delete(thread_state_); } } -bool Fork::Enabled() { return supportEnabled_; } +bool Fork::Enabled() { return support_enabled_; } // Testing Only void Fork::Enable(bool enable) { - overrideEnabled_ = true; - supportEnabled_ = enable; + override_enabled_ = true; + support_enabled_ = enable; } void Fork::IncExecCtxCount() { - if (supportEnabled_) { - execCtxState_->IncExecCtxCount(); + if (support_enabled_) { + exec_ctx_state_->IncExecCtxCount(); } } void Fork::DecExecCtxCount() { - if (supportEnabled_) { - execCtxState_->DecExecCtxCount(); + if (support_enabled_) { + exec_ctx_state_->DecExecCtxCount(); } } +void Fork::SetResetChildPollingEngineFunc(Fork::child_postfork_func func) { + reset_child_polling_engine_ = func; +} +Fork::child_postfork_func Fork::GetResetChildPollingEngineFunc() { + return reset_child_polling_engine_; +} + bool Fork::BlockExecCtx() { - if (supportEnabled_) { - return execCtxState_->BlockExecCtx(); + if (support_enabled_) { + return exec_ctx_state_->BlockExecCtx(); } return false; } void Fork::AllowExecCtx() { - if (supportEnabled_) { - execCtxState_->AllowExecCtx(); + if (support_enabled_) { + exec_ctx_state_->AllowExecCtx(); } } void Fork::IncThreadCount() { - if (supportEnabled_) { - threadState_->IncThreadCount(); + if (support_enabled_) { + thread_state_->IncThreadCount(); } } void Fork::DecThreadCount() { - if (supportEnabled_) { - threadState_->DecThreadCount(); + if (support_enabled_) { + thread_state_->DecThreadCount(); } } void Fork::AwaitThreads() { - if (supportEnabled_) { - threadState_->AwaitThreads(); + if (support_enabled_) { + thread_state_->AwaitThreads(); } } -internal::ExecCtxState* Fork::execCtxState_ = nullptr; -internal::ThreadState* Fork::threadState_ = nullptr; -bool Fork::supportEnabled_ = false; -bool Fork::overrideEnabled_ = false; - +internal::ExecCtxState* Fork::exec_ctx_state_ = nullptr; +internal::ThreadState* Fork::thread_state_ = nullptr; +bool Fork::support_enabled_ = false; +bool Fork::override_enabled_ = false; +Fork::child_postfork_func Fork::reset_child_polling_engine_ = nullptr; } // namespace grpc_core diff --git a/src/core/lib/gprpp/fork.h b/src/core/lib/gprpp/fork.h index 123e22c4c6f..5a7404f0d91 100644 --- a/src/core/lib/gprpp/fork.h +++ b/src/core/lib/gprpp/fork.h @@ -33,6 +33,8 @@ class ThreadState; class Fork { public: + typedef void (*child_postfork_func)(void); + static void GlobalInit(); static void GlobalShutdown(); @@ -46,6 +48,12 @@ class Fork { // Decrement the count of active ExecCtxs static void DecExecCtxCount(); + // Provide a function that will be invoked in the child's postfork handler to + // reset the polling engine's internal state. + static void SetResetChildPollingEngineFunc( + child_postfork_func reset_child_polling_engine); + static child_postfork_func GetResetChildPollingEngineFunc(); + // Check if there is a single active ExecCtx // (the one used to invoke this function). If there are more, // return false. Otherwise, return true and block creation of @@ -68,10 +76,11 @@ class Fork { static void Enable(bool enable); private: - static internal::ExecCtxState* execCtxState_; - static internal::ThreadState* threadState_; - static bool supportEnabled_; - static bool overrideEnabled_; + static internal::ExecCtxState* exec_ctx_state_; + static internal::ThreadState* thread_state_; + static bool support_enabled_; + static bool override_enabled_; + static child_postfork_func reset_child_polling_engine_; }; } // namespace grpc_core diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index 66e0f1fd6db..aa5016bd8fd 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -131,6 +131,13 @@ static void epoll_set_shutdown() { * Fd Declarations */ +/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ +struct grpc_fork_fd_list { + grpc_fd* fd; + grpc_fd* next; + grpc_fd* prev; +}; + struct grpc_fd { int fd; @@ -141,6 +148,9 @@ struct grpc_fd { struct grpc_fd* freelist_next; grpc_iomgr_object iomgr_object; + + /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ + grpc_fork_fd_list* fork_fd_list; }; static void fd_global_init(void); @@ -256,6 +266,10 @@ static bool append_error(grpc_error** composite, grpc_error* error, static grpc_fd* fd_freelist = nullptr; static gpr_mu fd_freelist_mu; +/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ +static grpc_fd* fork_fd_list_head = nullptr; +static gpr_mu fork_fd_list_mu; + static void fd_global_init(void) { gpr_mu_init(&fd_freelist_mu); } static void fd_global_shutdown(void) { @@ -269,6 +283,38 @@ static void fd_global_shutdown(void) { gpr_mu_destroy(&fd_freelist_mu); } +static void fork_fd_list_add_grpc_fd(grpc_fd* fd) { + if (grpc_core::Fork::Enabled()) { + gpr_mu_lock(&fork_fd_list_mu); + fd->fork_fd_list = + static_cast(gpr_malloc(sizeof(grpc_fork_fd_list))); + fd->fork_fd_list->next = fork_fd_list_head; + fd->fork_fd_list->prev = nullptr; + if (fork_fd_list_head != nullptr) { + fork_fd_list_head->fork_fd_list->prev = fd; + } + fork_fd_list_head = fd; + gpr_mu_unlock(&fork_fd_list_mu); + } +} + +static void fork_fd_list_remove_grpc_fd(grpc_fd* fd) { + if (grpc_core::Fork::Enabled()) { + gpr_mu_lock(&fork_fd_list_mu); + if (fork_fd_list_head == fd) { + fork_fd_list_head = fd->fork_fd_list->next; + } + if (fd->fork_fd_list->prev != nullptr) { + fd->fork_fd_list->prev->fork_fd_list->next = fd->fork_fd_list->next; + } + if (fd->fork_fd_list->next != nullptr) { + fd->fork_fd_list->next->fork_fd_list->prev = fd->fork_fd_list->prev; + } + gpr_free(fd->fork_fd_list); + gpr_mu_unlock(&fork_fd_list_mu); + } +} + static grpc_fd* fd_create(int fd, const char* name, bool track_err) { grpc_fd* new_fd = nullptr; @@ -295,6 +341,7 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) { char* fd_name; gpr_asprintf(&fd_name, "%s fd=%d", name, fd); grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name); + fork_fd_list_add_grpc_fd(new_fd); #ifndef NDEBUG if (grpc_trace_fd_refcount.enabled()) { gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, new_fd, fd_name); @@ -361,6 +408,7 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_REF(error)); grpc_iomgr_unregister_object(&fd->iomgr_object); + fork_fd_list_remove_grpc_fd(fd); fd->read_closure->DestroyEvent(); fd->write_closure->DestroyEvent(); fd->error_closure->DestroyEvent(); @@ -1190,6 +1238,10 @@ static void shutdown_engine(void) { fd_global_shutdown(); pollset_global_shutdown(); epoll_set_shutdown(); + if (grpc_core::Fork::Enabled()) { + gpr_mu_destroy(&fork_fd_list_mu); + grpc_core::Fork::SetResetChildPollingEngineFunc(nullptr); + } } static const grpc_event_engine_vtable vtable = { @@ -1227,6 +1279,21 @@ static const grpc_event_engine_vtable vtable = { shutdown_engine, }; +/* Called by the child process's post-fork handler to close open fds, including + * the global epoll fd. This allows gRPC to shutdown in the child process + * without interfering with connections or RPCs ongoing in the parent. */ +static void reset_event_manager_on_fork() { + gpr_mu_lock(&fork_fd_list_mu); + while (fork_fd_list_head != nullptr) { + close(fork_fd_list_head->fd); + fork_fd_list_head->fd = -1; + fork_fd_list_head = fork_fd_list_head->fork_fd_list->next; + } + gpr_mu_unlock(&fork_fd_list_mu); + shutdown_engine(); + grpc_init_epoll1_linux(true); +} + /* It is possible that GLIBC has epoll but the underlying kernel doesn't. * Create epoll_fd (epoll_set_init() takes care of that) to make sure epoll * support is available */ @@ -1248,6 +1315,11 @@ const grpc_event_engine_vtable* grpc_init_epoll1_linux(bool explicit_request) { return nullptr; } + if (grpc_core::Fork::Enabled()) { + gpr_mu_init(&fork_fd_list_mu); + grpc_core::Fork::SetResetChildPollingEngineFunc( + reset_event_manager_on_fork); + } return &vtable; } diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index b37384b8db7..a5b61fb4ce3 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -84,6 +84,11 @@ void grpc_postfork_child() { if (!skipped_handler) { grpc_core::Fork::AllowExecCtx(); grpc_core::ExecCtx exec_ctx; + grpc_core::Fork::child_postfork_func reset_polling_engine = + grpc_core::Fork::GetResetChildPollingEngineFunc(); + if (reset_polling_engine != nullptr) { + reset_polling_engine(); + } grpc_timer_manager_set_threading(true); grpc_executor_set_threading(true); } diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index e9246991df1..6876601785b 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -111,6 +111,10 @@ class _RPCState(object): # prior to termination of the RPC. self.cancelled = False self.callbacks = [] + self.fork_epoch = cygrpc.get_fork_epoch() + + def reset_postfork_child(self): + self.condition = threading.Condition() def _abort(state, code, details): @@ -166,21 +170,30 @@ def _event_handler(state, response_deserializer): done = not state.due for callback in callbacks: callback() - return done + return done and state.fork_epoch >= cygrpc.get_fork_epoch() return handle_event def _consume_request_iterator(request_iterator, state, call, request_serializer, event_handler): + if cygrpc.is_fork_support_enabled(): + condition_wait_timeout = 1.0 + else: + condition_wait_timeout = None def consume_request_iterator(): # pylint: disable=too-many-branches while True: + return_from_user_request_generator_invoked = False try: + # The thread may die in user-code. Do not block fork for this. + cygrpc.enter_user_request_generator() request = next(request_iterator) except StopIteration: break except Exception: # pylint: disable=broad-except + cygrpc.return_from_user_request_generator() + return_from_user_request_generator_invoked = True code = grpc.StatusCode.UNKNOWN details = 'Exception iterating requests!' _LOGGER.exception(details) @@ -188,6 +201,9 @@ def _consume_request_iterator(request_iterator, state, call, request_serializer, details) _abort(state, code, details) return + finally: + if not return_from_user_request_generator_invoked: + cygrpc.return_from_user_request_generator() serialized_request = _common.serialize(request, request_serializer) with state.condition: if state.code is None and not state.cancelled: @@ -208,7 +224,8 @@ def _consume_request_iterator(request_iterator, state, call, request_serializer, else: return while True: - state.condition.wait() + state.condition.wait(condition_wait_timeout) + cygrpc.block_if_fork_in_progress(state) if state.code is None: if cygrpc.OperationType.send_message not in state.due: break @@ -224,8 +241,9 @@ def _consume_request_iterator(request_iterator, state, call, request_serializer, if operating: state.due.add(cygrpc.OperationType.send_close_from_client) - consumption_thread = threading.Thread(target=consume_request_iterator) - consumption_thread.daemon = True + consumption_thread = cygrpc.ForkManagedThread( + target=consume_request_iterator) + consumption_thread.setDaemon(True) consumption_thread.start() @@ -671,13 +689,20 @@ class _ChannelCallState(object): self.lock = threading.Lock() self.channel = channel self.managed_calls = 0 + self.threading = False + + def reset_postfork_child(self): + self.managed_calls = 0 def _run_channel_spin_thread(state): def channel_spin(): while True: + cygrpc.block_if_fork_in_progress(state) event = state.channel.next_call_event() + if event.completion_type == cygrpc.CompletionType.queue_timeout: + continue call_completed = event.tag(event) if call_completed: with state.lock: @@ -685,8 +710,8 @@ def _run_channel_spin_thread(state): if state.managed_calls == 0: return - channel_spin_thread = threading.Thread(target=channel_spin) - channel_spin_thread.daemon = True + channel_spin_thread = cygrpc.ForkManagedThread(target=channel_spin) + channel_spin_thread.setDaemon(True) channel_spin_thread.start() @@ -742,6 +767,13 @@ class _ChannelConnectivityState(object): self.callbacks_and_connectivities = [] self.delivering = False + def reset_postfork_child(self): + self.polling = False + self.connectivity = None + self.try_to_connect = False + self.callbacks_and_connectivities = [] + self.delivering = False + def _deliveries(state): callbacks_needing_update = [] @@ -758,6 +790,7 @@ def _deliver(state, initial_connectivity, initial_callbacks): callbacks = initial_callbacks while True: for callback in callbacks: + cygrpc.block_if_fork_in_progress(state) callable_util.call_logging_exceptions( callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE, connectivity) @@ -771,7 +804,7 @@ def _deliver(state, initial_connectivity, initial_callbacks): def _spawn_delivery(state, callbacks): - delivering_thread = threading.Thread( + delivering_thread = cygrpc.ForkManagedThread( target=_deliver, args=( state, state.connectivity, @@ -799,6 +832,7 @@ def _poll_connectivity(state, channel, initial_try_to_connect): while True: event = channel.watch_connectivity_state(connectivity, time.time() + 0.2) + cygrpc.block_if_fork_in_progress(state) with state.lock: if not state.callbacks_and_connectivities and not state.try_to_connect: state.polling = False @@ -826,10 +860,10 @@ def _moot(state): def _subscribe(state, callback, try_to_connect): with state.lock: if not state.callbacks_and_connectivities and not state.polling: - polling_thread = threading.Thread( + polling_thread = cygrpc.ForkManagedThread( target=_poll_connectivity, args=(state, state.channel, bool(try_to_connect))) - polling_thread.daemon = True + polling_thread.setDaemon(True) polling_thread.start() state.polling = True state.callbacks_and_connectivities.append([callback, None]) @@ -876,6 +910,7 @@ class Channel(grpc.Channel): _common.encode(target), _options(options), credentials) self._call_state = _ChannelCallState(self._channel) self._connectivity_state = _ChannelConnectivityState(self._channel) + cygrpc.fork_register_channel(self) def subscribe(self, callback, try_to_connect=None): _subscribe(self._connectivity_state, callback, try_to_connect) @@ -919,6 +954,11 @@ class Channel(grpc.Channel): self._channel.close(cygrpc.StatusCode.cancelled, 'Channel closed!') _moot(self._connectivity_state) + def _close_on_fork(self): + self._channel.close_on_fork(cygrpc.StatusCode.cancelled, + 'Channel closed due to fork') + _moot(self._connectivity_state) + def __enter__(self): return self @@ -939,4 +979,5 @@ class Channel(grpc.Channel): # for as long as they are in use and to close them after using them, # then deletion of this grpc._channel.Channel instance can be made to # effect closure of the underlying cygrpc.Channel instance. + cygrpc.fork_unregister_channel(self) _moot(self._connectivity_state) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi index a0de862d947..24e85b08e72 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi @@ -19,7 +19,7 @@ cdef class Call: def __cinit__(self): # Create an *empty* call - grpc_init() + fork_handlers_and_grpc_init() self.c_call = NULL self.references = [] diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi index f067d76fab6..ced32abba14 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi @@ -40,6 +40,7 @@ cdef class _ChannelState: # field and just use the NULLness of c_channel as an indication that the # channel is closed. cdef object open + cdef object closed_reason # A dict from _BatchOperationTag to _CallState cdef dict integrated_call_states diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index aa187e88a62..a81ff4d823b 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -15,6 +15,7 @@ cimport cpython import threading +import time _INTERNAL_CALL_ERROR_MESSAGE_FORMAT = ( 'Internal gRPC call error %d. ' + @@ -83,6 +84,7 @@ cdef class _ChannelState: self.integrated_call_states = {} self.segregated_call_states = set() self.connectivity_due = set() + self.closed_reason = None cdef tuple _operate(grpc_call *c_call, object operations, object user_tag): @@ -142,10 +144,10 @@ cdef _cancel( _check_and_raise_call_error_no_metadata(c_call_error) -cdef BatchOperationEvent _next_call_event( +cdef _next_call_event( _ChannelState channel_state, grpc_completion_queue *c_completion_queue, - on_success): - tag, event = _latent_event(c_completion_queue, None) + on_success, deadline): + tag, event = _latent_event(c_completion_queue, deadline) with channel_state.condition: on_success(tag) channel_state.condition.notify_all() @@ -229,8 +231,7 @@ cdef void _call( call_state.due.update(started_tags) on_success(started_tags) else: - raise ValueError('Cannot invoke RPC on closed channel!') - + raise ValueError('Cannot invoke RPC: %s' % channel_state.closed_reason) cdef void _process_integrated_call_tag( _ChannelState state, _BatchOperationTag tag) except *: cdef _CallState call_state = state.integrated_call_states.pop(tag) @@ -302,7 +303,7 @@ cdef class SegregatedCall: _process_segregated_call_tag( self._channel_state, self._call_state, self._c_completion_queue, tag) return _next_call_event( - self._channel_state, self._c_completion_queue, on_success) + self._channel_state, self._c_completion_queue, on_success, None) cdef SegregatedCall _segregated_call( @@ -346,7 +347,7 @@ cdef object _watch_connectivity_state( state.c_connectivity_completion_queue, tag) state.connectivity_due.add(tag) else: - raise ValueError('Cannot invoke RPC on closed channel!') + raise ValueError('Cannot invoke RPC: %s' % state.closed_reason) completed_tag, event = _latent_event( state.c_connectivity_completion_queue, None) with state.condition: @@ -355,12 +356,15 @@ cdef object _watch_connectivity_state( return event -cdef _close(_ChannelState state, grpc_status_code code, object details): +cdef _close(Channel channel, grpc_status_code code, object details, + drain_calls): + cdef _ChannelState state = channel._state cdef _CallState call_state encoded_details = _encode(details) with state.condition: if state.open: state.open = False + state.closed_reason = details for call_state in set(state.integrated_call_states.values()): grpc_call_cancel_with_status( call_state.c_call, code, encoded_details, NULL) @@ -370,12 +374,19 @@ cdef _close(_ChannelState state, grpc_status_code code, object details): # TODO(https://github.com/grpc/grpc/issues/3064): Cancel connectivity # watching. - while state.integrated_call_states: - state.condition.wait() - while state.segregated_call_states: - state.condition.wait() - while state.connectivity_due: - state.condition.wait() + if drain_calls: + while not _calls_drained(state): + event = channel.next_call_event() + if event.completion_type == CompletionType.queue_timeout: + continue + event.tag(event) + else: + while state.integrated_call_states: + state.condition.wait() + while state.segregated_call_states: + state.condition.wait() + while state.connectivity_due: + state.condition.wait() _destroy_c_completion_queue(state.c_call_completion_queue) _destroy_c_completion_queue(state.c_connectivity_completion_queue) @@ -390,13 +401,17 @@ cdef _close(_ChannelState state, grpc_status_code code, object details): state.condition.wait() +cdef _calls_drained(_ChannelState state): + return not (state.integrated_call_states or state.segregated_call_states or + state.connectivity_due) + cdef class Channel: def __cinit__( self, bytes target, object arguments, ChannelCredentials channel_credentials): arguments = () if arguments is None else tuple(arguments) - grpc_init() + fork_handlers_and_grpc_init() self._state = _ChannelState() self._vtable.copy = &_copy_pointer self._vtable.destroy = &_destroy_pointer @@ -435,9 +450,14 @@ cdef class Channel: def next_call_event(self): def on_success(tag): - _process_integrated_call_tag(self._state, tag) - return _next_call_event( - self._state, self._state.c_call_completion_queue, on_success) + if tag is not None: + _process_integrated_call_tag(self._state, tag) + if is_fork_support_enabled(): + queue_deadline = time.time() + 1.0 + else: + queue_deadline = None + return _next_call_event(self._state, self._state.c_call_completion_queue, + on_success, queue_deadline) def segregated_call( self, int flags, method, host, object deadline, object metadata, @@ -452,11 +472,14 @@ cdef class Channel: return grpc_channel_check_connectivity_state( self._state.c_channel, try_to_connect) else: - raise ValueError('Cannot invoke RPC on closed channel!') + raise ValueError('Cannot invoke RPC: %s' % self._state.closed_reason) def watch_connectivity_state( self, grpc_connectivity_state last_observed_state, object deadline): return _watch_connectivity_state(self._state, last_observed_state, deadline) def close(self, code, details): - _close(self._state, code, details) + _close(self, code, details, False) + + def close_on_fork(self, code, details): + _close(self, code, details, True) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi index a2d765546a5..141116df5dd 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -71,7 +71,7 @@ cdef class CompletionQueue: def __cinit__(self, shutdown_cq=False): cdef grpc_completion_queue_attributes c_attrs - grpc_init() + fork_handlers_and_grpc_init() if shutdown_cq: c_attrs.version = 1 c_attrs.cq_completion_type = GRPC_CQ_NEXT diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 0a25218e19e..e3c1c8215cb 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -21,7 +21,7 @@ from libc.stdint cimport uintptr_t def _spawn_callback_in_thread(cb_func, args): - threading.Thread(target=cb_func, args=args).start() + ForkManagedThread(target=cb_func, args=args).start() async_callback_func = _spawn_callback_in_thread @@ -114,7 +114,7 @@ cdef class ChannelCredentials: cdef class SSLSessionCacheLRU: def __cinit__(self, capacity): - grpc_init() + fork_handlers_and_grpc_init() self._cache = grpc_ssl_session_cache_create_lru(capacity) def __int__(self): @@ -172,7 +172,7 @@ cdef class CompositeChannelCredentials(ChannelCredentials): cdef class ServerCertificateConfig: def __cinit__(self): - grpc_init() + fork_handlers_and_grpc_init() self.c_cert_config = NULL self.c_pem_root_certs = NULL self.c_ssl_pem_key_cert_pairs = NULL @@ -187,7 +187,7 @@ cdef class ServerCertificateConfig: cdef class ServerCredentials: def __cinit__(self): - grpc_init() + fork_handlers_and_grpc_init() self.c_credentials = NULL self.references = [] self.initial_cert_config = None diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pxd.pxi new file mode 100644 index 00000000000..a925bdd2e69 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pxd.pxi @@ -0,0 +1,29 @@ +# 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. + + +cdef extern from "pthread.h" nogil: + int pthread_atfork( + void (*prepare)() nogil, + void (*parent)() nogil, + void (*child)() nogil) + + +cdef void __prefork() nogil + + +cdef void __postfork_parent() nogil + + +cdef void __postfork_child() nogil \ No newline at end of file diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi new file mode 100644 index 00000000000..1176258da89 --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi @@ -0,0 +1,203 @@ +# 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. + + +import logging +import os +import threading + +_LOGGER = logging.getLogger(__name__) + +_AWAIT_THREADS_TIMEOUT_SECONDS = 5 + +_TRUE_VALUES = ['yes', 'Yes', 'YES', 'true', 'True', 'TRUE', '1'] + +# This flag enables experimental support within gRPC Python for applications +# that will fork() without exec(). When enabled, gRPC Python will attempt to +# pause all of its internally created threads before the fork syscall proceeds. +# +# For this to be successful, the application must not have multiple threads of +# its own calling into gRPC when fork is invoked. Any callbacks from gRPC +# Python-spawned threads into user code (e.g., callbacks for asynchronous RPCs) +# must not block and should execute quickly. +# +# This flag is not supported on Windows. +_GRPC_ENABLE_FORK_SUPPORT = ( + os.environ.get('GRPC_ENABLE_FORK_SUPPORT', '0') + .lower() in _TRUE_VALUES) + +_GRPC_POLL_STRATEGY = os.environ.get('GRPC_POLL_STRATEGY') + +cdef void __prefork() nogil: + with gil: + with _fork_state.fork_in_progress_condition: + _fork_state.fork_in_progress = True + if not _fork_state.active_thread_count.await_zero_threads( + _AWAIT_THREADS_TIMEOUT_SECONDS): + _LOGGER.error( + 'Failed to shutdown gRPC Python threads prior to fork. ' + 'Behavior after fork will be undefined.') + + +cdef void __postfork_parent() nogil: + with gil: + with _fork_state.fork_in_progress_condition: + _fork_state.fork_in_progress = False + _fork_state.fork_in_progress_condition.notify_all() + + +cdef void __postfork_child() nogil: + with gil: + # Thread could be holding the fork_in_progress_condition inside of + # block_if_fork_in_progress() when fork occurs. Reset the lock here. + _fork_state.fork_in_progress_condition = threading.Condition() + # A thread in return_from_user_request_generator() may hold this lock + # when fork occurs. + _fork_state.active_thread_count = _ActiveThreadCount() + for state_to_reset in _fork_state.postfork_states_to_reset: + state_to_reset.reset_postfork_child() + _fork_state.fork_epoch += 1 + for channel in _fork_state.channels: + channel._close_on_fork() + # TODO(ericgribkoff) Check and abort if core is not shutdown + with _fork_state.fork_in_progress_condition: + _fork_state.fork_in_progress = False + + +def fork_handlers_and_grpc_init(): + grpc_init() + if _GRPC_ENABLE_FORK_SUPPORT: + # TODO(ericgribkoff) epoll1 is default for grpcio distribution. Decide whether to expose + # grpc_get_poll_strategy_name() from ev_posix.cc to get actual polling choice. + if _GRPC_POLL_STRATEGY is not None and _GRPC_POLL_STRATEGY != "epoll1": + _LOGGER.error( + 'gRPC Python fork support is only compatible with the epoll1 ' + 'polling engine') + return + with _fork_state.fork_handler_registered_lock: + if not _fork_state.fork_handler_registered: + pthread_atfork(&__prefork, &__postfork_parent, &__postfork_child) + _fork_state.fork_handler_registered = True + + +class ForkManagedThread(object): + def __init__(self, target, args=()): + if _GRPC_ENABLE_FORK_SUPPORT: + def managed_target(*args): + try: + target(*args) + finally: + _fork_state.active_thread_count.decrement() + self._thread = threading.Thread(target=managed_target, args=args) + else: + self._thread = threading.Thread(target=target, args=args) + + def setDaemon(self, daemonic): + self._thread.daemon = daemonic + + def start(self): + if _GRPC_ENABLE_FORK_SUPPORT: + _fork_state.active_thread_count.increment() + self._thread.start() + + def join(self): + self._thread.join() + + +def block_if_fork_in_progress(postfork_state_to_reset=None): + if _GRPC_ENABLE_FORK_SUPPORT: + with _fork_state.fork_in_progress_condition: + if not _fork_state.fork_in_progress: + return + if postfork_state_to_reset is not None: + _fork_state.postfork_states_to_reset.append(postfork_state_to_reset) + _fork_state.active_thread_count.decrement() + _fork_state.fork_in_progress_condition.wait() + _fork_state.active_thread_count.increment() + + +def enter_user_request_generator(): + if _GRPC_ENABLE_FORK_SUPPORT: + _fork_state.active_thread_count.decrement() + + +def return_from_user_request_generator(): + if _GRPC_ENABLE_FORK_SUPPORT: + _fork_state.active_thread_count.increment() + block_if_fork_in_progress() + + +def get_fork_epoch(): + return _fork_state.fork_epoch + + +def is_fork_support_enabled(): + return _GRPC_ENABLE_FORK_SUPPORT + + +def fork_register_channel(channel): + if _GRPC_ENABLE_FORK_SUPPORT: + _fork_state.channels.add(channel) + + +def fork_unregister_channel(channel): + if _GRPC_ENABLE_FORK_SUPPORT: + _fork_state.channels.remove(channel) + + +class _ActiveThreadCount(object): + def __init__(self): + self._num_active_threads = 0 + self._condition = threading.Condition() + + def increment(self): + with self._condition: + self._num_active_threads += 1 + + def decrement(self): + with self._condition: + self._num_active_threads -= 1 + if self._num_active_threads == 0: + self._condition.notify_all() + + def await_zero_threads(self, timeout_secs): + end_time = time.time() + timeout_secs + wait_time = timeout_secs + with self._condition: + while True: + if self._num_active_threads > 0: + self._condition.wait(wait_time) + if self._num_active_threads == 0: + return True + # Thread count may have increased before this re-obtains the + # lock after a notify(). Wait again until timeout_secs has + # elapsed. + wait_time = end_time - time.time() + if wait_time <= 0: + return False + + +class _ForkState(object): + def __init__(self): + self.fork_in_progress_condition = threading.Condition() + self.fork_in_progress = False + self.postfork_states_to_reset = [] + self.fork_handler_registered_lock = threading.Lock() + self.fork_handler_registered = False + self.active_thread_count = _ActiveThreadCount() + self.fork_epoch = 0 + self.channels = set() + + +_fork_state = _ForkState() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/fork_windows.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/fork_windows.pyx.pxi new file mode 100644 index 00000000000..8dc1ef3b1ad --- /dev/null +++ b/src/python/grpcio/grpc/_cython/_cygrpc/fork_windows.pyx.pxi @@ -0,0 +1,63 @@ +# 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. + + +import threading + +# No-op implementations for Windows. + +def fork_handlers_and_grpc_init(): + grpc_init() + + +class ForkManagedThread(object): + def __init__(self, target, args=()): + self._thread = threading.Thread(target=target, args=args) + + def setDaemon(self, daemonic): + self._thread.daemon = daemonic + + def start(self): + self._thread.start() + + def join(self): + self._thread.join() + + +def block_if_fork_in_progress(postfork_state_to_reset=None): + pass + + +def enter_user_request_generator(): + pass + + +def return_from_user_request_generator(): + pass + + +def get_fork_epoch(): + return 0 + + +def is_fork_support_enabled(): + return False + + +def fork_register_channel(channel): + pass + + +def fork_unregister_channel(channel): + pass diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index 37b98ebbdb6..fe98d559f34 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -127,7 +127,7 @@ class CompressionLevel: cdef class CallDetails: def __cinit__(self): - grpc_init() + fork_handlers_and_grpc_init() with nogil: grpc_call_details_init(&self.c_details) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index da3dd212441..db59d468dce 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -60,7 +60,7 @@ cdef grpc_ssl_certificate_config_reload_status _server_cert_config_fetcher_wrapp cdef class Server: def __cinit__(self, object arguments): - grpc_init() + fork_handlers_and_grpc_init() self.references = [] self.registered_completion_queues = [] self._vtable.copy = &_copy_pointer diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd index 0cc26bc0d05..8258b857bc4 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pxd +++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd @@ -31,3 +31,6 @@ include "_cygrpc/time.pxd.pxi" include "_cygrpc/_hooks.pxd.pxi" include "_cygrpc/grpc_gevent.pxd.pxi" + +IF UNAME_SYSNAME != "Windows": + include "_cygrpc/fork_posix.pxd.pxi" diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index 3cac406687c..026f7ba2e33 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -39,6 +39,11 @@ include "_cygrpc/_hooks.pyx.pxi" include "_cygrpc/grpc_gevent.pyx.pxi" +IF UNAME_SYSNAME == "Windows": + include "_cygrpc/fork_windows.pyx.pxi" +ELSE: + include "_cygrpc/fork_posix.pyx.pxi" + # # initialize gRPC # diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index a23c9800178..0dfbf3180bb 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -202,3 +202,28 @@ class RunInterop(test.test): from tests.interop import client sys.argv[1:] = self.args.split() client.test_interoperability() + + +class RunFork(test.test): + + description = 'run fork test client' + user_options = [('args=', 'a', 'pass-thru arguments for the client')] + + def initialize_options(self): + self.args = '' + + def finalize_options(self): + # distutils requires this override. + pass + + def run(self): + if self.distribution.install_requires: + self.distribution.fetch_build_eggs( + self.distribution.install_requires) + if self.distribution.tests_require: + self.distribution.fetch_build_eggs(self.distribution.tests_require) + # We import here to ensure that our setuptools parent has had a chance to + # edit the Python system path. + from tests.fork import client + sys.argv[1:] = self.args.split() + client.test_fork() diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index a94c0963ec1..61c98fa038b 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -52,6 +52,7 @@ COMMAND_CLASS = { 'preprocess': commands.GatherProto, 'build_package_protos': grpc_tools.command.BuildPackageProtos, 'build_py': commands.BuildPy, + 'run_fork': commands.RunFork, 'run_interop': commands.RunInterop, 'test_lite': commands.TestLite, 'test_gevent': commands.TestGevent, diff --git a/src/python/grpcio_tests/tests/fork/__init__.py b/src/python/grpcio_tests/tests/fork/__init__.py new file mode 100644 index 00000000000..9a26bac0101 --- /dev/null +++ b/src/python/grpcio_tests/tests/fork/__init__.py @@ -0,0 +1,13 @@ +# 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. diff --git a/src/python/grpcio_tests/tests/fork/client.py b/src/python/grpcio_tests/tests/fork/client.py new file mode 100644 index 00000000000..9a32629ed5a --- /dev/null +++ b/src/python/grpcio_tests/tests/fork/client.py @@ -0,0 +1,76 @@ +# 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. +"""The Python implementation of the GRPC interoperability test client.""" + +import argparse +import logging +import sys + +from tests.fork import methods + + +def _args(): + + def parse_bool(value): + if value == 'true': + return True + if value == 'false': + return False + raise argparse.ArgumentTypeError('Only true/false allowed') + + parser = argparse.ArgumentParser() + parser.add_argument( + '--server_host', + default="localhost", + type=str, + help='the host to which to connect') + parser.add_argument( + '--server_port', + type=int, + required=True, + help='the port to which to connect') + parser.add_argument( + '--test_case', + default='large_unary', + type=str, + help='the test case to execute') + parser.add_argument( + '--use_tls', + default=False, + type=parse_bool, + help='require a secure connection') + return parser.parse_args() + + +def _test_case_from_arg(test_case_arg): + for test_case in methods.TestCase: + if test_case_arg == test_case.value: + return test_case + else: + raise ValueError('No test case "%s"!' % test_case_arg) + + +def test_fork(): + logging.basicConfig(level=logging.INFO) + args = _args() + if args.test_case == "all": + for test_case in methods.TestCase: + test_case.run_test(args) + else: + test_case = _test_case_from_arg(args.test_case) + test_case.run_test(args) + + +if __name__ == '__main__': + test_fork() diff --git a/src/python/grpcio_tests/tests/fork/methods.py b/src/python/grpcio_tests/tests/fork/methods.py new file mode 100644 index 00000000000..889ef13cb28 --- /dev/null +++ b/src/python/grpcio_tests/tests/fork/methods.py @@ -0,0 +1,445 @@ +# 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. +"""Implementations of fork support test methods.""" + +import enum +import json +import logging +import multiprocessing +import os +import threading +import time + +import grpc + +from six.moves import queue + +from src.proto.grpc.testing import empty_pb2 +from src.proto.grpc.testing import messages_pb2 +from src.proto.grpc.testing import test_pb2_grpc + +_LOGGER = logging.getLogger(__name__) + + +def _channel(args): + target = '{}:{}'.format(args.server_host, args.server_port) + if args.use_tls: + channel_credentials = grpc.ssl_channel_credentials() + channel = grpc.secure_channel(target, channel_credentials) + else: + channel = grpc.insecure_channel(target) + return channel + + +def _validate_payload_type_and_length(response, expected_type, expected_length): + if response.payload.type is not expected_type: + raise ValueError('expected payload type %s, got %s' % + (expected_type, type(response.payload.type))) + elif len(response.payload.body) != expected_length: + raise ValueError('expected payload body size %d, got %d' % + (expected_length, len(response.payload.body))) + + +def _async_unary(stub): + size = 314159 + request = messages_pb2.SimpleRequest( + response_type=messages_pb2.COMPRESSABLE, + response_size=size, + payload=messages_pb2.Payload(body=b'\x00' * 271828)) + response_future = stub.UnaryCall.future(request) + response = response_future.result() + _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE, size) + + +def _blocking_unary(stub): + size = 314159 + request = messages_pb2.SimpleRequest( + response_type=messages_pb2.COMPRESSABLE, + response_size=size, + payload=messages_pb2.Payload(body=b'\x00' * 271828)) + response = stub.UnaryCall(request) + _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE, size) + + +class _Pipe(object): + + def __init__(self): + self._condition = threading.Condition() + self._values = [] + self._open = True + + def __iter__(self): + return self + + def __next__(self): + return self.next() + + def next(self): + with self._condition: + while not self._values and self._open: + self._condition.wait() + if self._values: + return self._values.pop(0) + else: + raise StopIteration() + + def add(self, value): + with self._condition: + self._values.append(value) + self._condition.notify() + + def close(self): + with self._condition: + self._open = False + self._condition.notify() + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + self.close() + + +class _ChildProcess(object): + + def __init__(self, task, args=None): + if args is None: + args = () + self._exceptions = multiprocessing.Queue() + + def record_exceptions(): + try: + task(*args) + except Exception as e: # pylint: disable=broad-except + self._exceptions.put(e) + + self._process = multiprocessing.Process(target=record_exceptions) + + def start(self): + self._process.start() + + def finish(self): + self._process.join() + if self._process.exitcode != 0: + raise ValueError('Child process failed with exitcode %d' % + self._process.exitcode) + try: + exception = self._exceptions.get(block=False) + raise ValueError('Child process failed: %s' % exception) + except queue.Empty: + pass + + +def _async_unary_same_channel(channel): + + def child_target(): + try: + _async_unary(stub) + raise Exception( + 'Child should not be able to re-use channel after fork') + except ValueError as expected_value_error: + pass + + stub = test_pb2_grpc.TestServiceStub(channel) + _async_unary(stub) + child_process = _ChildProcess(child_target) + child_process.start() + _async_unary(stub) + child_process.finish() + + +def _async_unary_new_channel(channel, args): + + def child_target(): + child_channel = _channel(args) + child_stub = test_pb2_grpc.TestServiceStub(child_channel) + _async_unary(child_stub) + child_channel.close() + + stub = test_pb2_grpc.TestServiceStub(channel) + _async_unary(stub) + child_process = _ChildProcess(child_target) + child_process.start() + _async_unary(stub) + child_process.finish() + + +def _blocking_unary_same_channel(channel): + + def child_target(): + try: + _blocking_unary(stub) + raise Exception( + 'Child should not be able to re-use channel after fork') + except ValueError as expected_value_error: + pass + + stub = test_pb2_grpc.TestServiceStub(channel) + _blocking_unary(stub) + child_process = _ChildProcess(child_target) + child_process.start() + child_process.finish() + + +def _blocking_unary_new_channel(channel, args): + + def child_target(): + child_channel = _channel(args) + child_stub = test_pb2_grpc.TestServiceStub(child_channel) + _blocking_unary(child_stub) + child_channel.close() + + stub = test_pb2_grpc.TestServiceStub(channel) + _blocking_unary(stub) + child_process = _ChildProcess(child_target) + child_process.start() + _blocking_unary(stub) + child_process.finish() + + +# Verify that the fork channel registry can handle already closed channels +def _close_channel_before_fork(channel, args): + + def child_target(): + new_channel.close() + child_channel = _channel(args) + child_stub = test_pb2_grpc.TestServiceStub(child_channel) + _blocking_unary(child_stub) + child_channel.close() + + stub = test_pb2_grpc.TestServiceStub(channel) + _blocking_unary(stub) + channel.close() + + new_channel = _channel(args) + new_stub = test_pb2_grpc.TestServiceStub(new_channel) + child_process = _ChildProcess(child_target) + child_process.start() + _blocking_unary(new_stub) + child_process.finish() + + +def _connectivity_watch(channel, args): + + def child_target(): + + def child_connectivity_callback(state): + child_states.append(state) + + child_states = [] + child_channel = _channel(args) + child_stub = test_pb2_grpc.TestServiceStub(child_channel) + child_channel.subscribe(child_connectivity_callback) + _async_unary(child_stub) + if len(child_states + ) < 2 or child_states[-1] != grpc.ChannelConnectivity.READY: + raise ValueError('Channel did not move to READY') + if len(parent_states) > 1: + raise ValueError('Received connectivity updates on parent callback') + child_channel.unsubscribe(child_connectivity_callback) + child_channel.close() + + def parent_connectivity_callback(state): + parent_states.append(state) + + parent_states = [] + channel.subscribe(parent_connectivity_callback) + stub = test_pb2_grpc.TestServiceStub(channel) + child_process = _ChildProcess(child_target) + child_process.start() + _async_unary(stub) + if len(parent_states + ) < 2 or parent_states[-1] != grpc.ChannelConnectivity.READY: + raise ValueError('Channel did not move to READY') + channel.unsubscribe(parent_connectivity_callback) + child_process.finish() + + # Need to unsubscribe or _channel.py in _poll_connectivity triggers a + # "Cannot invoke RPC on closed channel!" error. + # TODO(ericgribkoff) Fix issue with channel.close() and connectivity polling + channel.unsubscribe(parent_connectivity_callback) + + +def _ping_pong_with_child_processes_after_first_response( + channel, args, child_target, run_after_close=True): + request_response_sizes = ( + 31415, + 9, + 2653, + 58979, + ) + request_payload_sizes = ( + 27182, + 8, + 1828, + 45904, + ) + stub = test_pb2_grpc.TestServiceStub(channel) + pipe = _Pipe() + parent_bidi_call = stub.FullDuplexCall(pipe) + child_processes = [] + first_message_received = False + for response_size, payload_size in zip(request_response_sizes, + request_payload_sizes): + request = messages_pb2.StreamingOutputCallRequest( + response_type=messages_pb2.COMPRESSABLE, + response_parameters=( + messages_pb2.ResponseParameters(size=response_size),), + payload=messages_pb2.Payload(body=b'\x00' * payload_size)) + pipe.add(request) + if first_message_received: + child_process = _ChildProcess(child_target, + (parent_bidi_call, channel, args)) + child_process.start() + child_processes.append(child_process) + response = next(parent_bidi_call) + first_message_received = True + child_process = _ChildProcess(child_target, + (parent_bidi_call, channel, args)) + child_process.start() + child_processes.append(child_process) + _validate_payload_type_and_length(response, messages_pb2.COMPRESSABLE, + response_size) + pipe.close() + if run_after_close: + child_process = _ChildProcess(child_target, + (parent_bidi_call, channel, args)) + child_process.start() + child_processes.append(child_process) + for child_process in child_processes: + child_process.finish() + + +def _in_progress_bidi_continue_call(channel): + + def child_target(parent_bidi_call, parent_channel, args): + stub = test_pb2_grpc.TestServiceStub(parent_channel) + try: + _async_unary(stub) + raise Exception( + 'Child should not be able to re-use channel after fork') + except ValueError as expected_value_error: + pass + inherited_code = parent_bidi_call.code() + inherited_details = parent_bidi_call.details() + if inherited_code != grpc.StatusCode.CANCELLED: + raise ValueError( + 'Expected inherited code CANCELLED, got %s' % inherited_code) + if inherited_details != 'Channel closed due to fork': + raise ValueError( + 'Expected inherited details Channel closed due to fork, got %s' + % inherited_details) + + # Don't run child_target after closing the parent call, as the call may have + # received a status from the server before fork occurs. + _ping_pong_with_child_processes_after_first_response( + channel, None, child_target, run_after_close=False) + + +def _in_progress_bidi_same_channel_async_call(channel): + + def child_target(parent_bidi_call, parent_channel, args): + stub = test_pb2_grpc.TestServiceStub(parent_channel) + try: + _async_unary(stub) + raise Exception( + 'Child should not be able to re-use channel after fork') + except ValueError as expected_value_error: + pass + + _ping_pong_with_child_processes_after_first_response( + channel, None, child_target) + + +def _in_progress_bidi_same_channel_blocking_call(channel): + + def child_target(parent_bidi_call, parent_channel, args): + stub = test_pb2_grpc.TestServiceStub(parent_channel) + try: + _blocking_unary(stub) + raise Exception( + 'Child should not be able to re-use channel after fork') + except ValueError as expected_value_error: + pass + + _ping_pong_with_child_processes_after_first_response( + channel, None, child_target) + + +def _in_progress_bidi_new_channel_async_call(channel, args): + + def child_target(parent_bidi_call, parent_channel, args): + channel = _channel(args) + stub = test_pb2_grpc.TestServiceStub(channel) + _async_unary(stub) + + _ping_pong_with_child_processes_after_first_response( + channel, args, child_target) + + +def _in_progress_bidi_new_channel_blocking_call(channel, args): + + def child_target(parent_bidi_call, parent_channel, args): + channel = _channel(args) + stub = test_pb2_grpc.TestServiceStub(channel) + _blocking_unary(stub) + + _ping_pong_with_child_processes_after_first_response( + channel, args, child_target) + + +@enum.unique +class TestCase(enum.Enum): + + CONNECTIVITY_WATCH = 'connectivity_watch' + CLOSE_CHANNEL_BEFORE_FORK = 'close_channel_before_fork' + ASYNC_UNARY_SAME_CHANNEL = 'async_unary_same_channel' + ASYNC_UNARY_NEW_CHANNEL = 'async_unary_new_channel' + BLOCKING_UNARY_SAME_CHANNEL = 'blocking_unary_same_channel' + BLOCKING_UNARY_NEW_CHANNEL = 'blocking_unary_new_channel' + IN_PROGRESS_BIDI_CONTINUE_CALL = 'in_progress_bidi_continue_call' + IN_PROGRESS_BIDI_SAME_CHANNEL_ASYNC_CALL = 'in_progress_bidi_same_channel_async_call' + IN_PROGRESS_BIDI_SAME_CHANNEL_BLOCKING_CALL = 'in_progress_bidi_same_channel_blocking_call' + IN_PROGRESS_BIDI_NEW_CHANNEL_ASYNC_CALL = 'in_progress_bidi_new_channel_async_call' + IN_PROGRESS_BIDI_NEW_CHANNEL_BLOCKING_CALL = 'in_progress_bidi_new_channel_blocking_call' + + def run_test(self, args): + _LOGGER.info("Running %s", self) + channel = _channel(args) + if self is TestCase.ASYNC_UNARY_SAME_CHANNEL: + _async_unary_same_channel(channel) + elif self is TestCase.ASYNC_UNARY_NEW_CHANNEL: + _async_unary_new_channel(channel, args) + elif self is TestCase.BLOCKING_UNARY_SAME_CHANNEL: + _blocking_unary_same_channel(channel) + elif self is TestCase.BLOCKING_UNARY_NEW_CHANNEL: + _blocking_unary_new_channel(channel, args) + elif self is TestCase.CLOSE_CHANNEL_BEFORE_FORK: + _close_channel_before_fork(channel, args) + elif self is TestCase.CONNECTIVITY_WATCH: + _connectivity_watch(channel, args) + elif self is TestCase.IN_PROGRESS_BIDI_CONTINUE_CALL: + _in_progress_bidi_continue_call(channel) + elif self is TestCase.IN_PROGRESS_BIDI_SAME_CHANNEL_ASYNC_CALL: + _in_progress_bidi_same_channel_async_call(channel) + elif self is TestCase.IN_PROGRESS_BIDI_SAME_CHANNEL_BLOCKING_CALL: + _in_progress_bidi_same_channel_blocking_call(channel) + elif self is TestCase.IN_PROGRESS_BIDI_NEW_CHANNEL_ASYNC_CALL: + _in_progress_bidi_new_channel_async_call(channel, args) + elif self is TestCase.IN_PROGRESS_BIDI_NEW_CHANNEL_BLOCKING_CALL: + _in_progress_bidi_new_channel_blocking_call(channel, args) + else: + raise NotImplementedError( + 'Test case "%s" not implemented!' % self.name) + channel.close() diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index ebc41c63f06..76d5d22d572 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -32,6 +32,8 @@ "unit._credentials_test.CredentialsTest", "unit._cython._cancel_many_calls_test.CancelManyCallsTest", "unit._cython._channel_test.ChannelTest", + "unit._cython._fork_test.ForkPosixTester", + "unit._cython._fork_test.ForkWindowsTester", "unit._cython._no_messages_server_completion_queue_per_call_test.Test", "unit._cython._no_messages_single_server_completion_queue_test.Test", "unit._cython._read_some_but_not_all_responses_test.ReadSomeButNotAllResponsesTest", diff --git a/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py b/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py new file mode 100644 index 00000000000..aeb02458a7e --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_cython/_fork_test.py @@ -0,0 +1,68 @@ +# 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. + +import os +import threading +import unittest + +from grpc._cython import cygrpc + + +def _get_number_active_threads(): + return cygrpc._fork_state.active_thread_count._num_active_threads + + +@unittest.skipIf(os.name == 'nt', 'Posix-specific tests') +class ForkPosixTester(unittest.TestCase): + + def setUp(self): + cygrpc._GRPC_ENABLE_FORK_SUPPORT = True + + def testForkManagedThread(self): + + def cb(): + self.assertEqual(1, _get_number_active_threads()) + + thread = cygrpc.ForkManagedThread(cb) + thread.start() + thread.join() + self.assertEqual(0, _get_number_active_threads()) + + def testForkManagedThreadThrowsException(self): + + def cb(): + self.assertEqual(1, _get_number_active_threads()) + raise Exception("expected exception") + + thread = cygrpc.ForkManagedThread(cb) + thread.start() + thread.join() + self.assertEqual(0, _get_number_active_threads()) + + +@unittest.skipUnless(os.name == 'nt', 'Windows-specific tests') +class ForkWindowsTester(unittest.TestCase): + + def testForkManagedThreadIsNoOp(self): + + def cb(): + pass + + thread = cygrpc.ForkManagedThread(cb) + thread.start() + thread.join() + + +if __name__ == '__main__': + unittest.main(verbosity=2) From 0ff641a2468e9c2563e2884a0aac987ea55849c4 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 22 Aug 2018 12:25:08 -0700 Subject: [PATCH 185/546] Define the allow pthread atfork macro for gRPC Python MacOS builds --- src/python/grpcio/commands.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py index 4c2ebaeaea2..0a3097111fc 100644 --- a/src/python/grpcio/commands.py +++ b/src/python/grpcio/commands.py @@ -265,8 +265,17 @@ class BuildExt(build_ext.build_ext): os.path.join(target_path, 'libgpr.a'), os.path.join(target_path, 'libgrpc.a') ] + # Running make separately for Mac means we lose all + # Extension.define_macros configured in setup.py. Re-add the macro + # for gRPC Core's fork handlers. + # TODO(ericgribkoff) Decide what to do about the other missing core + # macros, including GRPC_ENABLE_FORK_SUPPORT, which defaults to 1 + # on Linux but remains unset on Mac. + extra_defines = [ + 'EXTRA_DEFINES="GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1"' + ] make_process = subprocess.Popen( - ['make'] + targets, + ['make'] + extra_defines + targets, stdout=subprocess.PIPE, stderr=subprocess.PIPE) make_out, make_err = make_process.communicate() From b59d8674d24d9b40d8d8b2b40f2be0118ff524d2 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 10 Aug 2018 10:13:36 -0700 Subject: [PATCH 186/546] Python post-fork handler: exit if grpc shutdown fails --- grpc.def | 1 + include/grpc/grpc.h | 6 ++++++ src/core/lib/iomgr/fork_posix.cc | 2 +- src/core/lib/surface/init.h | 1 - src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi | 4 ++++ src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi | 1 + src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 ++ src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 +++ test/core/surface/public_headers_must_be_c89.c | 1 + 9 files changed, 19 insertions(+), 2 deletions(-) diff --git a/grpc.def b/grpc.def index 009de4e8688..72e3e90c62a 100644 --- a/grpc.def +++ b/grpc.def @@ -15,6 +15,7 @@ EXPORTS grpc_register_plugin grpc_init grpc_shutdown + grpc_is_initialized grpc_version_string grpc_g_stands_for grpc_completion_queue_factory_lookup diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 897b89851a0..4e50cd0bacb 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -79,6 +79,12 @@ GRPCAPI void grpc_init(void); destroyed. */ GRPCAPI void grpc_shutdown(void); +/** EXPERIMENTAL. Returns 1 if the grpc library has been initialized. + TODO(ericgribkoff) Decide if this should be promoted to non-experimental as + part of stabilizing the fork support API, as tracked in + https://github.com/grpc/grpc/issues/15334 */ +GRPCAPI int grpc_is_initialized(void); + /** Return a string representing the current version of grpc */ GRPCAPI const char* grpc_version_string(void); diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index a5b61fb4ce3..ac85c81de2d 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include "src/core/lib/gpr/env.h" @@ -34,7 +35,6 @@ #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/timer_manager.h" #include "src/core/lib/iomgr/wakeup_fd_posix.h" -#include "src/core/lib/surface/init.h" /* * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK diff --git a/src/core/lib/surface/init.h b/src/core/lib/surface/init.h index 9353208332f..193f51447d9 100644 --- a/src/core/lib/surface/init.h +++ b/src/core/lib/surface/init.h @@ -22,6 +22,5 @@ void grpc_register_security_filters(void); void grpc_security_pre_init(void); void grpc_security_init(void); -int grpc_is_initialized(void); #endif /* GRPC_CORE_LIB_SURFACE_INIT_H */ diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi index 1176258da89..0d2516977b8 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi @@ -73,6 +73,10 @@ cdef void __postfork_child() nogil: # TODO(ericgribkoff) Check and abort if core is not shutdown with _fork_state.fork_in_progress_condition: _fork_state.fork_in_progress = False + if grpc_is_initialized() > 0: + with gil: + _LOGGER.error('Failed to shutdown gRPC Core after fork()') + os._exit(os.EX_USAGE) def fork_handlers_and_grpc_init(): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index bcbfec0c9ff..47812193194 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -322,6 +322,7 @@ cdef extern from "grpc/grpc.h": void grpc_init() nogil void grpc_shutdown() nogil + int grpc_is_initialized() nogil ctypedef struct grpc_completion_queue_factory: pass diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 37b97aabd41..f44f89dfa04 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -38,6 +38,7 @@ grpc_call_details_destroy_type grpc_call_details_destroy_import; grpc_register_plugin_type grpc_register_plugin_import; grpc_init_type grpc_init_import; grpc_shutdown_type grpc_shutdown_import; +grpc_is_initialized_type grpc_is_initialized_import; grpc_version_string_type grpc_version_string_import; grpc_g_stands_for_type grpc_g_stands_for_import; grpc_completion_queue_factory_lookup_type grpc_completion_queue_factory_lookup_import; @@ -291,6 +292,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_register_plugin_import = (grpc_register_plugin_type) GetProcAddress(library, "grpc_register_plugin"); grpc_init_import = (grpc_init_type) GetProcAddress(library, "grpc_init"); grpc_shutdown_import = (grpc_shutdown_type) GetProcAddress(library, "grpc_shutdown"); + grpc_is_initialized_import = (grpc_is_initialized_type) GetProcAddress(library, "grpc_is_initialized"); grpc_version_string_import = (grpc_version_string_type) GetProcAddress(library, "grpc_version_string"); grpc_g_stands_for_import = (grpc_g_stands_for_type) GetProcAddress(library, "grpc_g_stands_for"); grpc_completion_queue_factory_lookup_import = (grpc_completion_queue_factory_lookup_type) GetProcAddress(library, "grpc_completion_queue_factory_lookup"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index f7a00046e31..99433f0e401 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -89,6 +89,9 @@ extern grpc_init_type grpc_init_import; typedef void(*grpc_shutdown_type)(void); extern grpc_shutdown_type grpc_shutdown_import; #define grpc_shutdown grpc_shutdown_import +typedef int(*grpc_is_initialized_type)(void); +extern grpc_is_initialized_type grpc_is_initialized_import; +#define grpc_is_initialized grpc_is_initialized_import typedef const char*(*grpc_version_string_type)(void); extern grpc_version_string_type grpc_version_string_import; #define grpc_version_string grpc_version_string_import diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 42dc95b9bb6..b832a1661be 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -77,6 +77,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_register_plugin); printf("%lx", (unsigned long) grpc_init); printf("%lx", (unsigned long) grpc_shutdown); + printf("%lx", (unsigned long) grpc_is_initialized); printf("%lx", (unsigned long) grpc_version_string); printf("%lx", (unsigned long) grpc_g_stands_for); printf("%lx", (unsigned long) grpc_completion_queue_factory_lookup); From 3a5da64e5d556b1ff57341239c0c981902c74c7e Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Wed, 22 Aug 2018 18:09:44 -0700 Subject: [PATCH 187/546] Move _server_cert_config_fetcher_wrapper to credentials.pyx.pxi --- .../grpc/_cython/_cygrpc/credentials.pyx.pxi | 38 +++++++++++++++++++ .../grpc/_cython/_cygrpc/server.pyx.pxi | 37 ------------------ 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index e3c1c8215cb..38fd9e78b2d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -282,3 +282,41 @@ def server_credentials_ssl_dynamic_cert_config(initial_cert_config, # C-core assumes ownership of c_options credentials.c_credentials = grpc_ssl_server_credentials_create_with_options(c_options) return credentials + +cdef grpc_ssl_certificate_config_reload_status _server_cert_config_fetcher_wrapper( + void* user_data, grpc_ssl_server_certificate_config **config) with gil: + # This is a credentials.ServerCertificateConfig + cdef ServerCertificateConfig cert_config = None + if not user_data: + raise ValueError('internal error: user_data must be specified') + credentials = user_data + if not credentials.initial_cert_config_fetched: + # C-core is asking for the initial cert config + credentials.initial_cert_config_fetched = True + cert_config = credentials.initial_cert_config._certificate_configuration + else: + user_cb = credentials.cert_config_fetcher + try: + cert_config_wrapper = user_cb() + except Exception: + _LOGGER.exception('Error fetching certificate config') + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL + if cert_config_wrapper is None: + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED + elif not isinstance( + cert_config_wrapper, grpc.ServerCertificateConfiguration): + _LOGGER.error( + 'Error fetching certificate configuration: certificate ' + 'configuration must be of type grpc.ServerCertificateConfiguration, ' + 'not %s' % type(cert_config_wrapper).__name__) + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL + else: + cert_config = cert_config_wrapper._certificate_configuration + config[0] = cert_config.c_cert_config + # our caller will assume ownership of memory, so we have to recreate + # a copy of c_cert_config here + cert_config.c_cert_config = grpc_ssl_server_certificate_config_create( + cert_config.c_pem_root_certs, cert_config.c_ssl_pem_key_cert_pairs, + cert_config.c_ssl_pem_key_cert_pairs_count) + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW + diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index db59d468dce..ce701724fd3 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -20,43 +20,6 @@ import grpc _LOGGER = logging.getLogger(__name__) -cdef grpc_ssl_certificate_config_reload_status _server_cert_config_fetcher_wrapper( - void* user_data, grpc_ssl_server_certificate_config **config) with gil: - # This is a credentials.ServerCertificateConfig - cdef ServerCertificateConfig cert_config = None - if not user_data: - raise ValueError('internal error: user_data must be specified') - credentials = user_data - if not credentials.initial_cert_config_fetched: - # C-core is asking for the initial cert config - credentials.initial_cert_config_fetched = True - cert_config = credentials.initial_cert_config._certificate_configuration - else: - user_cb = credentials.cert_config_fetcher - try: - cert_config_wrapper = user_cb() - except Exception: - _LOGGER.exception('Error fetching certificate config') - return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL - if cert_config_wrapper is None: - return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED - elif not isinstance( - cert_config_wrapper, grpc.ServerCertificateConfiguration): - _LOGGER.error( - 'Error fetching certificate configuration: certificate ' - 'configuration must be of type grpc.ServerCertificateConfiguration, ' - 'not %s' % type(cert_config_wrapper).__name__) - return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL - else: - cert_config = cert_config_wrapper._certificate_configuration - config[0] = cert_config.c_cert_config - # our caller will assume ownership of memory, so we have to recreate - # a copy of c_cert_config here - cert_config.c_cert_config = grpc_ssl_server_certificate_config_create( - cert_config.c_pem_root_certs, cert_config.c_ssl_pem_key_cert_pairs, - cert_config.c_ssl_pem_key_cert_pairs_count) - return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW - cdef class Server: def __cinit__(self, object arguments): From dc7bedd128f030b53541ed7d356858cd3bb094e6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 Aug 2018 11:36:46 +0200 Subject: [PATCH 188/546] C#: fix subchannel sharing for secure channels --- .../Grpc.Core.Tests/ChannelCredentialsTest.cs | 37 ++++++++++++++---- src/csharp/Grpc.Core.Tests/FakeCredentials.cs | 10 +---- src/csharp/Grpc.Core/Channel.cs | 2 +- src/csharp/Grpc.Core/ChannelCredentials.cs | 39 +++++++++++++++---- 4 files changed, 63 insertions(+), 25 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/ChannelCredentialsTest.cs b/src/csharp/Grpc.Core.Tests/ChannelCredentialsTest.cs index 62cc904a613..843d88bfb6a 100644 --- a/src/csharp/Grpc.Core.Tests/ChannelCredentialsTest.cs +++ b/src/csharp/Grpc.Core.Tests/ChannelCredentialsTest.cs @@ -17,13 +17,7 @@ #endregion using System; -using System.Diagnostics; -using System.Runtime.InteropServices; -using System.Threading; -using System.Threading.Tasks; -using Grpc.Core; using Grpc.Core.Internal; -using Grpc.Core.Utils; using NUnit.Framework; namespace Grpc.Core.Tests @@ -44,9 +38,38 @@ namespace Grpc.Core.Tests Assert.Throws(typeof(ArgumentNullException), () => ChannelCredentials.Create(null, new FakeCallCredentials())); Assert.Throws(typeof(ArgumentNullException), () => ChannelCredentials.Create(new FakeChannelCredentials(true), null)); - + // forbid composing non-composable Assert.Throws(typeof(ArgumentException), () => ChannelCredentials.Create(new FakeChannelCredentials(false), new FakeCallCredentials())); } + + [Test] + public void ChannelCredentials_NativeCredentialsAreReused() + { + // always returning the same native object is critical for subchannel sharing to work with secure channels + var creds = new SslCredentials(); + var nativeCreds1 = creds.GetNativeCredentials(); + var nativeCreds2 = creds.GetNativeCredentials(); + Assert.AreSame(nativeCreds1, nativeCreds2); + } + + [Test] + public void ChannelCredentials_CreateExceptionIsCached() + { + var creds = new ChannelCredentialsWithCreateNativeThrows(); + var ex1 = Assert.Throws(typeof(Exception), () => creds.GetNativeCredentials()); + var ex2 = Assert.Throws(typeof(Exception), () => creds.GetNativeCredentials()); + Assert.AreSame(ex1, ex2); + } + + internal class ChannelCredentialsWithCreateNativeThrows : ChannelCredentials + { + internal override bool IsComposable => false; + + internal override ChannelCredentialsSafeHandle CreateNativeCredentials() + { + throw new Exception("Creation of native credentials has failed on purpose."); + } + } } } diff --git a/src/csharp/Grpc.Core.Tests/FakeCredentials.cs b/src/csharp/Grpc.Core.Tests/FakeCredentials.cs index 7d658576e5b..f23c9e97574 100644 --- a/src/csharp/Grpc.Core.Tests/FakeCredentials.cs +++ b/src/csharp/Grpc.Core.Tests/FakeCredentials.cs @@ -16,15 +16,7 @@ #endregion -using System; -using System.Diagnostics; -using System.Runtime.InteropServices; -using System.Threading; -using System.Threading.Tasks; -using Grpc.Core; using Grpc.Core.Internal; -using Grpc.Core.Utils; -using NUnit.Framework; namespace Grpc.Core.Tests { @@ -42,7 +34,7 @@ namespace Grpc.Core.Tests get { return composable; } } - internal override ChannelCredentialsSafeHandle ToNativeCredentials() + internal override ChannelCredentialsSafeHandle CreateNativeCredentials() { return null; } diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs index e9930b6fbc4..7912b06b718 100644 --- a/src/csharp/Grpc.Core/Channel.cs +++ b/src/csharp/Grpc.Core/Channel.cs @@ -72,9 +72,9 @@ namespace Grpc.Core this.environment = GrpcEnvironment.AddRef(); this.completionQueue = this.environment.PickCompletionQueue(); - using (var nativeCredentials = credentials.ToNativeCredentials()) using (var nativeChannelArgs = ChannelOptions.CreateChannelArgs(this.options.Values)) { + var nativeCredentials = credentials.GetNativeCredentials(); if (nativeCredentials != null) { this.handle = ChannelSafeHandle.CreateSecure(nativeCredentials, target, nativeChannelArgs); diff --git a/src/csharp/Grpc.Core/ChannelCredentials.cs b/src/csharp/Grpc.Core/ChannelCredentials.cs index ba482897d75..3ce32f31b76 100644 --- a/src/csharp/Grpc.Core/ChannelCredentials.cs +++ b/src/csharp/Grpc.Core/ChannelCredentials.cs @@ -31,6 +31,19 @@ namespace Grpc.Core public abstract class ChannelCredentials { static readonly ChannelCredentials InsecureInstance = new InsecureCredentialsImpl(); + readonly Lazy cachedNativeCredentials; + + /// + /// Creates a new instance of channel credentials + /// + public ChannelCredentials() + { + // Native credentials object need to be kept alive once initialized for subchannel sharing to work correctly + // with secure connections. See https://github.com/grpc/grpc/issues/15207. + // We rely on finalizer to clean up the native portion of ChannelCredentialsSafeHandle after the ChannelCredentials + // instance becomes unused. + this.cachedNativeCredentials = new Lazy(() => CreateNativeCredentials()); + } /// /// Returns instance of credentials that provides no security and @@ -57,11 +70,22 @@ namespace Grpc.Core } /// - /// Creates native object for the credentials. May return null if insecure channel - /// should be created. + /// Gets native object for the credentials, creating one if it already doesn't exist. May return null if insecure channel + /// should be created. Caller must not call Dispose() on the returned native credentials as their lifetime + /// is managed by this class (and instances of native credentials are cached). + /// + /// The native credentials. + internal ChannelCredentialsSafeHandle GetNativeCredentials() + { + return cachedNativeCredentials.Value; + } + + /// + /// Creates a new native object for the credentials. May return null if insecure channel + /// should be created. For internal use only, use instead. /// /// The native credentials. - internal abstract ChannelCredentialsSafeHandle ToNativeCredentials(); + internal abstract ChannelCredentialsSafeHandle CreateNativeCredentials(); /// /// Returns true if this credential type allows being composed by CompositeCredentials. @@ -73,7 +97,7 @@ namespace Grpc.Core private sealed class InsecureCredentialsImpl : ChannelCredentials { - internal override ChannelCredentialsSafeHandle ToNativeCredentials() + internal override ChannelCredentialsSafeHandle CreateNativeCredentials() { return null; } @@ -145,7 +169,7 @@ namespace Grpc.Core get { return true; } } - internal override ChannelCredentialsSafeHandle ToNativeCredentials() + internal override ChannelCredentialsSafeHandle CreateNativeCredentials() { return ChannelCredentialsSafeHandle.CreateSslCredentials(rootCertificates, keyCertificatePair); } @@ -173,12 +197,11 @@ namespace Grpc.Core GrpcPreconditions.CheckArgument(channelCredentials.IsComposable, "Supplied channel credentials do not allow composition."); } - internal override ChannelCredentialsSafeHandle ToNativeCredentials() + internal override ChannelCredentialsSafeHandle CreateNativeCredentials() { - using (var channelCreds = channelCredentials.ToNativeCredentials()) using (var callCreds = callCredentials.ToNativeCredentials()) { - var nativeComposite = ChannelCredentialsSafeHandle.CreateComposite(channelCreds, callCreds); + var nativeComposite = ChannelCredentialsSafeHandle.CreateComposite(channelCredentials.GetNativeCredentials(), callCreds); if (nativeComposite.IsInvalid) { throw new ArgumentException("Error creating native composite credentials. Likely, this is because you are trying to compose incompatible credentials."); From e7fb4e57ae5628285b75a82b54df6b6bf9e15b5e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 Aug 2018 15:43:15 +0200 Subject: [PATCH 189/546] avoid deadlock while cancelling a call --- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 27 ++++++++++++++-- .../Grpc.Core/Internal/AsyncCallBase.cs | 32 ++++++++++++++++--- .../Grpc.Core/Internal/AsyncCallServer.cs | 10 ++++-- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 3c9e090ba44..66902f3caae 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -325,9 +325,18 @@ namespace Grpc.Core.Internal } } - protected override void OnAfterReleaseResources() + protected override void OnAfterReleaseResourcesLocked() { details.Channel.RemoveCallReference(this); + } + + protected override void OnAfterReleaseResourcesUnlocked() + { + // If cancellation callback is in progress, this can block + // so we need to do this outside of call's lock to prevent + // deadlock. + // See https://github.com/grpc/grpc/issues/14777 + // See https://github.com/dotnet/corefx/issues/14903 cancellationTokenRegistration?.Dispose(); } @@ -448,6 +457,7 @@ namespace Grpc.Core.Internal TResponse msg = default(TResponse); var deserializeException = TryDeserialize(receivedMessage, out msg); + bool releasedResources; lock (myLock) { finished = true; @@ -464,7 +474,12 @@ namespace Grpc.Core.Internal streamingWriteTcs = null; } - ReleaseResourcesIfPossible(); + releasedResources = ReleaseResourcesIfPossible(); + } + + if (releasedResources) + { + OnAfterReleaseResourcesUnlocked(); } responseHeadersTcs.SetResult(responseHeaders); @@ -494,6 +509,7 @@ namespace Grpc.Core.Internal TaskCompletionSource delayedStreamingWriteTcs = null; + bool releasedResources; lock (myLock) { finished = true; @@ -504,7 +520,12 @@ namespace Grpc.Core.Internal streamingWriteTcs = null; } - ReleaseResourcesIfPossible(); + releasedResources = ReleaseResourcesIfPossible(); + } + + if (releasedResources) + { + OnAfterReleaseResourcesUnlocked(); } if (delayedStreamingWriteTcs != null) diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs index 3273c26b88f..5a53049e4bd 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs @@ -196,10 +196,14 @@ namespace Grpc.Core.Internal call.Dispose(); } disposed = true; - OnAfterReleaseResources(); + OnAfterReleaseResourcesLocked(); } - protected virtual void OnAfterReleaseResources() + protected virtual void OnAfterReleaseResourcesLocked() + { + } + + protected virtual void OnAfterReleaseResourcesUnlocked() { } @@ -235,6 +239,7 @@ namespace Grpc.Core.Internal { bool delayCompletion = false; TaskCompletionSource origTcs = null; + bool releasedResources; lock (myLock) { if (!success && !finished && IsClient) { @@ -252,7 +257,12 @@ namespace Grpc.Core.Internal streamingWriteTcs = null; } - ReleaseResourcesIfPossible(); + releasedResources = ReleaseResourcesIfPossible(); + } + + if (releasedResources) + { + OnAfterReleaseResourcesUnlocked(); } if (!success) @@ -282,9 +292,15 @@ namespace Grpc.Core.Internal /// protected void HandleSendStatusFromServerFinished(bool success) { + bool releasedResources; lock (myLock) { - ReleaseResourcesIfPossible(); + releasedResources = ReleaseResourcesIfPossible(); + } + + if (releasedResources) + { + OnAfterReleaseResourcesUnlocked(); } if (!success) @@ -310,6 +326,7 @@ namespace Grpc.Core.Internal var deserializeException = (success && receivedMessage != null) ? TryDeserialize(receivedMessage, out msg) : null; TaskCompletionSource origTcs = null; + bool releasedResources; lock (myLock) { origTcs = streamingReadTcs; @@ -332,7 +349,12 @@ namespace Grpc.Core.Internal streamingReadTcs = null; } - ReleaseResourcesIfPossible(); + releasedResources = ReleaseResourcesIfPossible(); + } + + if (releasedResources) + { + OnAfterReleaseResourcesUnlocked(); } if (deserializeException != null && !IsClient) diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs index 11acb275334..0ceca4abb8f 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs @@ -184,7 +184,7 @@ namespace Grpc.Core.Internal throw new InvalidOperationException("Call be only called for client calls"); } - protected override void OnAfterReleaseResources() + protected override void OnAfterReleaseResourcesLocked() { server.RemoveCallReference(this); } @@ -206,6 +206,7 @@ namespace Grpc.Core.Internal { // NOTE: because this event is a result of batch containing GRPC_OP_RECV_CLOSE_ON_SERVER, // success will be always set to true. + bool releasedResources; lock (myLock) { finished = true; @@ -217,7 +218,12 @@ namespace Grpc.Core.Internal streamingReadTcs = new TaskCompletionSource(); streamingReadTcs.SetResult(default(TRequest)); } - ReleaseResourcesIfPossible(); + releasedResources = ReleaseResourcesIfPossible(); + } + + if (releasedResources) + { + OnAfterReleaseResourcesUnlocked(); } if (cancelled) From b03578c679bd97589bf2dc58c280c0c6ba636bad Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 23 Aug 2018 07:04:30 -0700 Subject: [PATCH 190/546] Address reviewer feedback with comments/assertions --- test/core/end2end/inproc_callback_test.cc | 78 ++++++++++++++++------- 1 file changed, 54 insertions(+), 24 deletions(-) diff --git a/test/core/end2end/inproc_callback_test.cc b/test/core/end2end/inproc_callback_test.cc index 05257dd4bf5..c174d8f44e1 100644 --- a/test/core/end2end/inproc_callback_test.cc +++ b/test/core/end2end/inproc_callback_test.cc @@ -69,11 +69,16 @@ class ShutdownCallback : public grpc_core::CQCallbackInterface { gpr_cv_broadcast(&cv_); gpr_mu_unlock(&mu_); } - void Wait(gpr_timespec deadline) { + // The Wait function waits for a specified amount of + // time for the completion of the shutdown and returns + // whether it was successfully shut down + bool Wait(gpr_timespec deadline) { gpr_mu_lock(&mu_); while (!done_ && !gpr_cv_wait(&cv_, &mu_, deadline)) { } + bool ret = done_; gpr_mu_unlock(&mu_); + return ret; } private: @@ -85,6 +90,12 @@ class ShutdownCallback : public grpc_core::CQCallbackInterface { ShutdownCallback* g_shutdown_callback; } // namespace +// The following global structure is the tag collection. It holds +// all information related to tags expected and tags received +// during the execution, with each callback setting a tag. +// The tag sets are implemented and checked using arrays and +// linear lookups (rather than maps) so that this test doesn't +// need the C++ standard library. static gpr_mu tags_mu; static gpr_cv tags_cv; const size_t kAvailableTags = 4; @@ -93,6 +104,10 @@ bool tags_valid[kAvailableTags]; bool tags_expected[kAvailableTags]; bool tags_needed[kAvailableTags]; +// Mark that a tag is expected; this function must be +// executed in the main thread only while there are no +// other threads altering the expectation set (e.g., +// running callbacks). static void expect_tag(intptr_t tag, bool ok) { size_t idx = static_cast(tag); GPR_ASSERT(idx < kAvailableTags); @@ -100,6 +115,10 @@ static void expect_tag(intptr_t tag, bool ok) { tags_expected[idx] = ok; } +// The tag verifier doesn't have to drive the CQ at all (unlike the +// next-based end2end tests) because the tags will get set when the +// callbacks are executed, which happens when a particular batch +// related to a callback is complete static void verify_tags(gpr_timespec deadline) { bool done = false; @@ -143,6 +162,30 @@ static void verify_tags(gpr_timespec deadline) { gpr_mu_unlock(&tags_mu); } +// This function creates a callback functor that emits the +// desired tag into the global tag set +static grpc_core::CQCallbackInterface* tag(intptr_t t) { + auto func = [t](bool ok) { + gpr_mu_lock(&tags_mu); + gpr_log(GPR_DEBUG, "Completing operation %" PRIdPTR, t); + bool was_empty = true; + for (size_t i = 0; i < kAvailableTags; i++) { + if (tags_valid[i]) { + was_empty = false; + } + } + size_t idx = static_cast(t); + tags[idx] = ok; + tags_valid[idx] = true; + if (was_empty) { + gpr_cv_signal(&tags_cv); + } + gpr_mu_unlock(&tags_mu); + }; + auto cb = NewDeletingCallback(func); + return cb; +} + static grpc_end2end_test_fixture inproc_create_fixture( grpc_channel_args* client_args, grpc_channel_args* server_args) { grpc_end2end_test_fixture f; @@ -180,28 +223,6 @@ void inproc_tear_down(grpc_end2end_test_fixture* f) { gpr_free(ffd); } -static grpc_core::CQCallbackInterface* tag(intptr_t t) { - auto func = [t](bool ok) { - gpr_mu_lock(&tags_mu); - gpr_log(GPR_DEBUG, "Completing operation %" PRIdPTR, t); - bool was_empty = true; - for (size_t i = 0; i < kAvailableTags; i++) { - if (tags_valid[i]) { - was_empty = false; - } - } - size_t idx = static_cast(t); - tags[idx] = ok; - tags_valid[idx] = true; - if (was_empty) { - gpr_cv_signal(&tags_cv); - } - gpr_mu_unlock(&tags_mu); - }; - auto cb = NewDeletingCallback(func); - return cb; -} - static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, const char* test_name, grpc_channel_args* client_args, @@ -221,7 +242,8 @@ static gpr_timespec n_seconds_from_now(int n) { static gpr_timespec five_seconds_from_now() { return n_seconds_from_now(5); } static void drain_cq(grpc_completion_queue* cq) { - g_shutdown_callback->Wait(five_seconds_from_now()); + // Wait for the shutdown callback to arrive, or fail the test + GPR_ASSERT(g_shutdown_callback->Wait(five_seconds_from_now())); gpr_log(GPR_DEBUG, "CQ shutdown wait complete"); grpc_core::Delete(g_shutdown_callback); } @@ -288,6 +310,7 @@ static void simple_request_body(grpc_end2end_test_config config, grpc_metadata_array_init(&request_metadata_recv); grpc_call_details_init(&call_details); + // Create a basic client unary request batch (no payload) memset(ops, 0, sizeof(ops)); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; @@ -316,9 +339,13 @@ static void simple_request_body(grpc_end2end_test_config config, nullptr); GPR_ASSERT(GRPC_CALL_OK == error); + // Register a call at the server-side to match the incoming client call error = grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(2)); GPR_ASSERT(GRPC_CALL_OK == error); + + // We expect that the server call creation callback (and no others) will + // execute now since no other batch should be complete. expect_tag(2, true); verify_tags(deadline); @@ -331,6 +358,7 @@ static void simple_request_body(grpc_end2end_test_config config, gpr_log(GPR_DEBUG, "client_peer=%s", peer); gpr_free(peer); + // Create the server response batch (no payload) memset(ops, 0, sizeof(ops)); op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; @@ -355,6 +383,8 @@ static void simple_request_body(grpc_end2end_test_config config, nullptr); GPR_ASSERT(GRPC_CALL_OK == error); + // Both the client request and server response batches should get complete + // now and we should see that their callbacks have been executed expect_tag(3, true); expect_tag(1, true); verify_tags(deadline); From ba9c343e3dd464f4e789ad4a89fc3c468c28e64d Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 23 Aug 2018 08:08:47 -0700 Subject: [PATCH 191/546] Clang format --- test/core/end2end/inproc_callback_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/core/end2end/inproc_callback_test.cc b/test/core/end2end/inproc_callback_test.cc index c174d8f44e1..59d8ed987f5 100644 --- a/test/core/end2end/inproc_callback_test.cc +++ b/test/core/end2end/inproc_callback_test.cc @@ -91,10 +91,10 @@ ShutdownCallback* g_shutdown_callback; } // namespace // The following global structure is the tag collection. It holds -// all information related to tags expected and tags received +// all information related to tags expected and tags received // during the execution, with each callback setting a tag. // The tag sets are implemented and checked using arrays and -// linear lookups (rather than maps) so that this test doesn't +// linear lookups (rather than maps) so that this test doesn't // need the C++ standard library. static gpr_mu tags_mu; static gpr_cv tags_cv; From fe20ad62a05955b56d0fe27f05d355db2e2314b5 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 Aug 2018 17:16:49 +0200 Subject: [PATCH 192/546] improve doc comments for security constants --- include/grpc/grpc_security_constants.h | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h index 944a1e927f0..d72150a4024 100644 --- a/include/grpc/grpc_security_constants.h +++ b/include/grpc/grpc_security_constants.h @@ -57,15 +57,16 @@ typedef enum { } grpc_ssl_certificate_config_reload_status; typedef enum { - /** Server does not request client certificate. A client can present a self - signed or signed certificates if it wishes to do so and they would be - accepted. */ + /** Server does not request client certificate. A client may present a self + signed or signed certificates if it wishes to do so and either option would + be accepted. */ GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, /** Server requests client certificate but does not enforce that the client presents a certificate. If the client presents a certificate, the client authentication is left to - the application based on the metadata like certificate etc. + the application (the necessary metadata will be available to the + application via authentication context properties, see grpc_auth_context). The key cert pair should still be valid for the SSL connection to be established. */ @@ -74,26 +75,27 @@ typedef enum { presents a certificate. If the client presents a certificate, the client authentication is done by - grpc framework (The client needs to either present a signed cert or skip no - certificate for a successful connection). + the gRPC framework (the client needs to either present a signed cert or not + present a certificate at all for a successful connection). The key cert pair should still be valid for the SSL connection to be established. */ GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, - /** Server requests client certificate but enforces that the client presents a + /** Server requests client certificate and enforces that the client presents a certificate. If the client presents a certificate, the client authentication is left to - the application based on the metadata like certificate etc. + the application (the necessary metadata will be available to the + application via authentication context properties, see grpc_auth_context). The key cert pair should still be valid for the SSL connection to be established. */ GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, - /** Server requests client certificate but enforces that the client presents a + /** Server requests client certificate and enforces that the client presents a certificate. - The cerificate presented by the client is verified by grpc framework (The - client needs to present signed certs for a successful connection). + The cerificate presented by the client is verified by the gRPC framework + (the client needs to present signed certs for a successful connection). The key cert pair should still be valid for the SSL connection to be established. */ From 458775d4f956072c965eaf3bc24a972daee840a7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 Aug 2018 17:37:43 +0200 Subject: [PATCH 193/546] improve wording --- include/grpc/grpc_security_constants.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h index d72150a4024..c115cd36592 100644 --- a/include/grpc/grpc_security_constants.h +++ b/include/grpc/grpc_security_constants.h @@ -58,8 +58,8 @@ typedef enum { typedef enum { /** Server does not request client certificate. A client may present a self - signed or signed certificates if it wishes to do so and either option would - be accepted. */ + signed or signed certificate or not present a certificate at all and any of + those option would be accepted. */ GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, /** Server requests client certificate but does not enforce that the client presents a certificate. From a80fa8732f0d67783e7230c89c708ae9e3334398 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 Aug 2018 18:15:19 +0200 Subject: [PATCH 194/546] C#: allow dot in metadata keys --- src/csharp/Grpc.Core.Tests/MetadataTest.cs | 2 ++ src/csharp/Grpc.Core/Metadata.cs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/MetadataTest.cs b/src/csharp/Grpc.Core.Tests/MetadataTest.cs index 89167317573..171c5c470e5 100644 --- a/src/csharp/Grpc.Core.Tests/MetadataTest.cs +++ b/src/csharp/Grpc.Core.Tests/MetadataTest.cs @@ -66,6 +66,8 @@ namespace Grpc.Core.Tests new Metadata.Entry("0123456789abc", "XYZ"); new Metadata.Entry("-abc", "XYZ"); new Metadata.Entry("a_bc_", "XYZ"); + new Metadata.Entry("abc.xyz", "XYZ"); + new Metadata.Entry("abc.xyz-bin", new byte[] {1, 2, 3}); Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc[", "xyz")); Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc/", "xyz")); } diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs index 0e4456278cf..281952d6d41 100644 --- a/src/csharp/Grpc.Core/Metadata.cs +++ b/src/csharp/Grpc.Core/Metadata.cs @@ -225,7 +225,7 @@ namespace Grpc.Core /// public class Entry { - private static readonly Regex ValidKeyRegex = new Regex("^[a-z0-9_-]+$"); + private static readonly Regex ValidKeyRegex = new Regex("^[.a-z0-9_-]+$"); readonly string key; readonly string value; @@ -360,7 +360,7 @@ namespace Grpc.Core { var normalized = GrpcPreconditions.CheckNotNull(key, "key").ToLowerInvariant(); GrpcPreconditions.CheckArgument(ValidKeyRegex.IsMatch(normalized), - "Metadata entry key not valid. Keys can only contain lowercase alphanumeric characters, underscores and hyphens."); + "Metadata entry key not valid. Keys can only contain lowercase alphanumeric characters, underscores, hyphens and dots."); return normalized; } From acc020caf77240f7504af9c2c1ea5a0dac1884d6 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 20 Aug 2018 23:00:02 -0700 Subject: [PATCH 195/546] Support tracking and closing fds post-fork in ev_poll_posix This extends gRPC Python's fork compatibility to Mac OS, which does not support epoll The changes are a no-op if fork support is disabled --- src/core/lib/iomgr/ev_poll_posix.cc | 108 ++++++++++++++++++ .../grpc/_cython/_cygrpc/fork_posix.pyx.pxi | 12 +- 2 files changed, 116 insertions(+), 4 deletions(-) diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index fb4c71ef71b..dd71ccdd0ca 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -60,6 +60,19 @@ typedef struct grpc_fd_watcher { grpc_fd* fd; } grpc_fd_watcher; +typedef struct grpc_cached_wakeup_fd grpc_cached_wakeup_fd; + +/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ +struct grpc_fork_fd_list { + /* Only one of fd or cached_wakeup_fd will be set. The unused field will be + set to nullptr. */ + grpc_fd* fd; + grpc_cached_wakeup_fd* cached_wakeup_fd; + + grpc_fork_fd_list* next; + grpc_fork_fd_list* prev; +}; + struct grpc_fd { int fd; /* refst format: @@ -108,8 +121,15 @@ struct grpc_fd { grpc_closure* on_done_closure; grpc_iomgr_object iomgr_object; + + /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ + grpc_fork_fd_list* fork_fd_list; }; +/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ +static grpc_fork_fd_list* fork_fd_list_head = nullptr; +static gpr_mu fork_fd_list_mu; + /* Begin polling on an fd. Registers that the given pollset is interested in this fd - so that if read or writability interest changes, the pollset can be kicked to pick up that @@ -156,6 +176,9 @@ static void fd_unref(grpc_fd* fd); typedef struct grpc_cached_wakeup_fd { grpc_wakeup_fd fd; struct grpc_cached_wakeup_fd* next; + + /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ + grpc_fork_fd_list* fork_fd_list; } grpc_cached_wakeup_fd; struct grpc_pollset_worker { @@ -280,6 +303,58 @@ typedef struct poll_hash_table { poll_hash_table poll_cache; grpc_cv_fd_table g_cvfds; +/******************************************************************************* + * functions to track opened fds. No-ops unless GRPC_ENABLE_FORK_SUPPORT=1. + */ + +static void fork_fd_list_remove_node(grpc_fork_fd_list* node) { + if (grpc_core::Fork::Enabled()) { + gpr_mu_lock(&fork_fd_list_mu); + if (fork_fd_list_head == node) { + fork_fd_list_head = node->next; + } + if (node->prev != nullptr) { + node->prev->next = node->next; + } + if (node->next != nullptr) { + node->next->prev = node->prev; + } + gpr_free(node); + gpr_mu_unlock(&fork_fd_list_mu); + } +} + +static void fork_fd_list_add_node(grpc_fork_fd_list* node) { + gpr_mu_lock(&fork_fd_list_mu); + node->next = fork_fd_list_head; + node->prev = nullptr; + if (fork_fd_list_head != nullptr) { + fork_fd_list_head->prev = node; + } + fork_fd_list_head = node; + gpr_mu_unlock(&fork_fd_list_mu); +} + +static void fork_fd_list_add_grpc_fd(grpc_fd* fd) { + if (grpc_core::Fork::Enabled()) { + fd->fork_fd_list = + static_cast(gpr_malloc(sizeof(grpc_fork_fd_list))); + fd->fork_fd_list->fd = fd; + fd->fork_fd_list->cached_wakeup_fd = nullptr; + fork_fd_list_add_node(fd->fork_fd_list); + } +} + +static void fork_fd_list_add_wakeup_fd(grpc_cached_wakeup_fd* fd) { + if (grpc_core::Fork::Enabled()) { + fd->fork_fd_list = + static_cast(gpr_malloc(sizeof(grpc_fork_fd_list))); + fd->fork_fd_list->cached_wakeup_fd = fd; + fd->fork_fd_list->fd = nullptr; + fork_fd_list_add_node(fd->fork_fd_list); + } +} + /******************************************************************************* * fd_posix.c */ @@ -319,6 +394,7 @@ static void unref_by(grpc_fd* fd, int n) { if (old == n) { gpr_mu_destroy(&fd->mu); grpc_iomgr_unregister_object(&fd->iomgr_object); + fork_fd_list_remove_node(fd->fork_fd_list); if (fd->shutdown) GRPC_ERROR_UNREF(fd->shutdown_error); gpr_free(fd); } else { @@ -347,6 +423,7 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) { gpr_asprintf(&name2, "%s fd=%d", name, fd); grpc_iomgr_register_object(&r->iomgr_object, name2); gpr_free(name2); + fork_fd_list_add_grpc_fd(r); return r; } @@ -822,6 +899,7 @@ static void pollset_destroy(grpc_pollset* pollset) { GPR_ASSERT(!pollset_has_workers(pollset)); while (pollset->local_wakeup_cache) { grpc_cached_wakeup_fd* next = pollset->local_wakeup_cache->next; + fork_fd_list_remove_node(pollset->local_wakeup_cache->fork_fd_list); grpc_wakeup_fd_destroy(&pollset->local_wakeup_cache->fd); gpr_free(pollset->local_wakeup_cache); pollset->local_wakeup_cache = next; @@ -895,6 +973,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset, worker.wakeup_fd = static_cast( gpr_malloc(sizeof(*worker.wakeup_fd))); error = grpc_wakeup_fd_init(&worker.wakeup_fd->fd); + fork_fd_list_add_wakeup_fd(worker.wakeup_fd); if (error != GRPC_ERROR_NONE) { GRPC_LOG_IF_ERROR("pollset_work", GRPC_ERROR_REF(error)); return error; @@ -1705,6 +1784,10 @@ static void shutdown_engine(void) { if (grpc_cv_wakeup_fds_enabled()) { global_cv_fd_table_shutdown(); } + if (grpc_core::Fork::Enabled()) { + gpr_mu_destroy(&fork_fd_list_mu); + grpc_core::Fork::SetResetChildPollingEngineFunc(nullptr); + } } static const grpc_event_engine_vtable vtable = { @@ -1742,6 +1825,26 @@ static const grpc_event_engine_vtable vtable = { shutdown_engine, }; +/* Called by the child process's post-fork handler to close open fds, including + * worker wakeup fds. This allows gRPC to shutdown in the child process without + * interfering with connections or RPCs ongoing in the parent. */ +static void reset_event_manager_on_fork() { + gpr_mu_lock(&fork_fd_list_mu); + while (fork_fd_list_head != nullptr) { + if (fork_fd_list_head->fd != nullptr) { + close(fork_fd_list_head->fd->fd); + fork_fd_list_head->fd->fd = -1; + } else { + close(fork_fd_list_head->cached_wakeup_fd->fd.read_fd); + fork_fd_list_head->cached_wakeup_fd->fd.read_fd = -1; + close(fork_fd_list_head->cached_wakeup_fd->fd.write_fd); + fork_fd_list_head->cached_wakeup_fd->fd.write_fd = -1; + } + fork_fd_list_head = fork_fd_list_head->next; + } + gpr_mu_unlock(&fork_fd_list_mu); +} + const grpc_event_engine_vtable* grpc_init_poll_posix(bool explicit_request) { if (!grpc_has_wakeup_fd()) { gpr_log(GPR_ERROR, "Skipping poll because of no wakeup fd."); @@ -1750,6 +1853,11 @@ const grpc_event_engine_vtable* grpc_init_poll_posix(bool explicit_request) { if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) { return nullptr; } + if (grpc_core::Fork::Enabled()) { + gpr_mu_init(&fork_fd_list_mu); + grpc_core::Fork::SetResetChildPollingEngineFunc( + reset_event_manager_on_fork); + } return &vtable; } diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi index 0d2516977b8..303bcd976ce 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi @@ -23,6 +23,8 @@ _AWAIT_THREADS_TIMEOUT_SECONDS = 5 _TRUE_VALUES = ['yes', 'Yes', 'YES', 'true', 'True', 'TRUE', '1'] +_SUPPORTED_POLL_STRATEGIES = ['epoll1', 'poll'] + # This flag enables experimental support within gRPC Python for applications # that will fork() without exec(). When enabled, gRPC Python will attempt to # pause all of its internally created threads before the fork syscall proceeds. @@ -82,12 +84,14 @@ cdef void __postfork_child() nogil: def fork_handlers_and_grpc_init(): grpc_init() if _GRPC_ENABLE_FORK_SUPPORT: - # TODO(ericgribkoff) epoll1 is default for grpcio distribution. Decide whether to expose - # grpc_get_poll_strategy_name() from ev_posix.cc to get actual polling choice. - if _GRPC_POLL_STRATEGY is not None and _GRPC_POLL_STRATEGY != "epoll1": + # TODO(ericgribkoff) epoll1 is default for grpcio distribution (poll is + # default on mac). Decide whether to expose grpc_get_poll_strategy_name() + # from ev_posix.cc to get actual poller. + if (_GRPC_POLL_STRATEGY is not None and + _GRPC_POLL_STRATEGY not in _SUPPORTED_POLL_STRATEGIES): _LOGGER.error( 'gRPC Python fork support is only compatible with the epoll1 ' - 'polling engine') + 'and poll polling strategies') return with _fork_state.fork_handler_registered_lock: if not _fork_state.fork_handler_registered: From 3d1dacd73d2e75ab4214231f32300c466c30f536 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 23 Aug 2018 09:12:23 -0700 Subject: [PATCH 196/546] Check poll strategy in core fork handler and log error if unsupported --- src/core/lib/iomgr/fork_posix.cc | 6 ++++++ .../grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi | 13 ------------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc index ac85c81de2d..e957bad73d3 100644 --- a/src/core/lib/iomgr/fork_posix.cc +++ b/src/core/lib/iomgr/fork_posix.cc @@ -58,6 +58,12 @@ void grpc_prefork() { "environment variable GRPC_ENABLE_FORK_SUPPORT=1"); return; } + if (strcmp(grpc_get_poll_strategy_name(), "epoll1") != 0 && + strcmp(grpc_get_poll_strategy_name(), "poll") != 0) { + gpr_log(GPR_ERROR, + "Fork support is only compatible with the epoll1 and poll polling " + "strategies"); + } if (!grpc_core::Fork::BlockExecCtx()) { gpr_log(GPR_INFO, "Other threads are currently calling into gRPC, skipping fork() " diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi index 303bcd976ce..433ae1f374f 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi @@ -23,8 +23,6 @@ _AWAIT_THREADS_TIMEOUT_SECONDS = 5 _TRUE_VALUES = ['yes', 'Yes', 'YES', 'true', 'True', 'TRUE', '1'] -_SUPPORTED_POLL_STRATEGIES = ['epoll1', 'poll'] - # This flag enables experimental support within gRPC Python for applications # that will fork() without exec(). When enabled, gRPC Python will attempt to # pause all of its internally created threads before the fork syscall proceeds. @@ -39,8 +37,6 @@ _GRPC_ENABLE_FORK_SUPPORT = ( os.environ.get('GRPC_ENABLE_FORK_SUPPORT', '0') .lower() in _TRUE_VALUES) -_GRPC_POLL_STRATEGY = os.environ.get('GRPC_POLL_STRATEGY') - cdef void __prefork() nogil: with gil: with _fork_state.fork_in_progress_condition: @@ -84,15 +80,6 @@ cdef void __postfork_child() nogil: def fork_handlers_and_grpc_init(): grpc_init() if _GRPC_ENABLE_FORK_SUPPORT: - # TODO(ericgribkoff) epoll1 is default for grpcio distribution (poll is - # default on mac). Decide whether to expose grpc_get_poll_strategy_name() - # from ev_posix.cc to get actual poller. - if (_GRPC_POLL_STRATEGY is not None and - _GRPC_POLL_STRATEGY not in _SUPPORTED_POLL_STRATEGIES): - _LOGGER.error( - 'gRPC Python fork support is only compatible with the epoll1 ' - 'and poll polling strategies') - return with _fork_state.fork_handler_registered_lock: if not _fork_state.fork_handler_registered: pthread_atfork(&__prefork, &__postfork_parent, &__postfork_child) From b24b212ee585d376c618235905757b2445ac6461 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 14 Aug 2018 10:21:27 -0700 Subject: [PATCH 197/546] Make symbols of BoringSSL private to gRPC --- BUILD | 10 + build.yaml | 6 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 5 +- grpc.gemspec | 1 + package.xml | 1 + .../lib/security/credentials/jwt/json_token.h | 2 + .../security/credentials/jwt/jwt_verifier.cc | 2 + src/core/tsi/alts/crypt/aes_gcm.cc | 2 + src/core/tsi/grpc_shadow_boringssl.h | 3006 +++++++++++ src/core/tsi/ssl/session_cache/ssl_session.h | 2 + .../tsi/ssl/session_cache/ssl_session_cache.h | 2 + src/core/tsi/ssl_transport_security.cc | 2 + src/core/tsi/ssl_types.h | 2 + src/objective-c/BoringSSL-GRPC.podspec | 4527 +++++++++++++++++ src/objective-c/BoringSSL.podspec | 1539 ------ src/objective-c/examples/Sample/Podfile | 2 +- src/objective-c/examples/SwiftSample/Podfile | 2 +- .../grpc_shadow_boringssl_symbol_list | 2974 +++++++++++ src/objective-c/tests/Connectivity/Podfile | 2 +- .../tests/CronetUnitTests/CronetUnitTests.m | 4 +- src/objective-c/tests/Podfile | 6 +- .../tests/Tests.xcodeproj/project.pbxproj | 8 + templates/gRPC-Core.podspec.template | 3 +- .../core/tsi/grpc_shadow_boringssl.h.template | 40 + .../BoringSSL-GRPC.podspec.template | 1561 ++++++ test/core/iomgr/ios/CFStreamTests/Podfile | 1 + .../buildgen/plugins/grpc_shadow_boringssl.py | 32 + .../check_shadow_boringssl_symbol_list.sh | 32 + ...erate_grpc_shadow_boringssl_symbol_list.sh | 45 + .../clang_format_all_the_things.sh | 2 +- tools/doxygen/Doxyfile.core.internal | 1 + .../generated/sources_and_headers.json | 17 + tools/run_tests/sanity/sanity_tests.yaml | 1 + 34 files changed, 12294 insertions(+), 1549 deletions(-) create mode 100644 src/core/tsi/grpc_shadow_boringssl.h create mode 100644 src/objective-c/BoringSSL-GRPC.podspec delete mode 100644 src/objective-c/BoringSSL.podspec create mode 100644 src/objective-c/grpc_shadow_boringssl_symbol_list create mode 100644 templates/src/core/tsi/grpc_shadow_boringssl.h.template create mode 100644 templates/src/objective-c/BoringSSL-GRPC.podspec.template create mode 100644 tools/buildgen/plugins/grpc_shadow_boringssl.py create mode 100755 tools/distrib/check_shadow_boringssl_symbol_list.sh create mode 100755 tools/distrib/generate_grpc_shadow_boringssl_symbol_list.sh diff --git a/BUILD b/BUILD index 81390dd1aa1..b76d47b325e 100644 --- a/BUILD +++ b/BUILD @@ -1543,6 +1543,7 @@ grpc_cc_library( "grpc_base", "grpc_transport_chttp2_alpn", "tsi", + "grpc_shadow_boringssl", ], ) @@ -1803,6 +1804,7 @@ grpc_cc_library( "gpr", "grpc_base", "tsi_interface", + "grpc_shadow_boringssl", ], ) @@ -1899,6 +1901,7 @@ grpc_cc_library( "grpc_base", "grpc_transport_chttp2_client_insecure", "tsi_interface", + "grpc_shadow_boringssl", ], ) @@ -2154,4 +2157,11 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "grpc_shadow_boringssl", + hdrs = [ + "src/core/tsi/grpc_shadow_boringssl.h", + ], +) + grpc_generate_one_off_targets() diff --git a/build.yaml b/build.yaml index 70af96046cb..4f7efc90d02 100644 --- a/build.yaml +++ b/build.yaml @@ -69,6 +69,7 @@ filegroups: - grpc_transport_chttp2_client_insecure - tsi_interface - tsi + - grpc_shadow_boringssl - name: alts_util public_headers: - include/grpc/grpc_security.h @@ -835,6 +836,7 @@ filegroups: - grpc_base - grpc_transport_chttp2_alpn - tsi + - grpc_shadow_boringssl - name: grpc_server_backward_compatibility headers: - src/core/ext/filters/workarounds/workaround_utils.h @@ -842,6 +844,9 @@ filegroups: - src/core/ext/filters/workarounds/workaround_utils.cc uses: - grpc_base +- name: grpc_shadow_boringssl + headers: + - src/core/tsi/grpc_shadow_boringssl.h - name: grpc_test_util_base build: test headers: @@ -1103,6 +1108,7 @@ filegroups: - tsi_interface - grpc_base - grpc_trace + - grpc_shadow_boringssl - name: tsi_interface headers: - src/core/tsi/transport_security.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 1d9237bf627..f33cfb652b0 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -345,6 +345,7 @@ Pod::Spec.new do |s| 'src/core/tsi/ssl_transport_security.h', 'src/core/tsi/ssl_types.h', 'src/core/tsi/transport_security_grpc.h', + 'src/core/tsi/grpc_shadow_boringssl.h', 'src/core/ext/transport/chttp2/server/chttp2_server.h', 'src/core/ext/transport/inproc/inproc_transport.h', 'src/core/lib/avl/avl.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 5c3649afbde..e62a7962a21 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -181,8 +181,9 @@ Pod::Spec.new do |s| ss.header_mappings_dir = '.' ss.libraries = 'z' ss.dependency "#{s.name}/Interface", version - ss.dependency 'BoringSSL', '~> 10.0' + ss.dependency 'BoringSSL-GRPC', '0.0.1' ss.dependency 'nanopb', '~> 0.3' + ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS' # To save you from scrolling, this is the last part of the podspec. ss.source_files = 'src/core/lib/gpr/alloc.h', @@ -356,6 +357,7 @@ Pod::Spec.new do |s| 'src/core/tsi/ssl_transport_security.h', 'src/core/tsi/ssl_types.h', 'src/core/tsi/transport_security_grpc.h', + 'src/core/tsi/grpc_shadow_boringssl.h', 'src/core/ext/transport/chttp2/server/chttp2_server.h', 'src/core/ext/transport/inproc/inproc_transport.h', 'src/core/lib/avl/avl.h', @@ -949,6 +951,7 @@ Pod::Spec.new do |s| 'src/core/tsi/ssl_transport_security.h', 'src/core/tsi/ssl_types.h', 'src/core/tsi/transport_security_grpc.h', + 'src/core/tsi/grpc_shadow_boringssl.h', 'src/core/ext/transport/chttp2/server/chttp2_server.h', 'src/core/ext/transport/inproc/inproc_transport.h', 'src/core/lib/avl/avl.h', diff --git a/grpc.gemspec b/grpc.gemspec index c250316b995..841e2727330 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -293,6 +293,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/tsi/ssl_transport_security.h ) s.files += %w( src/core/tsi/ssl_types.h ) s.files += %w( src/core/tsi/transport_security_grpc.h ) + s.files += %w( src/core/tsi/grpc_shadow_boringssl.h ) s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.h ) s.files += %w( src/core/ext/transport/inproc/inproc_transport.h ) s.files += %w( src/core/lib/avl/avl.h ) diff --git a/package.xml b/package.xml index acdc6ffdb38..b8c4eed2eb6 100644 --- a/package.xml +++ b/package.xml @@ -298,6 +298,7 @@ + diff --git a/src/core/lib/security/credentials/jwt/json_token.h b/src/core/lib/security/credentials/jwt/json_token.h index d0fb4ebd0a0..3ed990140d3 100644 --- a/src/core/lib/security/credentials/jwt/json_token.h +++ b/src/core/lib/security/credentials/jwt/json_token.h @@ -21,6 +21,8 @@ #include +#include "src/core/tsi/grpc_shadow_boringssl.h" + #include #include diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc index 5c47276e32f..c7d1b36ff0a 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc @@ -18,6 +18,8 @@ #include +#include "src/core/tsi/grpc_shadow_boringssl.h" + #include "src/core/lib/security/credentials/jwt/jwt_verifier.h" #include diff --git a/src/core/tsi/alts/crypt/aes_gcm.cc b/src/core/tsi/alts/crypt/aes_gcm.cc index 02b1ac4492f..c638ce76eed 100644 --- a/src/core/tsi/alts/crypt/aes_gcm.cc +++ b/src/core/tsi/alts/crypt/aes_gcm.cc @@ -18,6 +18,8 @@ #include +#include "src/core/tsi/grpc_shadow_boringssl.h" + #include "src/core/tsi/alts/crypt/gsec.h" #include diff --git a/src/core/tsi/grpc_shadow_boringssl.h b/src/core/tsi/grpc_shadow_boringssl.h new file mode 100644 index 00000000000..074be6d8d9c --- /dev/null +++ b/src/core/tsi/grpc_shadow_boringssl.h @@ -0,0 +1,3006 @@ + +/* + * + * 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. + * + */ + +// This file is autogenerated from a template file. Please make +// modifications to +// `templates/src/objective-c/tsi/grpc_shadow_boringssl.h.template` +// instead. This file can be regenerated from the template by running +// `tools/buildgen/generate_projects.sh`. + +#ifndef GRPC_CORE_TSI_GRPC_SHADOW_BORINGSSL_H +#define GRPC_CORE_TSI_GRPC_SHADOW_BORINGSSL_H + +#ifdef GRPC_SHADOW_BORINGSSL_SYMBOLS + +#define BIO_f_ssl GRPC_SHADOW_BIO_f_ssl +#define BIO_set_ssl GRPC_SHADOW_BIO_set_ssl +#define SSL_CTX_add_client_custom_ext GRPC_SHADOW_SSL_CTX_add_client_custom_ext +#define SSL_CTX_add_server_custom_ext GRPC_SHADOW_SSL_CTX_add_server_custom_ext +#define DTLSv1_get_timeout GRPC_SHADOW_DTLSv1_get_timeout +#define DTLSv1_handle_timeout GRPC_SHADOW_DTLSv1_handle_timeout +#define DTLSv1_set_initial_timeout_duration GRPC_SHADOW_DTLSv1_set_initial_timeout_duration +#define SSL_CTX_set_srtp_profiles GRPC_SHADOW_SSL_CTX_set_srtp_profiles +#define SSL_CTX_set_tlsext_use_srtp GRPC_SHADOW_SSL_CTX_set_tlsext_use_srtp +#define SSL_get_selected_srtp_profile GRPC_SHADOW_SSL_get_selected_srtp_profile +#define SSL_get_srtp_profiles GRPC_SHADOW_SSL_get_srtp_profiles +#define SSL_set_srtp_profiles GRPC_SHADOW_SSL_set_srtp_profiles +#define SSL_set_tlsext_use_srtp GRPC_SHADOW_SSL_set_tlsext_use_srtp +#define DTLS_client_method GRPC_SHADOW_DTLS_client_method +#define DTLS_method GRPC_SHADOW_DTLS_method +#define DTLS_server_method GRPC_SHADOW_DTLS_server_method +#define DTLS_with_buffers_method GRPC_SHADOW_DTLS_with_buffers_method +#define DTLSv1_2_client_method GRPC_SHADOW_DTLSv1_2_client_method +#define DTLSv1_2_method GRPC_SHADOW_DTLSv1_2_method +#define DTLSv1_2_server_method GRPC_SHADOW_DTLSv1_2_server_method +#define DTLSv1_client_method GRPC_SHADOW_DTLSv1_client_method +#define DTLSv1_method GRPC_SHADOW_DTLSv1_method +#define DTLSv1_server_method GRPC_SHADOW_DTLSv1_server_method +#define SSL_SESSION_from_bytes GRPC_SHADOW_SSL_SESSION_from_bytes +#define SSL_SESSION_to_bytes GRPC_SHADOW_SSL_SESSION_to_bytes +#define SSL_SESSION_to_bytes_for_ticket GRPC_SHADOW_SSL_SESSION_to_bytes_for_ticket +#define i2d_SSL_SESSION GRPC_SHADOW_i2d_SSL_SESSION +#define SSL_CTX_set0_client_CAs GRPC_SHADOW_SSL_CTX_set0_client_CAs +#define SSL_CTX_set_cert_cb GRPC_SHADOW_SSL_CTX_set_cert_cb +#define SSL_CTX_set_chain_and_key GRPC_SHADOW_SSL_CTX_set_chain_and_key +#define SSL_CTX_set_ocsp_response GRPC_SHADOW_SSL_CTX_set_ocsp_response +#define SSL_CTX_set_signed_cert_timestamp_list GRPC_SHADOW_SSL_CTX_set_signed_cert_timestamp_list +#define SSL_CTX_use_certificate_ASN1 GRPC_SHADOW_SSL_CTX_use_certificate_ASN1 +#define SSL_get0_peer_certificates GRPC_SHADOW_SSL_get0_peer_certificates +#define SSL_get0_server_requested_CAs GRPC_SHADOW_SSL_get0_server_requested_CAs +#define SSL_set0_client_CAs GRPC_SHADOW_SSL_set0_client_CAs +#define SSL_set_cert_cb GRPC_SHADOW_SSL_set_cert_cb +#define SSL_set_chain_and_key GRPC_SHADOW_SSL_set_chain_and_key +#define SSL_set_ocsp_response GRPC_SHADOW_SSL_set_ocsp_response +#define SSL_set_signed_cert_timestamp_list GRPC_SHADOW_SSL_set_signed_cert_timestamp_list +#define SSL_use_certificate_ASN1 GRPC_SHADOW_SSL_use_certificate_ASN1 +#define SSL_CIPHER_description GRPC_SHADOW_SSL_CIPHER_description +#define SSL_CIPHER_get_auth_nid GRPC_SHADOW_SSL_CIPHER_get_auth_nid +#define SSL_CIPHER_get_bits GRPC_SHADOW_SSL_CIPHER_get_bits +#define SSL_CIPHER_get_cipher_nid GRPC_SHADOW_SSL_CIPHER_get_cipher_nid +#define SSL_CIPHER_get_digest_nid GRPC_SHADOW_SSL_CIPHER_get_digest_nid +#define SSL_CIPHER_get_id GRPC_SHADOW_SSL_CIPHER_get_id +#define SSL_CIPHER_get_kx_name GRPC_SHADOW_SSL_CIPHER_get_kx_name +#define SSL_CIPHER_get_kx_nid GRPC_SHADOW_SSL_CIPHER_get_kx_nid +#define SSL_CIPHER_get_max_version GRPC_SHADOW_SSL_CIPHER_get_max_version +#define SSL_CIPHER_get_min_version GRPC_SHADOW_SSL_CIPHER_get_min_version +#define SSL_CIPHER_get_name GRPC_SHADOW_SSL_CIPHER_get_name +#define SSL_CIPHER_get_prf_nid GRPC_SHADOW_SSL_CIPHER_get_prf_nid +#define SSL_CIPHER_get_rfc_name GRPC_SHADOW_SSL_CIPHER_get_rfc_name +#define SSL_CIPHER_get_version GRPC_SHADOW_SSL_CIPHER_get_version +#define SSL_CIPHER_is_aead GRPC_SHADOW_SSL_CIPHER_is_aead +#define SSL_CIPHER_is_block_cipher GRPC_SHADOW_SSL_CIPHER_is_block_cipher +#define SSL_CIPHER_standard_name GRPC_SHADOW_SSL_CIPHER_standard_name +#define SSL_COMP_add_compression_method GRPC_SHADOW_SSL_COMP_add_compression_method +#define SSL_COMP_free_compression_methods GRPC_SHADOW_SSL_COMP_free_compression_methods +#define SSL_COMP_get0_name GRPC_SHADOW_SSL_COMP_get0_name +#define SSL_COMP_get_compression_methods GRPC_SHADOW_SSL_COMP_get_compression_methods +#define SSL_COMP_get_id GRPC_SHADOW_SSL_COMP_get_id +#define SSL_COMP_get_name GRPC_SHADOW_SSL_COMP_get_name +#define SSL_get_cipher_by_value GRPC_SHADOW_SSL_get_cipher_by_value +#define SSL_CTX_get_default_passwd_cb GRPC_SHADOW_SSL_CTX_get_default_passwd_cb +#define SSL_CTX_get_default_passwd_cb_userdata GRPC_SHADOW_SSL_CTX_get_default_passwd_cb_userdata +#define SSL_CTX_set_default_passwd_cb GRPC_SHADOW_SSL_CTX_set_default_passwd_cb +#define SSL_CTX_set_default_passwd_cb_userdata GRPC_SHADOW_SSL_CTX_set_default_passwd_cb_userdata +#define SSL_CTX_use_PrivateKey_file GRPC_SHADOW_SSL_CTX_use_PrivateKey_file +#define SSL_CTX_use_RSAPrivateKey_file GRPC_SHADOW_SSL_CTX_use_RSAPrivateKey_file +#define SSL_CTX_use_certificate_chain_file GRPC_SHADOW_SSL_CTX_use_certificate_chain_file +#define SSL_CTX_use_certificate_file GRPC_SHADOW_SSL_CTX_use_certificate_file +#define SSL_add_file_cert_subjects_to_stack GRPC_SHADOW_SSL_add_file_cert_subjects_to_stack +#define SSL_load_client_CA_file GRPC_SHADOW_SSL_load_client_CA_file +#define SSL_use_PrivateKey_file GRPC_SHADOW_SSL_use_PrivateKey_file +#define SSL_use_RSAPrivateKey_file GRPC_SHADOW_SSL_use_RSAPrivateKey_file +#define SSL_use_certificate_file GRPC_SHADOW_SSL_use_certificate_file +#define SSL_get_curve_name GRPC_SHADOW_SSL_get_curve_name +#define ERR_load_SSL_strings GRPC_SHADOW_ERR_load_SSL_strings +#define OPENSSL_init_ssl GRPC_SHADOW_OPENSSL_init_ssl +#define SSL_CTX_check_private_key GRPC_SHADOW_SSL_CTX_check_private_key +#define SSL_CTX_cipher_in_group GRPC_SHADOW_SSL_CTX_cipher_in_group +#define SSL_CTX_clear_mode GRPC_SHADOW_SSL_CTX_clear_mode +#define SSL_CTX_clear_options GRPC_SHADOW_SSL_CTX_clear_options +#define SSL_CTX_enable_ocsp_stapling GRPC_SHADOW_SSL_CTX_enable_ocsp_stapling +#define SSL_CTX_enable_signed_cert_timestamps GRPC_SHADOW_SSL_CTX_enable_signed_cert_timestamps +#define SSL_CTX_enable_tls_channel_id GRPC_SHADOW_SSL_CTX_enable_tls_channel_id +#define SSL_CTX_free GRPC_SHADOW_SSL_CTX_free +#define SSL_CTX_get0_privatekey GRPC_SHADOW_SSL_CTX_get0_privatekey +#define SSL_CTX_get_ciphers GRPC_SHADOW_SSL_CTX_get_ciphers +#define SSL_CTX_get_ex_data GRPC_SHADOW_SSL_CTX_get_ex_data +#define SSL_CTX_get_ex_new_index GRPC_SHADOW_SSL_CTX_get_ex_new_index +#define SSL_CTX_get_keylog_callback GRPC_SHADOW_SSL_CTX_get_keylog_callback +#define SSL_CTX_get_max_cert_list GRPC_SHADOW_SSL_CTX_get_max_cert_list +#define SSL_CTX_get_mode GRPC_SHADOW_SSL_CTX_get_mode +#define SSL_CTX_get_options GRPC_SHADOW_SSL_CTX_get_options +#define SSL_CTX_get_quiet_shutdown GRPC_SHADOW_SSL_CTX_get_quiet_shutdown +#define SSL_CTX_get_read_ahead GRPC_SHADOW_SSL_CTX_get_read_ahead +#define SSL_CTX_get_session_cache_mode GRPC_SHADOW_SSL_CTX_get_session_cache_mode +#define SSL_CTX_get_tlsext_ticket_keys GRPC_SHADOW_SSL_CTX_get_tlsext_ticket_keys +#define SSL_CTX_need_tmp_RSA GRPC_SHADOW_SSL_CTX_need_tmp_RSA +#define SSL_CTX_new GRPC_SHADOW_SSL_CTX_new +#define SSL_CTX_sess_accept GRPC_SHADOW_SSL_CTX_sess_accept +#define SSL_CTX_sess_accept_good GRPC_SHADOW_SSL_CTX_sess_accept_good +#define SSL_CTX_sess_accept_renegotiate GRPC_SHADOW_SSL_CTX_sess_accept_renegotiate +#define SSL_CTX_sess_cache_full GRPC_SHADOW_SSL_CTX_sess_cache_full +#define SSL_CTX_sess_cb_hits GRPC_SHADOW_SSL_CTX_sess_cb_hits +#define SSL_CTX_sess_connect GRPC_SHADOW_SSL_CTX_sess_connect +#define SSL_CTX_sess_connect_good GRPC_SHADOW_SSL_CTX_sess_connect_good +#define SSL_CTX_sess_connect_renegotiate GRPC_SHADOW_SSL_CTX_sess_connect_renegotiate +#define SSL_CTX_sess_get_cache_size GRPC_SHADOW_SSL_CTX_sess_get_cache_size +#define SSL_CTX_sess_hits GRPC_SHADOW_SSL_CTX_sess_hits +#define SSL_CTX_sess_misses GRPC_SHADOW_SSL_CTX_sess_misses +#define SSL_CTX_sess_number GRPC_SHADOW_SSL_CTX_sess_number +#define SSL_CTX_sess_set_cache_size GRPC_SHADOW_SSL_CTX_sess_set_cache_size +#define SSL_CTX_sess_timeouts GRPC_SHADOW_SSL_CTX_sess_timeouts +#define SSL_CTX_set0_buffer_pool GRPC_SHADOW_SSL_CTX_set0_buffer_pool +#define SSL_CTX_set1_curves GRPC_SHADOW_SSL_CTX_set1_curves +#define SSL_CTX_set1_curves_list GRPC_SHADOW_SSL_CTX_set1_curves_list +#define SSL_CTX_set1_tls_channel_id GRPC_SHADOW_SSL_CTX_set1_tls_channel_id +#define SSL_CTX_set_allow_unknown_alpn_protos GRPC_SHADOW_SSL_CTX_set_allow_unknown_alpn_protos +#define SSL_CTX_set_alpn_protos GRPC_SHADOW_SSL_CTX_set_alpn_protos +#define SSL_CTX_set_alpn_select_cb GRPC_SHADOW_SSL_CTX_set_alpn_select_cb +#define SSL_CTX_set_cipher_list GRPC_SHADOW_SSL_CTX_set_cipher_list +#define SSL_CTX_set_current_time_cb GRPC_SHADOW_SSL_CTX_set_current_time_cb +#define SSL_CTX_set_custom_verify GRPC_SHADOW_SSL_CTX_set_custom_verify +#define SSL_CTX_set_dos_protection_cb GRPC_SHADOW_SSL_CTX_set_dos_protection_cb +#define SSL_CTX_set_early_data_enabled GRPC_SHADOW_SSL_CTX_set_early_data_enabled +#define SSL_CTX_set_ex_data GRPC_SHADOW_SSL_CTX_set_ex_data +#define SSL_CTX_set_false_start_allowed_without_alpn GRPC_SHADOW_SSL_CTX_set_false_start_allowed_without_alpn +#define SSL_CTX_set_grease_enabled GRPC_SHADOW_SSL_CTX_set_grease_enabled +#define SSL_CTX_set_keylog_callback GRPC_SHADOW_SSL_CTX_set_keylog_callback +#define SSL_CTX_set_max_cert_list GRPC_SHADOW_SSL_CTX_set_max_cert_list +#define SSL_CTX_set_max_send_fragment GRPC_SHADOW_SSL_CTX_set_max_send_fragment +#define SSL_CTX_set_mode GRPC_SHADOW_SSL_CTX_set_mode +#define SSL_CTX_set_msg_callback GRPC_SHADOW_SSL_CTX_set_msg_callback +#define SSL_CTX_set_msg_callback_arg GRPC_SHADOW_SSL_CTX_set_msg_callback_arg +#define SSL_CTX_set_next_proto_select_cb GRPC_SHADOW_SSL_CTX_set_next_proto_select_cb +#define SSL_CTX_set_next_protos_advertised_cb GRPC_SHADOW_SSL_CTX_set_next_protos_advertised_cb +#define SSL_CTX_set_options GRPC_SHADOW_SSL_CTX_set_options +#define SSL_CTX_set_psk_client_callback GRPC_SHADOW_SSL_CTX_set_psk_client_callback +#define SSL_CTX_set_psk_server_callback GRPC_SHADOW_SSL_CTX_set_psk_server_callback +#define SSL_CTX_set_quiet_shutdown GRPC_SHADOW_SSL_CTX_set_quiet_shutdown +#define SSL_CTX_set_read_ahead GRPC_SHADOW_SSL_CTX_set_read_ahead +#define SSL_CTX_set_retain_only_sha256_of_client_certs GRPC_SHADOW_SSL_CTX_set_retain_only_sha256_of_client_certs +#define SSL_CTX_set_select_certificate_cb GRPC_SHADOW_SSL_CTX_set_select_certificate_cb +#define SSL_CTX_set_session_cache_mode GRPC_SHADOW_SSL_CTX_set_session_cache_mode +#define SSL_CTX_set_session_id_context GRPC_SHADOW_SSL_CTX_set_session_id_context +#define SSL_CTX_set_strict_cipher_list GRPC_SHADOW_SSL_CTX_set_strict_cipher_list +#define SSL_CTX_set_ticket_aead_method GRPC_SHADOW_SSL_CTX_set_ticket_aead_method +#define SSL_CTX_set_tls13_variant GRPC_SHADOW_SSL_CTX_set_tls13_variant +#define SSL_CTX_set_tls_channel_id_enabled GRPC_SHADOW_SSL_CTX_set_tls_channel_id_enabled +#define SSL_CTX_set_tlsext_servername_arg GRPC_SHADOW_SSL_CTX_set_tlsext_servername_arg +#define SSL_CTX_set_tlsext_servername_callback GRPC_SHADOW_SSL_CTX_set_tlsext_servername_callback +#define SSL_CTX_set_tlsext_ticket_key_cb GRPC_SHADOW_SSL_CTX_set_tlsext_ticket_key_cb +#define SSL_CTX_set_tlsext_ticket_keys GRPC_SHADOW_SSL_CTX_set_tlsext_ticket_keys +#define SSL_CTX_set_tmp_dh GRPC_SHADOW_SSL_CTX_set_tmp_dh +#define SSL_CTX_set_tmp_dh_callback GRPC_SHADOW_SSL_CTX_set_tmp_dh_callback +#define SSL_CTX_set_tmp_ecdh GRPC_SHADOW_SSL_CTX_set_tmp_ecdh +#define SSL_CTX_set_tmp_rsa GRPC_SHADOW_SSL_CTX_set_tmp_rsa +#define SSL_CTX_set_tmp_rsa_callback GRPC_SHADOW_SSL_CTX_set_tmp_rsa_callback +#define SSL_CTX_up_ref GRPC_SHADOW_SSL_CTX_up_ref +#define SSL_CTX_use_psk_identity_hint GRPC_SHADOW_SSL_CTX_use_psk_identity_hint +#define SSL_accept GRPC_SHADOW_SSL_accept +#define SSL_cache_hit GRPC_SHADOW_SSL_cache_hit +#define SSL_certs_clear GRPC_SHADOW_SSL_certs_clear +#define SSL_check_private_key GRPC_SHADOW_SSL_check_private_key +#define SSL_clear GRPC_SHADOW_SSL_clear +#define SSL_clear_mode GRPC_SHADOW_SSL_clear_mode +#define SSL_clear_options GRPC_SHADOW_SSL_clear_options +#define SSL_connect GRPC_SHADOW_SSL_connect +#define SSL_cutthrough_complete GRPC_SHADOW_SSL_cutthrough_complete +#define SSL_do_handshake GRPC_SHADOW_SSL_do_handshake +#define SSL_dummy_pq_padding_used GRPC_SHADOW_SSL_dummy_pq_padding_used +#define SSL_early_data_accepted GRPC_SHADOW_SSL_early_data_accepted +#define SSL_enable_ocsp_stapling GRPC_SHADOW_SSL_enable_ocsp_stapling +#define SSL_enable_signed_cert_timestamps GRPC_SHADOW_SSL_enable_signed_cert_timestamps +#define SSL_enable_tls_channel_id GRPC_SHADOW_SSL_enable_tls_channel_id +#define SSL_free GRPC_SHADOW_SSL_free +#define SSL_get0_alpn_selected GRPC_SHADOW_SSL_get0_alpn_selected +#define SSL_get0_certificate_types GRPC_SHADOW_SSL_get0_certificate_types +#define SSL_get0_next_proto_negotiated GRPC_SHADOW_SSL_get0_next_proto_negotiated +#define SSL_get0_ocsp_response GRPC_SHADOW_SSL_get0_ocsp_response +#define SSL_get0_session_id_context GRPC_SHADOW_SSL_get0_session_id_context +#define SSL_get0_signed_cert_timestamp_list GRPC_SHADOW_SSL_get0_signed_cert_timestamp_list +#define SSL_get_SSL_CTX GRPC_SHADOW_SSL_get_SSL_CTX +#define SSL_get_cipher_list GRPC_SHADOW_SSL_get_cipher_list +#define SSL_get_ciphers GRPC_SHADOW_SSL_get_ciphers +#define SSL_get_client_random GRPC_SHADOW_SSL_get_client_random +#define SSL_get_current_cipher GRPC_SHADOW_SSL_get_current_cipher +#define SSL_get_current_compression GRPC_SHADOW_SSL_get_current_compression +#define SSL_get_current_expansion GRPC_SHADOW_SSL_get_current_expansion +#define SSL_get_curve_id GRPC_SHADOW_SSL_get_curve_id +#define SSL_get_default_timeout GRPC_SHADOW_SSL_get_default_timeout +#define SSL_get_error GRPC_SHADOW_SSL_get_error +#define SSL_get_ex_data GRPC_SHADOW_SSL_get_ex_data +#define SSL_get_ex_new_index GRPC_SHADOW_SSL_get_ex_new_index +#define SSL_get_extms_support GRPC_SHADOW_SSL_get_extms_support +#define SSL_get_fd GRPC_SHADOW_SSL_get_fd +#define SSL_get_finished GRPC_SHADOW_SSL_get_finished +#define SSL_get_info_callback GRPC_SHADOW_SSL_get_info_callback +#define SSL_get_ivs GRPC_SHADOW_SSL_get_ivs +#define SSL_get_max_cert_list GRPC_SHADOW_SSL_get_max_cert_list +#define SSL_get_mode GRPC_SHADOW_SSL_get_mode +#define SSL_get_negotiated_token_binding_param GRPC_SHADOW_SSL_get_negotiated_token_binding_param +#define SSL_get_options GRPC_SHADOW_SSL_get_options +#define SSL_get_peer_finished GRPC_SHADOW_SSL_get_peer_finished +#define SSL_get_peer_quic_transport_params GRPC_SHADOW_SSL_get_peer_quic_transport_params +#define SSL_get_peer_signature_algorithm GRPC_SHADOW_SSL_get_peer_signature_algorithm +#define SSL_get_pending_cipher GRPC_SHADOW_SSL_get_pending_cipher +#define SSL_get_privatekey GRPC_SHADOW_SSL_get_privatekey +#define SSL_get_psk_identity GRPC_SHADOW_SSL_get_psk_identity +#define SSL_get_psk_identity_hint GRPC_SHADOW_SSL_get_psk_identity_hint +#define SSL_get_quiet_shutdown GRPC_SHADOW_SSL_get_quiet_shutdown +#define SSL_get_rbio GRPC_SHADOW_SSL_get_rbio +#define SSL_get_read_ahead GRPC_SHADOW_SSL_get_read_ahead +#define SSL_get_read_sequence GRPC_SHADOW_SSL_get_read_sequence +#define SSL_get_rfd GRPC_SHADOW_SSL_get_rfd +#define SSL_get_secure_renegotiation_support GRPC_SHADOW_SSL_get_secure_renegotiation_support +#define SSL_get_server_random GRPC_SHADOW_SSL_get_server_random +#define SSL_get_server_tmp_key GRPC_SHADOW_SSL_get_server_tmp_key +#define SSL_get_servername GRPC_SHADOW_SSL_get_servername +#define SSL_get_servername_type GRPC_SHADOW_SSL_get_servername_type +#define SSL_get_shared_ciphers GRPC_SHADOW_SSL_get_shared_ciphers +#define SSL_get_shutdown GRPC_SHADOW_SSL_get_shutdown +#define SSL_get_structure_sizes GRPC_SHADOW_SSL_get_structure_sizes +#define SSL_get_ticket_age_skew GRPC_SHADOW_SSL_get_ticket_age_skew +#define SSL_get_tls_channel_id GRPC_SHADOW_SSL_get_tls_channel_id +#define SSL_get_tls_unique GRPC_SHADOW_SSL_get_tls_unique +#define SSL_get_verify_mode GRPC_SHADOW_SSL_get_verify_mode +#define SSL_get_wbio GRPC_SHADOW_SSL_get_wbio +#define SSL_get_wfd GRPC_SHADOW_SSL_get_wfd +#define SSL_get_write_sequence GRPC_SHADOW_SSL_get_write_sequence +#define SSL_in_early_data GRPC_SHADOW_SSL_in_early_data +#define SSL_in_false_start GRPC_SHADOW_SSL_in_false_start +#define SSL_in_init GRPC_SHADOW_SSL_in_init +#define SSL_is_draft_downgrade GRPC_SHADOW_SSL_is_draft_downgrade +#define SSL_is_dtls GRPC_SHADOW_SSL_is_dtls +#define SSL_is_init_finished GRPC_SHADOW_SSL_is_init_finished +#define SSL_is_server GRPC_SHADOW_SSL_is_server +#define SSL_is_token_binding_negotiated GRPC_SHADOW_SSL_is_token_binding_negotiated +#define SSL_library_init GRPC_SHADOW_SSL_library_init +#define SSL_load_error_strings GRPC_SHADOW_SSL_load_error_strings +#define SSL_need_tmp_RSA GRPC_SHADOW_SSL_need_tmp_RSA +#define SSL_new GRPC_SHADOW_SSL_new +#define SSL_num_renegotiations GRPC_SHADOW_SSL_num_renegotiations +#define SSL_peek GRPC_SHADOW_SSL_peek +#define SSL_pending GRPC_SHADOW_SSL_pending +#define SSL_read GRPC_SHADOW_SSL_read +#define SSL_renegotiate GRPC_SHADOW_SSL_renegotiate +#define SSL_renegotiate_pending GRPC_SHADOW_SSL_renegotiate_pending +#define SSL_reset_early_data_reject GRPC_SHADOW_SSL_reset_early_data_reject +#define SSL_select_next_proto GRPC_SHADOW_SSL_select_next_proto +#define SSL_send_fatal_alert GRPC_SHADOW_SSL_send_fatal_alert +#define SSL_session_reused GRPC_SHADOW_SSL_session_reused +#define SSL_set0_rbio GRPC_SHADOW_SSL_set0_rbio +#define SSL_set0_wbio GRPC_SHADOW_SSL_set0_wbio +#define SSL_set1_curves GRPC_SHADOW_SSL_set1_curves +#define SSL_set1_curves_list GRPC_SHADOW_SSL_set1_curves_list +#define SSL_set1_tls_channel_id GRPC_SHADOW_SSL_set1_tls_channel_id +#define SSL_set_SSL_CTX GRPC_SHADOW_SSL_set_SSL_CTX +#define SSL_set_accept_state GRPC_SHADOW_SSL_set_accept_state +#define SSL_set_alpn_protos GRPC_SHADOW_SSL_set_alpn_protos +#define SSL_set_bio GRPC_SHADOW_SSL_set_bio +#define SSL_set_cipher_list GRPC_SHADOW_SSL_set_cipher_list +#define SSL_set_connect_state GRPC_SHADOW_SSL_set_connect_state +#define SSL_set_custom_verify GRPC_SHADOW_SSL_set_custom_verify +#define SSL_set_dummy_pq_padding_size GRPC_SHADOW_SSL_set_dummy_pq_padding_size +#define SSL_set_early_data_enabled GRPC_SHADOW_SSL_set_early_data_enabled +#define SSL_set_ex_data GRPC_SHADOW_SSL_set_ex_data +#define SSL_set_fd GRPC_SHADOW_SSL_set_fd +#define SSL_set_info_callback GRPC_SHADOW_SSL_set_info_callback +#define SSL_set_max_cert_list GRPC_SHADOW_SSL_set_max_cert_list +#define SSL_set_max_send_fragment GRPC_SHADOW_SSL_set_max_send_fragment +#define SSL_set_mode GRPC_SHADOW_SSL_set_mode +#define SSL_set_msg_callback GRPC_SHADOW_SSL_set_msg_callback +#define SSL_set_msg_callback_arg GRPC_SHADOW_SSL_set_msg_callback_arg +#define SSL_set_mtu GRPC_SHADOW_SSL_set_mtu +#define SSL_set_options GRPC_SHADOW_SSL_set_options +#define SSL_set_psk_client_callback GRPC_SHADOW_SSL_set_psk_client_callback +#define SSL_set_psk_server_callback GRPC_SHADOW_SSL_set_psk_server_callback +#define SSL_set_quic_transport_params GRPC_SHADOW_SSL_set_quic_transport_params +#define SSL_set_quiet_shutdown GRPC_SHADOW_SSL_set_quiet_shutdown +#define SSL_set_read_ahead GRPC_SHADOW_SSL_set_read_ahead +#define SSL_set_renegotiate_mode GRPC_SHADOW_SSL_set_renegotiate_mode +#define SSL_set_retain_only_sha256_of_client_certs GRPC_SHADOW_SSL_set_retain_only_sha256_of_client_certs +#define SSL_set_rfd GRPC_SHADOW_SSL_set_rfd +#define SSL_set_session_id_context GRPC_SHADOW_SSL_set_session_id_context +#define SSL_set_shutdown GRPC_SHADOW_SSL_set_shutdown +#define SSL_set_state GRPC_SHADOW_SSL_set_state +#define SSL_set_strict_cipher_list GRPC_SHADOW_SSL_set_strict_cipher_list +#define SSL_set_tls13_variant GRPC_SHADOW_SSL_set_tls13_variant +#define SSL_set_tls_channel_id_enabled GRPC_SHADOW_SSL_set_tls_channel_id_enabled +#define SSL_set_tlsext_host_name GRPC_SHADOW_SSL_set_tlsext_host_name +#define SSL_set_tmp_dh GRPC_SHADOW_SSL_set_tmp_dh +#define SSL_set_tmp_dh_callback GRPC_SHADOW_SSL_set_tmp_dh_callback +#define SSL_set_tmp_ecdh GRPC_SHADOW_SSL_set_tmp_ecdh +#define SSL_set_tmp_rsa GRPC_SHADOW_SSL_set_tmp_rsa +#define SSL_set_tmp_rsa_callback GRPC_SHADOW_SSL_set_tmp_rsa_callback +#define SSL_set_token_binding_params GRPC_SHADOW_SSL_set_token_binding_params +#define SSL_set_wfd GRPC_SHADOW_SSL_set_wfd +#define SSL_shutdown GRPC_SHADOW_SSL_shutdown +#define SSL_state GRPC_SHADOW_SSL_state +#define SSL_total_renegotiations GRPC_SHADOW_SSL_total_renegotiations +#define SSL_use_psk_identity_hint GRPC_SHADOW_SSL_use_psk_identity_hint +#define SSL_want GRPC_SHADOW_SSL_want +#define SSL_write GRPC_SHADOW_SSL_write +#define SSL_CTX_set_private_key_method GRPC_SHADOW_SSL_CTX_set_private_key_method +#define SSL_CTX_set_signing_algorithm_prefs GRPC_SHADOW_SSL_CTX_set_signing_algorithm_prefs +#define SSL_CTX_set_verify_algorithm_prefs GRPC_SHADOW_SSL_CTX_set_verify_algorithm_prefs +#define SSL_CTX_use_PrivateKey GRPC_SHADOW_SSL_CTX_use_PrivateKey +#define SSL_CTX_use_PrivateKey_ASN1 GRPC_SHADOW_SSL_CTX_use_PrivateKey_ASN1 +#define SSL_CTX_use_RSAPrivateKey GRPC_SHADOW_SSL_CTX_use_RSAPrivateKey +#define SSL_CTX_use_RSAPrivateKey_ASN1 GRPC_SHADOW_SSL_CTX_use_RSAPrivateKey_ASN1 +#define SSL_get_signature_algorithm_digest GRPC_SHADOW_SSL_get_signature_algorithm_digest +#define SSL_get_signature_algorithm_key_type GRPC_SHADOW_SSL_get_signature_algorithm_key_type +#define SSL_get_signature_algorithm_name GRPC_SHADOW_SSL_get_signature_algorithm_name +#define SSL_is_signature_algorithm_rsa_pss GRPC_SHADOW_SSL_is_signature_algorithm_rsa_pss +#define SSL_set_private_key_method GRPC_SHADOW_SSL_set_private_key_method +#define SSL_set_signing_algorithm_prefs GRPC_SHADOW_SSL_set_signing_algorithm_prefs +#define SSL_use_PrivateKey GRPC_SHADOW_SSL_use_PrivateKey +#define SSL_use_PrivateKey_ASN1 GRPC_SHADOW_SSL_use_PrivateKey_ASN1 +#define SSL_use_RSAPrivateKey GRPC_SHADOW_SSL_use_RSAPrivateKey +#define SSL_use_RSAPrivateKey_ASN1 GRPC_SHADOW_SSL_use_RSAPrivateKey_ASN1 +#define SSL_CTX_add_session GRPC_SHADOW_SSL_CTX_add_session +#define SSL_CTX_flush_sessions GRPC_SHADOW_SSL_CTX_flush_sessions +#define SSL_CTX_get_channel_id_cb GRPC_SHADOW_SSL_CTX_get_channel_id_cb +#define SSL_CTX_get_info_callback GRPC_SHADOW_SSL_CTX_get_info_callback +#define SSL_CTX_get_timeout GRPC_SHADOW_SSL_CTX_get_timeout +#define SSL_CTX_remove_session GRPC_SHADOW_SSL_CTX_remove_session +#define SSL_CTX_sess_get_get_cb GRPC_SHADOW_SSL_CTX_sess_get_get_cb +#define SSL_CTX_sess_get_new_cb GRPC_SHADOW_SSL_CTX_sess_get_new_cb +#define SSL_CTX_sess_get_remove_cb GRPC_SHADOW_SSL_CTX_sess_get_remove_cb +#define SSL_CTX_sess_set_get_cb GRPC_SHADOW_SSL_CTX_sess_set_get_cb +#define SSL_CTX_sess_set_new_cb GRPC_SHADOW_SSL_CTX_sess_set_new_cb +#define SSL_CTX_sess_set_remove_cb GRPC_SHADOW_SSL_CTX_sess_set_remove_cb +#define SSL_CTX_set_channel_id_cb GRPC_SHADOW_SSL_CTX_set_channel_id_cb +#define SSL_CTX_set_info_callback GRPC_SHADOW_SSL_CTX_set_info_callback +#define SSL_CTX_set_session_psk_dhe_timeout GRPC_SHADOW_SSL_CTX_set_session_psk_dhe_timeout +#define SSL_CTX_set_timeout GRPC_SHADOW_SSL_CTX_set_timeout +#define SSL_SESSION_free GRPC_SHADOW_SSL_SESSION_free +#define SSL_SESSION_get0_peer GRPC_SHADOW_SSL_SESSION_get0_peer +#define SSL_SESSION_get0_ticket GRPC_SHADOW_SSL_SESSION_get0_ticket +#define SSL_SESSION_get_ex_data GRPC_SHADOW_SSL_SESSION_get_ex_data +#define SSL_SESSION_get_ex_new_index GRPC_SHADOW_SSL_SESSION_get_ex_new_index +#define SSL_SESSION_get_id GRPC_SHADOW_SSL_SESSION_get_id +#define SSL_SESSION_get_master_key GRPC_SHADOW_SSL_SESSION_get_master_key +#define SSL_SESSION_get_ticket_lifetime_hint GRPC_SHADOW_SSL_SESSION_get_ticket_lifetime_hint +#define SSL_SESSION_get_time GRPC_SHADOW_SSL_SESSION_get_time +#define SSL_SESSION_get_timeout GRPC_SHADOW_SSL_SESSION_get_timeout +#define SSL_SESSION_has_ticket GRPC_SHADOW_SSL_SESSION_has_ticket +#define SSL_SESSION_is_resumable GRPC_SHADOW_SSL_SESSION_is_resumable +#define SSL_SESSION_new GRPC_SHADOW_SSL_SESSION_new +#define SSL_SESSION_set1_id_context GRPC_SHADOW_SSL_SESSION_set1_id_context +#define SSL_SESSION_set_ex_data GRPC_SHADOW_SSL_SESSION_set_ex_data +#define SSL_SESSION_set_time GRPC_SHADOW_SSL_SESSION_set_time +#define SSL_SESSION_set_timeout GRPC_SHADOW_SSL_SESSION_set_timeout +#define SSL_SESSION_should_be_single_use GRPC_SHADOW_SSL_SESSION_should_be_single_use +#define SSL_SESSION_up_ref GRPC_SHADOW_SSL_SESSION_up_ref +#define SSL_get1_session GRPC_SHADOW_SSL_get1_session +#define SSL_get_session GRPC_SHADOW_SSL_get_session +#define SSL_magic_pending_session_ptr GRPC_SHADOW_SSL_magic_pending_session_ptr +#define SSL_set_session GRPC_SHADOW_SSL_set_session +#define SSL_alert_desc_string GRPC_SHADOW_SSL_alert_desc_string +#define SSL_alert_desc_string_long GRPC_SHADOW_SSL_alert_desc_string_long +#define SSL_alert_type_string GRPC_SHADOW_SSL_alert_type_string +#define SSL_alert_type_string_long GRPC_SHADOW_SSL_alert_type_string_long +#define SSL_state_string GRPC_SHADOW_SSL_state_string +#define SSL_state_string_long GRPC_SHADOW_SSL_state_string_long +#define SSL_CTX_set_max_proto_version GRPC_SHADOW_SSL_CTX_set_max_proto_version +#define SSL_CTX_set_min_proto_version GRPC_SHADOW_SSL_CTX_set_min_proto_version +#define SSL_SESSION_get_protocol_version GRPC_SHADOW_SSL_SESSION_get_protocol_version +#define SSL_SESSION_get_version GRPC_SHADOW_SSL_SESSION_get_version +#define SSL_SESSION_set_protocol_version GRPC_SHADOW_SSL_SESSION_set_protocol_version +#define SSL_get_version GRPC_SHADOW_SSL_get_version +#define SSL_set_max_proto_version GRPC_SHADOW_SSL_set_max_proto_version +#define SSL_set_min_proto_version GRPC_SHADOW_SSL_set_min_proto_version +#define SSL_version GRPC_SHADOW_SSL_version +#define PEM_read_SSL_SESSION GRPC_SHADOW_PEM_read_SSL_SESSION +#define PEM_read_bio_SSL_SESSION GRPC_SHADOW_PEM_read_bio_SSL_SESSION +#define PEM_write_SSL_SESSION GRPC_SHADOW_PEM_write_SSL_SESSION +#define PEM_write_bio_SSL_SESSION GRPC_SHADOW_PEM_write_bio_SSL_SESSION +#define SSL_CTX_add0_chain_cert GRPC_SHADOW_SSL_CTX_add0_chain_cert +#define SSL_CTX_add1_chain_cert GRPC_SHADOW_SSL_CTX_add1_chain_cert +#define SSL_CTX_add_client_CA GRPC_SHADOW_SSL_CTX_add_client_CA +#define SSL_CTX_add_extra_chain_cert GRPC_SHADOW_SSL_CTX_add_extra_chain_cert +#define SSL_CTX_clear_chain_certs GRPC_SHADOW_SSL_CTX_clear_chain_certs +#define SSL_CTX_clear_extra_chain_certs GRPC_SHADOW_SSL_CTX_clear_extra_chain_certs +#define SSL_CTX_get0_certificate GRPC_SHADOW_SSL_CTX_get0_certificate +#define SSL_CTX_get0_chain_certs GRPC_SHADOW_SSL_CTX_get0_chain_certs +#define SSL_CTX_get0_param GRPC_SHADOW_SSL_CTX_get0_param +#define SSL_CTX_get_cert_store GRPC_SHADOW_SSL_CTX_get_cert_store +#define SSL_CTX_get_client_CA_list GRPC_SHADOW_SSL_CTX_get_client_CA_list +#define SSL_CTX_get_extra_chain_certs GRPC_SHADOW_SSL_CTX_get_extra_chain_certs +#define SSL_CTX_get_verify_callback GRPC_SHADOW_SSL_CTX_get_verify_callback +#define SSL_CTX_get_verify_depth GRPC_SHADOW_SSL_CTX_get_verify_depth +#define SSL_CTX_get_verify_mode GRPC_SHADOW_SSL_CTX_get_verify_mode +#define SSL_CTX_load_verify_locations GRPC_SHADOW_SSL_CTX_load_verify_locations +#define SSL_CTX_set0_chain GRPC_SHADOW_SSL_CTX_set0_chain +#define SSL_CTX_set0_verify_cert_store GRPC_SHADOW_SSL_CTX_set0_verify_cert_store +#define SSL_CTX_set1_chain GRPC_SHADOW_SSL_CTX_set1_chain +#define SSL_CTX_set1_param GRPC_SHADOW_SSL_CTX_set1_param +#define SSL_CTX_set1_verify_cert_store GRPC_SHADOW_SSL_CTX_set1_verify_cert_store +#define SSL_CTX_set_cert_store GRPC_SHADOW_SSL_CTX_set_cert_store +#define SSL_CTX_set_cert_verify_callback GRPC_SHADOW_SSL_CTX_set_cert_verify_callback +#define SSL_CTX_set_client_CA_list GRPC_SHADOW_SSL_CTX_set_client_CA_list +#define SSL_CTX_set_client_cert_cb GRPC_SHADOW_SSL_CTX_set_client_cert_cb +#define SSL_CTX_set_default_verify_paths GRPC_SHADOW_SSL_CTX_set_default_verify_paths +#define SSL_CTX_set_purpose GRPC_SHADOW_SSL_CTX_set_purpose +#define SSL_CTX_set_trust GRPC_SHADOW_SSL_CTX_set_trust +#define SSL_CTX_set_verify GRPC_SHADOW_SSL_CTX_set_verify +#define SSL_CTX_set_verify_depth GRPC_SHADOW_SSL_CTX_set_verify_depth +#define SSL_CTX_use_certificate GRPC_SHADOW_SSL_CTX_use_certificate +#define SSL_add0_chain_cert GRPC_SHADOW_SSL_add0_chain_cert +#define SSL_add1_chain_cert GRPC_SHADOW_SSL_add1_chain_cert +#define SSL_add_client_CA GRPC_SHADOW_SSL_add_client_CA +#define SSL_alert_from_verify_result GRPC_SHADOW_SSL_alert_from_verify_result +#define SSL_clear_chain_certs GRPC_SHADOW_SSL_clear_chain_certs +#define SSL_dup_CA_list GRPC_SHADOW_SSL_dup_CA_list +#define SSL_get0_chain_certs GRPC_SHADOW_SSL_get0_chain_certs +#define SSL_get0_param GRPC_SHADOW_SSL_get0_param +#define SSL_get_certificate GRPC_SHADOW_SSL_get_certificate +#define SSL_get_client_CA_list GRPC_SHADOW_SSL_get_client_CA_list +#define SSL_get_ex_data_X509_STORE_CTX_idx GRPC_SHADOW_SSL_get_ex_data_X509_STORE_CTX_idx +#define SSL_get_peer_cert_chain GRPC_SHADOW_SSL_get_peer_cert_chain +#define SSL_get_peer_certificate GRPC_SHADOW_SSL_get_peer_certificate +#define SSL_get_peer_full_cert_chain GRPC_SHADOW_SSL_get_peer_full_cert_chain +#define SSL_get_verify_callback GRPC_SHADOW_SSL_get_verify_callback +#define SSL_get_verify_depth GRPC_SHADOW_SSL_get_verify_depth +#define SSL_get_verify_result GRPC_SHADOW_SSL_get_verify_result +#define SSL_set0_chain GRPC_SHADOW_SSL_set0_chain +#define SSL_set0_verify_cert_store GRPC_SHADOW_SSL_set0_verify_cert_store +#define SSL_set1_chain GRPC_SHADOW_SSL_set1_chain +#define SSL_set1_param GRPC_SHADOW_SSL_set1_param +#define SSL_set1_verify_cert_store GRPC_SHADOW_SSL_set1_verify_cert_store +#define SSL_set_client_CA_list GRPC_SHADOW_SSL_set_client_CA_list +#define SSL_set_purpose GRPC_SHADOW_SSL_set_purpose +#define SSL_set_trust GRPC_SHADOW_SSL_set_trust +#define SSL_set_verify GRPC_SHADOW_SSL_set_verify +#define SSL_set_verify_depth GRPC_SHADOW_SSL_set_verify_depth +#define SSL_set_verify_result GRPC_SHADOW_SSL_set_verify_result +#define SSL_use_certificate GRPC_SHADOW_SSL_use_certificate +#define d2i_SSL_SESSION GRPC_SHADOW_d2i_SSL_SESSION +#define d2i_SSL_SESSION_bio GRPC_SHADOW_d2i_SSL_SESSION_bio +#define i2d_SSL_SESSION_bio GRPC_SHADOW_i2d_SSL_SESSION_bio +#define SSL_export_early_keying_material GRPC_SHADOW_SSL_export_early_keying_material +#define SSL_export_keying_material GRPC_SHADOW_SSL_export_keying_material +#define SSL_generate_key_block GRPC_SHADOW_SSL_generate_key_block +#define SSL_get_key_block_len GRPC_SHADOW_SSL_get_key_block_len +#define SSL_CTX_set_ed25519_enabled GRPC_SHADOW_SSL_CTX_set_ed25519_enabled +#define SSL_early_callback_ctx_extension_get GRPC_SHADOW_SSL_early_callback_ctx_extension_get +#define SSL_extension_supported GRPC_SHADOW_SSL_extension_supported +#define SSLv23_client_method GRPC_SHADOW_SSLv23_client_method +#define SSLv23_method GRPC_SHADOW_SSLv23_method +#define SSLv23_server_method GRPC_SHADOW_SSLv23_server_method +#define TLS_client_method GRPC_SHADOW_TLS_client_method +#define TLS_method GRPC_SHADOW_TLS_method +#define TLS_server_method GRPC_SHADOW_TLS_server_method +#define TLS_with_buffers_method GRPC_SHADOW_TLS_with_buffers_method +#define TLSv1_1_client_method GRPC_SHADOW_TLSv1_1_client_method +#define TLSv1_1_method GRPC_SHADOW_TLSv1_1_method +#define TLSv1_1_server_method GRPC_SHADOW_TLSv1_1_server_method +#define TLSv1_2_client_method GRPC_SHADOW_TLSv1_2_client_method +#define TLSv1_2_method GRPC_SHADOW_TLSv1_2_method +#define TLSv1_2_server_method GRPC_SHADOW_TLSv1_2_server_method +#define TLSv1_client_method GRPC_SHADOW_TLSv1_client_method +#define TLSv1_method GRPC_SHADOW_TLSv1_method +#define TLSv1_server_method GRPC_SHADOW_TLSv1_server_method +#define SSL_max_seal_overhead GRPC_SHADOW_SSL_max_seal_overhead +#define OPENSSL_cpuid_setup GRPC_SHADOW_OPENSSL_cpuid_setup +#define CRYPTO_has_asm GRPC_SHADOW_CRYPTO_has_asm +#define CRYPTO_is_confidential_build GRPC_SHADOW_CRYPTO_is_confidential_build +#define CRYPTO_library_init GRPC_SHADOW_CRYPTO_library_init +#define CRYPTO_malloc_init GRPC_SHADOW_CRYPTO_malloc_init +#define ENGINE_load_builtin_engines GRPC_SHADOW_ENGINE_load_builtin_engines +#define ENGINE_register_all_complete GRPC_SHADOW_ENGINE_register_all_complete +#define OPENSSL_ia32cap_P GRPC_SHADOW_OPENSSL_ia32cap_P +#define OPENSSL_init_crypto GRPC_SHADOW_OPENSSL_init_crypto +#define OPENSSL_load_builtin_modules GRPC_SHADOW_OPENSSL_load_builtin_modules +#define OpenSSL_version GRPC_SHADOW_OpenSSL_version +#define OpenSSL_version_num GRPC_SHADOW_OpenSSL_version_num +#define SSLeay GRPC_SHADOW_SSLeay +#define SSLeay_version GRPC_SHADOW_SSLeay_version +#define CRYPTO_cleanup_all_ex_data GRPC_SHADOW_CRYPTO_cleanup_all_ex_data +#define CRYPTO_free_ex_data GRPC_SHADOW_CRYPTO_free_ex_data +#define CRYPTO_get_ex_data GRPC_SHADOW_CRYPTO_get_ex_data +#define CRYPTO_get_ex_new_index GRPC_SHADOW_CRYPTO_get_ex_new_index +#define CRYPTO_new_ex_data GRPC_SHADOW_CRYPTO_new_ex_data +#define CRYPTO_set_ex_data GRPC_SHADOW_CRYPTO_set_ex_data +#define BIO_snprintf GRPC_SHADOW_BIO_snprintf +#define BIO_vsnprintf GRPC_SHADOW_BIO_vsnprintf +#define CRYPTO_memcmp GRPC_SHADOW_CRYPTO_memcmp +#define OPENSSL_cleanse GRPC_SHADOW_OPENSSL_cleanse +#define OPENSSL_free GRPC_SHADOW_OPENSSL_free +#define OPENSSL_hash32 GRPC_SHADOW_OPENSSL_hash32 +#define OPENSSL_malloc GRPC_SHADOW_OPENSSL_malloc +#define OPENSSL_realloc GRPC_SHADOW_OPENSSL_realloc +#define OPENSSL_strcasecmp GRPC_SHADOW_OPENSSL_strcasecmp +#define OPENSSL_strdup GRPC_SHADOW_OPENSSL_strdup +#define OPENSSL_strncasecmp GRPC_SHADOW_OPENSSL_strncasecmp +#define OPENSSL_strnlen GRPC_SHADOW_OPENSSL_strnlen +#define OPENSSL_tolower GRPC_SHADOW_OPENSSL_tolower +#define CRYPTO_refcount_dec_and_test_zero GRPC_SHADOW_CRYPTO_refcount_dec_and_test_zero +#define CRYPTO_refcount_inc GRPC_SHADOW_CRYPTO_refcount_inc +#define CRYPTO_THREADID_current GRPC_SHADOW_CRYPTO_THREADID_current +#define CRYPTO_THREADID_set_callback GRPC_SHADOW_CRYPTO_THREADID_set_callback +#define CRYPTO_THREADID_set_numeric GRPC_SHADOW_CRYPTO_THREADID_set_numeric +#define CRYPTO_THREADID_set_pointer GRPC_SHADOW_CRYPTO_THREADID_set_pointer +#define CRYPTO_get_dynlock_create_callback GRPC_SHADOW_CRYPTO_get_dynlock_create_callback +#define CRYPTO_get_dynlock_destroy_callback GRPC_SHADOW_CRYPTO_get_dynlock_destroy_callback +#define CRYPTO_get_dynlock_lock_callback GRPC_SHADOW_CRYPTO_get_dynlock_lock_callback +#define CRYPTO_get_lock_name GRPC_SHADOW_CRYPTO_get_lock_name +#define CRYPTO_get_locking_callback GRPC_SHADOW_CRYPTO_get_locking_callback +#define CRYPTO_num_locks GRPC_SHADOW_CRYPTO_num_locks +#define CRYPTO_set_add_lock_callback GRPC_SHADOW_CRYPTO_set_add_lock_callback +#define CRYPTO_set_dynlock_create_callback GRPC_SHADOW_CRYPTO_set_dynlock_create_callback +#define CRYPTO_set_dynlock_destroy_callback GRPC_SHADOW_CRYPTO_set_dynlock_destroy_callback +#define CRYPTO_set_dynlock_lock_callback GRPC_SHADOW_CRYPTO_set_dynlock_lock_callback +#define CRYPTO_set_id_callback GRPC_SHADOW_CRYPTO_set_id_callback +#define CRYPTO_set_locking_callback GRPC_SHADOW_CRYPTO_set_locking_callback +#define CRYPTO_MUTEX_cleanup GRPC_SHADOW_CRYPTO_MUTEX_cleanup +#define CRYPTO_MUTEX_init GRPC_SHADOW_CRYPTO_MUTEX_init +#define CRYPTO_MUTEX_lock_read GRPC_SHADOW_CRYPTO_MUTEX_lock_read +#define CRYPTO_MUTEX_lock_write GRPC_SHADOW_CRYPTO_MUTEX_lock_write +#define CRYPTO_MUTEX_unlock_read GRPC_SHADOW_CRYPTO_MUTEX_unlock_read +#define CRYPTO_MUTEX_unlock_write GRPC_SHADOW_CRYPTO_MUTEX_unlock_write +#define CRYPTO_STATIC_MUTEX_lock_read GRPC_SHADOW_CRYPTO_STATIC_MUTEX_lock_read +#define CRYPTO_STATIC_MUTEX_lock_write GRPC_SHADOW_CRYPTO_STATIC_MUTEX_lock_write +#define CRYPTO_STATIC_MUTEX_unlock_read GRPC_SHADOW_CRYPTO_STATIC_MUTEX_unlock_read +#define CRYPTO_STATIC_MUTEX_unlock_write GRPC_SHADOW_CRYPTO_STATIC_MUTEX_unlock_write +#define CRYPTO_get_thread_local GRPC_SHADOW_CRYPTO_get_thread_local +#define CRYPTO_once GRPC_SHADOW_CRYPTO_once +#define CRYPTO_set_thread_local GRPC_SHADOW_CRYPTO_set_thread_local +#define sk_deep_copy GRPC_SHADOW_sk_deep_copy +#define sk_delete GRPC_SHADOW_sk_delete +#define sk_delete_ptr GRPC_SHADOW_sk_delete_ptr +#define sk_dup GRPC_SHADOW_sk_dup +#define sk_find GRPC_SHADOW_sk_find +#define sk_free GRPC_SHADOW_sk_free +#define sk_insert GRPC_SHADOW_sk_insert +#define sk_is_sorted GRPC_SHADOW_sk_is_sorted +#define sk_new GRPC_SHADOW_sk_new +#define sk_new_null GRPC_SHADOW_sk_new_null +#define sk_num GRPC_SHADOW_sk_num +#define sk_pop GRPC_SHADOW_sk_pop +#define sk_pop_free GRPC_SHADOW_sk_pop_free +#define sk_push GRPC_SHADOW_sk_push +#define sk_set GRPC_SHADOW_sk_set +#define sk_set_cmp_func GRPC_SHADOW_sk_set_cmp_func +#define sk_shift GRPC_SHADOW_sk_shift +#define sk_sort GRPC_SHADOW_sk_sort +#define sk_value GRPC_SHADOW_sk_value +#define sk_zero GRPC_SHADOW_sk_zero +#define lh_delete GRPC_SHADOW_lh_delete +#define lh_doall GRPC_SHADOW_lh_doall +#define lh_doall_arg GRPC_SHADOW_lh_doall_arg +#define lh_free GRPC_SHADOW_lh_free +#define lh_insert GRPC_SHADOW_lh_insert +#define lh_new GRPC_SHADOW_lh_new +#define lh_num_items GRPC_SHADOW_lh_num_items +#define lh_retrieve GRPC_SHADOW_lh_retrieve +#define lh_strhash GRPC_SHADOW_lh_strhash +#define ERR_SAVE_STATE_free GRPC_SHADOW_ERR_SAVE_STATE_free +#define ERR_add_error_data GRPC_SHADOW_ERR_add_error_data +#define ERR_add_error_dataf GRPC_SHADOW_ERR_add_error_dataf +#define ERR_clear_error GRPC_SHADOW_ERR_clear_error +#define ERR_clear_system_error GRPC_SHADOW_ERR_clear_system_error +#define ERR_error_string GRPC_SHADOW_ERR_error_string +#define ERR_error_string_n GRPC_SHADOW_ERR_error_string_n +#define ERR_free_strings GRPC_SHADOW_ERR_free_strings +#define ERR_func_error_string GRPC_SHADOW_ERR_func_error_string +#define ERR_get_error GRPC_SHADOW_ERR_get_error +#define ERR_get_error_line GRPC_SHADOW_ERR_get_error_line +#define ERR_get_error_line_data GRPC_SHADOW_ERR_get_error_line_data +#define ERR_get_next_error_library GRPC_SHADOW_ERR_get_next_error_library +#define ERR_lib_error_string GRPC_SHADOW_ERR_lib_error_string +#define ERR_load_BIO_strings GRPC_SHADOW_ERR_load_BIO_strings +#define ERR_load_ERR_strings GRPC_SHADOW_ERR_load_ERR_strings +#define ERR_load_crypto_strings GRPC_SHADOW_ERR_load_crypto_strings +#define ERR_peek_error GRPC_SHADOW_ERR_peek_error +#define ERR_peek_error_line GRPC_SHADOW_ERR_peek_error_line +#define ERR_peek_error_line_data GRPC_SHADOW_ERR_peek_error_line_data +#define ERR_peek_last_error GRPC_SHADOW_ERR_peek_last_error +#define ERR_peek_last_error_line GRPC_SHADOW_ERR_peek_last_error_line +#define ERR_peek_last_error_line_data GRPC_SHADOW_ERR_peek_last_error_line_data +#define ERR_pop_to_mark GRPC_SHADOW_ERR_pop_to_mark +#define ERR_print_errors_cb GRPC_SHADOW_ERR_print_errors_cb +#define ERR_print_errors_fp GRPC_SHADOW_ERR_print_errors_fp +#define ERR_put_error GRPC_SHADOW_ERR_put_error +#define ERR_reason_error_string GRPC_SHADOW_ERR_reason_error_string +#define ERR_remove_state GRPC_SHADOW_ERR_remove_state +#define ERR_remove_thread_state GRPC_SHADOW_ERR_remove_thread_state +#define ERR_restore_state GRPC_SHADOW_ERR_restore_state +#define ERR_save_state GRPC_SHADOW_ERR_save_state +#define ERR_set_mark GRPC_SHADOW_ERR_set_mark +#define kOpenSSLReasonStringData GRPC_SHADOW_kOpenSSLReasonStringData +#define kOpenSSLReasonValues GRPC_SHADOW_kOpenSSLReasonValues +#define kOpenSSLReasonValuesLen GRPC_SHADOW_kOpenSSLReasonValuesLen +#define EVP_DecodeBase64 GRPC_SHADOW_EVP_DecodeBase64 +#define EVP_DecodeBlock GRPC_SHADOW_EVP_DecodeBlock +#define EVP_DecodeFinal GRPC_SHADOW_EVP_DecodeFinal +#define EVP_DecodeInit GRPC_SHADOW_EVP_DecodeInit +#define EVP_DecodeUpdate GRPC_SHADOW_EVP_DecodeUpdate +#define EVP_DecodedLength GRPC_SHADOW_EVP_DecodedLength +#define EVP_EncodeBlock GRPC_SHADOW_EVP_EncodeBlock +#define EVP_EncodeFinal GRPC_SHADOW_EVP_EncodeFinal +#define EVP_EncodeInit GRPC_SHADOW_EVP_EncodeInit +#define EVP_EncodeUpdate GRPC_SHADOW_EVP_EncodeUpdate +#define EVP_EncodedLength GRPC_SHADOW_EVP_EncodedLength +#define CBB_finish_i2d GRPC_SHADOW_CBB_finish_i2d +#define CBS_asn1_ber_to_der GRPC_SHADOW_CBS_asn1_ber_to_der +#define CBS_get_asn1_implicit_string GRPC_SHADOW_CBS_get_asn1_implicit_string +#define CBS_asn1_bitstring_has_bit GRPC_SHADOW_CBS_asn1_bitstring_has_bit +#define CBS_asn1_oid_to_text GRPC_SHADOW_CBS_asn1_oid_to_text +#define CBS_contains_zero_byte GRPC_SHADOW_CBS_contains_zero_byte +#define CBS_copy_bytes GRPC_SHADOW_CBS_copy_bytes +#define CBS_data GRPC_SHADOW_CBS_data +#define CBS_get_any_asn1 GRPC_SHADOW_CBS_get_any_asn1 +#define CBS_get_any_asn1_element GRPC_SHADOW_CBS_get_any_asn1_element +#define CBS_get_any_ber_asn1_element GRPC_SHADOW_CBS_get_any_ber_asn1_element +#define CBS_get_asn1 GRPC_SHADOW_CBS_get_asn1 +#define CBS_get_asn1_bool GRPC_SHADOW_CBS_get_asn1_bool +#define CBS_get_asn1_element GRPC_SHADOW_CBS_get_asn1_element +#define CBS_get_asn1_uint64 GRPC_SHADOW_CBS_get_asn1_uint64 +#define CBS_get_bytes GRPC_SHADOW_CBS_get_bytes +#define CBS_get_last_u8 GRPC_SHADOW_CBS_get_last_u8 +#define CBS_get_optional_asn1 GRPC_SHADOW_CBS_get_optional_asn1 +#define CBS_get_optional_asn1_bool GRPC_SHADOW_CBS_get_optional_asn1_bool +#define CBS_get_optional_asn1_octet_string GRPC_SHADOW_CBS_get_optional_asn1_octet_string +#define CBS_get_optional_asn1_uint64 GRPC_SHADOW_CBS_get_optional_asn1_uint64 +#define CBS_get_u16 GRPC_SHADOW_CBS_get_u16 +#define CBS_get_u16_length_prefixed GRPC_SHADOW_CBS_get_u16_length_prefixed +#define CBS_get_u24 GRPC_SHADOW_CBS_get_u24 +#define CBS_get_u24_length_prefixed GRPC_SHADOW_CBS_get_u24_length_prefixed +#define CBS_get_u32 GRPC_SHADOW_CBS_get_u32 +#define CBS_get_u8 GRPC_SHADOW_CBS_get_u8 +#define CBS_get_u8_length_prefixed GRPC_SHADOW_CBS_get_u8_length_prefixed +#define CBS_init GRPC_SHADOW_CBS_init +#define CBS_is_valid_asn1_bitstring GRPC_SHADOW_CBS_is_valid_asn1_bitstring +#define CBS_len GRPC_SHADOW_CBS_len +#define CBS_mem_equal GRPC_SHADOW_CBS_mem_equal +#define CBS_peek_asn1_tag GRPC_SHADOW_CBS_peek_asn1_tag +#define CBS_skip GRPC_SHADOW_CBS_skip +#define CBS_stow GRPC_SHADOW_CBS_stow +#define CBS_strdup GRPC_SHADOW_CBS_strdup +#define CBB_add_asn1 GRPC_SHADOW_CBB_add_asn1 +#define CBB_add_asn1_bool GRPC_SHADOW_CBB_add_asn1_bool +#define CBB_add_asn1_octet_string GRPC_SHADOW_CBB_add_asn1_octet_string +#define CBB_add_asn1_oid_from_text GRPC_SHADOW_CBB_add_asn1_oid_from_text +#define CBB_add_asn1_uint64 GRPC_SHADOW_CBB_add_asn1_uint64 +#define CBB_add_bytes GRPC_SHADOW_CBB_add_bytes +#define CBB_add_space GRPC_SHADOW_CBB_add_space +#define CBB_add_u16 GRPC_SHADOW_CBB_add_u16 +#define CBB_add_u16_length_prefixed GRPC_SHADOW_CBB_add_u16_length_prefixed +#define CBB_add_u24 GRPC_SHADOW_CBB_add_u24 +#define CBB_add_u24_length_prefixed GRPC_SHADOW_CBB_add_u24_length_prefixed +#define CBB_add_u32 GRPC_SHADOW_CBB_add_u32 +#define CBB_add_u8 GRPC_SHADOW_CBB_add_u8 +#define CBB_add_u8_length_prefixed GRPC_SHADOW_CBB_add_u8_length_prefixed +#define CBB_cleanup GRPC_SHADOW_CBB_cleanup +#define CBB_data GRPC_SHADOW_CBB_data +#define CBB_did_write GRPC_SHADOW_CBB_did_write +#define CBB_discard_child GRPC_SHADOW_CBB_discard_child +#define CBB_finish GRPC_SHADOW_CBB_finish +#define CBB_flush GRPC_SHADOW_CBB_flush +#define CBB_flush_asn1_set_of GRPC_SHADOW_CBB_flush_asn1_set_of +#define CBB_init GRPC_SHADOW_CBB_init +#define CBB_init_fixed GRPC_SHADOW_CBB_init_fixed +#define CBB_len GRPC_SHADOW_CBB_len +#define CBB_reserve GRPC_SHADOW_CBB_reserve +#define CBB_zero GRPC_SHADOW_CBB_zero +#define CRYPTO_BUFFER_POOL_free GRPC_SHADOW_CRYPTO_BUFFER_POOL_free +#define CRYPTO_BUFFER_POOL_new GRPC_SHADOW_CRYPTO_BUFFER_POOL_new +#define CRYPTO_BUFFER_data GRPC_SHADOW_CRYPTO_BUFFER_data +#define CRYPTO_BUFFER_free GRPC_SHADOW_CRYPTO_BUFFER_free +#define CRYPTO_BUFFER_init_CBS GRPC_SHADOW_CRYPTO_BUFFER_init_CBS +#define CRYPTO_BUFFER_len GRPC_SHADOW_CRYPTO_BUFFER_len +#define CRYPTO_BUFFER_new GRPC_SHADOW_CRYPTO_BUFFER_new +#define CRYPTO_BUFFER_new_from_CBS GRPC_SHADOW_CRYPTO_BUFFER_new_from_CBS +#define CRYPTO_BUFFER_up_ref GRPC_SHADOW_CRYPTO_BUFFER_up_ref +#define AES_cbc_encrypt GRPC_SHADOW_AES_cbc_encrypt +#define AES_cfb128_encrypt GRPC_SHADOW_AES_cfb128_encrypt +#define AES_ctr128_encrypt GRPC_SHADOW_AES_ctr128_encrypt +#define AES_decrypt GRPC_SHADOW_AES_decrypt +#define AES_ecb_encrypt GRPC_SHADOW_AES_ecb_encrypt +#define AES_encrypt GRPC_SHADOW_AES_encrypt +#define AES_ofb128_encrypt GRPC_SHADOW_AES_ofb128_encrypt +#define AES_set_decrypt_key GRPC_SHADOW_AES_set_decrypt_key +#define AES_set_encrypt_key GRPC_SHADOW_AES_set_encrypt_key +#define AES_unwrap_key GRPC_SHADOW_AES_unwrap_key +#define AES_wrap_key GRPC_SHADOW_AES_wrap_key +#define BN_BLINDING_convert GRPC_SHADOW_BN_BLINDING_convert +#define BN_BLINDING_free GRPC_SHADOW_BN_BLINDING_free +#define BN_BLINDING_invert GRPC_SHADOW_BN_BLINDING_invert +#define BN_BLINDING_new GRPC_SHADOW_BN_BLINDING_new +#define BN_CTX_end GRPC_SHADOW_BN_CTX_end +#define BN_CTX_free GRPC_SHADOW_BN_CTX_free +#define BN_CTX_get GRPC_SHADOW_BN_CTX_get +#define BN_CTX_new GRPC_SHADOW_BN_CTX_new +#define BN_CTX_start GRPC_SHADOW_BN_CTX_start +#define BN_GENCB_call GRPC_SHADOW_BN_GENCB_call +#define BN_GENCB_set GRPC_SHADOW_BN_GENCB_set +#define BN_MONT_CTX_copy GRPC_SHADOW_BN_MONT_CTX_copy +#define BN_MONT_CTX_free GRPC_SHADOW_BN_MONT_CTX_free +#define BN_MONT_CTX_new GRPC_SHADOW_BN_MONT_CTX_new +#define BN_MONT_CTX_new_for_modulus GRPC_SHADOW_BN_MONT_CTX_new_for_modulus +#define BN_MONT_CTX_set GRPC_SHADOW_BN_MONT_CTX_set +#define BN_MONT_CTX_set_locked GRPC_SHADOW_BN_MONT_CTX_set_locked +#define BN_abs_is_word GRPC_SHADOW_BN_abs_is_word +#define BN_add GRPC_SHADOW_BN_add +#define BN_add_word GRPC_SHADOW_BN_add_word +#define BN_bin2bn GRPC_SHADOW_BN_bin2bn +#define BN_bn2bin GRPC_SHADOW_BN_bn2bin +#define BN_bn2bin_padded GRPC_SHADOW_BN_bn2bin_padded +#define BN_bn2le_padded GRPC_SHADOW_BN_bn2le_padded +#define BN_clear GRPC_SHADOW_BN_clear +#define BN_clear_bit GRPC_SHADOW_BN_clear_bit +#define BN_clear_free GRPC_SHADOW_BN_clear_free +#define BN_cmp GRPC_SHADOW_BN_cmp +#define BN_cmp_word GRPC_SHADOW_BN_cmp_word +#define BN_copy GRPC_SHADOW_BN_copy +#define BN_count_low_zero_bits GRPC_SHADOW_BN_count_low_zero_bits +#define BN_div GRPC_SHADOW_BN_div +#define BN_div_word GRPC_SHADOW_BN_div_word +#define BN_dup GRPC_SHADOW_BN_dup +#define BN_enhanced_miller_rabin_primality_test GRPC_SHADOW_BN_enhanced_miller_rabin_primality_test +#define BN_equal_consttime GRPC_SHADOW_BN_equal_consttime +#define BN_exp GRPC_SHADOW_BN_exp +#define BN_free GRPC_SHADOW_BN_free +#define BN_from_montgomery GRPC_SHADOW_BN_from_montgomery +#define BN_gcd GRPC_SHADOW_BN_gcd +#define BN_generate_prime_ex GRPC_SHADOW_BN_generate_prime_ex +#define BN_get_u64 GRPC_SHADOW_BN_get_u64 +#define BN_get_word GRPC_SHADOW_BN_get_word +#define BN_init GRPC_SHADOW_BN_init +#define BN_is_bit_set GRPC_SHADOW_BN_is_bit_set +#define BN_is_negative GRPC_SHADOW_BN_is_negative +#define BN_is_odd GRPC_SHADOW_BN_is_odd +#define BN_is_one GRPC_SHADOW_BN_is_one +#define BN_is_pow2 GRPC_SHADOW_BN_is_pow2 +#define BN_is_prime_ex GRPC_SHADOW_BN_is_prime_ex +#define BN_is_prime_fasttest_ex GRPC_SHADOW_BN_is_prime_fasttest_ex +#define BN_is_word GRPC_SHADOW_BN_is_word +#define BN_is_zero GRPC_SHADOW_BN_is_zero +#define BN_le2bn GRPC_SHADOW_BN_le2bn +#define BN_lshift GRPC_SHADOW_BN_lshift +#define BN_lshift1 GRPC_SHADOW_BN_lshift1 +#define BN_mask_bits GRPC_SHADOW_BN_mask_bits +#define BN_mod_add GRPC_SHADOW_BN_mod_add +#define BN_mod_add_quick GRPC_SHADOW_BN_mod_add_quick +#define BN_mod_exp GRPC_SHADOW_BN_mod_exp +#define BN_mod_exp2_mont GRPC_SHADOW_BN_mod_exp2_mont +#define BN_mod_exp_mont GRPC_SHADOW_BN_mod_exp_mont +#define BN_mod_exp_mont_consttime GRPC_SHADOW_BN_mod_exp_mont_consttime +#define BN_mod_exp_mont_word GRPC_SHADOW_BN_mod_exp_mont_word +#define BN_mod_inverse GRPC_SHADOW_BN_mod_inverse +#define BN_mod_inverse_blinded GRPC_SHADOW_BN_mod_inverse_blinded +#define BN_mod_inverse_odd GRPC_SHADOW_BN_mod_inverse_odd +#define BN_mod_lshift GRPC_SHADOW_BN_mod_lshift +#define BN_mod_lshift1 GRPC_SHADOW_BN_mod_lshift1 +#define BN_mod_lshift1_quick GRPC_SHADOW_BN_mod_lshift1_quick +#define BN_mod_lshift_quick GRPC_SHADOW_BN_mod_lshift_quick +#define BN_mod_mul GRPC_SHADOW_BN_mod_mul +#define BN_mod_mul_montgomery GRPC_SHADOW_BN_mod_mul_montgomery +#define BN_mod_pow2 GRPC_SHADOW_BN_mod_pow2 +#define BN_mod_sqr GRPC_SHADOW_BN_mod_sqr +#define BN_mod_sqrt GRPC_SHADOW_BN_mod_sqrt +#define BN_mod_sub GRPC_SHADOW_BN_mod_sub +#define BN_mod_sub_quick GRPC_SHADOW_BN_mod_sub_quick +#define BN_mod_word GRPC_SHADOW_BN_mod_word +#define BN_mul GRPC_SHADOW_BN_mul +#define BN_mul_word GRPC_SHADOW_BN_mul_word +#define BN_new GRPC_SHADOW_BN_new +#define BN_nnmod GRPC_SHADOW_BN_nnmod +#define BN_nnmod_pow2 GRPC_SHADOW_BN_nnmod_pow2 +#define BN_num_bits GRPC_SHADOW_BN_num_bits +#define BN_num_bits_word GRPC_SHADOW_BN_num_bits_word +#define BN_num_bytes GRPC_SHADOW_BN_num_bytes +#define BN_one GRPC_SHADOW_BN_one +#define BN_primality_test GRPC_SHADOW_BN_primality_test +#define BN_pseudo_rand GRPC_SHADOW_BN_pseudo_rand +#define BN_pseudo_rand_range GRPC_SHADOW_BN_pseudo_rand_range +#define BN_rand GRPC_SHADOW_BN_rand +#define BN_rand_range GRPC_SHADOW_BN_rand_range +#define BN_rand_range_ex GRPC_SHADOW_BN_rand_range_ex +#define BN_rshift GRPC_SHADOW_BN_rshift +#define BN_rshift1 GRPC_SHADOW_BN_rshift1 +#define BN_set_bit GRPC_SHADOW_BN_set_bit +#define BN_set_negative GRPC_SHADOW_BN_set_negative +#define BN_set_u64 GRPC_SHADOW_BN_set_u64 +#define BN_set_word GRPC_SHADOW_BN_set_word +#define BN_sqr GRPC_SHADOW_BN_sqr +#define BN_sqrt GRPC_SHADOW_BN_sqrt +#define BN_sub GRPC_SHADOW_BN_sub +#define BN_sub_word GRPC_SHADOW_BN_sub_word +#define BN_to_montgomery GRPC_SHADOW_BN_to_montgomery +#define BN_uadd GRPC_SHADOW_BN_uadd +#define BN_ucmp GRPC_SHADOW_BN_ucmp +#define BN_usub GRPC_SHADOW_BN_usub +#define BN_value_one GRPC_SHADOW_BN_value_one +#define BN_zero GRPC_SHADOW_BN_zero +#define BORINGSSL_self_test GRPC_SHADOW_BORINGSSL_self_test +#define CRYPTO_POLYVAL_finish GRPC_SHADOW_CRYPTO_POLYVAL_finish +#define CRYPTO_POLYVAL_init GRPC_SHADOW_CRYPTO_POLYVAL_init +#define CRYPTO_POLYVAL_update_blocks GRPC_SHADOW_CRYPTO_POLYVAL_update_blocks +#define CRYPTO_cbc128_decrypt GRPC_SHADOW_CRYPTO_cbc128_decrypt +#define CRYPTO_cbc128_encrypt GRPC_SHADOW_CRYPTO_cbc128_encrypt +#define CRYPTO_ccm128_decrypt GRPC_SHADOW_CRYPTO_ccm128_decrypt +#define CRYPTO_ccm128_encrypt GRPC_SHADOW_CRYPTO_ccm128_encrypt +#define CRYPTO_ccm128_init GRPC_SHADOW_CRYPTO_ccm128_init +#define CRYPTO_ccm128_max_input GRPC_SHADOW_CRYPTO_ccm128_max_input +#define CRYPTO_cfb128_1_encrypt GRPC_SHADOW_CRYPTO_cfb128_1_encrypt +#define CRYPTO_cfb128_8_encrypt GRPC_SHADOW_CRYPTO_cfb128_8_encrypt +#define CRYPTO_cfb128_encrypt GRPC_SHADOW_CRYPTO_cfb128_encrypt +#define CRYPTO_ctr128_encrypt GRPC_SHADOW_CRYPTO_ctr128_encrypt +#define CRYPTO_ctr128_encrypt_ctr32 GRPC_SHADOW_CRYPTO_ctr128_encrypt_ctr32 +#define CRYPTO_gcm128_aad GRPC_SHADOW_CRYPTO_gcm128_aad +#define CRYPTO_gcm128_decrypt GRPC_SHADOW_CRYPTO_gcm128_decrypt +#define CRYPTO_gcm128_decrypt_ctr32 GRPC_SHADOW_CRYPTO_gcm128_decrypt_ctr32 +#define CRYPTO_gcm128_encrypt GRPC_SHADOW_CRYPTO_gcm128_encrypt +#define CRYPTO_gcm128_encrypt_ctr32 GRPC_SHADOW_CRYPTO_gcm128_encrypt_ctr32 +#define CRYPTO_gcm128_finish GRPC_SHADOW_CRYPTO_gcm128_finish +#define CRYPTO_gcm128_init GRPC_SHADOW_CRYPTO_gcm128_init +#define CRYPTO_gcm128_setiv GRPC_SHADOW_CRYPTO_gcm128_setiv +#define CRYPTO_gcm128_tag GRPC_SHADOW_CRYPTO_gcm128_tag +#define CRYPTO_ghash_init GRPC_SHADOW_CRYPTO_ghash_init +#define CRYPTO_ofb128_encrypt GRPC_SHADOW_CRYPTO_ofb128_encrypt +#define CRYPTO_sysrand GRPC_SHADOW_CRYPTO_sysrand +#define CRYPTO_tls1_prf GRPC_SHADOW_CRYPTO_tls1_prf +#define CTR_DRBG_clear GRPC_SHADOW_CTR_DRBG_clear +#define CTR_DRBG_generate GRPC_SHADOW_CTR_DRBG_generate +#define CTR_DRBG_init GRPC_SHADOW_CTR_DRBG_init +#define CTR_DRBG_reseed GRPC_SHADOW_CTR_DRBG_reseed +#define DES_decrypt3 GRPC_SHADOW_DES_decrypt3 +#define DES_ecb3_encrypt GRPC_SHADOW_DES_ecb3_encrypt +#define DES_ecb_encrypt GRPC_SHADOW_DES_ecb_encrypt +#define DES_ede2_cbc_encrypt GRPC_SHADOW_DES_ede2_cbc_encrypt +#define DES_ede3_cbc_encrypt GRPC_SHADOW_DES_ede3_cbc_encrypt +#define DES_encrypt3 GRPC_SHADOW_DES_encrypt3 +#define DES_ncbc_encrypt GRPC_SHADOW_DES_ncbc_encrypt +#define DES_set_key GRPC_SHADOW_DES_set_key +#define DES_set_key_unchecked GRPC_SHADOW_DES_set_key_unchecked +#define DES_set_odd_parity GRPC_SHADOW_DES_set_odd_parity +#define ECDSA_SIG_free GRPC_SHADOW_ECDSA_SIG_free +#define ECDSA_SIG_get0 GRPC_SHADOW_ECDSA_SIG_get0 +#define ECDSA_SIG_new GRPC_SHADOW_ECDSA_SIG_new +#define ECDSA_SIG_set0 GRPC_SHADOW_ECDSA_SIG_set0 +#define ECDSA_do_sign GRPC_SHADOW_ECDSA_do_sign +#define ECDSA_do_verify GRPC_SHADOW_ECDSA_do_verify +#define EC_GFp_mont_method GRPC_SHADOW_EC_GFp_mont_method +#define EC_GFp_nistp224_method GRPC_SHADOW_EC_GFp_nistp224_method +#define EC_GFp_nistp256_method GRPC_SHADOW_EC_GFp_nistp256_method +#define EC_GFp_nistz256_method GRPC_SHADOW_EC_GFp_nistz256_method +#define EC_GROUP_cmp GRPC_SHADOW_EC_GROUP_cmp +#define EC_GROUP_dup GRPC_SHADOW_EC_GROUP_dup +#define EC_GROUP_free GRPC_SHADOW_EC_GROUP_free +#define EC_GROUP_get0_generator GRPC_SHADOW_EC_GROUP_get0_generator +#define EC_GROUP_get0_order GRPC_SHADOW_EC_GROUP_get0_order +#define EC_GROUP_get_cofactor GRPC_SHADOW_EC_GROUP_get_cofactor +#define EC_GROUP_get_curve_GFp GRPC_SHADOW_EC_GROUP_get_curve_GFp +#define EC_GROUP_get_curve_name GRPC_SHADOW_EC_GROUP_get_curve_name +#define EC_GROUP_get_degree GRPC_SHADOW_EC_GROUP_get_degree +#define EC_GROUP_get_order GRPC_SHADOW_EC_GROUP_get_order +#define EC_GROUP_method_of GRPC_SHADOW_EC_GROUP_method_of +#define EC_GROUP_new_by_curve_name GRPC_SHADOW_EC_GROUP_new_by_curve_name +#define EC_GROUP_new_curve_GFp GRPC_SHADOW_EC_GROUP_new_curve_GFp +#define EC_GROUP_set_asn1_flag GRPC_SHADOW_EC_GROUP_set_asn1_flag +#define EC_GROUP_set_generator GRPC_SHADOW_EC_GROUP_set_generator +#define EC_GROUP_set_point_conversion_form GRPC_SHADOW_EC_GROUP_set_point_conversion_form +#define EC_KEY_check_fips GRPC_SHADOW_EC_KEY_check_fips +#define EC_KEY_check_key GRPC_SHADOW_EC_KEY_check_key +#define EC_KEY_dup GRPC_SHADOW_EC_KEY_dup +#define EC_KEY_free GRPC_SHADOW_EC_KEY_free +#define EC_KEY_generate_key GRPC_SHADOW_EC_KEY_generate_key +#define EC_KEY_generate_key_fips GRPC_SHADOW_EC_KEY_generate_key_fips +#define EC_KEY_get0_group GRPC_SHADOW_EC_KEY_get0_group +#define EC_KEY_get0_private_key GRPC_SHADOW_EC_KEY_get0_private_key +#define EC_KEY_get0_public_key GRPC_SHADOW_EC_KEY_get0_public_key +#define EC_KEY_get_conv_form GRPC_SHADOW_EC_KEY_get_conv_form +#define EC_KEY_get_enc_flags GRPC_SHADOW_EC_KEY_get_enc_flags +#define EC_KEY_get_ex_data GRPC_SHADOW_EC_KEY_get_ex_data +#define EC_KEY_get_ex_new_index GRPC_SHADOW_EC_KEY_get_ex_new_index +#define EC_KEY_is_opaque GRPC_SHADOW_EC_KEY_is_opaque +#define EC_KEY_new GRPC_SHADOW_EC_KEY_new +#define EC_KEY_new_by_curve_name GRPC_SHADOW_EC_KEY_new_by_curve_name +#define EC_KEY_new_method GRPC_SHADOW_EC_KEY_new_method +#define EC_KEY_set_asn1_flag GRPC_SHADOW_EC_KEY_set_asn1_flag +#define EC_KEY_set_conv_form GRPC_SHADOW_EC_KEY_set_conv_form +#define EC_KEY_set_enc_flags GRPC_SHADOW_EC_KEY_set_enc_flags +#define EC_KEY_set_ex_data GRPC_SHADOW_EC_KEY_set_ex_data +#define EC_KEY_set_group GRPC_SHADOW_EC_KEY_set_group +#define EC_KEY_set_private_key GRPC_SHADOW_EC_KEY_set_private_key +#define EC_KEY_set_public_key GRPC_SHADOW_EC_KEY_set_public_key +#define EC_KEY_set_public_key_affine_coordinates GRPC_SHADOW_EC_KEY_set_public_key_affine_coordinates +#define EC_KEY_up_ref GRPC_SHADOW_EC_KEY_up_ref +#define EC_METHOD_get_field_type GRPC_SHADOW_EC_METHOD_get_field_type +#define EC_POINT_add GRPC_SHADOW_EC_POINT_add +#define EC_POINT_clear_free GRPC_SHADOW_EC_POINT_clear_free +#define EC_POINT_cmp GRPC_SHADOW_EC_POINT_cmp +#define EC_POINT_copy GRPC_SHADOW_EC_POINT_copy +#define EC_POINT_dbl GRPC_SHADOW_EC_POINT_dbl +#define EC_POINT_dup GRPC_SHADOW_EC_POINT_dup +#define EC_POINT_free GRPC_SHADOW_EC_POINT_free +#define EC_POINT_get_affine_coordinates_GFp GRPC_SHADOW_EC_POINT_get_affine_coordinates_GFp +#define EC_POINT_invert GRPC_SHADOW_EC_POINT_invert +#define EC_POINT_is_at_infinity GRPC_SHADOW_EC_POINT_is_at_infinity +#define EC_POINT_is_on_curve GRPC_SHADOW_EC_POINT_is_on_curve +#define EC_POINT_make_affine GRPC_SHADOW_EC_POINT_make_affine +#define EC_POINT_mul GRPC_SHADOW_EC_POINT_mul +#define EC_POINT_new GRPC_SHADOW_EC_POINT_new +#define EC_POINT_oct2point GRPC_SHADOW_EC_POINT_oct2point +#define EC_POINT_point2oct GRPC_SHADOW_EC_POINT_point2oct +#define EC_POINT_set_affine_coordinates_GFp GRPC_SHADOW_EC_POINT_set_affine_coordinates_GFp +#define EC_POINT_set_compressed_coordinates_GFp GRPC_SHADOW_EC_POINT_set_compressed_coordinates_GFp +#define EC_POINT_set_to_infinity GRPC_SHADOW_EC_POINT_set_to_infinity +#define EC_POINTs_make_affine GRPC_SHADOW_EC_POINTs_make_affine +#define EC_get_builtin_curves GRPC_SHADOW_EC_get_builtin_curves +#define EVP_AEAD_CTX_aead GRPC_SHADOW_EVP_AEAD_CTX_aead +#define EVP_AEAD_CTX_cleanup GRPC_SHADOW_EVP_AEAD_CTX_cleanup +#define EVP_AEAD_CTX_free GRPC_SHADOW_EVP_AEAD_CTX_free +#define EVP_AEAD_CTX_get_iv GRPC_SHADOW_EVP_AEAD_CTX_get_iv +#define EVP_AEAD_CTX_init GRPC_SHADOW_EVP_AEAD_CTX_init +#define EVP_AEAD_CTX_init_with_direction GRPC_SHADOW_EVP_AEAD_CTX_init_with_direction +#define EVP_AEAD_CTX_new GRPC_SHADOW_EVP_AEAD_CTX_new +#define EVP_AEAD_CTX_open GRPC_SHADOW_EVP_AEAD_CTX_open +#define EVP_AEAD_CTX_open_gather GRPC_SHADOW_EVP_AEAD_CTX_open_gather +#define EVP_AEAD_CTX_seal GRPC_SHADOW_EVP_AEAD_CTX_seal +#define EVP_AEAD_CTX_seal_scatter GRPC_SHADOW_EVP_AEAD_CTX_seal_scatter +#define EVP_AEAD_CTX_tag_len GRPC_SHADOW_EVP_AEAD_CTX_tag_len +#define EVP_AEAD_CTX_zero GRPC_SHADOW_EVP_AEAD_CTX_zero +#define EVP_AEAD_key_length GRPC_SHADOW_EVP_AEAD_key_length +#define EVP_AEAD_max_overhead GRPC_SHADOW_EVP_AEAD_max_overhead +#define EVP_AEAD_max_tag_len GRPC_SHADOW_EVP_AEAD_max_tag_len +#define EVP_AEAD_nonce_length GRPC_SHADOW_EVP_AEAD_nonce_length +#define EVP_CIPHER_CTX_block_size GRPC_SHADOW_EVP_CIPHER_CTX_block_size +#define EVP_CIPHER_CTX_cipher GRPC_SHADOW_EVP_CIPHER_CTX_cipher +#define EVP_CIPHER_CTX_cleanup GRPC_SHADOW_EVP_CIPHER_CTX_cleanup +#define EVP_CIPHER_CTX_copy GRPC_SHADOW_EVP_CIPHER_CTX_copy +#define EVP_CIPHER_CTX_ctrl GRPC_SHADOW_EVP_CIPHER_CTX_ctrl +#define EVP_CIPHER_CTX_flags GRPC_SHADOW_EVP_CIPHER_CTX_flags +#define EVP_CIPHER_CTX_free GRPC_SHADOW_EVP_CIPHER_CTX_free +#define EVP_CIPHER_CTX_get_app_data GRPC_SHADOW_EVP_CIPHER_CTX_get_app_data +#define EVP_CIPHER_CTX_init GRPC_SHADOW_EVP_CIPHER_CTX_init +#define EVP_CIPHER_CTX_iv_length GRPC_SHADOW_EVP_CIPHER_CTX_iv_length +#define EVP_CIPHER_CTX_key_length GRPC_SHADOW_EVP_CIPHER_CTX_key_length +#define EVP_CIPHER_CTX_mode GRPC_SHADOW_EVP_CIPHER_CTX_mode +#define EVP_CIPHER_CTX_new GRPC_SHADOW_EVP_CIPHER_CTX_new +#define EVP_CIPHER_CTX_nid GRPC_SHADOW_EVP_CIPHER_CTX_nid +#define EVP_CIPHER_CTX_reset GRPC_SHADOW_EVP_CIPHER_CTX_reset +#define EVP_CIPHER_CTX_set_app_data GRPC_SHADOW_EVP_CIPHER_CTX_set_app_data +#define EVP_CIPHER_CTX_set_flags GRPC_SHADOW_EVP_CIPHER_CTX_set_flags +#define EVP_CIPHER_CTX_set_key_length GRPC_SHADOW_EVP_CIPHER_CTX_set_key_length +#define EVP_CIPHER_CTX_set_padding GRPC_SHADOW_EVP_CIPHER_CTX_set_padding +#define EVP_CIPHER_block_size GRPC_SHADOW_EVP_CIPHER_block_size +#define EVP_CIPHER_flags GRPC_SHADOW_EVP_CIPHER_flags +#define EVP_CIPHER_iv_length GRPC_SHADOW_EVP_CIPHER_iv_length +#define EVP_CIPHER_key_length GRPC_SHADOW_EVP_CIPHER_key_length +#define EVP_CIPHER_mode GRPC_SHADOW_EVP_CIPHER_mode +#define EVP_CIPHER_nid GRPC_SHADOW_EVP_CIPHER_nid +#define EVP_Cipher GRPC_SHADOW_EVP_Cipher +#define EVP_CipherFinal_ex GRPC_SHADOW_EVP_CipherFinal_ex +#define EVP_CipherInit GRPC_SHADOW_EVP_CipherInit +#define EVP_CipherInit_ex GRPC_SHADOW_EVP_CipherInit_ex +#define EVP_CipherUpdate GRPC_SHADOW_EVP_CipherUpdate +#define EVP_DecryptFinal_ex GRPC_SHADOW_EVP_DecryptFinal_ex +#define EVP_DecryptInit GRPC_SHADOW_EVP_DecryptInit +#define EVP_DecryptInit_ex GRPC_SHADOW_EVP_DecryptInit_ex +#define EVP_DecryptUpdate GRPC_SHADOW_EVP_DecryptUpdate +#define EVP_Digest GRPC_SHADOW_EVP_Digest +#define EVP_DigestFinal GRPC_SHADOW_EVP_DigestFinal +#define EVP_DigestFinal_ex GRPC_SHADOW_EVP_DigestFinal_ex +#define EVP_DigestInit GRPC_SHADOW_EVP_DigestInit +#define EVP_DigestInit_ex GRPC_SHADOW_EVP_DigestInit_ex +#define EVP_DigestUpdate GRPC_SHADOW_EVP_DigestUpdate +#define EVP_EncryptFinal_ex GRPC_SHADOW_EVP_EncryptFinal_ex +#define EVP_EncryptInit GRPC_SHADOW_EVP_EncryptInit +#define EVP_EncryptInit_ex GRPC_SHADOW_EVP_EncryptInit_ex +#define EVP_EncryptUpdate GRPC_SHADOW_EVP_EncryptUpdate +#define EVP_MD_CTX_block_size GRPC_SHADOW_EVP_MD_CTX_block_size +#define EVP_MD_CTX_cleanup GRPC_SHADOW_EVP_MD_CTX_cleanup +#define EVP_MD_CTX_copy GRPC_SHADOW_EVP_MD_CTX_copy +#define EVP_MD_CTX_copy_ex GRPC_SHADOW_EVP_MD_CTX_copy_ex +#define EVP_MD_CTX_create GRPC_SHADOW_EVP_MD_CTX_create +#define EVP_MD_CTX_destroy GRPC_SHADOW_EVP_MD_CTX_destroy +#define EVP_MD_CTX_free GRPC_SHADOW_EVP_MD_CTX_free +#define EVP_MD_CTX_init GRPC_SHADOW_EVP_MD_CTX_init +#define EVP_MD_CTX_md GRPC_SHADOW_EVP_MD_CTX_md +#define EVP_MD_CTX_new GRPC_SHADOW_EVP_MD_CTX_new +#define EVP_MD_CTX_reset GRPC_SHADOW_EVP_MD_CTX_reset +#define EVP_MD_CTX_size GRPC_SHADOW_EVP_MD_CTX_size +#define EVP_MD_CTX_type GRPC_SHADOW_EVP_MD_CTX_type +#define EVP_MD_block_size GRPC_SHADOW_EVP_MD_block_size +#define EVP_MD_flags GRPC_SHADOW_EVP_MD_flags +#define EVP_MD_size GRPC_SHADOW_EVP_MD_size +#define EVP_MD_type GRPC_SHADOW_EVP_MD_type +#define EVP_add_cipher_alias GRPC_SHADOW_EVP_add_cipher_alias +#define EVP_add_digest GRPC_SHADOW_EVP_add_digest +#define EVP_aead_aes_128_gcm GRPC_SHADOW_EVP_aead_aes_128_gcm +#define EVP_aead_aes_128_gcm_tls12 GRPC_SHADOW_EVP_aead_aes_128_gcm_tls12 +#define EVP_aead_aes_256_gcm GRPC_SHADOW_EVP_aead_aes_256_gcm +#define EVP_aead_aes_256_gcm_tls12 GRPC_SHADOW_EVP_aead_aes_256_gcm_tls12 +#define EVP_aes_128_cbc GRPC_SHADOW_EVP_aes_128_cbc +#define EVP_aes_128_ctr GRPC_SHADOW_EVP_aes_128_ctr +#define EVP_aes_128_ecb GRPC_SHADOW_EVP_aes_128_ecb +#define EVP_aes_128_gcm GRPC_SHADOW_EVP_aes_128_gcm +#define EVP_aes_128_ofb GRPC_SHADOW_EVP_aes_128_ofb +#define EVP_aes_192_cbc GRPC_SHADOW_EVP_aes_192_cbc +#define EVP_aes_192_ctr GRPC_SHADOW_EVP_aes_192_ctr +#define EVP_aes_192_ecb GRPC_SHADOW_EVP_aes_192_ecb +#define EVP_aes_192_gcm GRPC_SHADOW_EVP_aes_192_gcm +#define EVP_aes_256_cbc GRPC_SHADOW_EVP_aes_256_cbc +#define EVP_aes_256_ctr GRPC_SHADOW_EVP_aes_256_ctr +#define EVP_aes_256_ecb GRPC_SHADOW_EVP_aes_256_ecb +#define EVP_aes_256_gcm GRPC_SHADOW_EVP_aes_256_gcm +#define EVP_aes_256_ofb GRPC_SHADOW_EVP_aes_256_ofb +#define EVP_des_cbc GRPC_SHADOW_EVP_des_cbc +#define EVP_des_ecb GRPC_SHADOW_EVP_des_ecb +#define EVP_des_ede GRPC_SHADOW_EVP_des_ede +#define EVP_des_ede3 GRPC_SHADOW_EVP_des_ede3 +#define EVP_des_ede3_cbc GRPC_SHADOW_EVP_des_ede3_cbc +#define EVP_des_ede_cbc GRPC_SHADOW_EVP_des_ede_cbc +#define EVP_has_aes_hardware GRPC_SHADOW_EVP_has_aes_hardware +#define EVP_md4 GRPC_SHADOW_EVP_md4 +#define EVP_md5 GRPC_SHADOW_EVP_md5 +#define EVP_md5_sha1 GRPC_SHADOW_EVP_md5_sha1 +#define EVP_sha1 GRPC_SHADOW_EVP_sha1 +#define EVP_sha224 GRPC_SHADOW_EVP_sha224 +#define EVP_sha256 GRPC_SHADOW_EVP_sha256 +#define EVP_sha384 GRPC_SHADOW_EVP_sha384 +#define EVP_sha512 GRPC_SHADOW_EVP_sha512 +#define HMAC GRPC_SHADOW_HMAC +#define HMAC_CTX_cleanup GRPC_SHADOW_HMAC_CTX_cleanup +#define HMAC_CTX_copy GRPC_SHADOW_HMAC_CTX_copy +#define HMAC_CTX_copy_ex GRPC_SHADOW_HMAC_CTX_copy_ex +#define HMAC_CTX_free GRPC_SHADOW_HMAC_CTX_free +#define HMAC_CTX_init GRPC_SHADOW_HMAC_CTX_init +#define HMAC_CTX_new GRPC_SHADOW_HMAC_CTX_new +#define HMAC_CTX_reset GRPC_SHADOW_HMAC_CTX_reset +#define HMAC_Final GRPC_SHADOW_HMAC_Final +#define HMAC_Init GRPC_SHADOW_HMAC_Init +#define HMAC_Init_ex GRPC_SHADOW_HMAC_Init_ex +#define HMAC_Update GRPC_SHADOW_HMAC_Update +#define HMAC_size GRPC_SHADOW_HMAC_size +#define MD4 GRPC_SHADOW_MD4 +#define MD4_Final GRPC_SHADOW_MD4_Final +#define MD4_Init GRPC_SHADOW_MD4_Init +#define MD4_Transform GRPC_SHADOW_MD4_Transform +#define MD4_Update GRPC_SHADOW_MD4_Update +#define MD5 GRPC_SHADOW_MD5 +#define MD5_Final GRPC_SHADOW_MD5_Final +#define MD5_Init GRPC_SHADOW_MD5_Init +#define MD5_Transform GRPC_SHADOW_MD5_Transform +#define MD5_Update GRPC_SHADOW_MD5_Update +#define OPENSSL_built_in_curves GRPC_SHADOW_OPENSSL_built_in_curves +#define RAND_bytes GRPC_SHADOW_RAND_bytes +#define RAND_bytes_with_additional_data GRPC_SHADOW_RAND_bytes_with_additional_data +#define RAND_pseudo_bytes GRPC_SHADOW_RAND_pseudo_bytes +#define RAND_set_urandom_fd GRPC_SHADOW_RAND_set_urandom_fd +#define RSAZ_1024_mod_exp_avx2 GRPC_SHADOW_RSAZ_1024_mod_exp_avx2 +#define RSA_add_pkcs1_prefix GRPC_SHADOW_RSA_add_pkcs1_prefix +#define RSA_bits GRPC_SHADOW_RSA_bits +#define RSA_blinding_on GRPC_SHADOW_RSA_blinding_on +#define RSA_check_fips GRPC_SHADOW_RSA_check_fips +#define RSA_check_key GRPC_SHADOW_RSA_check_key +#define RSA_decrypt GRPC_SHADOW_RSA_decrypt +#define RSA_default_method GRPC_SHADOW_RSA_default_method +#define RSA_encrypt GRPC_SHADOW_RSA_encrypt +#define RSA_flags GRPC_SHADOW_RSA_flags +#define RSA_free GRPC_SHADOW_RSA_free +#define RSA_generate_key_ex GRPC_SHADOW_RSA_generate_key_ex +#define RSA_generate_key_fips GRPC_SHADOW_RSA_generate_key_fips +#define RSA_get0_crt_params GRPC_SHADOW_RSA_get0_crt_params +#define RSA_get0_factors GRPC_SHADOW_RSA_get0_factors +#define RSA_get0_key GRPC_SHADOW_RSA_get0_key +#define RSA_get_ex_data GRPC_SHADOW_RSA_get_ex_data +#define RSA_get_ex_new_index GRPC_SHADOW_RSA_get_ex_new_index +#define RSA_is_opaque GRPC_SHADOW_RSA_is_opaque +#define RSA_new GRPC_SHADOW_RSA_new +#define RSA_new_method GRPC_SHADOW_RSA_new_method +#define RSA_padding_add_PKCS1_OAEP_mgf1 GRPC_SHADOW_RSA_padding_add_PKCS1_OAEP_mgf1 +#define RSA_padding_add_PKCS1_PSS_mgf1 GRPC_SHADOW_RSA_padding_add_PKCS1_PSS_mgf1 +#define RSA_padding_add_PKCS1_type_1 GRPC_SHADOW_RSA_padding_add_PKCS1_type_1 +#define RSA_padding_add_PKCS1_type_2 GRPC_SHADOW_RSA_padding_add_PKCS1_type_2 +#define RSA_padding_add_none GRPC_SHADOW_RSA_padding_add_none +#define RSA_padding_check_PKCS1_OAEP_mgf1 GRPC_SHADOW_RSA_padding_check_PKCS1_OAEP_mgf1 +#define RSA_padding_check_PKCS1_type_1 GRPC_SHADOW_RSA_padding_check_PKCS1_type_1 +#define RSA_padding_check_PKCS1_type_2 GRPC_SHADOW_RSA_padding_check_PKCS1_type_2 +#define RSA_private_decrypt GRPC_SHADOW_RSA_private_decrypt +#define RSA_private_encrypt GRPC_SHADOW_RSA_private_encrypt +#define RSA_private_transform GRPC_SHADOW_RSA_private_transform +#define RSA_public_decrypt GRPC_SHADOW_RSA_public_decrypt +#define RSA_public_encrypt GRPC_SHADOW_RSA_public_encrypt +#define RSA_set0_crt_params GRPC_SHADOW_RSA_set0_crt_params +#define RSA_set0_factors GRPC_SHADOW_RSA_set0_factors +#define RSA_set0_key GRPC_SHADOW_RSA_set0_key +#define RSA_set_ex_data GRPC_SHADOW_RSA_set_ex_data +#define RSA_sign GRPC_SHADOW_RSA_sign +#define RSA_sign_pss_mgf1 GRPC_SHADOW_RSA_sign_pss_mgf1 +#define RSA_sign_raw GRPC_SHADOW_RSA_sign_raw +#define RSA_size GRPC_SHADOW_RSA_size +#define RSA_up_ref GRPC_SHADOW_RSA_up_ref +#define RSA_verify GRPC_SHADOW_RSA_verify +#define RSA_verify_PKCS1_PSS_mgf1 GRPC_SHADOW_RSA_verify_PKCS1_PSS_mgf1 +#define RSA_verify_pss_mgf1 GRPC_SHADOW_RSA_verify_pss_mgf1 +#define RSA_verify_raw GRPC_SHADOW_RSA_verify_raw +#define SHA1 GRPC_SHADOW_SHA1 +#define SHA1_Final GRPC_SHADOW_SHA1_Final +#define SHA1_Init GRPC_SHADOW_SHA1_Init +#define SHA1_Transform GRPC_SHADOW_SHA1_Transform +#define SHA1_Update GRPC_SHADOW_SHA1_Update +#define SHA224 GRPC_SHADOW_SHA224 +#define SHA224_Final GRPC_SHADOW_SHA224_Final +#define SHA224_Init GRPC_SHADOW_SHA224_Init +#define SHA224_Update GRPC_SHADOW_SHA224_Update +#define SHA256 GRPC_SHADOW_SHA256 +#define SHA256_Final GRPC_SHADOW_SHA256_Final +#define SHA256_Init GRPC_SHADOW_SHA256_Init +#define SHA256_Transform GRPC_SHADOW_SHA256_Transform +#define SHA256_Update GRPC_SHADOW_SHA256_Update +#define SHA384 GRPC_SHADOW_SHA384 +#define SHA384_Final GRPC_SHADOW_SHA384_Final +#define SHA384_Init GRPC_SHADOW_SHA384_Init +#define SHA384_Update GRPC_SHADOW_SHA384_Update +#define SHA512 GRPC_SHADOW_SHA512 +#define SHA512_Final GRPC_SHADOW_SHA512_Final +#define SHA512_Init GRPC_SHADOW_SHA512_Init +#define SHA512_Transform GRPC_SHADOW_SHA512_Transform +#define SHA512_Update GRPC_SHADOW_SHA512_Update +#define aes_ctr_set_key GRPC_SHADOW_aes_ctr_set_key +#define bn_abs_sub_consttime GRPC_SHADOW_bn_abs_sub_consttime +#define bn_add_words GRPC_SHADOW_bn_add_words +#define bn_copy_words GRPC_SHADOW_bn_copy_words +#define bn_div_consttime GRPC_SHADOW_bn_div_consttime +#define bn_expand GRPC_SHADOW_bn_expand +#define bn_fits_in_words GRPC_SHADOW_bn_fits_in_words +#define bn_from_montgomery_small GRPC_SHADOW_bn_from_montgomery_small +#define bn_in_range_words GRPC_SHADOW_bn_in_range_words +#define bn_is_bit_set_words GRPC_SHADOW_bn_is_bit_set_words +#define bn_is_relatively_prime GRPC_SHADOW_bn_is_relatively_prime +#define bn_jacobi GRPC_SHADOW_bn_jacobi +#define bn_lcm_consttime GRPC_SHADOW_bn_lcm_consttime +#define bn_less_than_montgomery_R GRPC_SHADOW_bn_less_than_montgomery_R +#define bn_less_than_words GRPC_SHADOW_bn_less_than_words +#define bn_minimal_width GRPC_SHADOW_bn_minimal_width +#define bn_mod_add_consttime GRPC_SHADOW_bn_mod_add_consttime +#define bn_mod_exp_base_2_consttime GRPC_SHADOW_bn_mod_exp_base_2_consttime +#define bn_mod_exp_mont_small GRPC_SHADOW_bn_mod_exp_mont_small +#define bn_mod_inverse_consttime GRPC_SHADOW_bn_mod_inverse_consttime +#define bn_mod_inverse_prime GRPC_SHADOW_bn_mod_inverse_prime +#define bn_mod_inverse_prime_mont_small GRPC_SHADOW_bn_mod_inverse_prime_mont_small +#define bn_mod_inverse_secret_prime GRPC_SHADOW_bn_mod_inverse_secret_prime +#define bn_mod_lshift1_consttime GRPC_SHADOW_bn_mod_lshift1_consttime +#define bn_mod_lshift_consttime GRPC_SHADOW_bn_mod_lshift_consttime +#define bn_mod_mul_montgomery_small GRPC_SHADOW_bn_mod_mul_montgomery_small +#define bn_mod_sub_consttime GRPC_SHADOW_bn_mod_sub_consttime +#define bn_mod_u16_consttime GRPC_SHADOW_bn_mod_u16_consttime +#define bn_mont_n0 GRPC_SHADOW_bn_mont_n0 +#define bn_mul_add_words GRPC_SHADOW_bn_mul_add_words +#define bn_mul_comba4 GRPC_SHADOW_bn_mul_comba4 +#define bn_mul_comba8 GRPC_SHADOW_bn_mul_comba8 +#define bn_mul_consttime GRPC_SHADOW_bn_mul_consttime +#define bn_mul_small GRPC_SHADOW_bn_mul_small +#define bn_mul_words GRPC_SHADOW_bn_mul_words +#define bn_odd_number_is_obviously_composite GRPC_SHADOW_bn_odd_number_is_obviously_composite +#define bn_one_to_montgomery GRPC_SHADOW_bn_one_to_montgomery +#define bn_one_to_montgomery_small GRPC_SHADOW_bn_one_to_montgomery_small +#define bn_rand_range_words GRPC_SHADOW_bn_rand_range_words +#define bn_rand_secret_range GRPC_SHADOW_bn_rand_secret_range +#define bn_resize_words GRPC_SHADOW_bn_resize_words +#define bn_rshift1_words GRPC_SHADOW_bn_rshift1_words +#define bn_rshift_secret_shift GRPC_SHADOW_bn_rshift_secret_shift +#define bn_select_words GRPC_SHADOW_bn_select_words +#define bn_set_minimal_width GRPC_SHADOW_bn_set_minimal_width +#define bn_set_words GRPC_SHADOW_bn_set_words +#define bn_sqr_comba4 GRPC_SHADOW_bn_sqr_comba4 +#define bn_sqr_comba8 GRPC_SHADOW_bn_sqr_comba8 +#define bn_sqr_consttime GRPC_SHADOW_bn_sqr_consttime +#define bn_sqr_small GRPC_SHADOW_bn_sqr_small +#define bn_sqr_words GRPC_SHADOW_bn_sqr_words +#define bn_sub_words GRPC_SHADOW_bn_sub_words +#define bn_to_montgomery_small GRPC_SHADOW_bn_to_montgomery_small +#define bn_uadd_consttime GRPC_SHADOW_bn_uadd_consttime +#define bn_usub_consttime GRPC_SHADOW_bn_usub_consttime +#define bn_wexpand GRPC_SHADOW_bn_wexpand +#define crypto_gcm_clmul_enabled GRPC_SHADOW_crypto_gcm_clmul_enabled +#define ec_GFp_mont_field_decode GRPC_SHADOW_ec_GFp_mont_field_decode +#define ec_GFp_mont_field_encode GRPC_SHADOW_ec_GFp_mont_field_encode +#define ec_GFp_mont_field_mul GRPC_SHADOW_ec_GFp_mont_field_mul +#define ec_GFp_mont_field_sqr GRPC_SHADOW_ec_GFp_mont_field_sqr +#define ec_GFp_mont_group_finish GRPC_SHADOW_ec_GFp_mont_group_finish +#define ec_GFp_mont_group_init GRPC_SHADOW_ec_GFp_mont_group_init +#define ec_GFp_mont_group_set_curve GRPC_SHADOW_ec_GFp_mont_group_set_curve +#define ec_GFp_nistp_recode_scalar_bits GRPC_SHADOW_ec_GFp_nistp_recode_scalar_bits +#define ec_GFp_simple_add GRPC_SHADOW_ec_GFp_simple_add +#define ec_GFp_simple_cmp GRPC_SHADOW_ec_GFp_simple_cmp +#define ec_GFp_simple_dbl GRPC_SHADOW_ec_GFp_simple_dbl +#define ec_GFp_simple_field_mul GRPC_SHADOW_ec_GFp_simple_field_mul +#define ec_GFp_simple_field_sqr GRPC_SHADOW_ec_GFp_simple_field_sqr +#define ec_GFp_simple_group_finish GRPC_SHADOW_ec_GFp_simple_group_finish +#define ec_GFp_simple_group_get_curve GRPC_SHADOW_ec_GFp_simple_group_get_curve +#define ec_GFp_simple_group_get_degree GRPC_SHADOW_ec_GFp_simple_group_get_degree +#define ec_GFp_simple_group_init GRPC_SHADOW_ec_GFp_simple_group_init +#define ec_GFp_simple_group_set_curve GRPC_SHADOW_ec_GFp_simple_group_set_curve +#define ec_GFp_simple_invert GRPC_SHADOW_ec_GFp_simple_invert +#define ec_GFp_simple_is_at_infinity GRPC_SHADOW_ec_GFp_simple_is_at_infinity +#define ec_GFp_simple_is_on_curve GRPC_SHADOW_ec_GFp_simple_is_on_curve +#define ec_GFp_simple_make_affine GRPC_SHADOW_ec_GFp_simple_make_affine +#define ec_GFp_simple_point_copy GRPC_SHADOW_ec_GFp_simple_point_copy +#define ec_GFp_simple_point_finish GRPC_SHADOW_ec_GFp_simple_point_finish +#define ec_GFp_simple_point_init GRPC_SHADOW_ec_GFp_simple_point_init +#define ec_GFp_simple_point_set_affine_coordinates GRPC_SHADOW_ec_GFp_simple_point_set_affine_coordinates +#define ec_GFp_simple_point_set_to_infinity GRPC_SHADOW_ec_GFp_simple_point_set_to_infinity +#define ec_GFp_simple_points_make_affine GRPC_SHADOW_ec_GFp_simple_points_make_affine +#define ec_bignum_to_scalar GRPC_SHADOW_ec_bignum_to_scalar +#define ec_bignum_to_scalar_unchecked GRPC_SHADOW_ec_bignum_to_scalar_unchecked +#define ec_compute_wNAF GRPC_SHADOW_ec_compute_wNAF +#define ec_group_new GRPC_SHADOW_ec_group_new +#define ec_point_mul_scalar GRPC_SHADOW_ec_point_mul_scalar +#define ec_point_mul_scalar_public GRPC_SHADOW_ec_point_mul_scalar_public +#define ec_random_nonzero_scalar GRPC_SHADOW_ec_random_nonzero_scalar +#define ec_wNAF_mul GRPC_SHADOW_ec_wNAF_mul +#define kBoringSSLRSASqrtTwo GRPC_SHADOW_kBoringSSLRSASqrtTwo +#define kBoringSSLRSASqrtTwoLen GRPC_SHADOW_kBoringSSLRSASqrtTwoLen +#define md4_block_data_order GRPC_SHADOW_md4_block_data_order +#define rsa_default_decrypt GRPC_SHADOW_rsa_default_decrypt +#define rsa_default_private_transform GRPC_SHADOW_rsa_default_private_transform +#define rsa_default_sign_raw GRPC_SHADOW_rsa_default_sign_raw +#define rsa_default_size GRPC_SHADOW_rsa_default_size +#define FIPS_mode GRPC_SHADOW_FIPS_mode +#define aesni_gcm_decrypt GRPC_SHADOW_aesni_gcm_decrypt +#define aesni_gcm_encrypt GRPC_SHADOW_aesni_gcm_encrypt +#define aesni_cbc_encrypt GRPC_SHADOW_aesni_cbc_encrypt +#define aesni_ccm64_decrypt_blocks GRPC_SHADOW_aesni_ccm64_decrypt_blocks +#define aesni_ccm64_encrypt_blocks GRPC_SHADOW_aesni_ccm64_encrypt_blocks +#define aesni_ctr32_encrypt_blocks GRPC_SHADOW_aesni_ctr32_encrypt_blocks +#define aesni_decrypt GRPC_SHADOW_aesni_decrypt +#define aesni_ecb_encrypt GRPC_SHADOW_aesni_ecb_encrypt +#define aesni_encrypt GRPC_SHADOW_aesni_encrypt +#define aesni_ocb_decrypt GRPC_SHADOW_aesni_ocb_decrypt +#define aesni_ocb_encrypt GRPC_SHADOW_aesni_ocb_encrypt +#define aesni_set_decrypt_key GRPC_SHADOW_aesni_set_decrypt_key +#define aesni_set_encrypt_key GRPC_SHADOW_aesni_set_encrypt_key +#define aesni_xts_decrypt GRPC_SHADOW_aesni_xts_decrypt +#define aesni_xts_encrypt GRPC_SHADOW_aesni_xts_encrypt +#define asm_AES_cbc_encrypt GRPC_SHADOW_asm_AES_cbc_encrypt +#define asm_AES_decrypt GRPC_SHADOW_asm_AES_decrypt +#define asm_AES_encrypt GRPC_SHADOW_asm_AES_encrypt +#define asm_AES_set_decrypt_key GRPC_SHADOW_asm_AES_set_decrypt_key +#define asm_AES_set_encrypt_key GRPC_SHADOW_asm_AES_set_encrypt_key +#define bsaes_cbc_encrypt GRPC_SHADOW_bsaes_cbc_encrypt +#define bsaes_ctr32_encrypt_blocks GRPC_SHADOW_bsaes_ctr32_encrypt_blocks +#define bsaes_xts_decrypt GRPC_SHADOW_bsaes_xts_decrypt +#define bsaes_xts_encrypt GRPC_SHADOW_bsaes_xts_encrypt +#define gcm_ghash_4bit GRPC_SHADOW_gcm_ghash_4bit +#define gcm_ghash_avx GRPC_SHADOW_gcm_ghash_avx +#define gcm_ghash_clmul GRPC_SHADOW_gcm_ghash_clmul +#define gcm_gmult_4bit GRPC_SHADOW_gcm_gmult_4bit +#define gcm_gmult_avx GRPC_SHADOW_gcm_gmult_avx +#define gcm_gmult_clmul GRPC_SHADOW_gcm_gmult_clmul +#define gcm_init_avx GRPC_SHADOW_gcm_init_avx +#define gcm_init_clmul GRPC_SHADOW_gcm_init_clmul +#define md5_block_asm_data_order GRPC_SHADOW_md5_block_asm_data_order +#define ecp_nistz256_avx2_select_w7 GRPC_SHADOW_ecp_nistz256_avx2_select_w7 +#define ecp_nistz256_mul_mont GRPC_SHADOW_ecp_nistz256_mul_mont +#define ecp_nistz256_neg GRPC_SHADOW_ecp_nistz256_neg +#define ecp_nistz256_point_add GRPC_SHADOW_ecp_nistz256_point_add +#define ecp_nistz256_point_add_affine GRPC_SHADOW_ecp_nistz256_point_add_affine +#define ecp_nistz256_point_double GRPC_SHADOW_ecp_nistz256_point_double +#define ecp_nistz256_select_w5 GRPC_SHADOW_ecp_nistz256_select_w5 +#define ecp_nistz256_select_w7 GRPC_SHADOW_ecp_nistz256_select_w7 +#define ecp_nistz256_sqr_mont GRPC_SHADOW_ecp_nistz256_sqr_mont +#define CRYPTO_rdrand GRPC_SHADOW_CRYPTO_rdrand +#define CRYPTO_rdrand_multiple8_buf GRPC_SHADOW_CRYPTO_rdrand_multiple8_buf +#define rsaz_1024_gather5_avx2 GRPC_SHADOW_rsaz_1024_gather5_avx2 +#define rsaz_1024_mul_avx2 GRPC_SHADOW_rsaz_1024_mul_avx2 +#define rsaz_1024_norm2red_avx2 GRPC_SHADOW_rsaz_1024_norm2red_avx2 +#define rsaz_1024_red2norm_avx2 GRPC_SHADOW_rsaz_1024_red2norm_avx2 +#define rsaz_1024_scatter5_avx2 GRPC_SHADOW_rsaz_1024_scatter5_avx2 +#define rsaz_1024_sqr_avx2 GRPC_SHADOW_rsaz_1024_sqr_avx2 +#define rsaz_avx2_eligible GRPC_SHADOW_rsaz_avx2_eligible +#define sha1_block_data_order GRPC_SHADOW_sha1_block_data_order +#define sha256_block_data_order GRPC_SHADOW_sha256_block_data_order +#define sha512_block_data_order GRPC_SHADOW_sha512_block_data_order +#define vpaes_cbc_encrypt GRPC_SHADOW_vpaes_cbc_encrypt +#define vpaes_decrypt GRPC_SHADOW_vpaes_decrypt +#define vpaes_encrypt GRPC_SHADOW_vpaes_encrypt +#define vpaes_set_decrypt_key GRPC_SHADOW_vpaes_set_decrypt_key +#define vpaes_set_encrypt_key GRPC_SHADOW_vpaes_set_encrypt_key +#define bn_from_montgomery GRPC_SHADOW_bn_from_montgomery +#define bn_gather5 GRPC_SHADOW_bn_gather5 +#define bn_mul_mont_gather5 GRPC_SHADOW_bn_mul_mont_gather5 +#define bn_power5 GRPC_SHADOW_bn_power5 +#define bn_scatter5 GRPC_SHADOW_bn_scatter5 +#define bn_sqr8x_internal GRPC_SHADOW_bn_sqr8x_internal +#define bn_mul_mont GRPC_SHADOW_bn_mul_mont +#define EVP_get_digestbyname GRPC_SHADOW_EVP_get_digestbyname +#define EVP_get_digestbynid GRPC_SHADOW_EVP_get_digestbynid +#define EVP_get_digestbyobj GRPC_SHADOW_EVP_get_digestbyobj +#define EVP_marshal_digest_algorithm GRPC_SHADOW_EVP_marshal_digest_algorithm +#define EVP_parse_digest_algorithm GRPC_SHADOW_EVP_parse_digest_algorithm +#define EVP_get_cipherbyname GRPC_SHADOW_EVP_get_cipherbyname +#define EVP_get_cipherbynid GRPC_SHADOW_EVP_get_cipherbynid +#define EVP_BytesToKey GRPC_SHADOW_EVP_BytesToKey +#define EVP_enc_null GRPC_SHADOW_EVP_enc_null +#define EVP_rc2_40_cbc GRPC_SHADOW_EVP_rc2_40_cbc +#define EVP_rc2_cbc GRPC_SHADOW_EVP_rc2_cbc +#define EVP_rc4 GRPC_SHADOW_EVP_rc4 +#define EVP_aead_aes_128_gcm_siv GRPC_SHADOW_EVP_aead_aes_128_gcm_siv +#define EVP_aead_aes_256_gcm_siv GRPC_SHADOW_EVP_aead_aes_256_gcm_siv +#define EVP_aead_aes_128_ctr_hmac_sha256 GRPC_SHADOW_EVP_aead_aes_128_ctr_hmac_sha256 +#define EVP_aead_aes_256_ctr_hmac_sha256 GRPC_SHADOW_EVP_aead_aes_256_ctr_hmac_sha256 +#define EVP_aead_aes_128_ccm_bluetooth GRPC_SHADOW_EVP_aead_aes_128_ccm_bluetooth +#define EVP_aead_aes_128_ccm_bluetooth_8 GRPC_SHADOW_EVP_aead_aes_128_ccm_bluetooth_8 +#define EVP_aead_chacha20_poly1305 GRPC_SHADOW_EVP_aead_chacha20_poly1305 +#define EVP_tls_cbc_copy_mac GRPC_SHADOW_EVP_tls_cbc_copy_mac +#define EVP_tls_cbc_digest_record GRPC_SHADOW_EVP_tls_cbc_digest_record +#define EVP_tls_cbc_record_digest_supported GRPC_SHADOW_EVP_tls_cbc_record_digest_supported +#define EVP_tls_cbc_remove_padding GRPC_SHADOW_EVP_tls_cbc_remove_padding +#define EVP_aead_aes_128_cbc_sha1_tls GRPC_SHADOW_EVP_aead_aes_128_cbc_sha1_tls +#define EVP_aead_aes_128_cbc_sha1_tls_implicit_iv GRPC_SHADOW_EVP_aead_aes_128_cbc_sha1_tls_implicit_iv +#define EVP_aead_aes_128_cbc_sha256_tls GRPC_SHADOW_EVP_aead_aes_128_cbc_sha256_tls +#define EVP_aead_aes_256_cbc_sha1_tls GRPC_SHADOW_EVP_aead_aes_256_cbc_sha1_tls +#define EVP_aead_aes_256_cbc_sha1_tls_implicit_iv GRPC_SHADOW_EVP_aead_aes_256_cbc_sha1_tls_implicit_iv +#define EVP_aead_aes_256_cbc_sha256_tls GRPC_SHADOW_EVP_aead_aes_256_cbc_sha256_tls +#define EVP_aead_aes_256_cbc_sha384_tls GRPC_SHADOW_EVP_aead_aes_256_cbc_sha384_tls +#define EVP_aead_des_ede3_cbc_sha1_tls GRPC_SHADOW_EVP_aead_des_ede3_cbc_sha1_tls +#define EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv GRPC_SHADOW_EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv +#define EVP_aead_null_sha1_tls GRPC_SHADOW_EVP_aead_null_sha1_tls +#define EVP_aead_aes_128_cbc_sha1_ssl3 GRPC_SHADOW_EVP_aead_aes_128_cbc_sha1_ssl3 +#define EVP_aead_aes_256_cbc_sha1_ssl3 GRPC_SHADOW_EVP_aead_aes_256_cbc_sha1_ssl3 +#define EVP_aead_des_ede3_cbc_sha1_ssl3 GRPC_SHADOW_EVP_aead_des_ede3_cbc_sha1_ssl3 +#define EVP_aead_null_sha1_ssl3 GRPC_SHADOW_EVP_aead_null_sha1_ssl3 +#define aes128gcmsiv_aes_ks GRPC_SHADOW_aes128gcmsiv_aes_ks +#define aes128gcmsiv_aes_ks_enc_x1 GRPC_SHADOW_aes128gcmsiv_aes_ks_enc_x1 +#define aes128gcmsiv_dec GRPC_SHADOW_aes128gcmsiv_dec +#define aes128gcmsiv_ecb_enc_block GRPC_SHADOW_aes128gcmsiv_ecb_enc_block +#define aes128gcmsiv_enc_msg_x4 GRPC_SHADOW_aes128gcmsiv_enc_msg_x4 +#define aes128gcmsiv_enc_msg_x8 GRPC_SHADOW_aes128gcmsiv_enc_msg_x8 +#define aes128gcmsiv_kdf GRPC_SHADOW_aes128gcmsiv_kdf +#define aes256gcmsiv_aes_ks GRPC_SHADOW_aes256gcmsiv_aes_ks +#define aes256gcmsiv_aes_ks_enc_x1 GRPC_SHADOW_aes256gcmsiv_aes_ks_enc_x1 +#define aes256gcmsiv_dec GRPC_SHADOW_aes256gcmsiv_dec +#define aes256gcmsiv_ecb_enc_block GRPC_SHADOW_aes256gcmsiv_ecb_enc_block +#define aes256gcmsiv_enc_msg_x4 GRPC_SHADOW_aes256gcmsiv_enc_msg_x4 +#define aes256gcmsiv_enc_msg_x8 GRPC_SHADOW_aes256gcmsiv_enc_msg_x8 +#define aes256gcmsiv_kdf GRPC_SHADOW_aes256gcmsiv_kdf +#define aesgcmsiv_htable6_init GRPC_SHADOW_aesgcmsiv_htable6_init +#define aesgcmsiv_htable_init GRPC_SHADOW_aesgcmsiv_htable_init +#define aesgcmsiv_htable_polyval GRPC_SHADOW_aesgcmsiv_htable_polyval +#define aesgcmsiv_polyval_horner GRPC_SHADOW_aesgcmsiv_polyval_horner +#define chacha20_poly1305_open GRPC_SHADOW_chacha20_poly1305_open +#define chacha20_poly1305_seal GRPC_SHADOW_chacha20_poly1305_seal +#define RC4 GRPC_SHADOW_RC4 +#define RC4_set_key GRPC_SHADOW_RC4_set_key +#define CONF_VALUE_new GRPC_SHADOW_CONF_VALUE_new +#define CONF_modules_free GRPC_SHADOW_CONF_modules_free +#define CONF_modules_load_file GRPC_SHADOW_CONF_modules_load_file +#define CONF_parse_list GRPC_SHADOW_CONF_parse_list +#define NCONF_free GRPC_SHADOW_NCONF_free +#define NCONF_get_section GRPC_SHADOW_NCONF_get_section +#define NCONF_get_string GRPC_SHADOW_NCONF_get_string +#define NCONF_load GRPC_SHADOW_NCONF_load +#define NCONF_load_bio GRPC_SHADOW_NCONF_load_bio +#define NCONF_new GRPC_SHADOW_NCONF_new +#define OPENSSL_config GRPC_SHADOW_OPENSSL_config +#define OPENSSL_no_config GRPC_SHADOW_OPENSSL_no_config +#define CRYPTO_chacha_20 GRPC_SHADOW_CRYPTO_chacha_20 +#define ChaCha20_ctr32 GRPC_SHADOW_ChaCha20_ctr32 +#define CRYPTO_poly1305_finish GRPC_SHADOW_CRYPTO_poly1305_finish +#define CRYPTO_poly1305_init GRPC_SHADOW_CRYPTO_poly1305_init +#define CRYPTO_poly1305_update GRPC_SHADOW_CRYPTO_poly1305_update +#define SPAKE2_CTX_free GRPC_SHADOW_SPAKE2_CTX_free +#define SPAKE2_CTX_new GRPC_SHADOW_SPAKE2_CTX_new +#define SPAKE2_generate_msg GRPC_SHADOW_SPAKE2_generate_msg +#define SPAKE2_process_msg GRPC_SHADOW_SPAKE2_process_msg +#define ED25519_keypair GRPC_SHADOW_ED25519_keypair +#define ED25519_keypair_from_seed GRPC_SHADOW_ED25519_keypair_from_seed +#define ED25519_sign GRPC_SHADOW_ED25519_sign +#define ED25519_verify GRPC_SHADOW_ED25519_verify +#define X25519 GRPC_SHADOW_X25519 +#define X25519_keypair GRPC_SHADOW_X25519_keypair +#define X25519_public_from_private GRPC_SHADOW_X25519_public_from_private +#define x25519_ge_add GRPC_SHADOW_x25519_ge_add +#define x25519_ge_frombytes_vartime GRPC_SHADOW_x25519_ge_frombytes_vartime +#define x25519_ge_p1p1_to_p2 GRPC_SHADOW_x25519_ge_p1p1_to_p2 +#define x25519_ge_p1p1_to_p3 GRPC_SHADOW_x25519_ge_p1p1_to_p3 +#define x25519_ge_p3_to_cached GRPC_SHADOW_x25519_ge_p3_to_cached +#define x25519_ge_scalarmult GRPC_SHADOW_x25519_ge_scalarmult +#define x25519_ge_scalarmult_base GRPC_SHADOW_x25519_ge_scalarmult_base +#define x25519_ge_scalarmult_small_precomp GRPC_SHADOW_x25519_ge_scalarmult_small_precomp +#define x25519_ge_sub GRPC_SHADOW_x25519_ge_sub +#define x25519_ge_tobytes GRPC_SHADOW_x25519_ge_tobytes +#define x25519_sc_reduce GRPC_SHADOW_x25519_sc_reduce +#define BUF_MEM_append GRPC_SHADOW_BUF_MEM_append +#define BUF_MEM_free GRPC_SHADOW_BUF_MEM_free +#define BUF_MEM_grow GRPC_SHADOW_BUF_MEM_grow +#define BUF_MEM_grow_clean GRPC_SHADOW_BUF_MEM_grow_clean +#define BUF_MEM_new GRPC_SHADOW_BUF_MEM_new +#define BUF_MEM_reserve GRPC_SHADOW_BUF_MEM_reserve +#define BUF_memdup GRPC_SHADOW_BUF_memdup +#define BUF_strdup GRPC_SHADOW_BUF_strdup +#define BUF_strlcat GRPC_SHADOW_BUF_strlcat +#define BUF_strlcpy GRPC_SHADOW_BUF_strlcpy +#define BUF_strndup GRPC_SHADOW_BUF_strndup +#define BUF_strnlen GRPC_SHADOW_BUF_strnlen +#define BN_marshal_asn1 GRPC_SHADOW_BN_marshal_asn1 +#define BN_parse_asn1_unsigned GRPC_SHADOW_BN_parse_asn1_unsigned +#define BN_asc2bn GRPC_SHADOW_BN_asc2bn +#define BN_bn2cbb_padded GRPC_SHADOW_BN_bn2cbb_padded +#define BN_bn2dec GRPC_SHADOW_BN_bn2dec +#define BN_bn2hex GRPC_SHADOW_BN_bn2hex +#define BN_bn2mpi GRPC_SHADOW_BN_bn2mpi +#define BN_dec2bn GRPC_SHADOW_BN_dec2bn +#define BN_hex2bn GRPC_SHADOW_BN_hex2bn +#define BN_mpi2bn GRPC_SHADOW_BN_mpi2bn +#define BN_print GRPC_SHADOW_BN_print +#define BN_print_fp GRPC_SHADOW_BN_print_fp +#define BIO_callback_ctrl GRPC_SHADOW_BIO_callback_ctrl +#define BIO_clear_flags GRPC_SHADOW_BIO_clear_flags +#define BIO_clear_retry_flags GRPC_SHADOW_BIO_clear_retry_flags +#define BIO_copy_next_retry GRPC_SHADOW_BIO_copy_next_retry +#define BIO_ctrl GRPC_SHADOW_BIO_ctrl +#define BIO_ctrl_pending GRPC_SHADOW_BIO_ctrl_pending +#define BIO_eof GRPC_SHADOW_BIO_eof +#define BIO_find_type GRPC_SHADOW_BIO_find_type +#define BIO_flush GRPC_SHADOW_BIO_flush +#define BIO_free GRPC_SHADOW_BIO_free +#define BIO_free_all GRPC_SHADOW_BIO_free_all +#define BIO_get_data GRPC_SHADOW_BIO_get_data +#define BIO_get_init GRPC_SHADOW_BIO_get_init +#define BIO_get_new_index GRPC_SHADOW_BIO_get_new_index +#define BIO_get_retry_flags GRPC_SHADOW_BIO_get_retry_flags +#define BIO_get_retry_reason GRPC_SHADOW_BIO_get_retry_reason +#define BIO_get_shutdown GRPC_SHADOW_BIO_get_shutdown +#define BIO_gets GRPC_SHADOW_BIO_gets +#define BIO_indent GRPC_SHADOW_BIO_indent +#define BIO_int_ctrl GRPC_SHADOW_BIO_int_ctrl +#define BIO_meth_free GRPC_SHADOW_BIO_meth_free +#define BIO_meth_new GRPC_SHADOW_BIO_meth_new +#define BIO_meth_set_create GRPC_SHADOW_BIO_meth_set_create +#define BIO_meth_set_ctrl GRPC_SHADOW_BIO_meth_set_ctrl +#define BIO_meth_set_destroy GRPC_SHADOW_BIO_meth_set_destroy +#define BIO_meth_set_gets GRPC_SHADOW_BIO_meth_set_gets +#define BIO_meth_set_puts GRPC_SHADOW_BIO_meth_set_puts +#define BIO_meth_set_read GRPC_SHADOW_BIO_meth_set_read +#define BIO_meth_set_write GRPC_SHADOW_BIO_meth_set_write +#define BIO_method_type GRPC_SHADOW_BIO_method_type +#define BIO_new GRPC_SHADOW_BIO_new +#define BIO_next GRPC_SHADOW_BIO_next +#define BIO_number_read GRPC_SHADOW_BIO_number_read +#define BIO_number_written GRPC_SHADOW_BIO_number_written +#define BIO_pending GRPC_SHADOW_BIO_pending +#define BIO_pop GRPC_SHADOW_BIO_pop +#define BIO_ptr_ctrl GRPC_SHADOW_BIO_ptr_ctrl +#define BIO_push GRPC_SHADOW_BIO_push +#define BIO_puts GRPC_SHADOW_BIO_puts +#define BIO_read GRPC_SHADOW_BIO_read +#define BIO_read_asn1 GRPC_SHADOW_BIO_read_asn1 +#define BIO_reset GRPC_SHADOW_BIO_reset +#define BIO_set_close GRPC_SHADOW_BIO_set_close +#define BIO_set_data GRPC_SHADOW_BIO_set_data +#define BIO_set_flags GRPC_SHADOW_BIO_set_flags +#define BIO_set_init GRPC_SHADOW_BIO_set_init +#define BIO_set_retry_read GRPC_SHADOW_BIO_set_retry_read +#define BIO_set_retry_special GRPC_SHADOW_BIO_set_retry_special +#define BIO_set_retry_write GRPC_SHADOW_BIO_set_retry_write +#define BIO_set_shutdown GRPC_SHADOW_BIO_set_shutdown +#define BIO_set_write_buffer_size GRPC_SHADOW_BIO_set_write_buffer_size +#define BIO_should_io_special GRPC_SHADOW_BIO_should_io_special +#define BIO_should_read GRPC_SHADOW_BIO_should_read +#define BIO_should_retry GRPC_SHADOW_BIO_should_retry +#define BIO_should_write GRPC_SHADOW_BIO_should_write +#define BIO_test_flags GRPC_SHADOW_BIO_test_flags +#define BIO_up_ref GRPC_SHADOW_BIO_up_ref +#define BIO_vfree GRPC_SHADOW_BIO_vfree +#define BIO_wpending GRPC_SHADOW_BIO_wpending +#define BIO_write GRPC_SHADOW_BIO_write +#define ERR_print_errors GRPC_SHADOW_ERR_print_errors +#define BIO_get_mem_data GRPC_SHADOW_BIO_get_mem_data +#define BIO_get_mem_ptr GRPC_SHADOW_BIO_get_mem_ptr +#define BIO_mem_contents GRPC_SHADOW_BIO_mem_contents +#define BIO_new_mem_buf GRPC_SHADOW_BIO_new_mem_buf +#define BIO_s_mem GRPC_SHADOW_BIO_s_mem +#define BIO_set_mem_buf GRPC_SHADOW_BIO_set_mem_buf +#define BIO_set_mem_eof_return GRPC_SHADOW_BIO_set_mem_eof_return +#define BIO_do_connect GRPC_SHADOW_BIO_do_connect +#define BIO_new_connect GRPC_SHADOW_BIO_new_connect +#define BIO_s_connect GRPC_SHADOW_BIO_s_connect +#define BIO_set_conn_hostname GRPC_SHADOW_BIO_set_conn_hostname +#define BIO_set_conn_int_port GRPC_SHADOW_BIO_set_conn_int_port +#define BIO_set_conn_port GRPC_SHADOW_BIO_set_conn_port +#define BIO_set_nbio GRPC_SHADOW_BIO_set_nbio +#define BIO_get_fd GRPC_SHADOW_BIO_get_fd +#define BIO_new_fd GRPC_SHADOW_BIO_new_fd +#define BIO_s_fd GRPC_SHADOW_BIO_s_fd +#define BIO_set_fd GRPC_SHADOW_BIO_set_fd +#define bio_fd_should_retry GRPC_SHADOW_bio_fd_should_retry +#define BIO_append_filename GRPC_SHADOW_BIO_append_filename +#define BIO_get_fp GRPC_SHADOW_BIO_get_fp +#define BIO_new_file GRPC_SHADOW_BIO_new_file +#define BIO_new_fp GRPC_SHADOW_BIO_new_fp +#define BIO_read_filename GRPC_SHADOW_BIO_read_filename +#define BIO_rw_filename GRPC_SHADOW_BIO_rw_filename +#define BIO_s_file GRPC_SHADOW_BIO_s_file +#define BIO_set_fp GRPC_SHADOW_BIO_set_fp +#define BIO_write_filename GRPC_SHADOW_BIO_write_filename +#define BIO_hexdump GRPC_SHADOW_BIO_hexdump +#define BIO_ctrl_get_read_request GRPC_SHADOW_BIO_ctrl_get_read_request +#define BIO_ctrl_get_write_guarantee GRPC_SHADOW_BIO_ctrl_get_write_guarantee +#define BIO_new_bio_pair GRPC_SHADOW_BIO_new_bio_pair +#define BIO_shutdown_wr GRPC_SHADOW_BIO_shutdown_wr +#define BIO_printf GRPC_SHADOW_BIO_printf +#define BIO_new_socket GRPC_SHADOW_BIO_new_socket +#define BIO_s_socket GRPC_SHADOW_BIO_s_socket +#define bio_clear_socket_error GRPC_SHADOW_bio_clear_socket_error +#define bio_ip_and_port_to_socket_and_addr GRPC_SHADOW_bio_ip_and_port_to_socket_and_addr +#define bio_sock_error GRPC_SHADOW_bio_sock_error +#define bio_socket_nbio GRPC_SHADOW_bio_socket_nbio +#define RAND_enable_fork_unsafe_buffering GRPC_SHADOW_RAND_enable_fork_unsafe_buffering +#define rand_fork_unsafe_buffering_enabled GRPC_SHADOW_rand_fork_unsafe_buffering_enabled +#define RAND_SSLeay GRPC_SHADOW_RAND_SSLeay +#define RAND_add GRPC_SHADOW_RAND_add +#define RAND_cleanup GRPC_SHADOW_RAND_cleanup +#define RAND_egd GRPC_SHADOW_RAND_egd +#define RAND_file_name GRPC_SHADOW_RAND_file_name +#define RAND_get_rand_method GRPC_SHADOW_RAND_get_rand_method +#define RAND_load_file GRPC_SHADOW_RAND_load_file +#define RAND_poll GRPC_SHADOW_RAND_poll +#define RAND_seed GRPC_SHADOW_RAND_seed +#define RAND_set_rand_method GRPC_SHADOW_RAND_set_rand_method +#define RAND_status GRPC_SHADOW_RAND_status +#define OBJ_cbs2nid GRPC_SHADOW_OBJ_cbs2nid +#define OBJ_cmp GRPC_SHADOW_OBJ_cmp +#define OBJ_create GRPC_SHADOW_OBJ_create +#define OBJ_dup GRPC_SHADOW_OBJ_dup +#define OBJ_get0_data GRPC_SHADOW_OBJ_get0_data +#define OBJ_length GRPC_SHADOW_OBJ_length +#define OBJ_ln2nid GRPC_SHADOW_OBJ_ln2nid +#define OBJ_nid2cbb GRPC_SHADOW_OBJ_nid2cbb +#define OBJ_nid2ln GRPC_SHADOW_OBJ_nid2ln +#define OBJ_nid2obj GRPC_SHADOW_OBJ_nid2obj +#define OBJ_nid2sn GRPC_SHADOW_OBJ_nid2sn +#define OBJ_obj2nid GRPC_SHADOW_OBJ_obj2nid +#define OBJ_obj2txt GRPC_SHADOW_OBJ_obj2txt +#define OBJ_sn2nid GRPC_SHADOW_OBJ_sn2nid +#define OBJ_txt2nid GRPC_SHADOW_OBJ_txt2nid +#define OBJ_txt2obj GRPC_SHADOW_OBJ_txt2obj +#define OBJ_find_sigid_algs GRPC_SHADOW_OBJ_find_sigid_algs +#define OBJ_find_sigid_by_algs GRPC_SHADOW_OBJ_find_sigid_by_algs +#define ASN1_BIT_STRING_check GRPC_SHADOW_ASN1_BIT_STRING_check +#define ASN1_BIT_STRING_get_bit GRPC_SHADOW_ASN1_BIT_STRING_get_bit +#define ASN1_BIT_STRING_set GRPC_SHADOW_ASN1_BIT_STRING_set +#define ASN1_BIT_STRING_set_bit GRPC_SHADOW_ASN1_BIT_STRING_set_bit +#define c2i_ASN1_BIT_STRING GRPC_SHADOW_c2i_ASN1_BIT_STRING +#define i2c_ASN1_BIT_STRING GRPC_SHADOW_i2c_ASN1_BIT_STRING +#define d2i_ASN1_BOOLEAN GRPC_SHADOW_d2i_ASN1_BOOLEAN +#define i2d_ASN1_BOOLEAN GRPC_SHADOW_i2d_ASN1_BOOLEAN +#define ASN1_d2i_bio GRPC_SHADOW_ASN1_d2i_bio +#define ASN1_d2i_fp GRPC_SHADOW_ASN1_d2i_fp +#define ASN1_item_d2i_bio GRPC_SHADOW_ASN1_item_d2i_bio +#define ASN1_item_d2i_fp GRPC_SHADOW_ASN1_item_d2i_fp +#define ASN1_dup GRPC_SHADOW_ASN1_dup +#define ASN1_item_dup GRPC_SHADOW_ASN1_item_dup +#define ASN1_ENUMERATED_get GRPC_SHADOW_ASN1_ENUMERATED_get +#define ASN1_ENUMERATED_set GRPC_SHADOW_ASN1_ENUMERATED_set +#define ASN1_ENUMERATED_to_BN GRPC_SHADOW_ASN1_ENUMERATED_to_BN +#define BN_to_ASN1_ENUMERATED GRPC_SHADOW_BN_to_ASN1_ENUMERATED +#define ASN1_GENERALIZEDTIME_adj GRPC_SHADOW_ASN1_GENERALIZEDTIME_adj +#define ASN1_GENERALIZEDTIME_check GRPC_SHADOW_ASN1_GENERALIZEDTIME_check +#define ASN1_GENERALIZEDTIME_set GRPC_SHADOW_ASN1_GENERALIZEDTIME_set +#define ASN1_GENERALIZEDTIME_set_string GRPC_SHADOW_ASN1_GENERALIZEDTIME_set_string +#define asn1_generalizedtime_to_tm GRPC_SHADOW_asn1_generalizedtime_to_tm +#define ASN1_i2d_bio GRPC_SHADOW_ASN1_i2d_bio +#define ASN1_i2d_fp GRPC_SHADOW_ASN1_i2d_fp +#define ASN1_item_i2d_bio GRPC_SHADOW_ASN1_item_i2d_bio +#define ASN1_item_i2d_fp GRPC_SHADOW_ASN1_item_i2d_fp +#define ASN1_INTEGER_cmp GRPC_SHADOW_ASN1_INTEGER_cmp +#define ASN1_INTEGER_dup GRPC_SHADOW_ASN1_INTEGER_dup +#define ASN1_INTEGER_get GRPC_SHADOW_ASN1_INTEGER_get +#define ASN1_INTEGER_set GRPC_SHADOW_ASN1_INTEGER_set +#define ASN1_INTEGER_set_uint64 GRPC_SHADOW_ASN1_INTEGER_set_uint64 +#define ASN1_INTEGER_to_BN GRPC_SHADOW_ASN1_INTEGER_to_BN +#define BN_to_ASN1_INTEGER GRPC_SHADOW_BN_to_ASN1_INTEGER +#define c2i_ASN1_INTEGER GRPC_SHADOW_c2i_ASN1_INTEGER +#define d2i_ASN1_UINTEGER GRPC_SHADOW_d2i_ASN1_UINTEGER +#define i2c_ASN1_INTEGER GRPC_SHADOW_i2c_ASN1_INTEGER +#define ASN1_mbstring_copy GRPC_SHADOW_ASN1_mbstring_copy +#define ASN1_mbstring_ncopy GRPC_SHADOW_ASN1_mbstring_ncopy +#define ASN1_OBJECT_create GRPC_SHADOW_ASN1_OBJECT_create +#define ASN1_OBJECT_free GRPC_SHADOW_ASN1_OBJECT_free +#define ASN1_OBJECT_new GRPC_SHADOW_ASN1_OBJECT_new +#define c2i_ASN1_OBJECT GRPC_SHADOW_c2i_ASN1_OBJECT +#define d2i_ASN1_OBJECT GRPC_SHADOW_d2i_ASN1_OBJECT +#define i2a_ASN1_OBJECT GRPC_SHADOW_i2a_ASN1_OBJECT +#define i2d_ASN1_OBJECT GRPC_SHADOW_i2d_ASN1_OBJECT +#define i2t_ASN1_OBJECT GRPC_SHADOW_i2t_ASN1_OBJECT +#define ASN1_OCTET_STRING_cmp GRPC_SHADOW_ASN1_OCTET_STRING_cmp +#define ASN1_OCTET_STRING_dup GRPC_SHADOW_ASN1_OCTET_STRING_dup +#define ASN1_OCTET_STRING_set GRPC_SHADOW_ASN1_OCTET_STRING_set +#define ASN1_PRINTABLE_type GRPC_SHADOW_ASN1_PRINTABLE_type +#define ASN1_STRING_TABLE_add GRPC_SHADOW_ASN1_STRING_TABLE_add +#define ASN1_STRING_TABLE_cleanup GRPC_SHADOW_ASN1_STRING_TABLE_cleanup +#define ASN1_STRING_TABLE_get GRPC_SHADOW_ASN1_STRING_TABLE_get +#define ASN1_STRING_get_default_mask GRPC_SHADOW_ASN1_STRING_get_default_mask +#define ASN1_STRING_set_by_NID GRPC_SHADOW_ASN1_STRING_set_by_NID +#define ASN1_STRING_set_default_mask GRPC_SHADOW_ASN1_STRING_set_default_mask +#define ASN1_STRING_set_default_mask_asc GRPC_SHADOW_ASN1_STRING_set_default_mask_asc +#define ASN1_TIME_adj GRPC_SHADOW_ASN1_TIME_adj +#define ASN1_TIME_check GRPC_SHADOW_ASN1_TIME_check +#define ASN1_TIME_diff GRPC_SHADOW_ASN1_TIME_diff +#define ASN1_TIME_free GRPC_SHADOW_ASN1_TIME_free +#define ASN1_TIME_it GRPC_SHADOW_ASN1_TIME_it +#define ASN1_TIME_new GRPC_SHADOW_ASN1_TIME_new +#define ASN1_TIME_set GRPC_SHADOW_ASN1_TIME_set +#define ASN1_TIME_set_string GRPC_SHADOW_ASN1_TIME_set_string +#define ASN1_TIME_to_generalizedtime GRPC_SHADOW_ASN1_TIME_to_generalizedtime +#define d2i_ASN1_TIME GRPC_SHADOW_d2i_ASN1_TIME +#define i2d_ASN1_TIME GRPC_SHADOW_i2d_ASN1_TIME +#define ASN1_TYPE_cmp GRPC_SHADOW_ASN1_TYPE_cmp +#define ASN1_TYPE_get GRPC_SHADOW_ASN1_TYPE_get +#define ASN1_TYPE_set GRPC_SHADOW_ASN1_TYPE_set +#define ASN1_TYPE_set1 GRPC_SHADOW_ASN1_TYPE_set1 +#define ASN1_UTCTIME_adj GRPC_SHADOW_ASN1_UTCTIME_adj +#define ASN1_UTCTIME_check GRPC_SHADOW_ASN1_UTCTIME_check +#define ASN1_UTCTIME_cmp_time_t GRPC_SHADOW_ASN1_UTCTIME_cmp_time_t +#define ASN1_UTCTIME_set GRPC_SHADOW_ASN1_UTCTIME_set +#define ASN1_UTCTIME_set_string GRPC_SHADOW_ASN1_UTCTIME_set_string +#define asn1_utctime_to_tm GRPC_SHADOW_asn1_utctime_to_tm +#define UTF8_getc GRPC_SHADOW_UTF8_getc +#define UTF8_putc GRPC_SHADOW_UTF8_putc +#define ASN1_STRING_cmp GRPC_SHADOW_ASN1_STRING_cmp +#define ASN1_STRING_copy GRPC_SHADOW_ASN1_STRING_copy +#define ASN1_STRING_data GRPC_SHADOW_ASN1_STRING_data +#define ASN1_STRING_dup GRPC_SHADOW_ASN1_STRING_dup +#define ASN1_STRING_free GRPC_SHADOW_ASN1_STRING_free +#define ASN1_STRING_get0_data GRPC_SHADOW_ASN1_STRING_get0_data +#define ASN1_STRING_length GRPC_SHADOW_ASN1_STRING_length +#define ASN1_STRING_length_set GRPC_SHADOW_ASN1_STRING_length_set +#define ASN1_STRING_new GRPC_SHADOW_ASN1_STRING_new +#define ASN1_STRING_set GRPC_SHADOW_ASN1_STRING_set +#define ASN1_STRING_set0 GRPC_SHADOW_ASN1_STRING_set0 +#define ASN1_STRING_type GRPC_SHADOW_ASN1_STRING_type +#define ASN1_STRING_type_new GRPC_SHADOW_ASN1_STRING_type_new +#define ASN1_get_object GRPC_SHADOW_ASN1_get_object +#define ASN1_object_size GRPC_SHADOW_ASN1_object_size +#define ASN1_put_eoc GRPC_SHADOW_ASN1_put_eoc +#define ASN1_put_object GRPC_SHADOW_ASN1_put_object +#define ASN1_tag2str GRPC_SHADOW_ASN1_tag2str +#define ASN1_item_pack GRPC_SHADOW_ASN1_item_pack +#define ASN1_item_unpack GRPC_SHADOW_ASN1_item_unpack +#define i2a_ASN1_ENUMERATED GRPC_SHADOW_i2a_ASN1_ENUMERATED +#define i2a_ASN1_INTEGER GRPC_SHADOW_i2a_ASN1_INTEGER +#define i2a_ASN1_STRING GRPC_SHADOW_i2a_ASN1_STRING +#define ASN1_item_d2i GRPC_SHADOW_ASN1_item_d2i +#define ASN1_item_ex_d2i GRPC_SHADOW_ASN1_item_ex_d2i +#define ASN1_tag2bit GRPC_SHADOW_ASN1_tag2bit +#define asn1_ex_c2i GRPC_SHADOW_asn1_ex_c2i +#define ASN1_item_ex_i2d GRPC_SHADOW_ASN1_item_ex_i2d +#define ASN1_item_i2d GRPC_SHADOW_ASN1_item_i2d +#define ASN1_item_ndef_i2d GRPC_SHADOW_ASN1_item_ndef_i2d +#define asn1_ex_i2c GRPC_SHADOW_asn1_ex_i2c +#define ASN1_item_ex_free GRPC_SHADOW_ASN1_item_ex_free +#define ASN1_item_free GRPC_SHADOW_ASN1_item_free +#define ASN1_primitive_free GRPC_SHADOW_ASN1_primitive_free +#define ASN1_template_free GRPC_SHADOW_ASN1_template_free +#define asn1_item_combine_free GRPC_SHADOW_asn1_item_combine_free +#define ASN1_item_ex_new GRPC_SHADOW_ASN1_item_ex_new +#define ASN1_item_new GRPC_SHADOW_ASN1_item_new +#define ASN1_primitive_new GRPC_SHADOW_ASN1_primitive_new +#define ASN1_template_new GRPC_SHADOW_ASN1_template_new +#define ASN1_ANY_it GRPC_SHADOW_ASN1_ANY_it +#define ASN1_BIT_STRING_free GRPC_SHADOW_ASN1_BIT_STRING_free +#define ASN1_BIT_STRING_it GRPC_SHADOW_ASN1_BIT_STRING_it +#define ASN1_BIT_STRING_new GRPC_SHADOW_ASN1_BIT_STRING_new +#define ASN1_BMPSTRING_free GRPC_SHADOW_ASN1_BMPSTRING_free +#define ASN1_BMPSTRING_it GRPC_SHADOW_ASN1_BMPSTRING_it +#define ASN1_BMPSTRING_new GRPC_SHADOW_ASN1_BMPSTRING_new +#define ASN1_BOOLEAN_it GRPC_SHADOW_ASN1_BOOLEAN_it +#define ASN1_ENUMERATED_free GRPC_SHADOW_ASN1_ENUMERATED_free +#define ASN1_ENUMERATED_it GRPC_SHADOW_ASN1_ENUMERATED_it +#define ASN1_ENUMERATED_new GRPC_SHADOW_ASN1_ENUMERATED_new +#define ASN1_FBOOLEAN_it GRPC_SHADOW_ASN1_FBOOLEAN_it +#define ASN1_GENERALIZEDTIME_free GRPC_SHADOW_ASN1_GENERALIZEDTIME_free +#define ASN1_GENERALIZEDTIME_it GRPC_SHADOW_ASN1_GENERALIZEDTIME_it +#define ASN1_GENERALIZEDTIME_new GRPC_SHADOW_ASN1_GENERALIZEDTIME_new +#define ASN1_GENERALSTRING_free GRPC_SHADOW_ASN1_GENERALSTRING_free +#define ASN1_GENERALSTRING_it GRPC_SHADOW_ASN1_GENERALSTRING_it +#define ASN1_GENERALSTRING_new GRPC_SHADOW_ASN1_GENERALSTRING_new +#define ASN1_IA5STRING_free GRPC_SHADOW_ASN1_IA5STRING_free +#define ASN1_IA5STRING_it GRPC_SHADOW_ASN1_IA5STRING_it +#define ASN1_IA5STRING_new GRPC_SHADOW_ASN1_IA5STRING_new +#define ASN1_INTEGER_free GRPC_SHADOW_ASN1_INTEGER_free +#define ASN1_INTEGER_it GRPC_SHADOW_ASN1_INTEGER_it +#define ASN1_INTEGER_new GRPC_SHADOW_ASN1_INTEGER_new +#define ASN1_NULL_free GRPC_SHADOW_ASN1_NULL_free +#define ASN1_NULL_it GRPC_SHADOW_ASN1_NULL_it +#define ASN1_NULL_new GRPC_SHADOW_ASN1_NULL_new +#define ASN1_OBJECT_it GRPC_SHADOW_ASN1_OBJECT_it +#define ASN1_OCTET_STRING_NDEF_it GRPC_SHADOW_ASN1_OCTET_STRING_NDEF_it +#define ASN1_OCTET_STRING_free GRPC_SHADOW_ASN1_OCTET_STRING_free +#define ASN1_OCTET_STRING_it GRPC_SHADOW_ASN1_OCTET_STRING_it +#define ASN1_OCTET_STRING_new GRPC_SHADOW_ASN1_OCTET_STRING_new +#define ASN1_PRINTABLESTRING_free GRPC_SHADOW_ASN1_PRINTABLESTRING_free +#define ASN1_PRINTABLESTRING_it GRPC_SHADOW_ASN1_PRINTABLESTRING_it +#define ASN1_PRINTABLESTRING_new GRPC_SHADOW_ASN1_PRINTABLESTRING_new +#define ASN1_PRINTABLE_free GRPC_SHADOW_ASN1_PRINTABLE_free +#define ASN1_PRINTABLE_it GRPC_SHADOW_ASN1_PRINTABLE_it +#define ASN1_PRINTABLE_new GRPC_SHADOW_ASN1_PRINTABLE_new +#define ASN1_SEQUENCE_ANY_it GRPC_SHADOW_ASN1_SEQUENCE_ANY_it +#define ASN1_SEQUENCE_it GRPC_SHADOW_ASN1_SEQUENCE_it +#define ASN1_SET_ANY_it GRPC_SHADOW_ASN1_SET_ANY_it +#define ASN1_T61STRING_free GRPC_SHADOW_ASN1_T61STRING_free +#define ASN1_T61STRING_it GRPC_SHADOW_ASN1_T61STRING_it +#define ASN1_T61STRING_new GRPC_SHADOW_ASN1_T61STRING_new +#define ASN1_TBOOLEAN_it GRPC_SHADOW_ASN1_TBOOLEAN_it +#define ASN1_TYPE_free GRPC_SHADOW_ASN1_TYPE_free +#define ASN1_TYPE_new GRPC_SHADOW_ASN1_TYPE_new +#define ASN1_UNIVERSALSTRING_free GRPC_SHADOW_ASN1_UNIVERSALSTRING_free +#define ASN1_UNIVERSALSTRING_it GRPC_SHADOW_ASN1_UNIVERSALSTRING_it +#define ASN1_UNIVERSALSTRING_new GRPC_SHADOW_ASN1_UNIVERSALSTRING_new +#define ASN1_UTCTIME_free GRPC_SHADOW_ASN1_UTCTIME_free +#define ASN1_UTCTIME_it GRPC_SHADOW_ASN1_UTCTIME_it +#define ASN1_UTCTIME_new GRPC_SHADOW_ASN1_UTCTIME_new +#define ASN1_UTF8STRING_free GRPC_SHADOW_ASN1_UTF8STRING_free +#define ASN1_UTF8STRING_it GRPC_SHADOW_ASN1_UTF8STRING_it +#define ASN1_UTF8STRING_new GRPC_SHADOW_ASN1_UTF8STRING_new +#define ASN1_VISIBLESTRING_free GRPC_SHADOW_ASN1_VISIBLESTRING_free +#define ASN1_VISIBLESTRING_it GRPC_SHADOW_ASN1_VISIBLESTRING_it +#define ASN1_VISIBLESTRING_new GRPC_SHADOW_ASN1_VISIBLESTRING_new +#define DIRECTORYSTRING_free GRPC_SHADOW_DIRECTORYSTRING_free +#define DIRECTORYSTRING_it GRPC_SHADOW_DIRECTORYSTRING_it +#define DIRECTORYSTRING_new GRPC_SHADOW_DIRECTORYSTRING_new +#define DISPLAYTEXT_free GRPC_SHADOW_DISPLAYTEXT_free +#define DISPLAYTEXT_it GRPC_SHADOW_DISPLAYTEXT_it +#define DISPLAYTEXT_new GRPC_SHADOW_DISPLAYTEXT_new +#define d2i_ASN1_BIT_STRING GRPC_SHADOW_d2i_ASN1_BIT_STRING +#define d2i_ASN1_BMPSTRING GRPC_SHADOW_d2i_ASN1_BMPSTRING +#define d2i_ASN1_ENUMERATED GRPC_SHADOW_d2i_ASN1_ENUMERATED +#define d2i_ASN1_GENERALIZEDTIME GRPC_SHADOW_d2i_ASN1_GENERALIZEDTIME +#define d2i_ASN1_GENERALSTRING GRPC_SHADOW_d2i_ASN1_GENERALSTRING +#define d2i_ASN1_IA5STRING GRPC_SHADOW_d2i_ASN1_IA5STRING +#define d2i_ASN1_INTEGER GRPC_SHADOW_d2i_ASN1_INTEGER +#define d2i_ASN1_NULL GRPC_SHADOW_d2i_ASN1_NULL +#define d2i_ASN1_OCTET_STRING GRPC_SHADOW_d2i_ASN1_OCTET_STRING +#define d2i_ASN1_PRINTABLE GRPC_SHADOW_d2i_ASN1_PRINTABLE +#define d2i_ASN1_PRINTABLESTRING GRPC_SHADOW_d2i_ASN1_PRINTABLESTRING +#define d2i_ASN1_SEQUENCE_ANY GRPC_SHADOW_d2i_ASN1_SEQUENCE_ANY +#define d2i_ASN1_SET_ANY GRPC_SHADOW_d2i_ASN1_SET_ANY +#define d2i_ASN1_T61STRING GRPC_SHADOW_d2i_ASN1_T61STRING +#define d2i_ASN1_TYPE GRPC_SHADOW_d2i_ASN1_TYPE +#define d2i_ASN1_UNIVERSALSTRING GRPC_SHADOW_d2i_ASN1_UNIVERSALSTRING +#define d2i_ASN1_UTCTIME GRPC_SHADOW_d2i_ASN1_UTCTIME +#define d2i_ASN1_UTF8STRING GRPC_SHADOW_d2i_ASN1_UTF8STRING +#define d2i_ASN1_VISIBLESTRING GRPC_SHADOW_d2i_ASN1_VISIBLESTRING +#define d2i_DIRECTORYSTRING GRPC_SHADOW_d2i_DIRECTORYSTRING +#define d2i_DISPLAYTEXT GRPC_SHADOW_d2i_DISPLAYTEXT +#define i2d_ASN1_BIT_STRING GRPC_SHADOW_i2d_ASN1_BIT_STRING +#define i2d_ASN1_BMPSTRING GRPC_SHADOW_i2d_ASN1_BMPSTRING +#define i2d_ASN1_ENUMERATED GRPC_SHADOW_i2d_ASN1_ENUMERATED +#define i2d_ASN1_GENERALIZEDTIME GRPC_SHADOW_i2d_ASN1_GENERALIZEDTIME +#define i2d_ASN1_GENERALSTRING GRPC_SHADOW_i2d_ASN1_GENERALSTRING +#define i2d_ASN1_IA5STRING GRPC_SHADOW_i2d_ASN1_IA5STRING +#define i2d_ASN1_INTEGER GRPC_SHADOW_i2d_ASN1_INTEGER +#define i2d_ASN1_NULL GRPC_SHADOW_i2d_ASN1_NULL +#define i2d_ASN1_OCTET_STRING GRPC_SHADOW_i2d_ASN1_OCTET_STRING +#define i2d_ASN1_PRINTABLE GRPC_SHADOW_i2d_ASN1_PRINTABLE +#define i2d_ASN1_PRINTABLESTRING GRPC_SHADOW_i2d_ASN1_PRINTABLESTRING +#define i2d_ASN1_SEQUENCE_ANY GRPC_SHADOW_i2d_ASN1_SEQUENCE_ANY +#define i2d_ASN1_SET_ANY GRPC_SHADOW_i2d_ASN1_SET_ANY +#define i2d_ASN1_T61STRING GRPC_SHADOW_i2d_ASN1_T61STRING +#define i2d_ASN1_TYPE GRPC_SHADOW_i2d_ASN1_TYPE +#define i2d_ASN1_UNIVERSALSTRING GRPC_SHADOW_i2d_ASN1_UNIVERSALSTRING +#define i2d_ASN1_UTCTIME GRPC_SHADOW_i2d_ASN1_UTCTIME +#define i2d_ASN1_UTF8STRING GRPC_SHADOW_i2d_ASN1_UTF8STRING +#define i2d_ASN1_VISIBLESTRING GRPC_SHADOW_i2d_ASN1_VISIBLESTRING +#define i2d_DIRECTORYSTRING GRPC_SHADOW_i2d_DIRECTORYSTRING +#define i2d_DISPLAYTEXT GRPC_SHADOW_i2d_DISPLAYTEXT +#define asn1_do_adb GRPC_SHADOW_asn1_do_adb +#define asn1_enc_free GRPC_SHADOW_asn1_enc_free +#define asn1_enc_init GRPC_SHADOW_asn1_enc_init +#define asn1_enc_restore GRPC_SHADOW_asn1_enc_restore +#define asn1_enc_save GRPC_SHADOW_asn1_enc_save +#define asn1_get_choice_selector GRPC_SHADOW_asn1_get_choice_selector +#define asn1_get_field_ptr GRPC_SHADOW_asn1_get_field_ptr +#define asn1_refcount_dec_and_test_zero GRPC_SHADOW_asn1_refcount_dec_and_test_zero +#define asn1_refcount_set_one GRPC_SHADOW_asn1_refcount_set_one +#define asn1_set_choice_selector GRPC_SHADOW_asn1_set_choice_selector +#define OPENSSL_gmtime GRPC_SHADOW_OPENSSL_gmtime +#define OPENSSL_gmtime_adj GRPC_SHADOW_OPENSSL_gmtime_adj +#define OPENSSL_gmtime_diff GRPC_SHADOW_OPENSSL_gmtime_diff +#define ENGINE_free GRPC_SHADOW_ENGINE_free +#define ENGINE_get_ECDSA_method GRPC_SHADOW_ENGINE_get_ECDSA_method +#define ENGINE_get_RSA_method GRPC_SHADOW_ENGINE_get_RSA_method +#define ENGINE_new GRPC_SHADOW_ENGINE_new +#define ENGINE_set_ECDSA_method GRPC_SHADOW_ENGINE_set_ECDSA_method +#define ENGINE_set_RSA_method GRPC_SHADOW_ENGINE_set_RSA_method +#define METHOD_ref GRPC_SHADOW_METHOD_ref +#define METHOD_unref GRPC_SHADOW_METHOD_unref +#define DH_compute_key GRPC_SHADOW_DH_compute_key +#define DH_free GRPC_SHADOW_DH_free +#define DH_generate_key GRPC_SHADOW_DH_generate_key +#define DH_generate_parameters_ex GRPC_SHADOW_DH_generate_parameters_ex +#define DH_get0_key GRPC_SHADOW_DH_get0_key +#define DH_get0_pqg GRPC_SHADOW_DH_get0_pqg +#define DH_get_ex_data GRPC_SHADOW_DH_get_ex_data +#define DH_get_ex_new_index GRPC_SHADOW_DH_get_ex_new_index +#define DH_new GRPC_SHADOW_DH_new +#define DH_num_bits GRPC_SHADOW_DH_num_bits +#define DH_set0_key GRPC_SHADOW_DH_set0_key +#define DH_set0_pqg GRPC_SHADOW_DH_set0_pqg +#define DH_set_ex_data GRPC_SHADOW_DH_set_ex_data +#define DH_size GRPC_SHADOW_DH_size +#define DH_up_ref GRPC_SHADOW_DH_up_ref +#define DHparams_dup GRPC_SHADOW_DHparams_dup +#define BN_get_rfc3526_prime_1536 GRPC_SHADOW_BN_get_rfc3526_prime_1536 +#define DH_check GRPC_SHADOW_DH_check +#define DH_check_pub_key GRPC_SHADOW_DH_check_pub_key +#define DH_marshal_parameters GRPC_SHADOW_DH_marshal_parameters +#define DH_parse_parameters GRPC_SHADOW_DH_parse_parameters +#define d2i_DHparams GRPC_SHADOW_d2i_DHparams +#define i2d_DHparams GRPC_SHADOW_i2d_DHparams +#define DSA_SIG_free GRPC_SHADOW_DSA_SIG_free +#define DSA_SIG_new GRPC_SHADOW_DSA_SIG_new +#define DSA_check_signature GRPC_SHADOW_DSA_check_signature +#define DSA_do_check_signature GRPC_SHADOW_DSA_do_check_signature +#define DSA_do_sign GRPC_SHADOW_DSA_do_sign +#define DSA_do_verify GRPC_SHADOW_DSA_do_verify +#define DSA_dup_DH GRPC_SHADOW_DSA_dup_DH +#define DSA_free GRPC_SHADOW_DSA_free +#define DSA_generate_key GRPC_SHADOW_DSA_generate_key +#define DSA_generate_parameters_ex GRPC_SHADOW_DSA_generate_parameters_ex +#define DSA_get0_key GRPC_SHADOW_DSA_get0_key +#define DSA_get0_pqg GRPC_SHADOW_DSA_get0_pqg +#define DSA_get_ex_data GRPC_SHADOW_DSA_get_ex_data +#define DSA_get_ex_new_index GRPC_SHADOW_DSA_get_ex_new_index +#define DSA_new GRPC_SHADOW_DSA_new +#define DSA_set0_key GRPC_SHADOW_DSA_set0_key +#define DSA_set0_pqg GRPC_SHADOW_DSA_set0_pqg +#define DSA_set_ex_data GRPC_SHADOW_DSA_set_ex_data +#define DSA_sign GRPC_SHADOW_DSA_sign +#define DSA_size GRPC_SHADOW_DSA_size +#define DSA_up_ref GRPC_SHADOW_DSA_up_ref +#define DSA_verify GRPC_SHADOW_DSA_verify +#define DSAparams_dup GRPC_SHADOW_DSAparams_dup +#define DSA_SIG_marshal GRPC_SHADOW_DSA_SIG_marshal +#define DSA_SIG_parse GRPC_SHADOW_DSA_SIG_parse +#define DSA_marshal_parameters GRPC_SHADOW_DSA_marshal_parameters +#define DSA_marshal_private_key GRPC_SHADOW_DSA_marshal_private_key +#define DSA_marshal_public_key GRPC_SHADOW_DSA_marshal_public_key +#define DSA_parse_parameters GRPC_SHADOW_DSA_parse_parameters +#define DSA_parse_private_key GRPC_SHADOW_DSA_parse_private_key +#define DSA_parse_public_key GRPC_SHADOW_DSA_parse_public_key +#define d2i_DSAPrivateKey GRPC_SHADOW_d2i_DSAPrivateKey +#define d2i_DSAPublicKey GRPC_SHADOW_d2i_DSAPublicKey +#define d2i_DSA_SIG GRPC_SHADOW_d2i_DSA_SIG +#define d2i_DSAparams GRPC_SHADOW_d2i_DSAparams +#define i2d_DSAPrivateKey GRPC_SHADOW_i2d_DSAPrivateKey +#define i2d_DSAPublicKey GRPC_SHADOW_i2d_DSAPublicKey +#define i2d_DSA_SIG GRPC_SHADOW_i2d_DSA_SIG +#define i2d_DSAparams GRPC_SHADOW_i2d_DSAparams +#define RSAPrivateKey_dup GRPC_SHADOW_RSAPrivateKey_dup +#define RSAPublicKey_dup GRPC_SHADOW_RSAPublicKey_dup +#define RSA_marshal_private_key GRPC_SHADOW_RSA_marshal_private_key +#define RSA_marshal_public_key GRPC_SHADOW_RSA_marshal_public_key +#define RSA_parse_private_key GRPC_SHADOW_RSA_parse_private_key +#define RSA_parse_public_key GRPC_SHADOW_RSA_parse_public_key +#define RSA_private_key_from_bytes GRPC_SHADOW_RSA_private_key_from_bytes +#define RSA_private_key_to_bytes GRPC_SHADOW_RSA_private_key_to_bytes +#define RSA_public_key_from_bytes GRPC_SHADOW_RSA_public_key_from_bytes +#define RSA_public_key_to_bytes GRPC_SHADOW_RSA_public_key_to_bytes +#define d2i_RSAPrivateKey GRPC_SHADOW_d2i_RSAPrivateKey +#define d2i_RSAPublicKey GRPC_SHADOW_d2i_RSAPublicKey +#define i2d_RSAPrivateKey GRPC_SHADOW_i2d_RSAPrivateKey +#define i2d_RSAPublicKey GRPC_SHADOW_i2d_RSAPublicKey +#define EC_KEY_marshal_curve_name GRPC_SHADOW_EC_KEY_marshal_curve_name +#define EC_KEY_marshal_private_key GRPC_SHADOW_EC_KEY_marshal_private_key +#define EC_KEY_parse_curve_name GRPC_SHADOW_EC_KEY_parse_curve_name +#define EC_KEY_parse_parameters GRPC_SHADOW_EC_KEY_parse_parameters +#define EC_KEY_parse_private_key GRPC_SHADOW_EC_KEY_parse_private_key +#define EC_POINT_point2cbb GRPC_SHADOW_EC_POINT_point2cbb +#define d2i_ECParameters GRPC_SHADOW_d2i_ECParameters +#define d2i_ECPrivateKey GRPC_SHADOW_d2i_ECPrivateKey +#define i2d_ECParameters GRPC_SHADOW_i2d_ECParameters +#define i2d_ECPrivateKey GRPC_SHADOW_i2d_ECPrivateKey +#define i2o_ECPublicKey GRPC_SHADOW_i2o_ECPublicKey +#define o2i_ECPublicKey GRPC_SHADOW_o2i_ECPublicKey +#define ECDH_compute_key GRPC_SHADOW_ECDH_compute_key +#define ECDSA_SIG_from_bytes GRPC_SHADOW_ECDSA_SIG_from_bytes +#define ECDSA_SIG_marshal GRPC_SHADOW_ECDSA_SIG_marshal +#define ECDSA_SIG_max_len GRPC_SHADOW_ECDSA_SIG_max_len +#define ECDSA_SIG_parse GRPC_SHADOW_ECDSA_SIG_parse +#define ECDSA_SIG_to_bytes GRPC_SHADOW_ECDSA_SIG_to_bytes +#define ECDSA_sign GRPC_SHADOW_ECDSA_sign +#define ECDSA_size GRPC_SHADOW_ECDSA_size +#define ECDSA_verify GRPC_SHADOW_ECDSA_verify +#define d2i_ECDSA_SIG GRPC_SHADOW_d2i_ECDSA_SIG +#define i2d_ECDSA_SIG GRPC_SHADOW_i2d_ECDSA_SIG +#define AES_CMAC GRPC_SHADOW_AES_CMAC +#define CMAC_CTX_free GRPC_SHADOW_CMAC_CTX_free +#define CMAC_CTX_new GRPC_SHADOW_CMAC_CTX_new +#define CMAC_Final GRPC_SHADOW_CMAC_Final +#define CMAC_Init GRPC_SHADOW_CMAC_Init +#define CMAC_Reset GRPC_SHADOW_CMAC_Reset +#define CMAC_Update GRPC_SHADOW_CMAC_Update +#define EVP_DigestSign GRPC_SHADOW_EVP_DigestSign +#define EVP_DigestSignFinal GRPC_SHADOW_EVP_DigestSignFinal +#define EVP_DigestSignInit GRPC_SHADOW_EVP_DigestSignInit +#define EVP_DigestSignUpdate GRPC_SHADOW_EVP_DigestSignUpdate +#define EVP_DigestVerify GRPC_SHADOW_EVP_DigestVerify +#define EVP_DigestVerifyFinal GRPC_SHADOW_EVP_DigestVerifyFinal +#define EVP_DigestVerifyInit GRPC_SHADOW_EVP_DigestVerifyInit +#define EVP_DigestVerifyUpdate GRPC_SHADOW_EVP_DigestVerifyUpdate +#define EVP_PKEY_CTX_get_signature_md GRPC_SHADOW_EVP_PKEY_CTX_get_signature_md +#define EVP_PKEY_CTX_set_signature_md GRPC_SHADOW_EVP_PKEY_CTX_set_signature_md +#define EVP_PKEY_assign GRPC_SHADOW_EVP_PKEY_assign +#define EVP_PKEY_assign_DSA GRPC_SHADOW_EVP_PKEY_assign_DSA +#define EVP_PKEY_assign_EC_KEY GRPC_SHADOW_EVP_PKEY_assign_EC_KEY +#define EVP_PKEY_assign_RSA GRPC_SHADOW_EVP_PKEY_assign_RSA +#define EVP_PKEY_bits GRPC_SHADOW_EVP_PKEY_bits +#define EVP_PKEY_cmp GRPC_SHADOW_EVP_PKEY_cmp +#define EVP_PKEY_cmp_parameters GRPC_SHADOW_EVP_PKEY_cmp_parameters +#define EVP_PKEY_copy_parameters GRPC_SHADOW_EVP_PKEY_copy_parameters +#define EVP_PKEY_free GRPC_SHADOW_EVP_PKEY_free +#define EVP_PKEY_get0_DH GRPC_SHADOW_EVP_PKEY_get0_DH +#define EVP_PKEY_get0_DSA GRPC_SHADOW_EVP_PKEY_get0_DSA +#define EVP_PKEY_get0_EC_KEY GRPC_SHADOW_EVP_PKEY_get0_EC_KEY +#define EVP_PKEY_get0_RSA GRPC_SHADOW_EVP_PKEY_get0_RSA +#define EVP_PKEY_get1_DSA GRPC_SHADOW_EVP_PKEY_get1_DSA +#define EVP_PKEY_get1_EC_KEY GRPC_SHADOW_EVP_PKEY_get1_EC_KEY +#define EVP_PKEY_get1_RSA GRPC_SHADOW_EVP_PKEY_get1_RSA +#define EVP_PKEY_id GRPC_SHADOW_EVP_PKEY_id +#define EVP_PKEY_is_opaque GRPC_SHADOW_EVP_PKEY_is_opaque +#define EVP_PKEY_missing_parameters GRPC_SHADOW_EVP_PKEY_missing_parameters +#define EVP_PKEY_new GRPC_SHADOW_EVP_PKEY_new +#define EVP_PKEY_set1_DSA GRPC_SHADOW_EVP_PKEY_set1_DSA +#define EVP_PKEY_set1_EC_KEY GRPC_SHADOW_EVP_PKEY_set1_EC_KEY +#define EVP_PKEY_set1_RSA GRPC_SHADOW_EVP_PKEY_set1_RSA +#define EVP_PKEY_set_type GRPC_SHADOW_EVP_PKEY_set_type +#define EVP_PKEY_size GRPC_SHADOW_EVP_PKEY_size +#define EVP_PKEY_type GRPC_SHADOW_EVP_PKEY_type +#define EVP_PKEY_up_ref GRPC_SHADOW_EVP_PKEY_up_ref +#define EVP_cleanup GRPC_SHADOW_EVP_cleanup +#define OPENSSL_add_all_algorithms_conf GRPC_SHADOW_OPENSSL_add_all_algorithms_conf +#define OpenSSL_add_all_algorithms GRPC_SHADOW_OpenSSL_add_all_algorithms +#define OpenSSL_add_all_ciphers GRPC_SHADOW_OpenSSL_add_all_ciphers +#define OpenSSL_add_all_digests GRPC_SHADOW_OpenSSL_add_all_digests +#define EVP_marshal_private_key GRPC_SHADOW_EVP_marshal_private_key +#define EVP_marshal_public_key GRPC_SHADOW_EVP_marshal_public_key +#define EVP_parse_private_key GRPC_SHADOW_EVP_parse_private_key +#define EVP_parse_public_key GRPC_SHADOW_EVP_parse_public_key +#define d2i_AutoPrivateKey GRPC_SHADOW_d2i_AutoPrivateKey +#define d2i_PrivateKey GRPC_SHADOW_d2i_PrivateKey +#define i2d_PublicKey GRPC_SHADOW_i2d_PublicKey +#define EVP_PKEY_CTX_ctrl GRPC_SHADOW_EVP_PKEY_CTX_ctrl +#define EVP_PKEY_CTX_dup GRPC_SHADOW_EVP_PKEY_CTX_dup +#define EVP_PKEY_CTX_free GRPC_SHADOW_EVP_PKEY_CTX_free +#define EVP_PKEY_CTX_get0_pkey GRPC_SHADOW_EVP_PKEY_CTX_get0_pkey +#define EVP_PKEY_CTX_new GRPC_SHADOW_EVP_PKEY_CTX_new +#define EVP_PKEY_CTX_new_id GRPC_SHADOW_EVP_PKEY_CTX_new_id +#define EVP_PKEY_decrypt GRPC_SHADOW_EVP_PKEY_decrypt +#define EVP_PKEY_decrypt_init GRPC_SHADOW_EVP_PKEY_decrypt_init +#define EVP_PKEY_derive GRPC_SHADOW_EVP_PKEY_derive +#define EVP_PKEY_derive_init GRPC_SHADOW_EVP_PKEY_derive_init +#define EVP_PKEY_derive_set_peer GRPC_SHADOW_EVP_PKEY_derive_set_peer +#define EVP_PKEY_encrypt GRPC_SHADOW_EVP_PKEY_encrypt +#define EVP_PKEY_encrypt_init GRPC_SHADOW_EVP_PKEY_encrypt_init +#define EVP_PKEY_keygen GRPC_SHADOW_EVP_PKEY_keygen +#define EVP_PKEY_keygen_init GRPC_SHADOW_EVP_PKEY_keygen_init +#define EVP_PKEY_sign GRPC_SHADOW_EVP_PKEY_sign +#define EVP_PKEY_sign_init GRPC_SHADOW_EVP_PKEY_sign_init +#define EVP_PKEY_verify GRPC_SHADOW_EVP_PKEY_verify +#define EVP_PKEY_verify_init GRPC_SHADOW_EVP_PKEY_verify_init +#define EVP_PKEY_verify_recover GRPC_SHADOW_EVP_PKEY_verify_recover +#define EVP_PKEY_verify_recover_init GRPC_SHADOW_EVP_PKEY_verify_recover_init +#define dsa_asn1_meth GRPC_SHADOW_dsa_asn1_meth +#define ec_pkey_meth GRPC_SHADOW_ec_pkey_meth +#define ec_asn1_meth GRPC_SHADOW_ec_asn1_meth +#define ed25519_pkey_meth GRPC_SHADOW_ed25519_pkey_meth +#define EVP_PKEY_new_ed25519_private GRPC_SHADOW_EVP_PKEY_new_ed25519_private +#define EVP_PKEY_new_ed25519_public GRPC_SHADOW_EVP_PKEY_new_ed25519_public +#define ed25519_asn1_meth GRPC_SHADOW_ed25519_asn1_meth +#define EVP_PKEY_CTX_get0_rsa_oaep_label GRPC_SHADOW_EVP_PKEY_CTX_get0_rsa_oaep_label +#define EVP_PKEY_CTX_get_rsa_mgf1_md GRPC_SHADOW_EVP_PKEY_CTX_get_rsa_mgf1_md +#define EVP_PKEY_CTX_get_rsa_oaep_md GRPC_SHADOW_EVP_PKEY_CTX_get_rsa_oaep_md +#define EVP_PKEY_CTX_get_rsa_padding GRPC_SHADOW_EVP_PKEY_CTX_get_rsa_padding +#define EVP_PKEY_CTX_get_rsa_pss_saltlen GRPC_SHADOW_EVP_PKEY_CTX_get_rsa_pss_saltlen +#define EVP_PKEY_CTX_set0_rsa_oaep_label GRPC_SHADOW_EVP_PKEY_CTX_set0_rsa_oaep_label +#define EVP_PKEY_CTX_set_rsa_keygen_bits GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_keygen_bits +#define EVP_PKEY_CTX_set_rsa_keygen_pubexp GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_keygen_pubexp +#define EVP_PKEY_CTX_set_rsa_mgf1_md GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_mgf1_md +#define EVP_PKEY_CTX_set_rsa_oaep_md GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_oaep_md +#define EVP_PKEY_CTX_set_rsa_padding GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_padding +#define EVP_PKEY_CTX_set_rsa_pss_saltlen GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_pss_saltlen +#define rsa_pkey_meth GRPC_SHADOW_rsa_pkey_meth +#define rsa_asn1_meth GRPC_SHADOW_rsa_asn1_meth +#define PKCS5_PBKDF2_HMAC GRPC_SHADOW_PKCS5_PBKDF2_HMAC +#define PKCS5_PBKDF2_HMAC_SHA1 GRPC_SHADOW_PKCS5_PBKDF2_HMAC_SHA1 +#define EVP_PKEY_print_params GRPC_SHADOW_EVP_PKEY_print_params +#define EVP_PKEY_print_private GRPC_SHADOW_EVP_PKEY_print_private +#define EVP_PKEY_print_public GRPC_SHADOW_EVP_PKEY_print_public +#define EVP_PBE_scrypt GRPC_SHADOW_EVP_PBE_scrypt +#define EVP_SignFinal GRPC_SHADOW_EVP_SignFinal +#define EVP_SignInit GRPC_SHADOW_EVP_SignInit +#define EVP_SignInit_ex GRPC_SHADOW_EVP_SignInit_ex +#define EVP_SignUpdate GRPC_SHADOW_EVP_SignUpdate +#define EVP_VerifyFinal GRPC_SHADOW_EVP_VerifyFinal +#define EVP_VerifyInit GRPC_SHADOW_EVP_VerifyInit +#define EVP_VerifyInit_ex GRPC_SHADOW_EVP_VerifyInit_ex +#define EVP_VerifyUpdate GRPC_SHADOW_EVP_VerifyUpdate +#define HKDF GRPC_SHADOW_HKDF +#define HKDF_expand GRPC_SHADOW_HKDF_expand +#define HKDF_extract GRPC_SHADOW_HKDF_extract +#define PEM_read_DSAPrivateKey GRPC_SHADOW_PEM_read_DSAPrivateKey +#define PEM_read_DSA_PUBKEY GRPC_SHADOW_PEM_read_DSA_PUBKEY +#define PEM_read_DSAparams GRPC_SHADOW_PEM_read_DSAparams +#define PEM_read_ECPrivateKey GRPC_SHADOW_PEM_read_ECPrivateKey +#define PEM_read_EC_PUBKEY GRPC_SHADOW_PEM_read_EC_PUBKEY +#define PEM_read_PUBKEY GRPC_SHADOW_PEM_read_PUBKEY +#define PEM_read_RSAPrivateKey GRPC_SHADOW_PEM_read_RSAPrivateKey +#define PEM_read_RSAPublicKey GRPC_SHADOW_PEM_read_RSAPublicKey +#define PEM_read_RSA_PUBKEY GRPC_SHADOW_PEM_read_RSA_PUBKEY +#define PEM_read_X509_CRL GRPC_SHADOW_PEM_read_X509_CRL +#define PEM_read_X509_REQ GRPC_SHADOW_PEM_read_X509_REQ +#define PEM_read_bio_DSAPrivateKey GRPC_SHADOW_PEM_read_bio_DSAPrivateKey +#define PEM_read_bio_DSA_PUBKEY GRPC_SHADOW_PEM_read_bio_DSA_PUBKEY +#define PEM_read_bio_DSAparams GRPC_SHADOW_PEM_read_bio_DSAparams +#define PEM_read_bio_ECPrivateKey GRPC_SHADOW_PEM_read_bio_ECPrivateKey +#define PEM_read_bio_EC_PUBKEY GRPC_SHADOW_PEM_read_bio_EC_PUBKEY +#define PEM_read_bio_PUBKEY GRPC_SHADOW_PEM_read_bio_PUBKEY +#define PEM_read_bio_RSAPrivateKey GRPC_SHADOW_PEM_read_bio_RSAPrivateKey +#define PEM_read_bio_RSAPublicKey GRPC_SHADOW_PEM_read_bio_RSAPublicKey +#define PEM_read_bio_RSA_PUBKEY GRPC_SHADOW_PEM_read_bio_RSA_PUBKEY +#define PEM_read_bio_X509_CRL GRPC_SHADOW_PEM_read_bio_X509_CRL +#define PEM_read_bio_X509_REQ GRPC_SHADOW_PEM_read_bio_X509_REQ +#define PEM_write_DHparams GRPC_SHADOW_PEM_write_DHparams +#define PEM_write_DSAPrivateKey GRPC_SHADOW_PEM_write_DSAPrivateKey +#define PEM_write_DSA_PUBKEY GRPC_SHADOW_PEM_write_DSA_PUBKEY +#define PEM_write_DSAparams GRPC_SHADOW_PEM_write_DSAparams +#define PEM_write_ECPrivateKey GRPC_SHADOW_PEM_write_ECPrivateKey +#define PEM_write_EC_PUBKEY GRPC_SHADOW_PEM_write_EC_PUBKEY +#define PEM_write_PUBKEY GRPC_SHADOW_PEM_write_PUBKEY +#define PEM_write_RSAPrivateKey GRPC_SHADOW_PEM_write_RSAPrivateKey +#define PEM_write_RSAPublicKey GRPC_SHADOW_PEM_write_RSAPublicKey +#define PEM_write_RSA_PUBKEY GRPC_SHADOW_PEM_write_RSA_PUBKEY +#define PEM_write_X509_CRL GRPC_SHADOW_PEM_write_X509_CRL +#define PEM_write_X509_REQ GRPC_SHADOW_PEM_write_X509_REQ +#define PEM_write_X509_REQ_NEW GRPC_SHADOW_PEM_write_X509_REQ_NEW +#define PEM_write_bio_DHparams GRPC_SHADOW_PEM_write_bio_DHparams +#define PEM_write_bio_DSAPrivateKey GRPC_SHADOW_PEM_write_bio_DSAPrivateKey +#define PEM_write_bio_DSA_PUBKEY GRPC_SHADOW_PEM_write_bio_DSA_PUBKEY +#define PEM_write_bio_DSAparams GRPC_SHADOW_PEM_write_bio_DSAparams +#define PEM_write_bio_ECPrivateKey GRPC_SHADOW_PEM_write_bio_ECPrivateKey +#define PEM_write_bio_EC_PUBKEY GRPC_SHADOW_PEM_write_bio_EC_PUBKEY +#define PEM_write_bio_PUBKEY GRPC_SHADOW_PEM_write_bio_PUBKEY +#define PEM_write_bio_RSAPrivateKey GRPC_SHADOW_PEM_write_bio_RSAPrivateKey +#define PEM_write_bio_RSAPublicKey GRPC_SHADOW_PEM_write_bio_RSAPublicKey +#define PEM_write_bio_RSA_PUBKEY GRPC_SHADOW_PEM_write_bio_RSA_PUBKEY +#define PEM_write_bio_X509_CRL GRPC_SHADOW_PEM_write_bio_X509_CRL +#define PEM_write_bio_X509_REQ GRPC_SHADOW_PEM_write_bio_X509_REQ +#define PEM_write_bio_X509_REQ_NEW GRPC_SHADOW_PEM_write_bio_X509_REQ_NEW +#define PEM_X509_INFO_read GRPC_SHADOW_PEM_X509_INFO_read +#define PEM_X509_INFO_read_bio GRPC_SHADOW_PEM_X509_INFO_read_bio +#define PEM_X509_INFO_write_bio GRPC_SHADOW_PEM_X509_INFO_write_bio +#define PEM_ASN1_read GRPC_SHADOW_PEM_ASN1_read +#define PEM_ASN1_write GRPC_SHADOW_PEM_ASN1_write +#define PEM_ASN1_write_bio GRPC_SHADOW_PEM_ASN1_write_bio +#define PEM_bytes_read_bio GRPC_SHADOW_PEM_bytes_read_bio +#define PEM_def_callback GRPC_SHADOW_PEM_def_callback +#define PEM_dek_info GRPC_SHADOW_PEM_dek_info +#define PEM_do_header GRPC_SHADOW_PEM_do_header +#define PEM_get_EVP_CIPHER_INFO GRPC_SHADOW_PEM_get_EVP_CIPHER_INFO +#define PEM_proc_type GRPC_SHADOW_PEM_proc_type +#define PEM_read GRPC_SHADOW_PEM_read +#define PEM_read_bio GRPC_SHADOW_PEM_read_bio +#define PEM_write GRPC_SHADOW_PEM_write +#define PEM_write_bio GRPC_SHADOW_PEM_write_bio +#define PEM_ASN1_read_bio GRPC_SHADOW_PEM_ASN1_read_bio +#define PEM_read_PKCS8 GRPC_SHADOW_PEM_read_PKCS8 +#define PEM_read_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_PEM_read_PKCS8_PRIV_KEY_INFO +#define PEM_read_bio_PKCS8 GRPC_SHADOW_PEM_read_bio_PKCS8 +#define PEM_read_bio_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_PEM_read_bio_PKCS8_PRIV_KEY_INFO +#define PEM_write_PKCS8 GRPC_SHADOW_PEM_write_PKCS8 +#define PEM_write_PKCS8PrivateKey GRPC_SHADOW_PEM_write_PKCS8PrivateKey +#define PEM_write_PKCS8PrivateKey_nid GRPC_SHADOW_PEM_write_PKCS8PrivateKey_nid +#define PEM_write_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_PEM_write_PKCS8_PRIV_KEY_INFO +#define PEM_write_bio_PKCS8 GRPC_SHADOW_PEM_write_bio_PKCS8 +#define PEM_write_bio_PKCS8PrivateKey GRPC_SHADOW_PEM_write_bio_PKCS8PrivateKey +#define PEM_write_bio_PKCS8PrivateKey_nid GRPC_SHADOW_PEM_write_bio_PKCS8PrivateKey_nid +#define PEM_write_bio_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_PEM_write_bio_PKCS8_PRIV_KEY_INFO +#define d2i_PKCS8PrivateKey_bio GRPC_SHADOW_d2i_PKCS8PrivateKey_bio +#define d2i_PKCS8PrivateKey_fp GRPC_SHADOW_d2i_PKCS8PrivateKey_fp +#define i2d_PKCS8PrivateKey_bio GRPC_SHADOW_i2d_PKCS8PrivateKey_bio +#define i2d_PKCS8PrivateKey_fp GRPC_SHADOW_i2d_PKCS8PrivateKey_fp +#define i2d_PKCS8PrivateKey_nid_bio GRPC_SHADOW_i2d_PKCS8PrivateKey_nid_bio +#define i2d_PKCS8PrivateKey_nid_fp GRPC_SHADOW_i2d_PKCS8PrivateKey_nid_fp +#define PEM_read_DHparams GRPC_SHADOW_PEM_read_DHparams +#define PEM_read_PrivateKey GRPC_SHADOW_PEM_read_PrivateKey +#define PEM_read_bio_DHparams GRPC_SHADOW_PEM_read_bio_DHparams +#define PEM_read_bio_PrivateKey GRPC_SHADOW_PEM_read_bio_PrivateKey +#define PEM_write_PrivateKey GRPC_SHADOW_PEM_write_PrivateKey +#define PEM_write_bio_PrivateKey GRPC_SHADOW_PEM_write_bio_PrivateKey +#define PEM_read_X509 GRPC_SHADOW_PEM_read_X509 +#define PEM_read_bio_X509 GRPC_SHADOW_PEM_read_bio_X509 +#define PEM_write_X509 GRPC_SHADOW_PEM_write_X509 +#define PEM_write_bio_X509 GRPC_SHADOW_PEM_write_bio_X509 +#define PEM_read_X509_AUX GRPC_SHADOW_PEM_read_X509_AUX +#define PEM_read_bio_X509_AUX GRPC_SHADOW_PEM_read_bio_X509_AUX +#define PEM_write_X509_AUX GRPC_SHADOW_PEM_write_X509_AUX +#define PEM_write_bio_X509_AUX GRPC_SHADOW_PEM_write_bio_X509_AUX +#define ASN1_digest GRPC_SHADOW_ASN1_digest +#define ASN1_item_digest GRPC_SHADOW_ASN1_item_digest +#define ASN1_item_sign GRPC_SHADOW_ASN1_item_sign +#define ASN1_item_sign_ctx GRPC_SHADOW_ASN1_item_sign_ctx +#define ASN1_STRING_print_ex GRPC_SHADOW_ASN1_STRING_print_ex +#define ASN1_STRING_print_ex_fp GRPC_SHADOW_ASN1_STRING_print_ex_fp +#define ASN1_STRING_to_UTF8 GRPC_SHADOW_ASN1_STRING_to_UTF8 +#define X509_NAME_print_ex GRPC_SHADOW_X509_NAME_print_ex +#define X509_NAME_print_ex_fp GRPC_SHADOW_X509_NAME_print_ex_fp +#define ASN1_item_verify GRPC_SHADOW_ASN1_item_verify +#define x509_digest_sign_algorithm GRPC_SHADOW_x509_digest_sign_algorithm +#define x509_digest_verify_init GRPC_SHADOW_x509_digest_verify_init +#define ASN1_generate_nconf GRPC_SHADOW_ASN1_generate_nconf +#define ASN1_generate_v3 GRPC_SHADOW_ASN1_generate_v3 +#define X509_LOOKUP_hash_dir GRPC_SHADOW_X509_LOOKUP_hash_dir +#define X509_LOOKUP_file GRPC_SHADOW_X509_LOOKUP_file +#define X509_load_cert_crl_file GRPC_SHADOW_X509_load_cert_crl_file +#define X509_load_cert_file GRPC_SHADOW_X509_load_cert_file +#define X509_load_crl_file GRPC_SHADOW_X509_load_crl_file +#define i2d_PrivateKey GRPC_SHADOW_i2d_PrivateKey +#define RSA_PSS_PARAMS_free GRPC_SHADOW_RSA_PSS_PARAMS_free +#define RSA_PSS_PARAMS_it GRPC_SHADOW_RSA_PSS_PARAMS_it +#define RSA_PSS_PARAMS_new GRPC_SHADOW_RSA_PSS_PARAMS_new +#define d2i_RSA_PSS_PARAMS GRPC_SHADOW_d2i_RSA_PSS_PARAMS +#define i2d_RSA_PSS_PARAMS GRPC_SHADOW_i2d_RSA_PSS_PARAMS +#define x509_print_rsa_pss_params GRPC_SHADOW_x509_print_rsa_pss_params +#define x509_rsa_ctx_to_pss GRPC_SHADOW_x509_rsa_ctx_to_pss +#define x509_rsa_pss_to_ctx GRPC_SHADOW_x509_rsa_pss_to_ctx +#define X509_CRL_print GRPC_SHADOW_X509_CRL_print +#define X509_CRL_print_fp GRPC_SHADOW_X509_CRL_print_fp +#define X509_REQ_print GRPC_SHADOW_X509_REQ_print +#define X509_REQ_print_ex GRPC_SHADOW_X509_REQ_print_ex +#define X509_REQ_print_fp GRPC_SHADOW_X509_REQ_print_fp +#define ASN1_GENERALIZEDTIME_print GRPC_SHADOW_ASN1_GENERALIZEDTIME_print +#define ASN1_STRING_print GRPC_SHADOW_ASN1_STRING_print +#define ASN1_TIME_print GRPC_SHADOW_ASN1_TIME_print +#define ASN1_UTCTIME_print GRPC_SHADOW_ASN1_UTCTIME_print +#define X509_NAME_print GRPC_SHADOW_X509_NAME_print +#define X509_ocspid_print GRPC_SHADOW_X509_ocspid_print +#define X509_print GRPC_SHADOW_X509_print +#define X509_print_ex GRPC_SHADOW_X509_print_ex +#define X509_print_ex_fp GRPC_SHADOW_X509_print_ex_fp +#define X509_print_fp GRPC_SHADOW_X509_print_fp +#define X509_signature_print GRPC_SHADOW_X509_signature_print +#define X509_CERT_AUX_print GRPC_SHADOW_X509_CERT_AUX_print +#define PKCS8_pkey_get0 GRPC_SHADOW_PKCS8_pkey_get0 +#define PKCS8_pkey_set0 GRPC_SHADOW_PKCS8_pkey_set0 +#define X509_signature_dump GRPC_SHADOW_X509_signature_dump +#define X509_ATTRIBUTE_count GRPC_SHADOW_X509_ATTRIBUTE_count +#define X509_ATTRIBUTE_create_by_NID GRPC_SHADOW_X509_ATTRIBUTE_create_by_NID +#define X509_ATTRIBUTE_create_by_OBJ GRPC_SHADOW_X509_ATTRIBUTE_create_by_OBJ +#define X509_ATTRIBUTE_create_by_txt GRPC_SHADOW_X509_ATTRIBUTE_create_by_txt +#define X509_ATTRIBUTE_get0_data GRPC_SHADOW_X509_ATTRIBUTE_get0_data +#define X509_ATTRIBUTE_get0_object GRPC_SHADOW_X509_ATTRIBUTE_get0_object +#define X509_ATTRIBUTE_get0_type GRPC_SHADOW_X509_ATTRIBUTE_get0_type +#define X509_ATTRIBUTE_set1_data GRPC_SHADOW_X509_ATTRIBUTE_set1_data +#define X509_ATTRIBUTE_set1_object GRPC_SHADOW_X509_ATTRIBUTE_set1_object +#define X509at_add1_attr GRPC_SHADOW_X509at_add1_attr +#define X509at_add1_attr_by_NID GRPC_SHADOW_X509at_add1_attr_by_NID +#define X509at_add1_attr_by_OBJ GRPC_SHADOW_X509at_add1_attr_by_OBJ +#define X509at_add1_attr_by_txt GRPC_SHADOW_X509at_add1_attr_by_txt +#define X509at_delete_attr GRPC_SHADOW_X509at_delete_attr +#define X509at_get0_data_by_OBJ GRPC_SHADOW_X509at_get0_data_by_OBJ +#define X509at_get_attr GRPC_SHADOW_X509at_get_attr +#define X509at_get_attr_by_NID GRPC_SHADOW_X509at_get_attr_by_NID +#define X509at_get_attr_by_OBJ GRPC_SHADOW_X509at_get_attr_by_OBJ +#define X509at_get_attr_count GRPC_SHADOW_X509at_get_attr_count +#define X509_CRL_check_suiteb GRPC_SHADOW_X509_CRL_check_suiteb +#define X509_CRL_cmp GRPC_SHADOW_X509_CRL_cmp +#define X509_CRL_match GRPC_SHADOW_X509_CRL_match +#define X509_NAME_cmp GRPC_SHADOW_X509_NAME_cmp +#define X509_NAME_hash GRPC_SHADOW_X509_NAME_hash +#define X509_NAME_hash_old GRPC_SHADOW_X509_NAME_hash_old +#define X509_chain_check_suiteb GRPC_SHADOW_X509_chain_check_suiteb +#define X509_chain_up_ref GRPC_SHADOW_X509_chain_up_ref +#define X509_check_private_key GRPC_SHADOW_X509_check_private_key +#define X509_cmp GRPC_SHADOW_X509_cmp +#define X509_find_by_issuer_and_serial GRPC_SHADOW_X509_find_by_issuer_and_serial +#define X509_find_by_subject GRPC_SHADOW_X509_find_by_subject +#define X509_get0_pubkey_bitstr GRPC_SHADOW_X509_get0_pubkey_bitstr +#define X509_get_issuer_name GRPC_SHADOW_X509_get_issuer_name +#define X509_get_pubkey GRPC_SHADOW_X509_get_pubkey +#define X509_get_serialNumber GRPC_SHADOW_X509_get_serialNumber +#define X509_get_subject_name GRPC_SHADOW_X509_get_subject_name +#define X509_issuer_and_serial_cmp GRPC_SHADOW_X509_issuer_and_serial_cmp +#define X509_issuer_and_serial_hash GRPC_SHADOW_X509_issuer_and_serial_hash +#define X509_issuer_name_cmp GRPC_SHADOW_X509_issuer_name_cmp +#define X509_issuer_name_hash GRPC_SHADOW_X509_issuer_name_hash +#define X509_issuer_name_hash_old GRPC_SHADOW_X509_issuer_name_hash_old +#define X509_subject_name_cmp GRPC_SHADOW_X509_subject_name_cmp +#define X509_subject_name_hash GRPC_SHADOW_X509_subject_name_hash +#define X509_subject_name_hash_old GRPC_SHADOW_X509_subject_name_hash_old +#define X509_STORE_load_locations GRPC_SHADOW_X509_STORE_load_locations +#define X509_STORE_set_default_paths GRPC_SHADOW_X509_STORE_set_default_paths +#define X509_get_default_cert_area GRPC_SHADOW_X509_get_default_cert_area +#define X509_get_default_cert_dir GRPC_SHADOW_X509_get_default_cert_dir +#define X509_get_default_cert_dir_env GRPC_SHADOW_X509_get_default_cert_dir_env +#define X509_get_default_cert_file GRPC_SHADOW_X509_get_default_cert_file +#define X509_get_default_cert_file_env GRPC_SHADOW_X509_get_default_cert_file_env +#define X509_get_default_private_dir GRPC_SHADOW_X509_get_default_private_dir +#define X509_CRL_add1_ext_i2d GRPC_SHADOW_X509_CRL_add1_ext_i2d +#define X509_CRL_add_ext GRPC_SHADOW_X509_CRL_add_ext +#define X509_CRL_delete_ext GRPC_SHADOW_X509_CRL_delete_ext +#define X509_CRL_get_ext GRPC_SHADOW_X509_CRL_get_ext +#define X509_CRL_get_ext_by_NID GRPC_SHADOW_X509_CRL_get_ext_by_NID +#define X509_CRL_get_ext_by_OBJ GRPC_SHADOW_X509_CRL_get_ext_by_OBJ +#define X509_CRL_get_ext_by_critical GRPC_SHADOW_X509_CRL_get_ext_by_critical +#define X509_CRL_get_ext_count GRPC_SHADOW_X509_CRL_get_ext_count +#define X509_CRL_get_ext_d2i GRPC_SHADOW_X509_CRL_get_ext_d2i +#define X509_REVOKED_add1_ext_i2d GRPC_SHADOW_X509_REVOKED_add1_ext_i2d +#define X509_REVOKED_add_ext GRPC_SHADOW_X509_REVOKED_add_ext +#define X509_REVOKED_delete_ext GRPC_SHADOW_X509_REVOKED_delete_ext +#define X509_REVOKED_get_ext GRPC_SHADOW_X509_REVOKED_get_ext +#define X509_REVOKED_get_ext_by_NID GRPC_SHADOW_X509_REVOKED_get_ext_by_NID +#define X509_REVOKED_get_ext_by_OBJ GRPC_SHADOW_X509_REVOKED_get_ext_by_OBJ +#define X509_REVOKED_get_ext_by_critical GRPC_SHADOW_X509_REVOKED_get_ext_by_critical +#define X509_REVOKED_get_ext_count GRPC_SHADOW_X509_REVOKED_get_ext_count +#define X509_REVOKED_get_ext_d2i GRPC_SHADOW_X509_REVOKED_get_ext_d2i +#define X509_add1_ext_i2d GRPC_SHADOW_X509_add1_ext_i2d +#define X509_add_ext GRPC_SHADOW_X509_add_ext +#define X509_delete_ext GRPC_SHADOW_X509_delete_ext +#define X509_get_ext GRPC_SHADOW_X509_get_ext +#define X509_get_ext_by_NID GRPC_SHADOW_X509_get_ext_by_NID +#define X509_get_ext_by_OBJ GRPC_SHADOW_X509_get_ext_by_OBJ +#define X509_get_ext_by_critical GRPC_SHADOW_X509_get_ext_by_critical +#define X509_get_ext_count GRPC_SHADOW_X509_get_ext_count +#define X509_get_ext_d2i GRPC_SHADOW_X509_get_ext_d2i +#define X509_LOOKUP_by_alias GRPC_SHADOW_X509_LOOKUP_by_alias +#define X509_LOOKUP_by_fingerprint GRPC_SHADOW_X509_LOOKUP_by_fingerprint +#define X509_LOOKUP_by_issuer_serial GRPC_SHADOW_X509_LOOKUP_by_issuer_serial +#define X509_LOOKUP_by_subject GRPC_SHADOW_X509_LOOKUP_by_subject +#define X509_LOOKUP_ctrl GRPC_SHADOW_X509_LOOKUP_ctrl +#define X509_LOOKUP_free GRPC_SHADOW_X509_LOOKUP_free +#define X509_LOOKUP_init GRPC_SHADOW_X509_LOOKUP_init +#define X509_LOOKUP_new GRPC_SHADOW_X509_LOOKUP_new +#define X509_LOOKUP_shutdown GRPC_SHADOW_X509_LOOKUP_shutdown +#define X509_OBJECT_free_contents GRPC_SHADOW_X509_OBJECT_free_contents +#define X509_OBJECT_get0_X509 GRPC_SHADOW_X509_OBJECT_get0_X509 +#define X509_OBJECT_get_type GRPC_SHADOW_X509_OBJECT_get_type +#define X509_OBJECT_idx_by_subject GRPC_SHADOW_X509_OBJECT_idx_by_subject +#define X509_OBJECT_retrieve_by_subject GRPC_SHADOW_X509_OBJECT_retrieve_by_subject +#define X509_OBJECT_retrieve_match GRPC_SHADOW_X509_OBJECT_retrieve_match +#define X509_OBJECT_up_ref_count GRPC_SHADOW_X509_OBJECT_up_ref_count +#define X509_STORE_CTX_get0_store GRPC_SHADOW_X509_STORE_CTX_get0_store +#define X509_STORE_CTX_get1_issuer GRPC_SHADOW_X509_STORE_CTX_get1_issuer +#define X509_STORE_add_cert GRPC_SHADOW_X509_STORE_add_cert +#define X509_STORE_add_crl GRPC_SHADOW_X509_STORE_add_crl +#define X509_STORE_add_lookup GRPC_SHADOW_X509_STORE_add_lookup +#define X509_STORE_free GRPC_SHADOW_X509_STORE_free +#define X509_STORE_get0_objects GRPC_SHADOW_X509_STORE_get0_objects +#define X509_STORE_get0_param GRPC_SHADOW_X509_STORE_get0_param +#define X509_STORE_get1_certs GRPC_SHADOW_X509_STORE_get1_certs +#define X509_STORE_get1_crls GRPC_SHADOW_X509_STORE_get1_crls +#define X509_STORE_get_by_subject GRPC_SHADOW_X509_STORE_get_by_subject +#define X509_STORE_new GRPC_SHADOW_X509_STORE_new +#define X509_STORE_set0_additional_untrusted GRPC_SHADOW_X509_STORE_set0_additional_untrusted +#define X509_STORE_set1_param GRPC_SHADOW_X509_STORE_set1_param +#define X509_STORE_set_depth GRPC_SHADOW_X509_STORE_set_depth +#define X509_STORE_set_flags GRPC_SHADOW_X509_STORE_set_flags +#define X509_STORE_set_lookup_crls_cb GRPC_SHADOW_X509_STORE_set_lookup_crls_cb +#define X509_STORE_set_purpose GRPC_SHADOW_X509_STORE_set_purpose +#define X509_STORE_set_trust GRPC_SHADOW_X509_STORE_set_trust +#define X509_STORE_set_verify_cb GRPC_SHADOW_X509_STORE_set_verify_cb +#define X509_STORE_up_ref GRPC_SHADOW_X509_STORE_up_ref +#define X509_NAME_oneline GRPC_SHADOW_X509_NAME_oneline +#define X509_REQ_to_X509 GRPC_SHADOW_X509_REQ_to_X509 +#define X509_REQ_add1_attr GRPC_SHADOW_X509_REQ_add1_attr +#define X509_REQ_add1_attr_by_NID GRPC_SHADOW_X509_REQ_add1_attr_by_NID +#define X509_REQ_add1_attr_by_OBJ GRPC_SHADOW_X509_REQ_add1_attr_by_OBJ +#define X509_REQ_add1_attr_by_txt GRPC_SHADOW_X509_REQ_add1_attr_by_txt +#define X509_REQ_add_extensions GRPC_SHADOW_X509_REQ_add_extensions +#define X509_REQ_add_extensions_nid GRPC_SHADOW_X509_REQ_add_extensions_nid +#define X509_REQ_check_private_key GRPC_SHADOW_X509_REQ_check_private_key +#define X509_REQ_delete_attr GRPC_SHADOW_X509_REQ_delete_attr +#define X509_REQ_extension_nid GRPC_SHADOW_X509_REQ_extension_nid +#define X509_REQ_get_attr GRPC_SHADOW_X509_REQ_get_attr +#define X509_REQ_get_attr_by_NID GRPC_SHADOW_X509_REQ_get_attr_by_NID +#define X509_REQ_get_attr_by_OBJ GRPC_SHADOW_X509_REQ_get_attr_by_OBJ +#define X509_REQ_get_attr_count GRPC_SHADOW_X509_REQ_get_attr_count +#define X509_REQ_get_extension_nids GRPC_SHADOW_X509_REQ_get_extension_nids +#define X509_REQ_get_extensions GRPC_SHADOW_X509_REQ_get_extensions +#define X509_REQ_get_pubkey GRPC_SHADOW_X509_REQ_get_pubkey +#define X509_REQ_set_extension_nids GRPC_SHADOW_X509_REQ_set_extension_nids +#define X509_to_X509_REQ GRPC_SHADOW_X509_to_X509_REQ +#define X509_get0_extensions GRPC_SHADOW_X509_get0_extensions +#define X509_get0_notAfter GRPC_SHADOW_X509_get0_notAfter +#define X509_get0_notBefore GRPC_SHADOW_X509_get0_notBefore +#define X509_set_issuer_name GRPC_SHADOW_X509_set_issuer_name +#define X509_set_notAfter GRPC_SHADOW_X509_set_notAfter +#define X509_set_notBefore GRPC_SHADOW_X509_set_notBefore +#define X509_set_pubkey GRPC_SHADOW_X509_set_pubkey +#define X509_set_serialNumber GRPC_SHADOW_X509_set_serialNumber +#define X509_set_subject_name GRPC_SHADOW_X509_set_subject_name +#define X509_set_version GRPC_SHADOW_X509_set_version +#define X509_TRUST_add GRPC_SHADOW_X509_TRUST_add +#define X509_TRUST_cleanup GRPC_SHADOW_X509_TRUST_cleanup +#define X509_TRUST_get0 GRPC_SHADOW_X509_TRUST_get0 +#define X509_TRUST_get0_name GRPC_SHADOW_X509_TRUST_get0_name +#define X509_TRUST_get_by_id GRPC_SHADOW_X509_TRUST_get_by_id +#define X509_TRUST_get_count GRPC_SHADOW_X509_TRUST_get_count +#define X509_TRUST_get_flags GRPC_SHADOW_X509_TRUST_get_flags +#define X509_TRUST_get_trust GRPC_SHADOW_X509_TRUST_get_trust +#define X509_TRUST_set GRPC_SHADOW_X509_TRUST_set +#define X509_TRUST_set_default GRPC_SHADOW_X509_TRUST_set_default +#define X509_check_trust GRPC_SHADOW_X509_check_trust +#define X509_verify_cert_error_string GRPC_SHADOW_X509_verify_cert_error_string +#define X509_EXTENSION_create_by_NID GRPC_SHADOW_X509_EXTENSION_create_by_NID +#define X509_EXTENSION_create_by_OBJ GRPC_SHADOW_X509_EXTENSION_create_by_OBJ +#define X509_EXTENSION_get_critical GRPC_SHADOW_X509_EXTENSION_get_critical +#define X509_EXTENSION_get_data GRPC_SHADOW_X509_EXTENSION_get_data +#define X509_EXTENSION_get_object GRPC_SHADOW_X509_EXTENSION_get_object +#define X509_EXTENSION_set_critical GRPC_SHADOW_X509_EXTENSION_set_critical +#define X509_EXTENSION_set_data GRPC_SHADOW_X509_EXTENSION_set_data +#define X509_EXTENSION_set_object GRPC_SHADOW_X509_EXTENSION_set_object +#define X509v3_add_ext GRPC_SHADOW_X509v3_add_ext +#define X509v3_delete_ext GRPC_SHADOW_X509v3_delete_ext +#define X509v3_get_ext GRPC_SHADOW_X509v3_get_ext +#define X509v3_get_ext_by_NID GRPC_SHADOW_X509v3_get_ext_by_NID +#define X509v3_get_ext_by_OBJ GRPC_SHADOW_X509v3_get_ext_by_OBJ +#define X509v3_get_ext_by_critical GRPC_SHADOW_X509v3_get_ext_by_critical +#define X509v3_get_ext_count GRPC_SHADOW_X509v3_get_ext_count +#define X509_CRL_diff GRPC_SHADOW_X509_CRL_diff +#define X509_STORE_CTX_cleanup GRPC_SHADOW_X509_STORE_CTX_cleanup +#define X509_STORE_CTX_free GRPC_SHADOW_X509_STORE_CTX_free +#define X509_STORE_CTX_get0_current_crl GRPC_SHADOW_X509_STORE_CTX_get0_current_crl +#define X509_STORE_CTX_get0_current_issuer GRPC_SHADOW_X509_STORE_CTX_get0_current_issuer +#define X509_STORE_CTX_get0_param GRPC_SHADOW_X509_STORE_CTX_get0_param +#define X509_STORE_CTX_get0_parent_ctx GRPC_SHADOW_X509_STORE_CTX_get0_parent_ctx +#define X509_STORE_CTX_get0_policy_tree GRPC_SHADOW_X509_STORE_CTX_get0_policy_tree +#define X509_STORE_CTX_get0_untrusted GRPC_SHADOW_X509_STORE_CTX_get0_untrusted +#define X509_STORE_CTX_get1_chain GRPC_SHADOW_X509_STORE_CTX_get1_chain +#define X509_STORE_CTX_get_chain GRPC_SHADOW_X509_STORE_CTX_get_chain +#define X509_STORE_CTX_get_current_cert GRPC_SHADOW_X509_STORE_CTX_get_current_cert +#define X509_STORE_CTX_get_error GRPC_SHADOW_X509_STORE_CTX_get_error +#define X509_STORE_CTX_get_error_depth GRPC_SHADOW_X509_STORE_CTX_get_error_depth +#define X509_STORE_CTX_get_ex_data GRPC_SHADOW_X509_STORE_CTX_get_ex_data +#define X509_STORE_CTX_get_ex_new_index GRPC_SHADOW_X509_STORE_CTX_get_ex_new_index +#define X509_STORE_CTX_get_explicit_policy GRPC_SHADOW_X509_STORE_CTX_get_explicit_policy +#define X509_STORE_CTX_init GRPC_SHADOW_X509_STORE_CTX_init +#define X509_STORE_CTX_new GRPC_SHADOW_X509_STORE_CTX_new +#define X509_STORE_CTX_purpose_inherit GRPC_SHADOW_X509_STORE_CTX_purpose_inherit +#define X509_STORE_CTX_set0_crls GRPC_SHADOW_X509_STORE_CTX_set0_crls +#define X509_STORE_CTX_set0_param GRPC_SHADOW_X509_STORE_CTX_set0_param +#define X509_STORE_CTX_set_cert GRPC_SHADOW_X509_STORE_CTX_set_cert +#define X509_STORE_CTX_set_chain GRPC_SHADOW_X509_STORE_CTX_set_chain +#define X509_STORE_CTX_set_default GRPC_SHADOW_X509_STORE_CTX_set_default +#define X509_STORE_CTX_set_depth GRPC_SHADOW_X509_STORE_CTX_set_depth +#define X509_STORE_CTX_set_error GRPC_SHADOW_X509_STORE_CTX_set_error +#define X509_STORE_CTX_set_ex_data GRPC_SHADOW_X509_STORE_CTX_set_ex_data +#define X509_STORE_CTX_set_flags GRPC_SHADOW_X509_STORE_CTX_set_flags +#define X509_STORE_CTX_set_purpose GRPC_SHADOW_X509_STORE_CTX_set_purpose +#define X509_STORE_CTX_set_time GRPC_SHADOW_X509_STORE_CTX_set_time +#define X509_STORE_CTX_set_trust GRPC_SHADOW_X509_STORE_CTX_set_trust +#define X509_STORE_CTX_set_verify_cb GRPC_SHADOW_X509_STORE_CTX_set_verify_cb +#define X509_STORE_CTX_trusted_stack GRPC_SHADOW_X509_STORE_CTX_trusted_stack +#define X509_STORE_CTX_zero GRPC_SHADOW_X509_STORE_CTX_zero +#define X509_cmp_current_time GRPC_SHADOW_X509_cmp_current_time +#define X509_cmp_time GRPC_SHADOW_X509_cmp_time +#define X509_gmtime_adj GRPC_SHADOW_X509_gmtime_adj +#define X509_time_adj GRPC_SHADOW_X509_time_adj +#define X509_time_adj_ex GRPC_SHADOW_X509_time_adj_ex +#define X509_verify_cert GRPC_SHADOW_X509_verify_cert +#define X509_VERIFY_PARAM_add0_policy GRPC_SHADOW_X509_VERIFY_PARAM_add0_policy +#define X509_VERIFY_PARAM_add0_table GRPC_SHADOW_X509_VERIFY_PARAM_add0_table +#define X509_VERIFY_PARAM_add1_host GRPC_SHADOW_X509_VERIFY_PARAM_add1_host +#define X509_VERIFY_PARAM_clear_flags GRPC_SHADOW_X509_VERIFY_PARAM_clear_flags +#define X509_VERIFY_PARAM_free GRPC_SHADOW_X509_VERIFY_PARAM_free +#define X509_VERIFY_PARAM_get0 GRPC_SHADOW_X509_VERIFY_PARAM_get0 +#define X509_VERIFY_PARAM_get0_name GRPC_SHADOW_X509_VERIFY_PARAM_get0_name +#define X509_VERIFY_PARAM_get0_peername GRPC_SHADOW_X509_VERIFY_PARAM_get0_peername +#define X509_VERIFY_PARAM_get_count GRPC_SHADOW_X509_VERIFY_PARAM_get_count +#define X509_VERIFY_PARAM_get_depth GRPC_SHADOW_X509_VERIFY_PARAM_get_depth +#define X509_VERIFY_PARAM_get_flags GRPC_SHADOW_X509_VERIFY_PARAM_get_flags +#define X509_VERIFY_PARAM_inherit GRPC_SHADOW_X509_VERIFY_PARAM_inherit +#define X509_VERIFY_PARAM_lookup GRPC_SHADOW_X509_VERIFY_PARAM_lookup +#define X509_VERIFY_PARAM_new GRPC_SHADOW_X509_VERIFY_PARAM_new +#define X509_VERIFY_PARAM_set1 GRPC_SHADOW_X509_VERIFY_PARAM_set1 +#define X509_VERIFY_PARAM_set1_email GRPC_SHADOW_X509_VERIFY_PARAM_set1_email +#define X509_VERIFY_PARAM_set1_host GRPC_SHADOW_X509_VERIFY_PARAM_set1_host +#define X509_VERIFY_PARAM_set1_ip GRPC_SHADOW_X509_VERIFY_PARAM_set1_ip +#define X509_VERIFY_PARAM_set1_ip_asc GRPC_SHADOW_X509_VERIFY_PARAM_set1_ip_asc +#define X509_VERIFY_PARAM_set1_name GRPC_SHADOW_X509_VERIFY_PARAM_set1_name +#define X509_VERIFY_PARAM_set1_policies GRPC_SHADOW_X509_VERIFY_PARAM_set1_policies +#define X509_VERIFY_PARAM_set_depth GRPC_SHADOW_X509_VERIFY_PARAM_set_depth +#define X509_VERIFY_PARAM_set_flags GRPC_SHADOW_X509_VERIFY_PARAM_set_flags +#define X509_VERIFY_PARAM_set_hostflags GRPC_SHADOW_X509_VERIFY_PARAM_set_hostflags +#define X509_VERIFY_PARAM_set_purpose GRPC_SHADOW_X509_VERIFY_PARAM_set_purpose +#define X509_VERIFY_PARAM_set_time GRPC_SHADOW_X509_VERIFY_PARAM_set_time +#define X509_VERIFY_PARAM_set_trust GRPC_SHADOW_X509_VERIFY_PARAM_set_trust +#define X509_VERIFY_PARAM_table_cleanup GRPC_SHADOW_X509_VERIFY_PARAM_table_cleanup +#define X509_CRL_set_issuer_name GRPC_SHADOW_X509_CRL_set_issuer_name +#define X509_CRL_set_lastUpdate GRPC_SHADOW_X509_CRL_set_lastUpdate +#define X509_CRL_set_nextUpdate GRPC_SHADOW_X509_CRL_set_nextUpdate +#define X509_CRL_set_version GRPC_SHADOW_X509_CRL_set_version +#define X509_CRL_sort GRPC_SHADOW_X509_CRL_sort +#define X509_CRL_up_ref GRPC_SHADOW_X509_CRL_up_ref +#define X509_REVOKED_set_revocationDate GRPC_SHADOW_X509_REVOKED_set_revocationDate +#define X509_REVOKED_set_serialNumber GRPC_SHADOW_X509_REVOKED_set_serialNumber +#define X509_NAME_ENTRY_create_by_NID GRPC_SHADOW_X509_NAME_ENTRY_create_by_NID +#define X509_NAME_ENTRY_create_by_OBJ GRPC_SHADOW_X509_NAME_ENTRY_create_by_OBJ +#define X509_NAME_ENTRY_create_by_txt GRPC_SHADOW_X509_NAME_ENTRY_create_by_txt +#define X509_NAME_ENTRY_get_data GRPC_SHADOW_X509_NAME_ENTRY_get_data +#define X509_NAME_ENTRY_get_object GRPC_SHADOW_X509_NAME_ENTRY_get_object +#define X509_NAME_ENTRY_set_data GRPC_SHADOW_X509_NAME_ENTRY_set_data +#define X509_NAME_ENTRY_set_object GRPC_SHADOW_X509_NAME_ENTRY_set_object +#define X509_NAME_add_entry GRPC_SHADOW_X509_NAME_add_entry +#define X509_NAME_add_entry_by_NID GRPC_SHADOW_X509_NAME_add_entry_by_NID +#define X509_NAME_add_entry_by_OBJ GRPC_SHADOW_X509_NAME_add_entry_by_OBJ +#define X509_NAME_add_entry_by_txt GRPC_SHADOW_X509_NAME_add_entry_by_txt +#define X509_NAME_delete_entry GRPC_SHADOW_X509_NAME_delete_entry +#define X509_NAME_entry_count GRPC_SHADOW_X509_NAME_entry_count +#define X509_NAME_get_entry GRPC_SHADOW_X509_NAME_get_entry +#define X509_NAME_get_index_by_NID GRPC_SHADOW_X509_NAME_get_index_by_NID +#define X509_NAME_get_index_by_OBJ GRPC_SHADOW_X509_NAME_get_index_by_OBJ +#define X509_NAME_get_text_by_NID GRPC_SHADOW_X509_NAME_get_text_by_NID +#define X509_NAME_get_text_by_OBJ GRPC_SHADOW_X509_NAME_get_text_by_OBJ +#define X509_REQ_set_pubkey GRPC_SHADOW_X509_REQ_set_pubkey +#define X509_REQ_set_subject_name GRPC_SHADOW_X509_REQ_set_subject_name +#define X509_REQ_set_version GRPC_SHADOW_X509_REQ_set_version +#define NETSCAPE_SPKI_b64_decode GRPC_SHADOW_NETSCAPE_SPKI_b64_decode +#define NETSCAPE_SPKI_b64_encode GRPC_SHADOW_NETSCAPE_SPKI_b64_encode +#define NETSCAPE_SPKI_get_pubkey GRPC_SHADOW_NETSCAPE_SPKI_get_pubkey +#define NETSCAPE_SPKI_set_pubkey GRPC_SHADOW_NETSCAPE_SPKI_set_pubkey +#define X509_ALGORS_it GRPC_SHADOW_X509_ALGORS_it +#define X509_ALGOR_cmp GRPC_SHADOW_X509_ALGOR_cmp +#define X509_ALGOR_dup GRPC_SHADOW_X509_ALGOR_dup +#define X509_ALGOR_free GRPC_SHADOW_X509_ALGOR_free +#define X509_ALGOR_get0 GRPC_SHADOW_X509_ALGOR_get0 +#define X509_ALGOR_it GRPC_SHADOW_X509_ALGOR_it +#define X509_ALGOR_new GRPC_SHADOW_X509_ALGOR_new +#define X509_ALGOR_set0 GRPC_SHADOW_X509_ALGOR_set0 +#define X509_ALGOR_set_md GRPC_SHADOW_X509_ALGOR_set_md +#define d2i_X509_ALGOR GRPC_SHADOW_d2i_X509_ALGOR +#define d2i_X509_ALGORS GRPC_SHADOW_d2i_X509_ALGORS +#define i2d_X509_ALGOR GRPC_SHADOW_i2d_X509_ALGOR +#define i2d_X509_ALGORS GRPC_SHADOW_i2d_X509_ALGORS +#define NETSCAPE_SPKI_sign GRPC_SHADOW_NETSCAPE_SPKI_sign +#define NETSCAPE_SPKI_verify GRPC_SHADOW_NETSCAPE_SPKI_verify +#define X509_CRL_digest GRPC_SHADOW_X509_CRL_digest +#define X509_CRL_sign GRPC_SHADOW_X509_CRL_sign +#define X509_CRL_sign_ctx GRPC_SHADOW_X509_CRL_sign_ctx +#define X509_NAME_digest GRPC_SHADOW_X509_NAME_digest +#define X509_REQ_digest GRPC_SHADOW_X509_REQ_digest +#define X509_REQ_sign GRPC_SHADOW_X509_REQ_sign +#define X509_REQ_sign_ctx GRPC_SHADOW_X509_REQ_sign_ctx +#define X509_REQ_verify GRPC_SHADOW_X509_REQ_verify +#define X509_digest GRPC_SHADOW_X509_digest +#define X509_pubkey_digest GRPC_SHADOW_X509_pubkey_digest +#define X509_sign GRPC_SHADOW_X509_sign +#define X509_sign_ctx GRPC_SHADOW_X509_sign_ctx +#define X509_verify GRPC_SHADOW_X509_verify +#define d2i_DSAPrivateKey_bio GRPC_SHADOW_d2i_DSAPrivateKey_bio +#define d2i_DSAPrivateKey_fp GRPC_SHADOW_d2i_DSAPrivateKey_fp +#define d2i_DSA_PUBKEY_bio GRPC_SHADOW_d2i_DSA_PUBKEY_bio +#define d2i_DSA_PUBKEY_fp GRPC_SHADOW_d2i_DSA_PUBKEY_fp +#define d2i_ECPrivateKey_bio GRPC_SHADOW_d2i_ECPrivateKey_bio +#define d2i_ECPrivateKey_fp GRPC_SHADOW_d2i_ECPrivateKey_fp +#define d2i_EC_PUBKEY_bio GRPC_SHADOW_d2i_EC_PUBKEY_bio +#define d2i_EC_PUBKEY_fp GRPC_SHADOW_d2i_EC_PUBKEY_fp +#define d2i_PKCS8_PRIV_KEY_INFO_bio GRPC_SHADOW_d2i_PKCS8_PRIV_KEY_INFO_bio +#define d2i_PKCS8_PRIV_KEY_INFO_fp GRPC_SHADOW_d2i_PKCS8_PRIV_KEY_INFO_fp +#define d2i_PKCS8_bio GRPC_SHADOW_d2i_PKCS8_bio +#define d2i_PKCS8_fp GRPC_SHADOW_d2i_PKCS8_fp +#define d2i_PUBKEY_bio GRPC_SHADOW_d2i_PUBKEY_bio +#define d2i_PUBKEY_fp GRPC_SHADOW_d2i_PUBKEY_fp +#define d2i_PrivateKey_bio GRPC_SHADOW_d2i_PrivateKey_bio +#define d2i_PrivateKey_fp GRPC_SHADOW_d2i_PrivateKey_fp +#define d2i_RSAPrivateKey_bio GRPC_SHADOW_d2i_RSAPrivateKey_bio +#define d2i_RSAPrivateKey_fp GRPC_SHADOW_d2i_RSAPrivateKey_fp +#define d2i_RSAPublicKey_bio GRPC_SHADOW_d2i_RSAPublicKey_bio +#define d2i_RSAPublicKey_fp GRPC_SHADOW_d2i_RSAPublicKey_fp +#define d2i_RSA_PUBKEY_bio GRPC_SHADOW_d2i_RSA_PUBKEY_bio +#define d2i_RSA_PUBKEY_fp GRPC_SHADOW_d2i_RSA_PUBKEY_fp +#define d2i_X509_CRL_bio GRPC_SHADOW_d2i_X509_CRL_bio +#define d2i_X509_CRL_fp GRPC_SHADOW_d2i_X509_CRL_fp +#define d2i_X509_REQ_bio GRPC_SHADOW_d2i_X509_REQ_bio +#define d2i_X509_REQ_fp GRPC_SHADOW_d2i_X509_REQ_fp +#define d2i_X509_bio GRPC_SHADOW_d2i_X509_bio +#define d2i_X509_fp GRPC_SHADOW_d2i_X509_fp +#define i2d_DSAPrivateKey_bio GRPC_SHADOW_i2d_DSAPrivateKey_bio +#define i2d_DSAPrivateKey_fp GRPC_SHADOW_i2d_DSAPrivateKey_fp +#define i2d_DSA_PUBKEY_bio GRPC_SHADOW_i2d_DSA_PUBKEY_bio +#define i2d_DSA_PUBKEY_fp GRPC_SHADOW_i2d_DSA_PUBKEY_fp +#define i2d_ECPrivateKey_bio GRPC_SHADOW_i2d_ECPrivateKey_bio +#define i2d_ECPrivateKey_fp GRPC_SHADOW_i2d_ECPrivateKey_fp +#define i2d_EC_PUBKEY_bio GRPC_SHADOW_i2d_EC_PUBKEY_bio +#define i2d_EC_PUBKEY_fp GRPC_SHADOW_i2d_EC_PUBKEY_fp +#define i2d_PKCS8PrivateKeyInfo_bio GRPC_SHADOW_i2d_PKCS8PrivateKeyInfo_bio +#define i2d_PKCS8PrivateKeyInfo_fp GRPC_SHADOW_i2d_PKCS8PrivateKeyInfo_fp +#define i2d_PKCS8_PRIV_KEY_INFO_bio GRPC_SHADOW_i2d_PKCS8_PRIV_KEY_INFO_bio +#define i2d_PKCS8_PRIV_KEY_INFO_fp GRPC_SHADOW_i2d_PKCS8_PRIV_KEY_INFO_fp +#define i2d_PKCS8_bio GRPC_SHADOW_i2d_PKCS8_bio +#define i2d_PKCS8_fp GRPC_SHADOW_i2d_PKCS8_fp +#define i2d_PUBKEY_bio GRPC_SHADOW_i2d_PUBKEY_bio +#define i2d_PUBKEY_fp GRPC_SHADOW_i2d_PUBKEY_fp +#define i2d_PrivateKey_bio GRPC_SHADOW_i2d_PrivateKey_bio +#define i2d_PrivateKey_fp GRPC_SHADOW_i2d_PrivateKey_fp +#define i2d_RSAPrivateKey_bio GRPC_SHADOW_i2d_RSAPrivateKey_bio +#define i2d_RSAPrivateKey_fp GRPC_SHADOW_i2d_RSAPrivateKey_fp +#define i2d_RSAPublicKey_bio GRPC_SHADOW_i2d_RSAPublicKey_bio +#define i2d_RSAPublicKey_fp GRPC_SHADOW_i2d_RSAPublicKey_fp +#define i2d_RSA_PUBKEY_bio GRPC_SHADOW_i2d_RSA_PUBKEY_bio +#define i2d_RSA_PUBKEY_fp GRPC_SHADOW_i2d_RSA_PUBKEY_fp +#define i2d_X509_CRL_bio GRPC_SHADOW_i2d_X509_CRL_bio +#define i2d_X509_CRL_fp GRPC_SHADOW_i2d_X509_CRL_fp +#define i2d_X509_REQ_bio GRPC_SHADOW_i2d_X509_REQ_bio +#define i2d_X509_REQ_fp GRPC_SHADOW_i2d_X509_REQ_fp +#define i2d_X509_bio GRPC_SHADOW_i2d_X509_bio +#define i2d_X509_fp GRPC_SHADOW_i2d_X509_fp +#define X509_ATTRIBUTE_SET_it GRPC_SHADOW_X509_ATTRIBUTE_SET_it +#define X509_ATTRIBUTE_create GRPC_SHADOW_X509_ATTRIBUTE_create +#define X509_ATTRIBUTE_dup GRPC_SHADOW_X509_ATTRIBUTE_dup +#define X509_ATTRIBUTE_free GRPC_SHADOW_X509_ATTRIBUTE_free +#define X509_ATTRIBUTE_it GRPC_SHADOW_X509_ATTRIBUTE_it +#define X509_ATTRIBUTE_new GRPC_SHADOW_X509_ATTRIBUTE_new +#define d2i_X509_ATTRIBUTE GRPC_SHADOW_d2i_X509_ATTRIBUTE +#define i2d_X509_ATTRIBUTE GRPC_SHADOW_i2d_X509_ATTRIBUTE +#define X509_CRL_INFO_free GRPC_SHADOW_X509_CRL_INFO_free +#define X509_CRL_INFO_it GRPC_SHADOW_X509_CRL_INFO_it +#define X509_CRL_INFO_new GRPC_SHADOW_X509_CRL_INFO_new +#define X509_CRL_METHOD_free GRPC_SHADOW_X509_CRL_METHOD_free +#define X509_CRL_METHOD_new GRPC_SHADOW_X509_CRL_METHOD_new +#define X509_CRL_add0_revoked GRPC_SHADOW_X509_CRL_add0_revoked +#define X509_CRL_dup GRPC_SHADOW_X509_CRL_dup +#define X509_CRL_free GRPC_SHADOW_X509_CRL_free +#define X509_CRL_get0_by_cert GRPC_SHADOW_X509_CRL_get0_by_cert +#define X509_CRL_get0_by_serial GRPC_SHADOW_X509_CRL_get0_by_serial +#define X509_CRL_get_meth_data GRPC_SHADOW_X509_CRL_get_meth_data +#define X509_CRL_it GRPC_SHADOW_X509_CRL_it +#define X509_CRL_new GRPC_SHADOW_X509_CRL_new +#define X509_CRL_set_default_method GRPC_SHADOW_X509_CRL_set_default_method +#define X509_CRL_set_meth_data GRPC_SHADOW_X509_CRL_set_meth_data +#define X509_CRL_verify GRPC_SHADOW_X509_CRL_verify +#define X509_REVOKED_dup GRPC_SHADOW_X509_REVOKED_dup +#define X509_REVOKED_free GRPC_SHADOW_X509_REVOKED_free +#define X509_REVOKED_it GRPC_SHADOW_X509_REVOKED_it +#define X509_REVOKED_new GRPC_SHADOW_X509_REVOKED_new +#define d2i_X509_CRL GRPC_SHADOW_d2i_X509_CRL +#define d2i_X509_CRL_INFO GRPC_SHADOW_d2i_X509_CRL_INFO +#define d2i_X509_REVOKED GRPC_SHADOW_d2i_X509_REVOKED +#define i2d_X509_CRL GRPC_SHADOW_i2d_X509_CRL +#define i2d_X509_CRL_INFO GRPC_SHADOW_i2d_X509_CRL_INFO +#define i2d_X509_REVOKED GRPC_SHADOW_i2d_X509_REVOKED +#define X509_EXTENSIONS_it GRPC_SHADOW_X509_EXTENSIONS_it +#define X509_EXTENSION_dup GRPC_SHADOW_X509_EXTENSION_dup +#define X509_EXTENSION_free GRPC_SHADOW_X509_EXTENSION_free +#define X509_EXTENSION_it GRPC_SHADOW_X509_EXTENSION_it +#define X509_EXTENSION_new GRPC_SHADOW_X509_EXTENSION_new +#define d2i_X509_EXTENSION GRPC_SHADOW_d2i_X509_EXTENSION +#define d2i_X509_EXTENSIONS GRPC_SHADOW_d2i_X509_EXTENSIONS +#define i2d_X509_EXTENSION GRPC_SHADOW_i2d_X509_EXTENSION +#define i2d_X509_EXTENSIONS GRPC_SHADOW_i2d_X509_EXTENSIONS +#define X509_INFO_free GRPC_SHADOW_X509_INFO_free +#define X509_INFO_new GRPC_SHADOW_X509_INFO_new +#define X509_NAME_ENTRIES_it GRPC_SHADOW_X509_NAME_ENTRIES_it +#define X509_NAME_ENTRY_dup GRPC_SHADOW_X509_NAME_ENTRY_dup +#define X509_NAME_ENTRY_free GRPC_SHADOW_X509_NAME_ENTRY_free +#define X509_NAME_ENTRY_it GRPC_SHADOW_X509_NAME_ENTRY_it +#define X509_NAME_ENTRY_new GRPC_SHADOW_X509_NAME_ENTRY_new +#define X509_NAME_ENTRY_set GRPC_SHADOW_X509_NAME_ENTRY_set +#define X509_NAME_INTERNAL_it GRPC_SHADOW_X509_NAME_INTERNAL_it +#define X509_NAME_dup GRPC_SHADOW_X509_NAME_dup +#define X509_NAME_free GRPC_SHADOW_X509_NAME_free +#define X509_NAME_get0_der GRPC_SHADOW_X509_NAME_get0_der +#define X509_NAME_it GRPC_SHADOW_X509_NAME_it +#define X509_NAME_new GRPC_SHADOW_X509_NAME_new +#define X509_NAME_set GRPC_SHADOW_X509_NAME_set +#define d2i_X509_NAME GRPC_SHADOW_d2i_X509_NAME +#define d2i_X509_NAME_ENTRY GRPC_SHADOW_d2i_X509_NAME_ENTRY +#define i2d_X509_NAME GRPC_SHADOW_i2d_X509_NAME +#define i2d_X509_NAME_ENTRY GRPC_SHADOW_i2d_X509_NAME_ENTRY +#define X509_PKEY_free GRPC_SHADOW_X509_PKEY_free +#define X509_PKEY_new GRPC_SHADOW_X509_PKEY_new +#define X509_PUBKEY_free GRPC_SHADOW_X509_PUBKEY_free +#define X509_PUBKEY_get GRPC_SHADOW_X509_PUBKEY_get +#define X509_PUBKEY_get0_param GRPC_SHADOW_X509_PUBKEY_get0_param +#define X509_PUBKEY_it GRPC_SHADOW_X509_PUBKEY_it +#define X509_PUBKEY_new GRPC_SHADOW_X509_PUBKEY_new +#define X509_PUBKEY_set GRPC_SHADOW_X509_PUBKEY_set +#define X509_PUBKEY_set0_param GRPC_SHADOW_X509_PUBKEY_set0_param +#define d2i_DSA_PUBKEY GRPC_SHADOW_d2i_DSA_PUBKEY +#define d2i_EC_PUBKEY GRPC_SHADOW_d2i_EC_PUBKEY +#define d2i_PUBKEY GRPC_SHADOW_d2i_PUBKEY +#define d2i_RSA_PUBKEY GRPC_SHADOW_d2i_RSA_PUBKEY +#define d2i_X509_PUBKEY GRPC_SHADOW_d2i_X509_PUBKEY +#define i2d_DSA_PUBKEY GRPC_SHADOW_i2d_DSA_PUBKEY +#define i2d_EC_PUBKEY GRPC_SHADOW_i2d_EC_PUBKEY +#define i2d_PUBKEY GRPC_SHADOW_i2d_PUBKEY +#define i2d_RSA_PUBKEY GRPC_SHADOW_i2d_RSA_PUBKEY +#define i2d_X509_PUBKEY GRPC_SHADOW_i2d_X509_PUBKEY +#define X509_REQ_INFO_free GRPC_SHADOW_X509_REQ_INFO_free +#define X509_REQ_INFO_it GRPC_SHADOW_X509_REQ_INFO_it +#define X509_REQ_INFO_new GRPC_SHADOW_X509_REQ_INFO_new +#define X509_REQ_dup GRPC_SHADOW_X509_REQ_dup +#define X509_REQ_free GRPC_SHADOW_X509_REQ_free +#define X509_REQ_it GRPC_SHADOW_X509_REQ_it +#define X509_REQ_new GRPC_SHADOW_X509_REQ_new +#define d2i_X509_REQ GRPC_SHADOW_d2i_X509_REQ +#define d2i_X509_REQ_INFO GRPC_SHADOW_d2i_X509_REQ_INFO +#define i2d_X509_REQ GRPC_SHADOW_i2d_X509_REQ +#define i2d_X509_REQ_INFO GRPC_SHADOW_i2d_X509_REQ_INFO +#define X509_SIG_free GRPC_SHADOW_X509_SIG_free +#define X509_SIG_it GRPC_SHADOW_X509_SIG_it +#define X509_SIG_new GRPC_SHADOW_X509_SIG_new +#define d2i_X509_SIG GRPC_SHADOW_d2i_X509_SIG +#define i2d_X509_SIG GRPC_SHADOW_i2d_X509_SIG +#define NETSCAPE_SPKAC_free GRPC_SHADOW_NETSCAPE_SPKAC_free +#define NETSCAPE_SPKAC_it GRPC_SHADOW_NETSCAPE_SPKAC_it +#define NETSCAPE_SPKAC_new GRPC_SHADOW_NETSCAPE_SPKAC_new +#define NETSCAPE_SPKI_free GRPC_SHADOW_NETSCAPE_SPKI_free +#define NETSCAPE_SPKI_it GRPC_SHADOW_NETSCAPE_SPKI_it +#define NETSCAPE_SPKI_new GRPC_SHADOW_NETSCAPE_SPKI_new +#define d2i_NETSCAPE_SPKAC GRPC_SHADOW_d2i_NETSCAPE_SPKAC +#define d2i_NETSCAPE_SPKI GRPC_SHADOW_d2i_NETSCAPE_SPKI +#define i2d_NETSCAPE_SPKAC GRPC_SHADOW_i2d_NETSCAPE_SPKAC +#define i2d_NETSCAPE_SPKI GRPC_SHADOW_i2d_NETSCAPE_SPKI +#define X509_VAL_free GRPC_SHADOW_X509_VAL_free +#define X509_VAL_it GRPC_SHADOW_X509_VAL_it +#define X509_VAL_new GRPC_SHADOW_X509_VAL_new +#define d2i_X509_VAL GRPC_SHADOW_d2i_X509_VAL +#define i2d_X509_VAL GRPC_SHADOW_i2d_X509_VAL +#define X509_CINF_free GRPC_SHADOW_X509_CINF_free +#define X509_CINF_it GRPC_SHADOW_X509_CINF_it +#define X509_CINF_new GRPC_SHADOW_X509_CINF_new +#define X509_dup GRPC_SHADOW_X509_dup +#define X509_free GRPC_SHADOW_X509_free +#define X509_get0_signature GRPC_SHADOW_X509_get0_signature +#define X509_get_ex_data GRPC_SHADOW_X509_get_ex_data +#define X509_get_ex_new_index GRPC_SHADOW_X509_get_ex_new_index +#define X509_get_signature_nid GRPC_SHADOW_X509_get_signature_nid +#define X509_it GRPC_SHADOW_X509_it +#define X509_new GRPC_SHADOW_X509_new +#define X509_parse_from_buffer GRPC_SHADOW_X509_parse_from_buffer +#define X509_set_ex_data GRPC_SHADOW_X509_set_ex_data +#define X509_up_ref GRPC_SHADOW_X509_up_ref +#define d2i_X509 GRPC_SHADOW_d2i_X509 +#define d2i_X509_AUX GRPC_SHADOW_d2i_X509_AUX +#define d2i_X509_CINF GRPC_SHADOW_d2i_X509_CINF +#define i2d_X509 GRPC_SHADOW_i2d_X509 +#define i2d_X509_AUX GRPC_SHADOW_i2d_X509_AUX +#define i2d_X509_CINF GRPC_SHADOW_i2d_X509_CINF +#define X509_CERT_AUX_free GRPC_SHADOW_X509_CERT_AUX_free +#define X509_CERT_AUX_it GRPC_SHADOW_X509_CERT_AUX_it +#define X509_CERT_AUX_new GRPC_SHADOW_X509_CERT_AUX_new +#define X509_add1_reject_object GRPC_SHADOW_X509_add1_reject_object +#define X509_add1_trust_object GRPC_SHADOW_X509_add1_trust_object +#define X509_alias_get0 GRPC_SHADOW_X509_alias_get0 +#define X509_alias_set1 GRPC_SHADOW_X509_alias_set1 +#define X509_keyid_get0 GRPC_SHADOW_X509_keyid_get0 +#define X509_keyid_set1 GRPC_SHADOW_X509_keyid_set1 +#define X509_reject_clear GRPC_SHADOW_X509_reject_clear +#define X509_trust_clear GRPC_SHADOW_X509_trust_clear +#define d2i_X509_CERT_AUX GRPC_SHADOW_d2i_X509_CERT_AUX +#define i2d_X509_CERT_AUX GRPC_SHADOW_i2d_X509_CERT_AUX +#define policy_cache_find_data GRPC_SHADOW_policy_cache_find_data +#define policy_cache_free GRPC_SHADOW_policy_cache_free +#define policy_cache_set GRPC_SHADOW_policy_cache_set +#define policy_data_free GRPC_SHADOW_policy_data_free +#define policy_data_new GRPC_SHADOW_policy_data_new +#define X509_policy_level_get0_node GRPC_SHADOW_X509_policy_level_get0_node +#define X509_policy_level_node_count GRPC_SHADOW_X509_policy_level_node_count +#define X509_policy_node_get0_parent GRPC_SHADOW_X509_policy_node_get0_parent +#define X509_policy_node_get0_policy GRPC_SHADOW_X509_policy_node_get0_policy +#define X509_policy_node_get0_qualifiers GRPC_SHADOW_X509_policy_node_get0_qualifiers +#define X509_policy_tree_get0_level GRPC_SHADOW_X509_policy_tree_get0_level +#define X509_policy_tree_get0_policies GRPC_SHADOW_X509_policy_tree_get0_policies +#define X509_policy_tree_get0_user_policies GRPC_SHADOW_X509_policy_tree_get0_user_policies +#define X509_policy_tree_level_count GRPC_SHADOW_X509_policy_tree_level_count +#define policy_cache_set_mapping GRPC_SHADOW_policy_cache_set_mapping +#define level_add_node GRPC_SHADOW_level_add_node +#define level_find_node GRPC_SHADOW_level_find_node +#define policy_node_cmp_new GRPC_SHADOW_policy_node_cmp_new +#define policy_node_free GRPC_SHADOW_policy_node_free +#define policy_node_match GRPC_SHADOW_policy_node_match +#define tree_find_sk GRPC_SHADOW_tree_find_sk +#define X509_policy_check GRPC_SHADOW_X509_policy_check +#define X509_policy_tree_free GRPC_SHADOW_X509_policy_tree_free +#define v3_akey_id GRPC_SHADOW_v3_akey_id +#define AUTHORITY_KEYID_free GRPC_SHADOW_AUTHORITY_KEYID_free +#define AUTHORITY_KEYID_it GRPC_SHADOW_AUTHORITY_KEYID_it +#define AUTHORITY_KEYID_new GRPC_SHADOW_AUTHORITY_KEYID_new +#define d2i_AUTHORITY_KEYID GRPC_SHADOW_d2i_AUTHORITY_KEYID +#define i2d_AUTHORITY_KEYID GRPC_SHADOW_i2d_AUTHORITY_KEYID +#define GENERAL_NAME_print GRPC_SHADOW_GENERAL_NAME_print +#define a2i_GENERAL_NAME GRPC_SHADOW_a2i_GENERAL_NAME +#define i2v_GENERAL_NAME GRPC_SHADOW_i2v_GENERAL_NAME +#define i2v_GENERAL_NAMES GRPC_SHADOW_i2v_GENERAL_NAMES +#define v2i_GENERAL_NAME GRPC_SHADOW_v2i_GENERAL_NAME +#define v2i_GENERAL_NAMES GRPC_SHADOW_v2i_GENERAL_NAMES +#define v2i_GENERAL_NAME_ex GRPC_SHADOW_v2i_GENERAL_NAME_ex +#define v3_alt GRPC_SHADOW_v3_alt +#define BASIC_CONSTRAINTS_free GRPC_SHADOW_BASIC_CONSTRAINTS_free +#define BASIC_CONSTRAINTS_it GRPC_SHADOW_BASIC_CONSTRAINTS_it +#define BASIC_CONSTRAINTS_new GRPC_SHADOW_BASIC_CONSTRAINTS_new +#define d2i_BASIC_CONSTRAINTS GRPC_SHADOW_d2i_BASIC_CONSTRAINTS +#define i2d_BASIC_CONSTRAINTS GRPC_SHADOW_i2d_BASIC_CONSTRAINTS +#define v3_bcons GRPC_SHADOW_v3_bcons +#define i2v_ASN1_BIT_STRING GRPC_SHADOW_i2v_ASN1_BIT_STRING +#define v2i_ASN1_BIT_STRING GRPC_SHADOW_v2i_ASN1_BIT_STRING +#define v3_key_usage GRPC_SHADOW_v3_key_usage +#define v3_nscert GRPC_SHADOW_v3_nscert +#define X509V3_EXT_CRL_add_nconf GRPC_SHADOW_X509V3_EXT_CRL_add_nconf +#define X509V3_EXT_REQ_add_nconf GRPC_SHADOW_X509V3_EXT_REQ_add_nconf +#define X509V3_EXT_add_nconf GRPC_SHADOW_X509V3_EXT_add_nconf +#define X509V3_EXT_add_nconf_sk GRPC_SHADOW_X509V3_EXT_add_nconf_sk +#define X509V3_EXT_i2d GRPC_SHADOW_X509V3_EXT_i2d +#define X509V3_EXT_nconf GRPC_SHADOW_X509V3_EXT_nconf +#define X509V3_EXT_nconf_nid GRPC_SHADOW_X509V3_EXT_nconf_nid +#define X509V3_get_section GRPC_SHADOW_X509V3_get_section +#define X509V3_get_string GRPC_SHADOW_X509V3_get_string +#define X509V3_section_free GRPC_SHADOW_X509V3_section_free +#define X509V3_set_ctx GRPC_SHADOW_X509V3_set_ctx +#define X509V3_set_nconf GRPC_SHADOW_X509V3_set_nconf +#define X509V3_string_free GRPC_SHADOW_X509V3_string_free +#define CERTIFICATEPOLICIES_free GRPC_SHADOW_CERTIFICATEPOLICIES_free +#define CERTIFICATEPOLICIES_it GRPC_SHADOW_CERTIFICATEPOLICIES_it +#define CERTIFICATEPOLICIES_new GRPC_SHADOW_CERTIFICATEPOLICIES_new +#define NOTICEREF_free GRPC_SHADOW_NOTICEREF_free +#define NOTICEREF_it GRPC_SHADOW_NOTICEREF_it +#define NOTICEREF_new GRPC_SHADOW_NOTICEREF_new +#define POLICYINFO_free GRPC_SHADOW_POLICYINFO_free +#define POLICYINFO_it GRPC_SHADOW_POLICYINFO_it +#define POLICYINFO_new GRPC_SHADOW_POLICYINFO_new +#define POLICYQUALINFO_free GRPC_SHADOW_POLICYQUALINFO_free +#define POLICYQUALINFO_it GRPC_SHADOW_POLICYQUALINFO_it +#define POLICYQUALINFO_new GRPC_SHADOW_POLICYQUALINFO_new +#define USERNOTICE_free GRPC_SHADOW_USERNOTICE_free +#define USERNOTICE_it GRPC_SHADOW_USERNOTICE_it +#define USERNOTICE_new GRPC_SHADOW_USERNOTICE_new +#define X509_POLICY_NODE_print GRPC_SHADOW_X509_POLICY_NODE_print +#define d2i_CERTIFICATEPOLICIES GRPC_SHADOW_d2i_CERTIFICATEPOLICIES +#define d2i_NOTICEREF GRPC_SHADOW_d2i_NOTICEREF +#define d2i_POLICYINFO GRPC_SHADOW_d2i_POLICYINFO +#define d2i_POLICYQUALINFO GRPC_SHADOW_d2i_POLICYQUALINFO +#define d2i_USERNOTICE GRPC_SHADOW_d2i_USERNOTICE +#define i2d_CERTIFICATEPOLICIES GRPC_SHADOW_i2d_CERTIFICATEPOLICIES +#define i2d_NOTICEREF GRPC_SHADOW_i2d_NOTICEREF +#define i2d_POLICYINFO GRPC_SHADOW_i2d_POLICYINFO +#define i2d_POLICYQUALINFO GRPC_SHADOW_i2d_POLICYQUALINFO +#define i2d_USERNOTICE GRPC_SHADOW_i2d_USERNOTICE +#define v3_cpols GRPC_SHADOW_v3_cpols +#define CRL_DIST_POINTS_free GRPC_SHADOW_CRL_DIST_POINTS_free +#define CRL_DIST_POINTS_it GRPC_SHADOW_CRL_DIST_POINTS_it +#define CRL_DIST_POINTS_new GRPC_SHADOW_CRL_DIST_POINTS_new +#define DIST_POINT_NAME_free GRPC_SHADOW_DIST_POINT_NAME_free +#define DIST_POINT_NAME_it GRPC_SHADOW_DIST_POINT_NAME_it +#define DIST_POINT_NAME_new GRPC_SHADOW_DIST_POINT_NAME_new +#define DIST_POINT_free GRPC_SHADOW_DIST_POINT_free +#define DIST_POINT_it GRPC_SHADOW_DIST_POINT_it +#define DIST_POINT_new GRPC_SHADOW_DIST_POINT_new +#define DIST_POINT_set_dpname GRPC_SHADOW_DIST_POINT_set_dpname +#define ISSUING_DIST_POINT_free GRPC_SHADOW_ISSUING_DIST_POINT_free +#define ISSUING_DIST_POINT_it GRPC_SHADOW_ISSUING_DIST_POINT_it +#define ISSUING_DIST_POINT_new GRPC_SHADOW_ISSUING_DIST_POINT_new +#define d2i_CRL_DIST_POINTS GRPC_SHADOW_d2i_CRL_DIST_POINTS +#define d2i_DIST_POINT GRPC_SHADOW_d2i_DIST_POINT +#define d2i_DIST_POINT_NAME GRPC_SHADOW_d2i_DIST_POINT_NAME +#define d2i_ISSUING_DIST_POINT GRPC_SHADOW_d2i_ISSUING_DIST_POINT +#define i2d_CRL_DIST_POINTS GRPC_SHADOW_i2d_CRL_DIST_POINTS +#define i2d_DIST_POINT GRPC_SHADOW_i2d_DIST_POINT +#define i2d_DIST_POINT_NAME GRPC_SHADOW_i2d_DIST_POINT_NAME +#define i2d_ISSUING_DIST_POINT GRPC_SHADOW_i2d_ISSUING_DIST_POINT +#define v3_crld GRPC_SHADOW_v3_crld +#define v3_freshest_crl GRPC_SHADOW_v3_freshest_crl +#define v3_idp GRPC_SHADOW_v3_idp +#define i2s_ASN1_ENUMERATED_TABLE GRPC_SHADOW_i2s_ASN1_ENUMERATED_TABLE +#define v3_crl_reason GRPC_SHADOW_v3_crl_reason +#define EXTENDED_KEY_USAGE_free GRPC_SHADOW_EXTENDED_KEY_USAGE_free +#define EXTENDED_KEY_USAGE_it GRPC_SHADOW_EXTENDED_KEY_USAGE_it +#define EXTENDED_KEY_USAGE_new GRPC_SHADOW_EXTENDED_KEY_USAGE_new +#define d2i_EXTENDED_KEY_USAGE GRPC_SHADOW_d2i_EXTENDED_KEY_USAGE +#define i2d_EXTENDED_KEY_USAGE GRPC_SHADOW_i2d_EXTENDED_KEY_USAGE +#define v3_ext_ku GRPC_SHADOW_v3_ext_ku +#define v3_ocsp_accresp GRPC_SHADOW_v3_ocsp_accresp +#define EDIPARTYNAME_free GRPC_SHADOW_EDIPARTYNAME_free +#define EDIPARTYNAME_it GRPC_SHADOW_EDIPARTYNAME_it +#define EDIPARTYNAME_new GRPC_SHADOW_EDIPARTYNAME_new +#define GENERAL_NAMES_free GRPC_SHADOW_GENERAL_NAMES_free +#define GENERAL_NAMES_it GRPC_SHADOW_GENERAL_NAMES_it +#define GENERAL_NAMES_new GRPC_SHADOW_GENERAL_NAMES_new +#define GENERAL_NAME_cmp GRPC_SHADOW_GENERAL_NAME_cmp +#define GENERAL_NAME_dup GRPC_SHADOW_GENERAL_NAME_dup +#define GENERAL_NAME_free GRPC_SHADOW_GENERAL_NAME_free +#define GENERAL_NAME_get0_otherName GRPC_SHADOW_GENERAL_NAME_get0_otherName +#define GENERAL_NAME_get0_value GRPC_SHADOW_GENERAL_NAME_get0_value +#define GENERAL_NAME_it GRPC_SHADOW_GENERAL_NAME_it +#define GENERAL_NAME_new GRPC_SHADOW_GENERAL_NAME_new +#define GENERAL_NAME_set0_othername GRPC_SHADOW_GENERAL_NAME_set0_othername +#define GENERAL_NAME_set0_value GRPC_SHADOW_GENERAL_NAME_set0_value +#define OTHERNAME_cmp GRPC_SHADOW_OTHERNAME_cmp +#define OTHERNAME_free GRPC_SHADOW_OTHERNAME_free +#define OTHERNAME_it GRPC_SHADOW_OTHERNAME_it +#define OTHERNAME_new GRPC_SHADOW_OTHERNAME_new +#define d2i_EDIPARTYNAME GRPC_SHADOW_d2i_EDIPARTYNAME +#define d2i_GENERAL_NAME GRPC_SHADOW_d2i_GENERAL_NAME +#define d2i_GENERAL_NAMES GRPC_SHADOW_d2i_GENERAL_NAMES +#define d2i_OTHERNAME GRPC_SHADOW_d2i_OTHERNAME +#define i2d_EDIPARTYNAME GRPC_SHADOW_i2d_EDIPARTYNAME +#define i2d_GENERAL_NAME GRPC_SHADOW_i2d_GENERAL_NAME +#define i2d_GENERAL_NAMES GRPC_SHADOW_i2d_GENERAL_NAMES +#define i2d_OTHERNAME GRPC_SHADOW_i2d_OTHERNAME +#define v3_ns_ia5_list GRPC_SHADOW_v3_ns_ia5_list +#define ACCESS_DESCRIPTION_free GRPC_SHADOW_ACCESS_DESCRIPTION_free +#define ACCESS_DESCRIPTION_it GRPC_SHADOW_ACCESS_DESCRIPTION_it +#define ACCESS_DESCRIPTION_new GRPC_SHADOW_ACCESS_DESCRIPTION_new +#define AUTHORITY_INFO_ACCESS_free GRPC_SHADOW_AUTHORITY_INFO_ACCESS_free +#define AUTHORITY_INFO_ACCESS_it GRPC_SHADOW_AUTHORITY_INFO_ACCESS_it +#define AUTHORITY_INFO_ACCESS_new GRPC_SHADOW_AUTHORITY_INFO_ACCESS_new +#define d2i_ACCESS_DESCRIPTION GRPC_SHADOW_d2i_ACCESS_DESCRIPTION +#define d2i_AUTHORITY_INFO_ACCESS GRPC_SHADOW_d2i_AUTHORITY_INFO_ACCESS +#define i2a_ACCESS_DESCRIPTION GRPC_SHADOW_i2a_ACCESS_DESCRIPTION +#define i2d_ACCESS_DESCRIPTION GRPC_SHADOW_i2d_ACCESS_DESCRIPTION +#define i2d_AUTHORITY_INFO_ACCESS GRPC_SHADOW_i2d_AUTHORITY_INFO_ACCESS +#define v3_info GRPC_SHADOW_v3_info +#define v3_sinfo GRPC_SHADOW_v3_sinfo +#define v3_crl_num GRPC_SHADOW_v3_crl_num +#define v3_delta_crl GRPC_SHADOW_v3_delta_crl +#define v3_inhibit_anyp GRPC_SHADOW_v3_inhibit_anyp +#define X509V3_EXT_add GRPC_SHADOW_X509V3_EXT_add +#define X509V3_EXT_add_alias GRPC_SHADOW_X509V3_EXT_add_alias +#define X509V3_EXT_add_list GRPC_SHADOW_X509V3_EXT_add_list +#define X509V3_EXT_cleanup GRPC_SHADOW_X509V3_EXT_cleanup +#define X509V3_EXT_d2i GRPC_SHADOW_X509V3_EXT_d2i +#define X509V3_EXT_free GRPC_SHADOW_X509V3_EXT_free +#define X509V3_EXT_get GRPC_SHADOW_X509V3_EXT_get +#define X509V3_EXT_get_nid GRPC_SHADOW_X509V3_EXT_get_nid +#define X509V3_add1_i2d GRPC_SHADOW_X509V3_add1_i2d +#define X509V3_add_standard_extensions GRPC_SHADOW_X509V3_add_standard_extensions +#define X509V3_get_d2i GRPC_SHADOW_X509V3_get_d2i +#define GENERAL_SUBTREE_free GRPC_SHADOW_GENERAL_SUBTREE_free +#define GENERAL_SUBTREE_it GRPC_SHADOW_GENERAL_SUBTREE_it +#define GENERAL_SUBTREE_new GRPC_SHADOW_GENERAL_SUBTREE_new +#define NAME_CONSTRAINTS_check GRPC_SHADOW_NAME_CONSTRAINTS_check +#define NAME_CONSTRAINTS_free GRPC_SHADOW_NAME_CONSTRAINTS_free +#define NAME_CONSTRAINTS_it GRPC_SHADOW_NAME_CONSTRAINTS_it +#define NAME_CONSTRAINTS_new GRPC_SHADOW_NAME_CONSTRAINTS_new +#define v3_name_constraints GRPC_SHADOW_v3_name_constraints +#define v3_pci GRPC_SHADOW_v3_pci +#define PROXY_CERT_INFO_EXTENSION_free GRPC_SHADOW_PROXY_CERT_INFO_EXTENSION_free +#define PROXY_CERT_INFO_EXTENSION_it GRPC_SHADOW_PROXY_CERT_INFO_EXTENSION_it +#define PROXY_CERT_INFO_EXTENSION_new GRPC_SHADOW_PROXY_CERT_INFO_EXTENSION_new +#define PROXY_POLICY_free GRPC_SHADOW_PROXY_POLICY_free +#define PROXY_POLICY_it GRPC_SHADOW_PROXY_POLICY_it +#define PROXY_POLICY_new GRPC_SHADOW_PROXY_POLICY_new +#define d2i_PROXY_CERT_INFO_EXTENSION GRPC_SHADOW_d2i_PROXY_CERT_INFO_EXTENSION +#define d2i_PROXY_POLICY GRPC_SHADOW_d2i_PROXY_POLICY +#define i2d_PROXY_CERT_INFO_EXTENSION GRPC_SHADOW_i2d_PROXY_CERT_INFO_EXTENSION +#define i2d_PROXY_POLICY GRPC_SHADOW_i2d_PROXY_POLICY +#define POLICY_CONSTRAINTS_free GRPC_SHADOW_POLICY_CONSTRAINTS_free +#define POLICY_CONSTRAINTS_it GRPC_SHADOW_POLICY_CONSTRAINTS_it +#define POLICY_CONSTRAINTS_new GRPC_SHADOW_POLICY_CONSTRAINTS_new +#define v3_policy_constraints GRPC_SHADOW_v3_policy_constraints +#define PKEY_USAGE_PERIOD_free GRPC_SHADOW_PKEY_USAGE_PERIOD_free +#define PKEY_USAGE_PERIOD_it GRPC_SHADOW_PKEY_USAGE_PERIOD_it +#define PKEY_USAGE_PERIOD_new GRPC_SHADOW_PKEY_USAGE_PERIOD_new +#define d2i_PKEY_USAGE_PERIOD GRPC_SHADOW_d2i_PKEY_USAGE_PERIOD +#define i2d_PKEY_USAGE_PERIOD GRPC_SHADOW_i2d_PKEY_USAGE_PERIOD +#define v3_pkey_usage_period GRPC_SHADOW_v3_pkey_usage_period +#define POLICY_MAPPINGS_it GRPC_SHADOW_POLICY_MAPPINGS_it +#define POLICY_MAPPING_free GRPC_SHADOW_POLICY_MAPPING_free +#define POLICY_MAPPING_it GRPC_SHADOW_POLICY_MAPPING_it +#define POLICY_MAPPING_new GRPC_SHADOW_POLICY_MAPPING_new +#define v3_policy_mappings GRPC_SHADOW_v3_policy_mappings +#define X509V3_EXT_print GRPC_SHADOW_X509V3_EXT_print +#define X509V3_EXT_print_fp GRPC_SHADOW_X509V3_EXT_print_fp +#define X509V3_EXT_val_prn GRPC_SHADOW_X509V3_EXT_val_prn +#define X509V3_extensions_print GRPC_SHADOW_X509V3_extensions_print +#define X509_PURPOSE_add GRPC_SHADOW_X509_PURPOSE_add +#define X509_PURPOSE_cleanup GRPC_SHADOW_X509_PURPOSE_cleanup +#define X509_PURPOSE_get0 GRPC_SHADOW_X509_PURPOSE_get0 +#define X509_PURPOSE_get0_name GRPC_SHADOW_X509_PURPOSE_get0_name +#define X509_PURPOSE_get0_sname GRPC_SHADOW_X509_PURPOSE_get0_sname +#define X509_PURPOSE_get_by_id GRPC_SHADOW_X509_PURPOSE_get_by_id +#define X509_PURPOSE_get_by_sname GRPC_SHADOW_X509_PURPOSE_get_by_sname +#define X509_PURPOSE_get_count GRPC_SHADOW_X509_PURPOSE_get_count +#define X509_PURPOSE_get_id GRPC_SHADOW_X509_PURPOSE_get_id +#define X509_PURPOSE_get_trust GRPC_SHADOW_X509_PURPOSE_get_trust +#define X509_PURPOSE_set GRPC_SHADOW_X509_PURPOSE_set +#define X509_check_akid GRPC_SHADOW_X509_check_akid +#define X509_check_ca GRPC_SHADOW_X509_check_ca +#define X509_check_issued GRPC_SHADOW_X509_check_issued +#define X509_check_purpose GRPC_SHADOW_X509_check_purpose +#define X509_supported_extension GRPC_SHADOW_X509_supported_extension +#define i2s_ASN1_OCTET_STRING GRPC_SHADOW_i2s_ASN1_OCTET_STRING +#define s2i_ASN1_OCTET_STRING GRPC_SHADOW_s2i_ASN1_OCTET_STRING +#define v3_skey_id GRPC_SHADOW_v3_skey_id +#define SXNETID_free GRPC_SHADOW_SXNETID_free +#define SXNETID_it GRPC_SHADOW_SXNETID_it +#define SXNETID_new GRPC_SHADOW_SXNETID_new +#define SXNET_add_id_INTEGER GRPC_SHADOW_SXNET_add_id_INTEGER +#define SXNET_add_id_asc GRPC_SHADOW_SXNET_add_id_asc +#define SXNET_add_id_ulong GRPC_SHADOW_SXNET_add_id_ulong +#define SXNET_free GRPC_SHADOW_SXNET_free +#define SXNET_get_id_INTEGER GRPC_SHADOW_SXNET_get_id_INTEGER +#define SXNET_get_id_asc GRPC_SHADOW_SXNET_get_id_asc +#define SXNET_get_id_ulong GRPC_SHADOW_SXNET_get_id_ulong +#define SXNET_it GRPC_SHADOW_SXNET_it +#define SXNET_new GRPC_SHADOW_SXNET_new +#define d2i_SXNET GRPC_SHADOW_d2i_SXNET +#define d2i_SXNETID GRPC_SHADOW_d2i_SXNETID +#define i2d_SXNET GRPC_SHADOW_i2d_SXNET +#define i2d_SXNETID GRPC_SHADOW_i2d_SXNETID +#define v3_sxnet GRPC_SHADOW_v3_sxnet +#define X509V3_NAME_from_section GRPC_SHADOW_X509V3_NAME_from_section +#define X509V3_add_value GRPC_SHADOW_X509V3_add_value +#define X509V3_add_value_bool GRPC_SHADOW_X509V3_add_value_bool +#define X509V3_add_value_bool_nf GRPC_SHADOW_X509V3_add_value_bool_nf +#define X509V3_add_value_int GRPC_SHADOW_X509V3_add_value_int +#define X509V3_add_value_uchar GRPC_SHADOW_X509V3_add_value_uchar +#define X509V3_conf_free GRPC_SHADOW_X509V3_conf_free +#define X509V3_get_value_bool GRPC_SHADOW_X509V3_get_value_bool +#define X509V3_get_value_int GRPC_SHADOW_X509V3_get_value_int +#define X509V3_parse_list GRPC_SHADOW_X509V3_parse_list +#define X509_REQ_get1_email GRPC_SHADOW_X509_REQ_get1_email +#define X509_check_email GRPC_SHADOW_X509_check_email +#define X509_check_host GRPC_SHADOW_X509_check_host +#define X509_check_ip GRPC_SHADOW_X509_check_ip +#define X509_check_ip_asc GRPC_SHADOW_X509_check_ip_asc +#define X509_email_free GRPC_SHADOW_X509_email_free +#define X509_get1_email GRPC_SHADOW_X509_get1_email +#define X509_get1_ocsp GRPC_SHADOW_X509_get1_ocsp +#define a2i_IPADDRESS GRPC_SHADOW_a2i_IPADDRESS +#define a2i_IPADDRESS_NC GRPC_SHADOW_a2i_IPADDRESS_NC +#define a2i_ipadd GRPC_SHADOW_a2i_ipadd +#define hex_to_string GRPC_SHADOW_hex_to_string +#define i2s_ASN1_ENUMERATED GRPC_SHADOW_i2s_ASN1_ENUMERATED +#define i2s_ASN1_INTEGER GRPC_SHADOW_i2s_ASN1_INTEGER +#define name_cmp GRPC_SHADOW_name_cmp +#define s2i_ASN1_INTEGER GRPC_SHADOW_s2i_ASN1_INTEGER +#define string_to_hex GRPC_SHADOW_string_to_hex +#define PKCS7_get_raw_certificates GRPC_SHADOW_PKCS7_get_raw_certificates +#define pkcs7_bundle GRPC_SHADOW_pkcs7_bundle +#define pkcs7_parse_header GRPC_SHADOW_pkcs7_parse_header +#define PKCS7_bundle_CRLs GRPC_SHADOW_PKCS7_bundle_CRLs +#define PKCS7_bundle_certificates GRPC_SHADOW_PKCS7_bundle_certificates +#define PKCS7_get_CRLs GRPC_SHADOW_PKCS7_get_CRLs +#define PKCS7_get_PEM_CRLs GRPC_SHADOW_PKCS7_get_PEM_CRLs +#define PKCS7_get_PEM_certificates GRPC_SHADOW_PKCS7_get_PEM_certificates +#define PKCS7_get_certificates GRPC_SHADOW_PKCS7_get_certificates +#define PKCS8_marshal_encrypted_private_key GRPC_SHADOW_PKCS8_marshal_encrypted_private_key +#define PKCS8_parse_encrypted_private_key GRPC_SHADOW_PKCS8_parse_encrypted_private_key +#define pkcs12_key_gen GRPC_SHADOW_pkcs12_key_gen +#define pkcs8_pbe_decrypt GRPC_SHADOW_pkcs8_pbe_decrypt +#define EVP_PKCS82PKEY GRPC_SHADOW_EVP_PKCS82PKEY +#define EVP_PKEY2PKCS8 GRPC_SHADOW_EVP_PKEY2PKCS8 +#define PKCS12_PBE_add GRPC_SHADOW_PKCS12_PBE_add +#define PKCS12_free GRPC_SHADOW_PKCS12_free +#define PKCS12_get_key_and_certs GRPC_SHADOW_PKCS12_get_key_and_certs +#define PKCS12_parse GRPC_SHADOW_PKCS12_parse +#define PKCS12_verify_mac GRPC_SHADOW_PKCS12_verify_mac +#define PKCS8_PRIV_KEY_INFO_free GRPC_SHADOW_PKCS8_PRIV_KEY_INFO_free +#define PKCS8_PRIV_KEY_INFO_it GRPC_SHADOW_PKCS8_PRIV_KEY_INFO_it +#define PKCS8_PRIV_KEY_INFO_new GRPC_SHADOW_PKCS8_PRIV_KEY_INFO_new +#define PKCS8_decrypt GRPC_SHADOW_PKCS8_decrypt +#define PKCS8_encrypt GRPC_SHADOW_PKCS8_encrypt +#define d2i_PKCS12 GRPC_SHADOW_d2i_PKCS12 +#define d2i_PKCS12_bio GRPC_SHADOW_d2i_PKCS12_bio +#define d2i_PKCS12_fp GRPC_SHADOW_d2i_PKCS12_fp +#define d2i_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_d2i_PKCS8_PRIV_KEY_INFO +#define i2d_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_i2d_PKCS8_PRIV_KEY_INFO +#define PKCS5_pbe2_decrypt_init GRPC_SHADOW_PKCS5_pbe2_decrypt_init +#define PKCS5_pbe2_encrypt_init GRPC_SHADOW_PKCS5_pbe2_encrypt_init + +#endif /* GRPC_SHADOW_BORINGSSL_SYMBOLS */ + +#endif /* GRPC_CORE_TSI_GRPC_SHADOW_BORINGSSL_H */ diff --git a/src/core/tsi/ssl/session_cache/ssl_session.h b/src/core/tsi/ssl/session_cache/ssl_session.h index 115221ec066..e847267cb30 100644 --- a/src/core/tsi/ssl/session_cache/ssl_session.h +++ b/src/core/tsi/ssl/session_cache/ssl_session.h @@ -21,6 +21,8 @@ #include +#include "src/core/tsi/grpc_shadow_boringssl.h" + #include extern "C" { diff --git a/src/core/tsi/ssl/session_cache/ssl_session_cache.h b/src/core/tsi/ssl/session_cache/ssl_session_cache.h index a90cca1a2ea..37fa2d124c9 100644 --- a/src/core/tsi/ssl/session_cache/ssl_session_cache.h +++ b/src/core/tsi/ssl/session_cache/ssl_session_cache.h @@ -21,6 +21,8 @@ #include +#include "src/core/tsi/grpc_shadow_boringssl.h" + #include #include diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index e66fc9ba034..1d6383afdb9 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -18,6 +18,8 @@ #include +#include "src/core/tsi/grpc_shadow_boringssl.h" + #include "src/core/tsi/ssl_transport_security.h" #include diff --git a/src/core/tsi/ssl_types.h b/src/core/tsi/ssl_types.h index b15d02be390..0ce5e2ee6f3 100644 --- a/src/core/tsi/ssl_types.h +++ b/src/core/tsi/ssl_types.h @@ -29,6 +29,8 @@ #include +#include "src/core/tsi/grpc_shadow_boringssl.h" + #include #ifdef OPENSSL_IS_BORINGSSL diff --git a/src/objective-c/BoringSSL-GRPC.podspec b/src/objective-c/BoringSSL-GRPC.podspec new file mode 100644 index 00000000000..704b35a29e8 --- /dev/null +++ b/src/objective-c/BoringSSL-GRPC.podspec @@ -0,0 +1,4527 @@ + +# This file has been automatically generated from a template file. +# Please make modifications to +# `templates/src/objective-c/BoringSSL-GRPC.podspec.template` instead. This +# file can be regenerated from the template by running +# `tools/buildgen/generate_projects.sh`. + +# BoringSSL CocoaPods podspec + +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Pod::Spec.new do |s| + s.name = 'BoringSSL-GRPC' + version = '0.0.1' + s.version = version + s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.' + # Adapted from the homepage: + s.description = <<-DESC + BoringSSL is a fork of OpenSSL that is designed to meet Google's needs. + + Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. + We don't recommend that third parties depend upon it. Doing so is likely to be frustrating + because there are no guarantees of API stability. Only the latest version of this pod is + supported, and every new version is a new major version. + + We update Google libraries and programs that use BoringSSL as needed when deciding to make API + changes. This allows us to mostly avoid compromises in the name of compatibility. It works for + us, but it may not work for you. + + As a Cocoapods pod, it has the advantage over OpenSSL's pods that the library doesn't need to + be precompiled. This eliminates the 10 - 20 minutes of wait the first time a user does "pod + install", lets it be used as a dynamic framework (pending solution of Cocoapods' issue #4605), + and works with bitcode automatically. It's also thought to be smaller than OpenSSL (which takes + 1MB - 2MB per ARM architecture), but we don't have specific numbers yet. + + BoringSSL arose because Google used OpenSSL for many years in various ways and, over time, built + up a large number of patches that were maintained while tracking upstream OpenSSL. As Google's + product portfolio became more complex, more copies of OpenSSL sprung up and the effort involved + in maintaining all these patches in multiple places was growing steadily. + + Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's not part of the + NDK) and a number of other apps/programs. + DESC + s.homepage = 'https://github.com/google/boringssl' + s.license = { :type => 'Mixed', :file => 'LICENSE' } + # "The name and email addresses of the library maintainers, not the Podspec maintainer." + s.authors = 'Adam Langley', 'David Benjamin', 'Matt Braithwaite' + + s.source = { + :git => 'https://github.com/google/boringssl.git', + :commit => "b29b21a81b32ec273f118f589f46d56ad3332420", + } + + s.ios.deployment_target = '5.0' + s.osx.deployment_target = '10.7' + + name = 'openssl' + + # When creating a dynamic framework, name it openssl.framework instead of BoringSSL.framework. + # This lets users write their includes like `#include ` as opposed to `#include + # `. + s.module_name = name + + # When creating a dynamic framework, copy the headers under `include/openssl/` into the root of + # the `Headers/` directory of the framework (i.e., not under `Headers/include/openssl`). + # + # TODO(jcanizales): Debug why this doesn't work on macOS. + s.header_mappings_dir = 'include/openssl' + + # The above has an undesired effect when creating a static library: It forces users to write + # includes like `#include `. `s.header_dir` adds a path prefix to that, and + # because Cocoapods lets omit the pod name when including headers of static libraries, the + # following lets users write `#include `. + s.header_dir = name + + # The module map and umbrella header created automatically by Cocoapods don't work for C libraries + # like this one. The following file, and a correct umbrella header, are created on the fly by the + # `prepare_command` of this pod. + s.module_map = 'include/openssl/BoringSSL.modulemap' + + # We don't need to inhibit all warnings; only -Wno-shorten-64-to-32. But Cocoapods' linter doesn't + # want that for some reason. + s.compiler_flags = '-DOPENSSL_NO_ASM', '-GCC_WARN_INHIBIT_ALL_WARNINGS', '-w' + s.requires_arc = false + + # Like many other C libraries, BoringSSL has its public headers under `include//` and its + # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't + # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in + # practice). Because we need our `header_mappings_dir` to be `include/openssl/` for the reason + # mentioned above, we work around the linter limitation by dividing the pod into two subspecs, one + # for public headers and the other for implementation. Each gets its own `header_mappings_dir`, + # making the linter happy. + s.subspec 'Interface' do |ss| + ss.header_mappings_dir = 'include/openssl' + ss.source_files = 'include/openssl/*.h' + end + s.subspec 'Implementation' do |ss| + ss.header_mappings_dir = '.' + ss.source_files = 'ssl/*.{h,cc}', + 'ssl/**/*.{h,cc}', + '*.{h,c}', + 'crypto/*.{h,c}', + 'crypto/**/*.{h,c}', + 'third_party/fiat/*.{h,c}' + ss.private_header_files = 'ssl/*.h', + 'ssl/**/*.h', + '*.h', + 'crypto/*.h', + 'crypto/**/*.h' + # bcm.c includes other source files, creating duplicated symbols. Since it is not used, we + # explicitly exclude it from the pod. + # TODO (mxyan): Work with BoringSSL team to remove this hack. + ss.exclude_files = 'crypto/fipsmodule/bcm.c', + '**/*_test.*', + '**/test_*.*', + '**/test/*.*' + + ss.dependency "#{s.name}/Interface", version + end + + s.prepare_command = <<-END_OF_COMMAND + # Add a module map and an umbrella header + cat > include/openssl/umbrella.h < include/openssl/BoringSSL.modulemap < err_data.c < + #include + #include + + + OPENSSL_COMPILE_ASSERT(ERR_LIB_NONE == 1, library_values_changed_1); + OPENSSL_COMPILE_ASSERT(ERR_LIB_SYS == 2, library_values_changed_2); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BN == 3, library_values_changed_3); + OPENSSL_COMPILE_ASSERT(ERR_LIB_RSA == 4, library_values_changed_4); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DH == 5, library_values_changed_5); + OPENSSL_COMPILE_ASSERT(ERR_LIB_EVP == 6, library_values_changed_6); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BUF == 7, library_values_changed_7); + OPENSSL_COMPILE_ASSERT(ERR_LIB_OBJ == 8, library_values_changed_8); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PEM == 9, library_values_changed_9); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DSA == 10, library_values_changed_10); + OPENSSL_COMPILE_ASSERT(ERR_LIB_X509 == 11, library_values_changed_11); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ASN1 == 12, library_values_changed_12); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CONF == 13, library_values_changed_13); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CRYPTO == 14, library_values_changed_14); + OPENSSL_COMPILE_ASSERT(ERR_LIB_EC == 15, library_values_changed_15); + OPENSSL_COMPILE_ASSERT(ERR_LIB_SSL == 16, library_values_changed_16); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BIO == 17, library_values_changed_17); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS7 == 18, library_values_changed_18); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS8 == 19, library_values_changed_19); + OPENSSL_COMPILE_ASSERT(ERR_LIB_X509V3 == 20, library_values_changed_20); + OPENSSL_COMPILE_ASSERT(ERR_LIB_RAND == 21, library_values_changed_21); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ENGINE == 22, library_values_changed_22); + OPENSSL_COMPILE_ASSERT(ERR_LIB_OCSP == 23, library_values_changed_23); + OPENSSL_COMPILE_ASSERT(ERR_LIB_UI == 24, library_values_changed_24); + OPENSSL_COMPILE_ASSERT(ERR_LIB_COMP == 25, library_values_changed_25); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDSA == 26, library_values_changed_26); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDH == 27, library_values_changed_27); + OPENSSL_COMPILE_ASSERT(ERR_LIB_HMAC == 28, library_values_changed_28); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DIGEST == 29, library_values_changed_29); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CIPHER == 30, library_values_changed_30); + OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 31, library_values_changed_31); + OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32); + OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num); + + const uint32_t kOpenSSLReasonValues[] = { + 0xc320838, + 0xc328852, + 0xc330861, + 0xc338871, + 0xc340880, + 0xc348899, + 0xc3508a5, + 0xc3588c2, + 0xc3608e2, + 0xc3688f0, + 0xc370900, + 0xc37890d, + 0xc38091d, + 0xc388928, + 0xc39093e, + 0xc39894d, + 0xc3a0961, + 0xc3a8845, + 0xc3b00ea, + 0xc3b88d4, + 0x10320845, + 0x10329513, + 0x1033151f, + 0x10339538, + 0x1034154b, + 0x10348eed, + 0x10350c5e, + 0x1035955e, + 0x10361573, + 0x10369586, + 0x103715a5, + 0x103795be, + 0x103815d3, + 0x103895f1, + 0x10391600, + 0x1039961c, + 0x103a1637, + 0x103a9646, + 0x103b1662, + 0x103b967d, + 0x103c1694, + 0x103c80ea, + 0x103d16a5, + 0x103d96b9, + 0x103e16d8, + 0x103e96e7, + 0x103f16fe, + 0x103f9711, + 0x10400c22, + 0x10409724, + 0x10411742, + 0x10419755, + 0x1042176f, + 0x1042977f, + 0x10431793, + 0x104397a9, + 0x104417c1, + 0x104497d6, + 0x104517ea, + 0x104597fc, + 0x104605fb, + 0x1046894d, + 0x10471811, + 0x10479828, + 0x1048183d, + 0x1048984b, + 0x10490e4f, + 0x14320c05, + 0x14328c13, + 0x14330c22, + 0x14338c34, + 0x143400ac, + 0x143480ea, + 0x18320083, + 0x18328f43, + 0x183300ac, + 0x18338f59, + 0x18340f6d, + 0x183480ea, + 0x18350f82, + 0x18358f9a, + 0x18360faf, + 0x18368fc3, + 0x18370fe7, + 0x18378ffd, + 0x18381011, + 0x18389021, + 0x18390a73, + 0x18399031, + 0x183a1059, + 0x183a907f, + 0x183b0c6a, + 0x183b90b4, + 0x183c10c6, + 0x183c90d1, + 0x183d10e1, + 0x183d90f2, + 0x183e1103, + 0x183e9115, + 0x183f113e, + 0x183f9157, + 0x1840116f, + 0x184086d3, + 0x184110a2, + 0x1841906d, + 0x1842108c, + 0x18429046, + 0x20321196, + 0x243211a2, + 0x24328993, + 0x243311b4, + 0x243391c1, + 0x243411ce, + 0x243491e0, + 0x243511ef, + 0x2435920c, + 0x24361219, + 0x24369227, + 0x24371235, + 0x24379243, + 0x2438124c, + 0x24389259, + 0x2439126c, + 0x28320c52, + 0x28328c6a, + 0x28330c22, + 0x28338c7d, + 0x28340c5e, + 0x283480ac, + 0x283500ea, + 0x2c322c30, + 0x2c329283, + 0x2c332c3e, + 0x2c33ac50, + 0x2c342c64, + 0x2c34ac76, + 0x2c352c91, + 0x2c35aca3, + 0x2c362cb6, + 0x2c36832d, + 0x2c372cc3, + 0x2c37acd5, + 0x2c382cfa, + 0x2c38ad11, + 0x2c392d1f, + 0x2c39ad2f, + 0x2c3a2d41, + 0x2c3aad55, + 0x2c3b2d66, + 0x2c3bad85, + 0x2c3c1295, + 0x2c3c92ab, + 0x2c3d2d99, + 0x2c3d92c4, + 0x2c3e2db6, + 0x2c3eadc4, + 0x2c3f2ddc, + 0x2c3fadf4, + 0x2c402e01, + 0x2c409196, + 0x2c412e12, + 0x2c41ae25, + 0x2c42116f, + 0x2c42ae36, + 0x2c430720, + 0x2c43ad77, + 0x2c442ce8, + 0x30320000, + 0x30328015, + 0x3033001f, + 0x30338038, + 0x3034004a, + 0x30348064, + 0x3035006b, + 0x30358083, + 0x30360094, + 0x303680ac, + 0x303700b9, + 0x303780c8, + 0x303800ea, + 0x303880f7, + 0x3039010a, + 0x30398125, + 0x303a013a, + 0x303a814e, + 0x303b0162, + 0x303b8173, + 0x303c018c, + 0x303c81a9, + 0x303d01b7, + 0x303d81cb, + 0x303e01db, + 0x303e81f4, + 0x303f0204, + 0x303f8217, + 0x30400226, + 0x30408232, + 0x30410247, + 0x30418257, + 0x3042026e, + 0x3042827b, + 0x3043028e, + 0x3043829d, + 0x304402b2, + 0x304482d3, + 0x304502e6, + 0x304582f9, + 0x30460312, + 0x3046832d, + 0x3047034a, + 0x30478363, + 0x30480371, + 0x30488382, + 0x30490391, + 0x304983a9, + 0x304a03bb, + 0x304a83cf, + 0x304b03ee, + 0x304b8401, + 0x304c040c, + 0x304c841d, + 0x304d0429, + 0x304d843f, + 0x304e044d, + 0x304e8463, + 0x304f0475, + 0x304f8487, + 0x3050049a, + 0x305084ad, + 0x305104be, + 0x305184ce, + 0x305204e6, + 0x305284fb, + 0x30530513, + 0x30538527, + 0x3054053f, + 0x30548558, + 0x30550571, + 0x3055858e, + 0x30560599, + 0x305685b1, + 0x305705c1, + 0x305785d2, + 0x305805e5, + 0x305885fb, + 0x30590604, + 0x30598619, + 0x305a062c, + 0x305a863b, + 0x305b065b, + 0x305b866a, + 0x305c068b, + 0x305c86a7, + 0x305d06b3, + 0x305d86d3, + 0x305e06ef, + 0x305e8700, + 0x305f0716, + 0x305f8720, + 0x34320b63, + 0x34328b77, + 0x34330b94, + 0x34338ba7, + 0x34340bb6, + 0x34348bef, + 0x34350bd3, + 0x3c320083, + 0x3c328ca7, + 0x3c330cc0, + 0x3c338cdb, + 0x3c340cf8, + 0x3c348d22, + 0x3c350d3d, + 0x3c358d63, + 0x3c360d7c, + 0x3c368d94, + 0x3c370da5, + 0x3c378db3, + 0x3c380dc0, + 0x3c388dd4, + 0x3c390c6a, + 0x3c398de8, + 0x3c3a0dfc, + 0x3c3a890d, + 0x3c3b0e0c, + 0x3c3b8e27, + 0x3c3c0e39, + 0x3c3c8e6c, + 0x3c3d0e76, + 0x3c3d8e8a, + 0x3c3e0e98, + 0x3c3e8ebd, + 0x3c3f0c93, + 0x3c3f8ea6, + 0x3c4000ac, + 0x3c4080ea, + 0x3c410d13, + 0x3c418d52, + 0x3c420e4f, + 0x403218a4, + 0x403298ba, + 0x403318e8, + 0x403398f2, + 0x40341909, + 0x40349927, + 0x40351937, + 0x40359949, + 0x40361956, + 0x40369962, + 0x40371977, + 0x40379989, + 0x40381994, + 0x403899a6, + 0x40390eed, + 0x403999b6, + 0x403a19c9, + 0x403a99ea, + 0x403b19fb, + 0x403b9a0b, + 0x403c0064, + 0x403c8083, + 0x403d1a8f, + 0x403d9aa5, + 0x403e1ab4, + 0x403e9aec, + 0x403f1b06, + 0x403f9b14, + 0x40401b29, + 0x40409b3d, + 0x40411b5a, + 0x40419b75, + 0x40421b8e, + 0x40429ba1, + 0x40431bb5, + 0x40439bcd, + 0x40441be4, + 0x404480ac, + 0x40451bf9, + 0x40459c0b, + 0x40461c2f, + 0x40469c4f, + 0x40471c5d, + 0x40479c84, + 0x40481cc1, + 0x40489cda, + 0x40491cf1, + 0x40499d0b, + 0x404a1d22, + 0x404a9d40, + 0x404b1d58, + 0x404b9d6f, + 0x404c1d85, + 0x404c9d97, + 0x404d1db8, + 0x404d9dda, + 0x404e1dee, + 0x404e9dfb, + 0x404f1e28, + 0x404f9e51, + 0x40501e8c, + 0x40509ea0, + 0x40511ebb, + 0x40521ecb, + 0x40529eef, + 0x40531f07, + 0x40539f1a, + 0x40541f2f, + 0x40549f52, + 0x40551f60, + 0x40559f7d, + 0x40561f8a, + 0x40569fa3, + 0x40571fbb, + 0x40579fce, + 0x40581fe3, + 0x4058a00a, + 0x40592039, + 0x4059a066, + 0x405a207a, + 0x405aa08a, + 0x405b20a2, + 0x405ba0b3, + 0x405c20c6, + 0x405ca105, + 0x405d2112, + 0x405da129, + 0x405e2167, + 0x405e8ab1, + 0x405f2188, + 0x405fa195, + 0x406021a3, + 0x4060a1c5, + 0x40612209, + 0x4061a241, + 0x40622258, + 0x4062a269, + 0x4063227a, + 0x4063a28f, + 0x406422a6, + 0x4064a2d2, + 0x406522ed, + 0x4065a304, + 0x4066231c, + 0x4066a346, + 0x40672371, + 0x4067a392, + 0x406823b9, + 0x4068a3da, + 0x4069240c, + 0x4069a43a, + 0x406a245b, + 0x406aa47b, + 0x406b2603, + 0x406ba626, + 0x406c263c, + 0x406ca8b7, + 0x406d28e6, + 0x406da90e, + 0x406e293c, + 0x406ea989, + 0x406f29a8, + 0x406fa9e0, + 0x407029f3, + 0x4070aa10, + 0x40710800, + 0x4071aa22, + 0x40722a35, + 0x4072aa4e, + 0x40732a66, + 0x40739482, + 0x40742a7a, + 0x4074aa94, + 0x40752aa5, + 0x4075aab9, + 0x40762ac7, + 0x40769259, + 0x40772aec, + 0x4077ab0e, + 0x40782b29, + 0x4078ab62, + 0x40792b79, + 0x4079ab8f, + 0x407a2b9b, + 0x407aabae, + 0x407b2bc3, + 0x407babd5, + 0x407c2c06, + 0x407cac0f, + 0x407d23f5, + 0x407d9e61, + 0x407e2b3e, + 0x407ea01a, + 0x407f1c71, + 0x407f9a31, + 0x40801e38, + 0x40809c99, + 0x40811edd, + 0x40819e12, + 0x40822927, + 0x40829a17, + 0x40831ff5, + 0x4083a2b7, + 0x40841cad, + 0x4084a052, + 0x408520d7, + 0x4085a1ed, + 0x40862149, + 0x40869e7b, + 0x4087296d, + 0x4087a21e, + 0x40881a78, + 0x4088a3a5, + 0x40891ac7, + 0x40899a54, + 0x408a265c, + 0x408a9862, + 0x408b2bea, + 0x408ba9bd, + 0x408c20e7, + 0x408c987e, + 0x41f4252e, + 0x41f925c0, + 0x41fe24b3, + 0x41fea6a8, + 0x41ff2799, + 0x42032547, + 0x42082569, + 0x4208a5a5, + 0x42092497, + 0x4209a5df, + 0x420a24ee, + 0x420aa4ce, + 0x420b250e, + 0x420ba587, + 0x420c27b5, + 0x420ca675, + 0x420d268f, + 0x420da6c6, + 0x421226e0, + 0x4217277c, + 0x4217a722, + 0x421c2744, + 0x421f26ff, + 0x422127cc, + 0x4226275f, + 0x422b289b, + 0x422ba849, + 0x422c2883, + 0x422ca808, + 0x422d27e7, + 0x422da868, + 0x422e282e, + 0x422ea954, + 0x4432072b, + 0x4432873a, + 0x44330746, + 0x44338754, + 0x44340767, + 0x44348778, + 0x4435077f, + 0x44358789, + 0x4436079c, + 0x443687b2, + 0x443707c4, + 0x443787d1, + 0x443807e0, + 0x443887e8, + 0x44390800, + 0x4439880e, + 0x443a0821, + 0x48321283, + 0x48329295, + 0x483312ab, + 0x483392c4, + 0x4c3212e9, + 0x4c3292f9, + 0x4c33130c, + 0x4c33932c, + 0x4c3400ac, + 0x4c3480ea, + 0x4c351338, + 0x4c359346, + 0x4c361362, + 0x4c369375, + 0x4c371384, + 0x4c379392, + 0x4c3813a7, + 0x4c3893b3, + 0x4c3913d3, + 0x4c3993fd, + 0x4c3a1416, + 0x4c3a942f, + 0x4c3b05fb, + 0x4c3b9448, + 0x4c3c145a, + 0x4c3c9469, + 0x4c3d1482, + 0x4c3d8c45, + 0x4c3e14db, + 0x4c3e9491, + 0x4c3f14fd, + 0x4c3f9259, + 0x4c4014a7, + 0x4c4092d5, + 0x4c4114cb, + 0x50322e48, + 0x5032ae57, + 0x50332e62, + 0x5033ae72, + 0x50342e8b, + 0x5034aea5, + 0x50352eb3, + 0x5035aec9, + 0x50362edb, + 0x5036aef1, + 0x50372f0a, + 0x5037af1d, + 0x50382f35, + 0x5038af46, + 0x50392f5b, + 0x5039af6f, + 0x503a2f8f, + 0x503aafa5, + 0x503b2fbd, + 0x503bafcf, + 0x503c2feb, + 0x503cb002, + 0x503d301b, + 0x503db031, + 0x503e303e, + 0x503eb054, + 0x503f3066, + 0x503f8382, + 0x50403079, + 0x5040b089, + 0x504130a3, + 0x5041b0b2, + 0x504230cc, + 0x5042b0e9, + 0x504330f9, + 0x5043b109, + 0x50443118, + 0x5044843f, + 0x5045312c, + 0x5045b14a, + 0x5046315d, + 0x5046b173, + 0x50473185, + 0x5047b19a, + 0x504831c0, + 0x5048b1ce, + 0x504931e1, + 0x5049b1f6, + 0x504a320c, + 0x504ab21c, + 0x504b323c, + 0x504bb24f, + 0x504c3272, + 0x504cb2a0, + 0x504d32b2, + 0x504db2cf, + 0x504e32ea, + 0x504eb306, + 0x504f3318, + 0x504fb32f, + 0x5050333e, + 0x505086ef, + 0x50513351, + 0x58320f2b, + 0x68320eed, + 0x68328c6a, + 0x68330c7d, + 0x68338efb, + 0x68340f0b, + 0x683480ea, + 0x6c320ec9, + 0x6c328c34, + 0x6c330ed4, + 0x74320a19, + 0x743280ac, + 0x74330c45, + 0x7832097e, + 0x78328993, + 0x7833099f, + 0x78338083, + 0x783409ae, + 0x783489c3, + 0x783509e2, + 0x78358a04, + 0x78360a19, + 0x78368a2f, + 0x78370a3f, + 0x78378a60, + 0x78380a73, + 0x78388a85, + 0x78390a92, + 0x78398ab1, + 0x783a0ac6, + 0x783a8ad4, + 0x783b0ade, + 0x783b8af2, + 0x783c0b09, + 0x783c8b1e, + 0x783d0b35, + 0x783d8b4a, + 0x783e0aa0, + 0x783e8a52, + 0x7c321185, + }; + + const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); + + const char kOpenSSLReasonStringData[] = + "ASN1_LENGTH_MISMATCH\\0" + "AUX_ERROR\\0" + "BAD_GET_ASN1_OBJECT_CALL\\0" + "BAD_OBJECT_HEADER\\0" + "BMPSTRING_IS_WRONG_LENGTH\\0" + "BN_LIB\\0" + "BOOLEAN_IS_WRONG_LENGTH\\0" + "BUFFER_TOO_SMALL\\0" + "CONTEXT_NOT_INITIALISED\\0" + "DECODE_ERROR\\0" + "DEPTH_EXCEEDED\\0" + "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\\0" + "ENCODE_ERROR\\0" + "ERROR_GETTING_TIME\\0" + "EXPECTING_AN_ASN1_SEQUENCE\\0" + "EXPECTING_AN_INTEGER\\0" + "EXPECTING_AN_OBJECT\\0" + "EXPECTING_A_BOOLEAN\\0" + "EXPECTING_A_TIME\\0" + "EXPLICIT_LENGTH_MISMATCH\\0" + "EXPLICIT_TAG_NOT_CONSTRUCTED\\0" + "FIELD_MISSING\\0" + "FIRST_NUM_TOO_LARGE\\0" + "HEADER_TOO_LONG\\0" + "ILLEGAL_BITSTRING_FORMAT\\0" + "ILLEGAL_BOOLEAN\\0" + "ILLEGAL_CHARACTERS\\0" + "ILLEGAL_FORMAT\\0" + "ILLEGAL_HEX\\0" + "ILLEGAL_IMPLICIT_TAG\\0" + "ILLEGAL_INTEGER\\0" + "ILLEGAL_NESTED_TAGGING\\0" + "ILLEGAL_NULL\\0" + "ILLEGAL_NULL_VALUE\\0" + "ILLEGAL_OBJECT\\0" + "ILLEGAL_OPTIONAL_ANY\\0" + "ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE\\0" + "ILLEGAL_TAGGED_ANY\\0" + "ILLEGAL_TIME_VALUE\\0" + "INTEGER_NOT_ASCII_FORMAT\\0" + "INTEGER_TOO_LARGE_FOR_LONG\\0" + "INVALID_BIT_STRING_BITS_LEFT\\0" + "INVALID_BMPSTRING_LENGTH\\0" + "INVALID_DIGIT\\0" + "INVALID_MODIFIER\\0" + "INVALID_NUMBER\\0" + "INVALID_OBJECT_ENCODING\\0" + "INVALID_SEPARATOR\\0" + "INVALID_TIME_FORMAT\\0" + "INVALID_UNIVERSALSTRING_LENGTH\\0" + "INVALID_UTF8STRING\\0" + "LIST_ERROR\\0" + "MISSING_ASN1_EOS\\0" + "MISSING_EOC\\0" + "MISSING_SECOND_NUMBER\\0" + "MISSING_VALUE\\0" + "MSTRING_NOT_UNIVERSAL\\0" + "MSTRING_WRONG_TAG\\0" + "NESTED_ASN1_ERROR\\0" + "NESTED_ASN1_STRING\\0" + "NON_HEX_CHARACTERS\\0" + "NOT_ASCII_FORMAT\\0" + "NOT_ENOUGH_DATA\\0" + "NO_MATCHING_CHOICE_TYPE\\0" + "NULL_IS_WRONG_LENGTH\\0" + "OBJECT_NOT_ASCII_FORMAT\\0" + "ODD_NUMBER_OF_CHARS\\0" + "SECOND_NUMBER_TOO_LARGE\\0" + "SEQUENCE_LENGTH_MISMATCH\\0" + "SEQUENCE_NOT_CONSTRUCTED\\0" + "SEQUENCE_OR_SET_NEEDS_CONFIG\\0" + "SHORT_LINE\\0" + "STREAMING_NOT_SUPPORTED\\0" + "STRING_TOO_LONG\\0" + "STRING_TOO_SHORT\\0" + "TAG_VALUE_TOO_HIGH\\0" + "TIME_NOT_ASCII_FORMAT\\0" + "TOO_LONG\\0" + "TYPE_NOT_CONSTRUCTED\\0" + "TYPE_NOT_PRIMITIVE\\0" + "UNEXPECTED_EOC\\0" + "UNIVERSALSTRING_IS_WRONG_LENGTH\\0" + "UNKNOWN_FORMAT\\0" + "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\\0" + "UNKNOWN_SIGNATURE_ALGORITHM\\0" + "UNKNOWN_TAG\\0" + "UNSUPPORTED_ANY_DEFINED_BY_TYPE\\0" + "UNSUPPORTED_PUBLIC_KEY_TYPE\\0" + "UNSUPPORTED_TYPE\\0" + "WRONG_PUBLIC_KEY_TYPE\\0" + "WRONG_TAG\\0" + "WRONG_TYPE\\0" + "BAD_FOPEN_MODE\\0" + "BROKEN_PIPE\\0" + "CONNECT_ERROR\\0" + "ERROR_SETTING_NBIO\\0" + "INVALID_ARGUMENT\\0" + "IN_USE\\0" + "KEEPALIVE\\0" + "NBIO_CONNECT_ERROR\\0" + "NO_HOSTNAME_SPECIFIED\\0" + "NO_PORT_SPECIFIED\\0" + "NO_SUCH_FILE\\0" + "NULL_PARAMETER\\0" + "SYS_LIB\\0" + "UNABLE_TO_CREATE_SOCKET\\0" + "UNINITIALIZED\\0" + "UNSUPPORTED_METHOD\\0" + "WRITE_TO_READ_ONLY_BIO\\0" + "ARG2_LT_ARG3\\0" + "BAD_ENCODING\\0" + "BAD_RECIPROCAL\\0" + "BIGNUM_TOO_LONG\\0" + "BITS_TOO_SMALL\\0" + "CALLED_WITH_EVEN_MODULUS\\0" + "DIV_BY_ZERO\\0" + "EXPAND_ON_STATIC_BIGNUM_DATA\\0" + "INPUT_NOT_REDUCED\\0" + "INVALID_INPUT\\0" + "INVALID_RANGE\\0" + "NEGATIVE_NUMBER\\0" + "NOT_A_SQUARE\\0" + "NOT_INITIALIZED\\0" + "NO_INVERSE\\0" + "PRIVATE_KEY_TOO_LARGE\\0" + "P_IS_NOT_PRIME\\0" + "TOO_MANY_ITERATIONS\\0" + "TOO_MANY_TEMPORARY_VARIABLES\\0" + "AES_KEY_SETUP_FAILED\\0" + "BAD_DECRYPT\\0" + "BAD_KEY_LENGTH\\0" + "CTRL_NOT_IMPLEMENTED\\0" + "CTRL_OPERATION_NOT_IMPLEMENTED\\0" + "DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH\\0" + "INITIALIZATION_ERROR\\0" + "INPUT_NOT_INITIALIZED\\0" + "INVALID_AD_SIZE\\0" + "INVALID_KEY_LENGTH\\0" + "INVALID_NONCE\\0" + "INVALID_NONCE_SIZE\\0" + "INVALID_OPERATION\\0" + "IV_TOO_LARGE\\0" + "NO_CIPHER_SET\\0" + "NO_DIRECTION_SET\\0" + "OUTPUT_ALIASES_INPUT\\0" + "TAG_TOO_LARGE\\0" + "TOO_LARGE\\0" + "UNSUPPORTED_AD_SIZE\\0" + "UNSUPPORTED_INPUT_SIZE\\0" + "UNSUPPORTED_KEY_SIZE\\0" + "UNSUPPORTED_NONCE_SIZE\\0" + "UNSUPPORTED_TAG_SIZE\\0" + "WRONG_FINAL_BLOCK_LENGTH\\0" + "LIST_CANNOT_BE_NULL\\0" + "MISSING_CLOSE_SQUARE_BRACKET\\0" + "MISSING_EQUAL_SIGN\\0" + "NO_CLOSE_BRACE\\0" + "UNABLE_TO_CREATE_NEW_SECTION\\0" + "VARIABLE_EXPANSION_TOO_LONG\\0" + "VARIABLE_HAS_NO_VALUE\\0" + "BAD_GENERATOR\\0" + "INVALID_PUBKEY\\0" + "MODULUS_TOO_LARGE\\0" + "NO_PRIVATE_VALUE\\0" + "UNKNOWN_HASH\\0" + "BAD_Q_VALUE\\0" + "BAD_VERSION\\0" + "MISSING_PARAMETERS\\0" + "NEED_NEW_SETUP_VALUES\\0" + "BIGNUM_OUT_OF_RANGE\\0" + "COORDINATES_OUT_OF_RANGE\\0" + "D2I_ECPKPARAMETERS_FAILURE\\0" + "EC_GROUP_NEW_BY_NAME_FAILURE\\0" + "GROUP2PKPARAMETERS_FAILURE\\0" + "GROUP_MISMATCH\\0" + "I2D_ECPKPARAMETERS_FAILURE\\0" + "INCOMPATIBLE_OBJECTS\\0" + "INVALID_COFACTOR\\0" + "INVALID_COMPRESSED_POINT\\0" + "INVALID_COMPRESSION_BIT\\0" + "INVALID_ENCODING\\0" + "INVALID_FIELD\\0" + "INVALID_FORM\\0" + "INVALID_GROUP_ORDER\\0" + "INVALID_PRIVATE_KEY\\0" + "MISSING_PRIVATE_KEY\\0" + "NON_NAMED_CURVE\\0" + "PKPARAMETERS2GROUP_FAILURE\\0" + "POINT_AT_INFINITY\\0" + "POINT_IS_NOT_ON_CURVE\\0" + "PUBLIC_KEY_VALIDATION_FAILED\\0" + "SLOT_FULL\\0" + "UNDEFINED_GENERATOR\\0" + "UNKNOWN_GROUP\\0" + "UNKNOWN_ORDER\\0" + "WRONG_CURVE_PARAMETERS\\0" + "WRONG_ORDER\\0" + "KDF_FAILED\\0" + "POINT_ARITHMETIC_FAILURE\\0" + "BAD_SIGNATURE\\0" + "NOT_IMPLEMENTED\\0" + "RANDOM_NUMBER_GENERATION_FAILED\\0" + "OPERATION_NOT_SUPPORTED\\0" + "COMMAND_NOT_SUPPORTED\\0" + "DIFFERENT_KEY_TYPES\\0" + "DIFFERENT_PARAMETERS\\0" + "EXPECTING_AN_EC_KEY_KEY\\0" + "EXPECTING_AN_RSA_KEY\\0" + "EXPECTING_A_DSA_KEY\\0" + "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\\0" + "INVALID_DIGEST_LENGTH\\0" + "INVALID_DIGEST_TYPE\\0" + "INVALID_KEYBITS\\0" + "INVALID_MGF1_MD\\0" + "INVALID_PADDING_MODE\\0" + "INVALID_PARAMETERS\\0" + "INVALID_PSS_SALTLEN\\0" + "INVALID_SIGNATURE\\0" + "KEYS_NOT_SET\\0" + "MEMORY_LIMIT_EXCEEDED\\0" + "NOT_A_PRIVATE_KEY\\0" + "NO_DEFAULT_DIGEST\\0" + "NO_KEY_SET\\0" + "NO_MDC2_SUPPORT\\0" + "NO_NID_FOR_CURVE\\0" + "NO_OPERATION_SET\\0" + "NO_PARAMETERS_SET\\0" + "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\\0" + "OPERATON_NOT_INITIALIZED\\0" + "UNKNOWN_PUBLIC_KEY_TYPE\\0" + "UNSUPPORTED_ALGORITHM\\0" + "OUTPUT_TOO_LARGE\\0" + "UNKNOWN_NID\\0" + "BAD_BASE64_DECODE\\0" + "BAD_END_LINE\\0" + "BAD_IV_CHARS\\0" + "BAD_PASSWORD_READ\\0" + "CIPHER_IS_NULL\\0" + "ERROR_CONVERTING_PRIVATE_KEY\\0" + "NOT_DEK_INFO\\0" + "NOT_ENCRYPTED\\0" + "NOT_PROC_TYPE\\0" + "NO_START_LINE\\0" + "READ_KEY\\0" + "SHORT_HEADER\\0" + "UNSUPPORTED_CIPHER\\0" + "UNSUPPORTED_ENCRYPTION\\0" + "BAD_PKCS7_VERSION\\0" + "NOT_PKCS7_SIGNED_DATA\\0" + "NO_CERTIFICATES_INCLUDED\\0" + "NO_CRLS_INCLUDED\\0" + "BAD_ITERATION_COUNT\\0" + "BAD_PKCS12_DATA\\0" + "BAD_PKCS12_VERSION\\0" + "CIPHER_HAS_NO_OBJECT_IDENTIFIER\\0" + "CRYPT_ERROR\\0" + "ENCRYPT_ERROR\\0" + "ERROR_SETTING_CIPHER_PARAMS\\0" + "INCORRECT_PASSWORD\\0" + "KEYGEN_FAILURE\\0" + "KEY_GEN_ERROR\\0" + "METHOD_NOT_SUPPORTED\\0" + "MISSING_MAC\\0" + "MULTIPLE_PRIVATE_KEYS_IN_PKCS12\\0" + "PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED\\0" + "PKCS12_TOO_DEEPLY_NESTED\\0" + "PRIVATE_KEY_DECODE_ERROR\\0" + "PRIVATE_KEY_ENCODE_ERROR\\0" + "UNKNOWN_ALGORITHM\\0" + "UNKNOWN_CIPHER\\0" + "UNKNOWN_CIPHER_ALGORITHM\\0" + "UNKNOWN_DIGEST\\0" + "UNSUPPORTED_KEYLENGTH\\0" + "UNSUPPORTED_KEY_DERIVATION_FUNCTION\\0" + "UNSUPPORTED_PRF\\0" + "UNSUPPORTED_PRIVATE_KEY_ALGORITHM\\0" + "UNSUPPORTED_SALT_TYPE\\0" + "BAD_E_VALUE\\0" + "BAD_FIXED_HEADER_DECRYPT\\0" + "BAD_PAD_BYTE_COUNT\\0" + "BAD_RSA_PARAMETERS\\0" + "BLOCK_TYPE_IS_NOT_01\\0" + "BN_NOT_INITIALIZED\\0" + "CANNOT_RECOVER_MULTI_PRIME_KEY\\0" + "CRT_PARAMS_ALREADY_GIVEN\\0" + "CRT_VALUES_INCORRECT\\0" + "DATA_LEN_NOT_EQUAL_TO_MOD_LEN\\0" + "DATA_TOO_LARGE\\0" + "DATA_TOO_LARGE_FOR_KEY_SIZE\\0" + "DATA_TOO_LARGE_FOR_MODULUS\\0" + "DATA_TOO_SMALL\\0" + "DATA_TOO_SMALL_FOR_KEY_SIZE\\0" + "DIGEST_TOO_BIG_FOR_RSA_KEY\\0" + "D_E_NOT_CONGRUENT_TO_1\\0" + "EMPTY_PUBLIC_KEY\\0" + "FIRST_OCTET_INVALID\\0" + "INCONSISTENT_SET_OF_CRT_VALUES\\0" + "INTERNAL_ERROR\\0" + "INVALID_MESSAGE_LENGTH\\0" + "KEY_SIZE_TOO_SMALL\\0" + "LAST_OCTET_INVALID\\0" + "MUST_HAVE_AT_LEAST_TWO_PRIMES\\0" + "NO_PUBLIC_EXPONENT\\0" + "NULL_BEFORE_BLOCK_MISSING\\0" + "N_NOT_EQUAL_P_Q\\0" + "OAEP_DECODING_ERROR\\0" + "ONLY_ONE_OF_P_Q_GIVEN\\0" + "OUTPUT_BUFFER_TOO_SMALL\\0" + "PADDING_CHECK_FAILED\\0" + "PKCS_DECODING_ERROR\\0" + "SLEN_CHECK_FAILED\\0" + "SLEN_RECOVERY_FAILED\\0" + "UNKNOWN_ALGORITHM_TYPE\\0" + "UNKNOWN_PADDING_TYPE\\0" + "VALUE_MISSING\\0" + "WRONG_SIGNATURE_LENGTH\\0" + "ALPN_MISMATCH_ON_EARLY_DATA\\0" + "APPLICATION_DATA_INSTEAD_OF_HANDSHAKE\\0" + "APP_DATA_IN_HANDSHAKE\\0" + "ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT\\0" + "BAD_ALERT\\0" + "BAD_CHANGE_CIPHER_SPEC\\0" + "BAD_DATA_RETURNED_BY_CALLBACK\\0" + "BAD_DH_P_LENGTH\\0" + "BAD_DIGEST_LENGTH\\0" + "BAD_ECC_CERT\\0" + "BAD_ECPOINT\\0" + "BAD_HANDSHAKE_RECORD\\0" + "BAD_HELLO_REQUEST\\0" + "BAD_LENGTH\\0" + "BAD_PACKET_LENGTH\\0" + "BAD_RSA_ENCRYPT\\0" + "BAD_SRTP_MKI_VALUE\\0" + "BAD_SRTP_PROTECTION_PROFILE_LIST\\0" + "BAD_SSL_FILETYPE\\0" + "BAD_WRITE_RETRY\\0" + "BIO_NOT_SET\\0" + "BLOCK_CIPHER_PAD_IS_WRONG\\0" + "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\\0" + "CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD\\0" + "CANNOT_PARSE_LEAF_CERT\\0" + "CA_DN_LENGTH_MISMATCH\\0" + "CA_DN_TOO_LONG\\0" + "CCS_RECEIVED_EARLY\\0" + "CERTIFICATE_AND_PRIVATE_KEY_MISMATCH\\0" + "CERTIFICATE_VERIFY_FAILED\\0" + "CERT_CB_ERROR\\0" + "CERT_LENGTH_MISMATCH\\0" + "CHANNEL_ID_NOT_P256\\0" + "CHANNEL_ID_SIGNATURE_INVALID\\0" + "CIPHER_OR_HASH_UNAVAILABLE\\0" + "CLIENTHELLO_PARSE_FAILED\\0" + "CLIENTHELLO_TLSEXT\\0" + "CONNECTION_REJECTED\\0" + "CONNECTION_TYPE_NOT_SET\\0" + "CUSTOM_EXTENSION_ERROR\\0" + "DATA_LENGTH_TOO_LONG\\0" + "DECRYPTION_FAILED\\0" + "DECRYPTION_FAILED_OR_BAD_RECORD_MAC\\0" + "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\\0" + "DH_P_TOO_LONG\\0" + "DIGEST_CHECK_FAILED\\0" + "DOWNGRADE_DETECTED\\0" + "DTLS_MESSAGE_TOO_BIG\\0" + "DUPLICATE_EXTENSION\\0" + "DUPLICATE_KEY_SHARE\\0" + "ECC_CERT_NOT_FOR_SIGNING\\0" + "EMS_STATE_INCONSISTENT\\0" + "ENCRYPTED_LENGTH_TOO_LONG\\0" + "ERROR_ADDING_EXTENSION\\0" + "ERROR_IN_RECEIVED_CIPHER_LIST\\0" + "ERROR_PARSING_EXTENSION\\0" + "EXCESSIVE_MESSAGE_SIZE\\0" + "EXTRA_DATA_IN_MESSAGE\\0" + "FRAGMENT_MISMATCH\\0" + "GOT_NEXT_PROTO_WITHOUT_EXTENSION\\0" + "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\\0" + "HTTPS_PROXY_REQUEST\\0" + "HTTP_REQUEST\\0" + "INAPPROPRIATE_FALLBACK\\0" + "INVALID_ALPN_PROTOCOL\\0" + "INVALID_COMMAND\\0" + "INVALID_COMPRESSION_LIST\\0" + "INVALID_MESSAGE\\0" + "INVALID_OUTER_RECORD_TYPE\\0" + "INVALID_SCT_LIST\\0" + "INVALID_SSL_SESSION\\0" + "INVALID_TICKET_KEYS_LENGTH\\0" + "LENGTH_MISMATCH\\0" + "MISSING_EXTENSION\\0" + "MISSING_KEY_SHARE\\0" + "MISSING_RSA_CERTIFICATE\\0" + "MISSING_TMP_DH_KEY\\0" + "MISSING_TMP_ECDH_KEY\\0" + "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\\0" + "MTU_TOO_SMALL\\0" + "NEGOTIATED_BOTH_NPN_AND_ALPN\\0" + "NESTED_GROUP\\0" + "NO_CERTIFICATES_RETURNED\\0" + "NO_CERTIFICATE_ASSIGNED\\0" + "NO_CERTIFICATE_SET\\0" + "NO_CIPHERS_AVAILABLE\\0" + "NO_CIPHERS_PASSED\\0" + "NO_CIPHERS_SPECIFIED\\0" + "NO_CIPHER_MATCH\\0" + "NO_COMMON_SIGNATURE_ALGORITHMS\\0" + "NO_COMPRESSION_SPECIFIED\\0" + "NO_GROUPS_SPECIFIED\\0" + "NO_METHOD_SPECIFIED\\0" + "NO_P256_SUPPORT\\0" + "NO_PRIVATE_KEY_ASSIGNED\\0" + "NO_RENEGOTIATION\\0" + "NO_REQUIRED_DIGEST\\0" + "NO_SHARED_CIPHER\\0" + "NO_SHARED_GROUP\\0" + "NO_SUPPORTED_VERSIONS_ENABLED\\0" + "NULL_SSL_CTX\\0" + "NULL_SSL_METHOD_PASSED\\0" + "OLD_SESSION_CIPHER_NOT_RETURNED\\0" + "OLD_SESSION_PRF_HASH_MISMATCH\\0" + "OLD_SESSION_VERSION_NOT_RETURNED\\0" + "PARSE_TLSEXT\\0" + "PATH_TOO_LONG\\0" + "PEER_DID_NOT_RETURN_A_CERTIFICATE\\0" + "PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\\0" + "PRE_SHARED_KEY_MUST_BE_LAST\\0" + "PROTOCOL_IS_SHUTDOWN\\0" + "PSK_IDENTITY_BINDER_COUNT_MISMATCH\\0" + "PSK_IDENTITY_NOT_FOUND\\0" + "PSK_NO_CLIENT_CB\\0" + "PSK_NO_SERVER_CB\\0" + "READ_TIMEOUT_EXPIRED\\0" + "RECORD_LENGTH_MISMATCH\\0" + "RECORD_TOO_LARGE\\0" + "RENEGOTIATION_EMS_MISMATCH\\0" + "RENEGOTIATION_ENCODING_ERR\\0" + "RENEGOTIATION_MISMATCH\\0" + "REQUIRED_CIPHER_MISSING\\0" + "RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION\\0" + "RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION\\0" + "SCSV_RECEIVED_WHEN_RENEGOTIATING\\0" + "SERVERHELLO_TLSEXT\\0" + "SERVER_CERT_CHANGED\\0" + "SESSION_ID_CONTEXT_UNINITIALIZED\\0" + "SESSION_MAY_NOT_BE_CREATED\\0" + "SHUTDOWN_WHILE_IN_INIT\\0" + "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\\0" + "SRTP_COULD_NOT_ALLOCATE_PROFILES\\0" + "SRTP_UNKNOWN_PROTECTION_PROFILE\\0" + "SSL3_EXT_INVALID_SERVERNAME\\0" + "SSLV3_ALERT_BAD_CERTIFICATE\\0" + "SSLV3_ALERT_BAD_RECORD_MAC\\0" + "SSLV3_ALERT_CERTIFICATE_EXPIRED\\0" + "SSLV3_ALERT_CERTIFICATE_REVOKED\\0" + "SSLV3_ALERT_CERTIFICATE_UNKNOWN\\0" + "SSLV3_ALERT_CLOSE_NOTIFY\\0" + "SSLV3_ALERT_DECOMPRESSION_FAILURE\\0" + "SSLV3_ALERT_HANDSHAKE_FAILURE\\0" + "SSLV3_ALERT_ILLEGAL_PARAMETER\\0" + "SSLV3_ALERT_NO_CERTIFICATE\\0" + "SSLV3_ALERT_UNEXPECTED_MESSAGE\\0" + "SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\\0" + "SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\\0" + "SSL_HANDSHAKE_FAILURE\\0" + "SSL_SESSION_ID_CONTEXT_TOO_LONG\\0" + "TICKET_ENCRYPTION_FAILED\\0" + "TLSV1_ALERT_ACCESS_DENIED\\0" + "TLSV1_ALERT_DECODE_ERROR\\0" + "TLSV1_ALERT_DECRYPTION_FAILED\\0" + "TLSV1_ALERT_DECRYPT_ERROR\\0" + "TLSV1_ALERT_EXPORT_RESTRICTION\\0" + "TLSV1_ALERT_INAPPROPRIATE_FALLBACK\\0" + "TLSV1_ALERT_INSUFFICIENT_SECURITY\\0" + "TLSV1_ALERT_INTERNAL_ERROR\\0" + "TLSV1_ALERT_NO_RENEGOTIATION\\0" + "TLSV1_ALERT_PROTOCOL_VERSION\\0" + "TLSV1_ALERT_RECORD_OVERFLOW\\0" + "TLSV1_ALERT_UNKNOWN_CA\\0" + "TLSV1_ALERT_USER_CANCELLED\\0" + "TLSV1_BAD_CERTIFICATE_HASH_VALUE\\0" + "TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\\0" + "TLSV1_CERTIFICATE_REQUIRED\\0" + "TLSV1_CERTIFICATE_UNOBTAINABLE\\0" + "TLSV1_UNKNOWN_PSK_IDENTITY\\0" + "TLSV1_UNRECOGNIZED_NAME\\0" + "TLSV1_UNSUPPORTED_EXTENSION\\0" + "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\\0" + "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\\0" + "TOO_MANY_EMPTY_FRAGMENTS\\0" + "TOO_MANY_KEY_UPDATES\\0" + "TOO_MANY_WARNING_ALERTS\\0" + "TOO_MUCH_READ_EARLY_DATA\\0" + "TOO_MUCH_SKIPPED_EARLY_DATA\\0" + "UNABLE_TO_FIND_ECDH_PARAMETERS\\0" + "UNEXPECTED_EXTENSION\\0" + "UNEXPECTED_EXTENSION_ON_EARLY_DATA\\0" + "UNEXPECTED_MESSAGE\\0" + "UNEXPECTED_OPERATOR_IN_GROUP\\0" + "UNEXPECTED_RECORD\\0" + "UNKNOWN_ALERT_TYPE\\0" + "UNKNOWN_CERTIFICATE_TYPE\\0" + "UNKNOWN_CIPHER_RETURNED\\0" + "UNKNOWN_CIPHER_TYPE\\0" + "UNKNOWN_KEY_EXCHANGE_TYPE\\0" + "UNKNOWN_PROTOCOL\\0" + "UNKNOWN_SSL_VERSION\\0" + "UNKNOWN_STATE\\0" + "UNSAFE_LEGACY_RENEGOTIATION_DISABLED\\0" + "UNSUPPORTED_COMPRESSION_ALGORITHM\\0" + "UNSUPPORTED_ELLIPTIC_CURVE\\0" + "UNSUPPORTED_PROTOCOL\\0" + "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\\0" + "WRONG_CERTIFICATE_TYPE\\0" + "WRONG_CIPHER_RETURNED\\0" + "WRONG_CURVE\\0" + "WRONG_MESSAGE_TYPE\\0" + "WRONG_SIGNATURE_TYPE\\0" + "WRONG_SSL_VERSION\\0" + "WRONG_VERSION_NUMBER\\0" + "WRONG_VERSION_ON_EARLY_DATA\\0" + "X509_LIB\\0" + "X509_VERIFICATION_SETUP_PROBLEMS\\0" + "AKID_MISMATCH\\0" + "BAD_X509_FILETYPE\\0" + "BASE64_DECODE_ERROR\\0" + "CANT_CHECK_DH_KEY\\0" + "CERT_ALREADY_IN_HASH_TABLE\\0" + "CRL_ALREADY_DELTA\\0" + "CRL_VERIFY_FAILURE\\0" + "IDP_MISMATCH\\0" + "INVALID_DIRECTORY\\0" + "INVALID_FIELD_NAME\\0" + "INVALID_PARAMETER\\0" + "INVALID_PSS_PARAMETERS\\0" + "INVALID_TRUST\\0" + "ISSUER_MISMATCH\\0" + "KEY_TYPE_MISMATCH\\0" + "KEY_VALUES_MISMATCH\\0" + "LOADING_CERT_DIR\\0" + "LOADING_DEFAULTS\\0" + "NAME_TOO_LONG\\0" + "NEWER_CRL_NOT_NEWER\\0" + "NO_CERT_SET_FOR_US_TO_VERIFY\\0" + "NO_CRL_NUMBER\\0" + "PUBLIC_KEY_DECODE_ERROR\\0" + "PUBLIC_KEY_ENCODE_ERROR\\0" + "SHOULD_RETRY\\0" + "UNKNOWN_KEY_TYPE\\0" + "UNKNOWN_PURPOSE_ID\\0" + "UNKNOWN_TRUST_ID\\0" + "WRONG_LOOKUP_TYPE\\0" + "BAD_IP_ADDRESS\\0" + "BAD_OBJECT\\0" + "BN_DEC2BN_ERROR\\0" + "BN_TO_ASN1_INTEGER_ERROR\\0" + "CANNOT_FIND_FREE_FUNCTION\\0" + "DIRNAME_ERROR\\0" + "DISTPOINT_ALREADY_SET\\0" + "DUPLICATE_ZONE_ID\\0" + "ERROR_CONVERTING_ZONE\\0" + "ERROR_CREATING_EXTENSION\\0" + "ERROR_IN_EXTENSION\\0" + "EXPECTED_A_SECTION_NAME\\0" + "EXTENSION_EXISTS\\0" + "EXTENSION_NAME_ERROR\\0" + "EXTENSION_NOT_FOUND\\0" + "EXTENSION_SETTING_NOT_SUPPORTED\\0" + "EXTENSION_VALUE_ERROR\\0" + "ILLEGAL_EMPTY_EXTENSION\\0" + "ILLEGAL_HEX_DIGIT\\0" + "INCORRECT_POLICY_SYNTAX_TAG\\0" + "INVALID_BOOLEAN_STRING\\0" + "INVALID_EXTENSION_STRING\\0" + "INVALID_MULTIPLE_RDNS\\0" + "INVALID_NAME\\0" + "INVALID_NULL_ARGUMENT\\0" + "INVALID_NULL_NAME\\0" + "INVALID_NULL_VALUE\\0" + "INVALID_NUMBERS\\0" + "INVALID_OBJECT_IDENTIFIER\\0" + "INVALID_OPTION\\0" + "INVALID_POLICY_IDENTIFIER\\0" + "INVALID_PROXY_POLICY_SETTING\\0" + "INVALID_PURPOSE\\0" + "INVALID_SECTION\\0" + "INVALID_SYNTAX\\0" + "ISSUER_DECODE_ERROR\\0" + "NEED_ORGANIZATION_AND_NUMBERS\\0" + "NO_CONFIG_DATABASE\\0" + "NO_ISSUER_CERTIFICATE\\0" + "NO_ISSUER_DETAILS\\0" + "NO_POLICY_IDENTIFIER\\0" + "NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED\\0" + "NO_PUBLIC_KEY\\0" + "NO_SUBJECT_DETAILS\\0" + "ODD_NUMBER_OF_DIGITS\\0" + "OPERATION_NOT_DEFINED\\0" + "OTHERNAME_ERROR\\0" + "POLICY_LANGUAGE_ALREADY_DEFINED\\0" + "POLICY_PATH_LENGTH\\0" + "POLICY_PATH_LENGTH_ALREADY_DEFINED\\0" + "POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY\\0" + "SECTION_NOT_FOUND\\0" + "UNABLE_TO_GET_ISSUER_DETAILS\\0" + "UNABLE_TO_GET_ISSUER_KEYID\\0" + "UNKNOWN_BIT_STRING_ARGUMENT\\0" + "UNKNOWN_EXTENSION\\0" + "UNKNOWN_EXTENSION_NAME\\0" + "UNKNOWN_OPTION\\0" + "UNSUPPORTED_OPTION\\0" + "USER_TOO_LONG\\0" + ""; + EOF + + sed -i'.back' '/^#define \\([A-Za-z0-9_]*\\) \\1/d' include/openssl/ssl.h + sed -i'.back' 'N;/^#define \\([A-Za-z0-9_]*\\) *\\\\\\n *\\1/d' include/openssl/ssl.h + sed -i'.back' 's/#ifndef md5_block_data_order/#ifndef GRPC_SHADOW_md5_block_data_order/g' crypto/fipsmodule/md5/md5.c + END_OF_COMMAND + + # Redefine symbols to avoid conflict when the same app also depends on OpenSSL. The list of + # symbols are src/objective-c/grpc_shadow_boringssl_symbol_list. + # This is the last part of this file. + s.prefix_header_contents = + '#define BIO_f_ssl GRPC_SHADOW_BIO_f_ssl', + '#define BIO_set_ssl GRPC_SHADOW_BIO_set_ssl', + '#define SSL_CTX_add_client_custom_ext GRPC_SHADOW_SSL_CTX_add_client_custom_ext', + '#define SSL_CTX_add_server_custom_ext GRPC_SHADOW_SSL_CTX_add_server_custom_ext', + '#define DTLSv1_get_timeout GRPC_SHADOW_DTLSv1_get_timeout', + '#define DTLSv1_handle_timeout GRPC_SHADOW_DTLSv1_handle_timeout', + '#define DTLSv1_set_initial_timeout_duration GRPC_SHADOW_DTLSv1_set_initial_timeout_duration', + '#define SSL_CTX_set_srtp_profiles GRPC_SHADOW_SSL_CTX_set_srtp_profiles', + '#define SSL_CTX_set_tlsext_use_srtp GRPC_SHADOW_SSL_CTX_set_tlsext_use_srtp', + '#define SSL_get_selected_srtp_profile GRPC_SHADOW_SSL_get_selected_srtp_profile', + '#define SSL_get_srtp_profiles GRPC_SHADOW_SSL_get_srtp_profiles', + '#define SSL_set_srtp_profiles GRPC_SHADOW_SSL_set_srtp_profiles', + '#define SSL_set_tlsext_use_srtp GRPC_SHADOW_SSL_set_tlsext_use_srtp', + '#define DTLS_client_method GRPC_SHADOW_DTLS_client_method', + '#define DTLS_method GRPC_SHADOW_DTLS_method', + '#define DTLS_server_method GRPC_SHADOW_DTLS_server_method', + '#define DTLS_with_buffers_method GRPC_SHADOW_DTLS_with_buffers_method', + '#define DTLSv1_2_client_method GRPC_SHADOW_DTLSv1_2_client_method', + '#define DTLSv1_2_method GRPC_SHADOW_DTLSv1_2_method', + '#define DTLSv1_2_server_method GRPC_SHADOW_DTLSv1_2_server_method', + '#define DTLSv1_client_method GRPC_SHADOW_DTLSv1_client_method', + '#define DTLSv1_method GRPC_SHADOW_DTLSv1_method', + '#define DTLSv1_server_method GRPC_SHADOW_DTLSv1_server_method', + '#define SSL_SESSION_from_bytes GRPC_SHADOW_SSL_SESSION_from_bytes', + '#define SSL_SESSION_to_bytes GRPC_SHADOW_SSL_SESSION_to_bytes', + '#define SSL_SESSION_to_bytes_for_ticket GRPC_SHADOW_SSL_SESSION_to_bytes_for_ticket', + '#define i2d_SSL_SESSION GRPC_SHADOW_i2d_SSL_SESSION', + '#define SSL_CTX_set0_client_CAs GRPC_SHADOW_SSL_CTX_set0_client_CAs', + '#define SSL_CTX_set_cert_cb GRPC_SHADOW_SSL_CTX_set_cert_cb', + '#define SSL_CTX_set_chain_and_key GRPC_SHADOW_SSL_CTX_set_chain_and_key', + '#define SSL_CTX_set_ocsp_response GRPC_SHADOW_SSL_CTX_set_ocsp_response', + '#define SSL_CTX_set_signed_cert_timestamp_list GRPC_SHADOW_SSL_CTX_set_signed_cert_timestamp_list', + '#define SSL_CTX_use_certificate_ASN1 GRPC_SHADOW_SSL_CTX_use_certificate_ASN1', + '#define SSL_get0_peer_certificates GRPC_SHADOW_SSL_get0_peer_certificates', + '#define SSL_get0_server_requested_CAs GRPC_SHADOW_SSL_get0_server_requested_CAs', + '#define SSL_set0_client_CAs GRPC_SHADOW_SSL_set0_client_CAs', + '#define SSL_set_cert_cb GRPC_SHADOW_SSL_set_cert_cb', + '#define SSL_set_chain_and_key GRPC_SHADOW_SSL_set_chain_and_key', + '#define SSL_set_ocsp_response GRPC_SHADOW_SSL_set_ocsp_response', + '#define SSL_set_signed_cert_timestamp_list GRPC_SHADOW_SSL_set_signed_cert_timestamp_list', + '#define SSL_use_certificate_ASN1 GRPC_SHADOW_SSL_use_certificate_ASN1', + '#define SSL_CIPHER_description GRPC_SHADOW_SSL_CIPHER_description', + '#define SSL_CIPHER_get_auth_nid GRPC_SHADOW_SSL_CIPHER_get_auth_nid', + '#define SSL_CIPHER_get_bits GRPC_SHADOW_SSL_CIPHER_get_bits', + '#define SSL_CIPHER_get_cipher_nid GRPC_SHADOW_SSL_CIPHER_get_cipher_nid', + '#define SSL_CIPHER_get_digest_nid GRPC_SHADOW_SSL_CIPHER_get_digest_nid', + '#define SSL_CIPHER_get_id GRPC_SHADOW_SSL_CIPHER_get_id', + '#define SSL_CIPHER_get_kx_name GRPC_SHADOW_SSL_CIPHER_get_kx_name', + '#define SSL_CIPHER_get_kx_nid GRPC_SHADOW_SSL_CIPHER_get_kx_nid', + '#define SSL_CIPHER_get_max_version GRPC_SHADOW_SSL_CIPHER_get_max_version', + '#define SSL_CIPHER_get_min_version GRPC_SHADOW_SSL_CIPHER_get_min_version', + '#define SSL_CIPHER_get_name GRPC_SHADOW_SSL_CIPHER_get_name', + '#define SSL_CIPHER_get_prf_nid GRPC_SHADOW_SSL_CIPHER_get_prf_nid', + '#define SSL_CIPHER_get_rfc_name GRPC_SHADOW_SSL_CIPHER_get_rfc_name', + '#define SSL_CIPHER_get_version GRPC_SHADOW_SSL_CIPHER_get_version', + '#define SSL_CIPHER_is_aead GRPC_SHADOW_SSL_CIPHER_is_aead', + '#define SSL_CIPHER_is_block_cipher GRPC_SHADOW_SSL_CIPHER_is_block_cipher', + '#define SSL_CIPHER_standard_name GRPC_SHADOW_SSL_CIPHER_standard_name', + '#define SSL_COMP_add_compression_method GRPC_SHADOW_SSL_COMP_add_compression_method', + '#define SSL_COMP_free_compression_methods GRPC_SHADOW_SSL_COMP_free_compression_methods', + '#define SSL_COMP_get0_name GRPC_SHADOW_SSL_COMP_get0_name', + '#define SSL_COMP_get_compression_methods GRPC_SHADOW_SSL_COMP_get_compression_methods', + '#define SSL_COMP_get_id GRPC_SHADOW_SSL_COMP_get_id', + '#define SSL_COMP_get_name GRPC_SHADOW_SSL_COMP_get_name', + '#define SSL_get_cipher_by_value GRPC_SHADOW_SSL_get_cipher_by_value', + '#define SSL_CTX_get_default_passwd_cb GRPC_SHADOW_SSL_CTX_get_default_passwd_cb', + '#define SSL_CTX_get_default_passwd_cb_userdata GRPC_SHADOW_SSL_CTX_get_default_passwd_cb_userdata', + '#define SSL_CTX_set_default_passwd_cb GRPC_SHADOW_SSL_CTX_set_default_passwd_cb', + '#define SSL_CTX_set_default_passwd_cb_userdata GRPC_SHADOW_SSL_CTX_set_default_passwd_cb_userdata', + '#define SSL_CTX_use_PrivateKey_file GRPC_SHADOW_SSL_CTX_use_PrivateKey_file', + '#define SSL_CTX_use_RSAPrivateKey_file GRPC_SHADOW_SSL_CTX_use_RSAPrivateKey_file', + '#define SSL_CTX_use_certificate_chain_file GRPC_SHADOW_SSL_CTX_use_certificate_chain_file', + '#define SSL_CTX_use_certificate_file GRPC_SHADOW_SSL_CTX_use_certificate_file', + '#define SSL_add_file_cert_subjects_to_stack GRPC_SHADOW_SSL_add_file_cert_subjects_to_stack', + '#define SSL_load_client_CA_file GRPC_SHADOW_SSL_load_client_CA_file', + '#define SSL_use_PrivateKey_file GRPC_SHADOW_SSL_use_PrivateKey_file', + '#define SSL_use_RSAPrivateKey_file GRPC_SHADOW_SSL_use_RSAPrivateKey_file', + '#define SSL_use_certificate_file GRPC_SHADOW_SSL_use_certificate_file', + '#define SSL_get_curve_name GRPC_SHADOW_SSL_get_curve_name', + '#define ERR_load_SSL_strings GRPC_SHADOW_ERR_load_SSL_strings', + '#define OPENSSL_init_ssl GRPC_SHADOW_OPENSSL_init_ssl', + '#define SSL_CTX_check_private_key GRPC_SHADOW_SSL_CTX_check_private_key', + '#define SSL_CTX_cipher_in_group GRPC_SHADOW_SSL_CTX_cipher_in_group', + '#define SSL_CTX_clear_mode GRPC_SHADOW_SSL_CTX_clear_mode', + '#define SSL_CTX_clear_options GRPC_SHADOW_SSL_CTX_clear_options', + '#define SSL_CTX_enable_ocsp_stapling GRPC_SHADOW_SSL_CTX_enable_ocsp_stapling', + '#define SSL_CTX_enable_signed_cert_timestamps GRPC_SHADOW_SSL_CTX_enable_signed_cert_timestamps', + '#define SSL_CTX_enable_tls_channel_id GRPC_SHADOW_SSL_CTX_enable_tls_channel_id', + '#define SSL_CTX_free GRPC_SHADOW_SSL_CTX_free', + '#define SSL_CTX_get0_privatekey GRPC_SHADOW_SSL_CTX_get0_privatekey', + '#define SSL_CTX_get_ciphers GRPC_SHADOW_SSL_CTX_get_ciphers', + '#define SSL_CTX_get_ex_data GRPC_SHADOW_SSL_CTX_get_ex_data', + '#define SSL_CTX_get_ex_new_index GRPC_SHADOW_SSL_CTX_get_ex_new_index', + '#define SSL_CTX_get_keylog_callback GRPC_SHADOW_SSL_CTX_get_keylog_callback', + '#define SSL_CTX_get_max_cert_list GRPC_SHADOW_SSL_CTX_get_max_cert_list', + '#define SSL_CTX_get_mode GRPC_SHADOW_SSL_CTX_get_mode', + '#define SSL_CTX_get_options GRPC_SHADOW_SSL_CTX_get_options', + '#define SSL_CTX_get_quiet_shutdown GRPC_SHADOW_SSL_CTX_get_quiet_shutdown', + '#define SSL_CTX_get_read_ahead GRPC_SHADOW_SSL_CTX_get_read_ahead', + '#define SSL_CTX_get_session_cache_mode GRPC_SHADOW_SSL_CTX_get_session_cache_mode', + '#define SSL_CTX_get_tlsext_ticket_keys GRPC_SHADOW_SSL_CTX_get_tlsext_ticket_keys', + '#define SSL_CTX_need_tmp_RSA GRPC_SHADOW_SSL_CTX_need_tmp_RSA', + '#define SSL_CTX_new GRPC_SHADOW_SSL_CTX_new', + '#define SSL_CTX_sess_accept GRPC_SHADOW_SSL_CTX_sess_accept', + '#define SSL_CTX_sess_accept_good GRPC_SHADOW_SSL_CTX_sess_accept_good', + '#define SSL_CTX_sess_accept_renegotiate GRPC_SHADOW_SSL_CTX_sess_accept_renegotiate', + '#define SSL_CTX_sess_cache_full GRPC_SHADOW_SSL_CTX_sess_cache_full', + '#define SSL_CTX_sess_cb_hits GRPC_SHADOW_SSL_CTX_sess_cb_hits', + '#define SSL_CTX_sess_connect GRPC_SHADOW_SSL_CTX_sess_connect', + '#define SSL_CTX_sess_connect_good GRPC_SHADOW_SSL_CTX_sess_connect_good', + '#define SSL_CTX_sess_connect_renegotiate GRPC_SHADOW_SSL_CTX_sess_connect_renegotiate', + '#define SSL_CTX_sess_get_cache_size GRPC_SHADOW_SSL_CTX_sess_get_cache_size', + '#define SSL_CTX_sess_hits GRPC_SHADOW_SSL_CTX_sess_hits', + '#define SSL_CTX_sess_misses GRPC_SHADOW_SSL_CTX_sess_misses', + '#define SSL_CTX_sess_number GRPC_SHADOW_SSL_CTX_sess_number', + '#define SSL_CTX_sess_set_cache_size GRPC_SHADOW_SSL_CTX_sess_set_cache_size', + '#define SSL_CTX_sess_timeouts GRPC_SHADOW_SSL_CTX_sess_timeouts', + '#define SSL_CTX_set0_buffer_pool GRPC_SHADOW_SSL_CTX_set0_buffer_pool', + '#define SSL_CTX_set1_curves GRPC_SHADOW_SSL_CTX_set1_curves', + '#define SSL_CTX_set1_curves_list GRPC_SHADOW_SSL_CTX_set1_curves_list', + '#define SSL_CTX_set1_tls_channel_id GRPC_SHADOW_SSL_CTX_set1_tls_channel_id', + '#define SSL_CTX_set_allow_unknown_alpn_protos GRPC_SHADOW_SSL_CTX_set_allow_unknown_alpn_protos', + '#define SSL_CTX_set_alpn_protos GRPC_SHADOW_SSL_CTX_set_alpn_protos', + '#define SSL_CTX_set_alpn_select_cb GRPC_SHADOW_SSL_CTX_set_alpn_select_cb', + '#define SSL_CTX_set_cipher_list GRPC_SHADOW_SSL_CTX_set_cipher_list', + '#define SSL_CTX_set_current_time_cb GRPC_SHADOW_SSL_CTX_set_current_time_cb', + '#define SSL_CTX_set_custom_verify GRPC_SHADOW_SSL_CTX_set_custom_verify', + '#define SSL_CTX_set_dos_protection_cb GRPC_SHADOW_SSL_CTX_set_dos_protection_cb', + '#define SSL_CTX_set_early_data_enabled GRPC_SHADOW_SSL_CTX_set_early_data_enabled', + '#define SSL_CTX_set_ex_data GRPC_SHADOW_SSL_CTX_set_ex_data', + '#define SSL_CTX_set_false_start_allowed_without_alpn GRPC_SHADOW_SSL_CTX_set_false_start_allowed_without_alpn', + '#define SSL_CTX_set_grease_enabled GRPC_SHADOW_SSL_CTX_set_grease_enabled', + '#define SSL_CTX_set_keylog_callback GRPC_SHADOW_SSL_CTX_set_keylog_callback', + '#define SSL_CTX_set_max_cert_list GRPC_SHADOW_SSL_CTX_set_max_cert_list', + '#define SSL_CTX_set_max_send_fragment GRPC_SHADOW_SSL_CTX_set_max_send_fragment', + '#define SSL_CTX_set_mode GRPC_SHADOW_SSL_CTX_set_mode', + '#define SSL_CTX_set_msg_callback GRPC_SHADOW_SSL_CTX_set_msg_callback', + '#define SSL_CTX_set_msg_callback_arg GRPC_SHADOW_SSL_CTX_set_msg_callback_arg', + '#define SSL_CTX_set_next_proto_select_cb GRPC_SHADOW_SSL_CTX_set_next_proto_select_cb', + '#define SSL_CTX_set_next_protos_advertised_cb GRPC_SHADOW_SSL_CTX_set_next_protos_advertised_cb', + '#define SSL_CTX_set_options GRPC_SHADOW_SSL_CTX_set_options', + '#define SSL_CTX_set_psk_client_callback GRPC_SHADOW_SSL_CTX_set_psk_client_callback', + '#define SSL_CTX_set_psk_server_callback GRPC_SHADOW_SSL_CTX_set_psk_server_callback', + '#define SSL_CTX_set_quiet_shutdown GRPC_SHADOW_SSL_CTX_set_quiet_shutdown', + '#define SSL_CTX_set_read_ahead GRPC_SHADOW_SSL_CTX_set_read_ahead', + '#define SSL_CTX_set_retain_only_sha256_of_client_certs GRPC_SHADOW_SSL_CTX_set_retain_only_sha256_of_client_certs', + '#define SSL_CTX_set_select_certificate_cb GRPC_SHADOW_SSL_CTX_set_select_certificate_cb', + '#define SSL_CTX_set_session_cache_mode GRPC_SHADOW_SSL_CTX_set_session_cache_mode', + '#define SSL_CTX_set_session_id_context GRPC_SHADOW_SSL_CTX_set_session_id_context', + '#define SSL_CTX_set_strict_cipher_list GRPC_SHADOW_SSL_CTX_set_strict_cipher_list', + '#define SSL_CTX_set_ticket_aead_method GRPC_SHADOW_SSL_CTX_set_ticket_aead_method', + '#define SSL_CTX_set_tls13_variant GRPC_SHADOW_SSL_CTX_set_tls13_variant', + '#define SSL_CTX_set_tls_channel_id_enabled GRPC_SHADOW_SSL_CTX_set_tls_channel_id_enabled', + '#define SSL_CTX_set_tlsext_servername_arg GRPC_SHADOW_SSL_CTX_set_tlsext_servername_arg', + '#define SSL_CTX_set_tlsext_servername_callback GRPC_SHADOW_SSL_CTX_set_tlsext_servername_callback', + '#define SSL_CTX_set_tlsext_ticket_key_cb GRPC_SHADOW_SSL_CTX_set_tlsext_ticket_key_cb', + '#define SSL_CTX_set_tlsext_ticket_keys GRPC_SHADOW_SSL_CTX_set_tlsext_ticket_keys', + '#define SSL_CTX_set_tmp_dh GRPC_SHADOW_SSL_CTX_set_tmp_dh', + '#define SSL_CTX_set_tmp_dh_callback GRPC_SHADOW_SSL_CTX_set_tmp_dh_callback', + '#define SSL_CTX_set_tmp_ecdh GRPC_SHADOW_SSL_CTX_set_tmp_ecdh', + '#define SSL_CTX_set_tmp_rsa GRPC_SHADOW_SSL_CTX_set_tmp_rsa', + '#define SSL_CTX_set_tmp_rsa_callback GRPC_SHADOW_SSL_CTX_set_tmp_rsa_callback', + '#define SSL_CTX_up_ref GRPC_SHADOW_SSL_CTX_up_ref', + '#define SSL_CTX_use_psk_identity_hint GRPC_SHADOW_SSL_CTX_use_psk_identity_hint', + '#define SSL_accept GRPC_SHADOW_SSL_accept', + '#define SSL_cache_hit GRPC_SHADOW_SSL_cache_hit', + '#define SSL_certs_clear GRPC_SHADOW_SSL_certs_clear', + '#define SSL_check_private_key GRPC_SHADOW_SSL_check_private_key', + '#define SSL_clear GRPC_SHADOW_SSL_clear', + '#define SSL_clear_mode GRPC_SHADOW_SSL_clear_mode', + '#define SSL_clear_options GRPC_SHADOW_SSL_clear_options', + '#define SSL_connect GRPC_SHADOW_SSL_connect', + '#define SSL_cutthrough_complete GRPC_SHADOW_SSL_cutthrough_complete', + '#define SSL_do_handshake GRPC_SHADOW_SSL_do_handshake', + '#define SSL_dummy_pq_padding_used GRPC_SHADOW_SSL_dummy_pq_padding_used', + '#define SSL_early_data_accepted GRPC_SHADOW_SSL_early_data_accepted', + '#define SSL_enable_ocsp_stapling GRPC_SHADOW_SSL_enable_ocsp_stapling', + '#define SSL_enable_signed_cert_timestamps GRPC_SHADOW_SSL_enable_signed_cert_timestamps', + '#define SSL_enable_tls_channel_id GRPC_SHADOW_SSL_enable_tls_channel_id', + '#define SSL_free GRPC_SHADOW_SSL_free', + '#define SSL_get0_alpn_selected GRPC_SHADOW_SSL_get0_alpn_selected', + '#define SSL_get0_certificate_types GRPC_SHADOW_SSL_get0_certificate_types', + '#define SSL_get0_next_proto_negotiated GRPC_SHADOW_SSL_get0_next_proto_negotiated', + '#define SSL_get0_ocsp_response GRPC_SHADOW_SSL_get0_ocsp_response', + '#define SSL_get0_session_id_context GRPC_SHADOW_SSL_get0_session_id_context', + '#define SSL_get0_signed_cert_timestamp_list GRPC_SHADOW_SSL_get0_signed_cert_timestamp_list', + '#define SSL_get_SSL_CTX GRPC_SHADOW_SSL_get_SSL_CTX', + '#define SSL_get_cipher_list GRPC_SHADOW_SSL_get_cipher_list', + '#define SSL_get_ciphers GRPC_SHADOW_SSL_get_ciphers', + '#define SSL_get_client_random GRPC_SHADOW_SSL_get_client_random', + '#define SSL_get_current_cipher GRPC_SHADOW_SSL_get_current_cipher', + '#define SSL_get_current_compression GRPC_SHADOW_SSL_get_current_compression', + '#define SSL_get_current_expansion GRPC_SHADOW_SSL_get_current_expansion', + '#define SSL_get_curve_id GRPC_SHADOW_SSL_get_curve_id', + '#define SSL_get_default_timeout GRPC_SHADOW_SSL_get_default_timeout', + '#define SSL_get_error GRPC_SHADOW_SSL_get_error', + '#define SSL_get_ex_data GRPC_SHADOW_SSL_get_ex_data', + '#define SSL_get_ex_new_index GRPC_SHADOW_SSL_get_ex_new_index', + '#define SSL_get_extms_support GRPC_SHADOW_SSL_get_extms_support', + '#define SSL_get_fd GRPC_SHADOW_SSL_get_fd', + '#define SSL_get_finished GRPC_SHADOW_SSL_get_finished', + '#define SSL_get_info_callback GRPC_SHADOW_SSL_get_info_callback', + '#define SSL_get_ivs GRPC_SHADOW_SSL_get_ivs', + '#define SSL_get_max_cert_list GRPC_SHADOW_SSL_get_max_cert_list', + '#define SSL_get_mode GRPC_SHADOW_SSL_get_mode', + '#define SSL_get_negotiated_token_binding_param GRPC_SHADOW_SSL_get_negotiated_token_binding_param', + '#define SSL_get_options GRPC_SHADOW_SSL_get_options', + '#define SSL_get_peer_finished GRPC_SHADOW_SSL_get_peer_finished', + '#define SSL_get_peer_quic_transport_params GRPC_SHADOW_SSL_get_peer_quic_transport_params', + '#define SSL_get_peer_signature_algorithm GRPC_SHADOW_SSL_get_peer_signature_algorithm', + '#define SSL_get_pending_cipher GRPC_SHADOW_SSL_get_pending_cipher', + '#define SSL_get_privatekey GRPC_SHADOW_SSL_get_privatekey', + '#define SSL_get_psk_identity GRPC_SHADOW_SSL_get_psk_identity', + '#define SSL_get_psk_identity_hint GRPC_SHADOW_SSL_get_psk_identity_hint', + '#define SSL_get_quiet_shutdown GRPC_SHADOW_SSL_get_quiet_shutdown', + '#define SSL_get_rbio GRPC_SHADOW_SSL_get_rbio', + '#define SSL_get_read_ahead GRPC_SHADOW_SSL_get_read_ahead', + '#define SSL_get_read_sequence GRPC_SHADOW_SSL_get_read_sequence', + '#define SSL_get_rfd GRPC_SHADOW_SSL_get_rfd', + '#define SSL_get_secure_renegotiation_support GRPC_SHADOW_SSL_get_secure_renegotiation_support', + '#define SSL_get_server_random GRPC_SHADOW_SSL_get_server_random', + '#define SSL_get_server_tmp_key GRPC_SHADOW_SSL_get_server_tmp_key', + '#define SSL_get_servername GRPC_SHADOW_SSL_get_servername', + '#define SSL_get_servername_type GRPC_SHADOW_SSL_get_servername_type', + '#define SSL_get_shared_ciphers GRPC_SHADOW_SSL_get_shared_ciphers', + '#define SSL_get_shutdown GRPC_SHADOW_SSL_get_shutdown', + '#define SSL_get_structure_sizes GRPC_SHADOW_SSL_get_structure_sizes', + '#define SSL_get_ticket_age_skew GRPC_SHADOW_SSL_get_ticket_age_skew', + '#define SSL_get_tls_channel_id GRPC_SHADOW_SSL_get_tls_channel_id', + '#define SSL_get_tls_unique GRPC_SHADOW_SSL_get_tls_unique', + '#define SSL_get_verify_mode GRPC_SHADOW_SSL_get_verify_mode', + '#define SSL_get_wbio GRPC_SHADOW_SSL_get_wbio', + '#define SSL_get_wfd GRPC_SHADOW_SSL_get_wfd', + '#define SSL_get_write_sequence GRPC_SHADOW_SSL_get_write_sequence', + '#define SSL_in_early_data GRPC_SHADOW_SSL_in_early_data', + '#define SSL_in_false_start GRPC_SHADOW_SSL_in_false_start', + '#define SSL_in_init GRPC_SHADOW_SSL_in_init', + '#define SSL_is_draft_downgrade GRPC_SHADOW_SSL_is_draft_downgrade', + '#define SSL_is_dtls GRPC_SHADOW_SSL_is_dtls', + '#define SSL_is_init_finished GRPC_SHADOW_SSL_is_init_finished', + '#define SSL_is_server GRPC_SHADOW_SSL_is_server', + '#define SSL_is_token_binding_negotiated GRPC_SHADOW_SSL_is_token_binding_negotiated', + '#define SSL_library_init GRPC_SHADOW_SSL_library_init', + '#define SSL_load_error_strings GRPC_SHADOW_SSL_load_error_strings', + '#define SSL_need_tmp_RSA GRPC_SHADOW_SSL_need_tmp_RSA', + '#define SSL_new GRPC_SHADOW_SSL_new', + '#define SSL_num_renegotiations GRPC_SHADOW_SSL_num_renegotiations', + '#define SSL_peek GRPC_SHADOW_SSL_peek', + '#define SSL_pending GRPC_SHADOW_SSL_pending', + '#define SSL_read GRPC_SHADOW_SSL_read', + '#define SSL_renegotiate GRPC_SHADOW_SSL_renegotiate', + '#define SSL_renegotiate_pending GRPC_SHADOW_SSL_renegotiate_pending', + '#define SSL_reset_early_data_reject GRPC_SHADOW_SSL_reset_early_data_reject', + '#define SSL_select_next_proto GRPC_SHADOW_SSL_select_next_proto', + '#define SSL_send_fatal_alert GRPC_SHADOW_SSL_send_fatal_alert', + '#define SSL_session_reused GRPC_SHADOW_SSL_session_reused', + '#define SSL_set0_rbio GRPC_SHADOW_SSL_set0_rbio', + '#define SSL_set0_wbio GRPC_SHADOW_SSL_set0_wbio', + '#define SSL_set1_curves GRPC_SHADOW_SSL_set1_curves', + '#define SSL_set1_curves_list GRPC_SHADOW_SSL_set1_curves_list', + '#define SSL_set1_tls_channel_id GRPC_SHADOW_SSL_set1_tls_channel_id', + '#define SSL_set_SSL_CTX GRPC_SHADOW_SSL_set_SSL_CTX', + '#define SSL_set_accept_state GRPC_SHADOW_SSL_set_accept_state', + '#define SSL_set_alpn_protos GRPC_SHADOW_SSL_set_alpn_protos', + '#define SSL_set_bio GRPC_SHADOW_SSL_set_bio', + '#define SSL_set_cipher_list GRPC_SHADOW_SSL_set_cipher_list', + '#define SSL_set_connect_state GRPC_SHADOW_SSL_set_connect_state', + '#define SSL_set_custom_verify GRPC_SHADOW_SSL_set_custom_verify', + '#define SSL_set_dummy_pq_padding_size GRPC_SHADOW_SSL_set_dummy_pq_padding_size', + '#define SSL_set_early_data_enabled GRPC_SHADOW_SSL_set_early_data_enabled', + '#define SSL_set_ex_data GRPC_SHADOW_SSL_set_ex_data', + '#define SSL_set_fd GRPC_SHADOW_SSL_set_fd', + '#define SSL_set_info_callback GRPC_SHADOW_SSL_set_info_callback', + '#define SSL_set_max_cert_list GRPC_SHADOW_SSL_set_max_cert_list', + '#define SSL_set_max_send_fragment GRPC_SHADOW_SSL_set_max_send_fragment', + '#define SSL_set_mode GRPC_SHADOW_SSL_set_mode', + '#define SSL_set_msg_callback GRPC_SHADOW_SSL_set_msg_callback', + '#define SSL_set_msg_callback_arg GRPC_SHADOW_SSL_set_msg_callback_arg', + '#define SSL_set_mtu GRPC_SHADOW_SSL_set_mtu', + '#define SSL_set_options GRPC_SHADOW_SSL_set_options', + '#define SSL_set_psk_client_callback GRPC_SHADOW_SSL_set_psk_client_callback', + '#define SSL_set_psk_server_callback GRPC_SHADOW_SSL_set_psk_server_callback', + '#define SSL_set_quic_transport_params GRPC_SHADOW_SSL_set_quic_transport_params', + '#define SSL_set_quiet_shutdown GRPC_SHADOW_SSL_set_quiet_shutdown', + '#define SSL_set_read_ahead GRPC_SHADOW_SSL_set_read_ahead', + '#define SSL_set_renegotiate_mode GRPC_SHADOW_SSL_set_renegotiate_mode', + '#define SSL_set_retain_only_sha256_of_client_certs GRPC_SHADOW_SSL_set_retain_only_sha256_of_client_certs', + '#define SSL_set_rfd GRPC_SHADOW_SSL_set_rfd', + '#define SSL_set_session_id_context GRPC_SHADOW_SSL_set_session_id_context', + '#define SSL_set_shutdown GRPC_SHADOW_SSL_set_shutdown', + '#define SSL_set_state GRPC_SHADOW_SSL_set_state', + '#define SSL_set_strict_cipher_list GRPC_SHADOW_SSL_set_strict_cipher_list', + '#define SSL_set_tls13_variant GRPC_SHADOW_SSL_set_tls13_variant', + '#define SSL_set_tls_channel_id_enabled GRPC_SHADOW_SSL_set_tls_channel_id_enabled', + '#define SSL_set_tlsext_host_name GRPC_SHADOW_SSL_set_tlsext_host_name', + '#define SSL_set_tmp_dh GRPC_SHADOW_SSL_set_tmp_dh', + '#define SSL_set_tmp_dh_callback GRPC_SHADOW_SSL_set_tmp_dh_callback', + '#define SSL_set_tmp_ecdh GRPC_SHADOW_SSL_set_tmp_ecdh', + '#define SSL_set_tmp_rsa GRPC_SHADOW_SSL_set_tmp_rsa', + '#define SSL_set_tmp_rsa_callback GRPC_SHADOW_SSL_set_tmp_rsa_callback', + '#define SSL_set_token_binding_params GRPC_SHADOW_SSL_set_token_binding_params', + '#define SSL_set_wfd GRPC_SHADOW_SSL_set_wfd', + '#define SSL_shutdown GRPC_SHADOW_SSL_shutdown', + '#define SSL_state GRPC_SHADOW_SSL_state', + '#define SSL_total_renegotiations GRPC_SHADOW_SSL_total_renegotiations', + '#define SSL_use_psk_identity_hint GRPC_SHADOW_SSL_use_psk_identity_hint', + '#define SSL_want GRPC_SHADOW_SSL_want', + '#define SSL_write GRPC_SHADOW_SSL_write', + '#define SSL_CTX_set_private_key_method GRPC_SHADOW_SSL_CTX_set_private_key_method', + '#define SSL_CTX_set_signing_algorithm_prefs GRPC_SHADOW_SSL_CTX_set_signing_algorithm_prefs', + '#define SSL_CTX_set_verify_algorithm_prefs GRPC_SHADOW_SSL_CTX_set_verify_algorithm_prefs', + '#define SSL_CTX_use_PrivateKey GRPC_SHADOW_SSL_CTX_use_PrivateKey', + '#define SSL_CTX_use_PrivateKey_ASN1 GRPC_SHADOW_SSL_CTX_use_PrivateKey_ASN1', + '#define SSL_CTX_use_RSAPrivateKey GRPC_SHADOW_SSL_CTX_use_RSAPrivateKey', + '#define SSL_CTX_use_RSAPrivateKey_ASN1 GRPC_SHADOW_SSL_CTX_use_RSAPrivateKey_ASN1', + '#define SSL_get_signature_algorithm_digest GRPC_SHADOW_SSL_get_signature_algorithm_digest', + '#define SSL_get_signature_algorithm_key_type GRPC_SHADOW_SSL_get_signature_algorithm_key_type', + '#define SSL_get_signature_algorithm_name GRPC_SHADOW_SSL_get_signature_algorithm_name', + '#define SSL_is_signature_algorithm_rsa_pss GRPC_SHADOW_SSL_is_signature_algorithm_rsa_pss', + '#define SSL_set_private_key_method GRPC_SHADOW_SSL_set_private_key_method', + '#define SSL_set_signing_algorithm_prefs GRPC_SHADOW_SSL_set_signing_algorithm_prefs', + '#define SSL_use_PrivateKey GRPC_SHADOW_SSL_use_PrivateKey', + '#define SSL_use_PrivateKey_ASN1 GRPC_SHADOW_SSL_use_PrivateKey_ASN1', + '#define SSL_use_RSAPrivateKey GRPC_SHADOW_SSL_use_RSAPrivateKey', + '#define SSL_use_RSAPrivateKey_ASN1 GRPC_SHADOW_SSL_use_RSAPrivateKey_ASN1', + '#define SSL_CTX_add_session GRPC_SHADOW_SSL_CTX_add_session', + '#define SSL_CTX_flush_sessions GRPC_SHADOW_SSL_CTX_flush_sessions', + '#define SSL_CTX_get_channel_id_cb GRPC_SHADOW_SSL_CTX_get_channel_id_cb', + '#define SSL_CTX_get_info_callback GRPC_SHADOW_SSL_CTX_get_info_callback', + '#define SSL_CTX_get_timeout GRPC_SHADOW_SSL_CTX_get_timeout', + '#define SSL_CTX_remove_session GRPC_SHADOW_SSL_CTX_remove_session', + '#define SSL_CTX_sess_get_get_cb GRPC_SHADOW_SSL_CTX_sess_get_get_cb', + '#define SSL_CTX_sess_get_new_cb GRPC_SHADOW_SSL_CTX_sess_get_new_cb', + '#define SSL_CTX_sess_get_remove_cb GRPC_SHADOW_SSL_CTX_sess_get_remove_cb', + '#define SSL_CTX_sess_set_get_cb GRPC_SHADOW_SSL_CTX_sess_set_get_cb', + '#define SSL_CTX_sess_set_new_cb GRPC_SHADOW_SSL_CTX_sess_set_new_cb', + '#define SSL_CTX_sess_set_remove_cb GRPC_SHADOW_SSL_CTX_sess_set_remove_cb', + '#define SSL_CTX_set_channel_id_cb GRPC_SHADOW_SSL_CTX_set_channel_id_cb', + '#define SSL_CTX_set_info_callback GRPC_SHADOW_SSL_CTX_set_info_callback', + '#define SSL_CTX_set_session_psk_dhe_timeout GRPC_SHADOW_SSL_CTX_set_session_psk_dhe_timeout', + '#define SSL_CTX_set_timeout GRPC_SHADOW_SSL_CTX_set_timeout', + '#define SSL_SESSION_free GRPC_SHADOW_SSL_SESSION_free', + '#define SSL_SESSION_get0_peer GRPC_SHADOW_SSL_SESSION_get0_peer', + '#define SSL_SESSION_get0_ticket GRPC_SHADOW_SSL_SESSION_get0_ticket', + '#define SSL_SESSION_get_ex_data GRPC_SHADOW_SSL_SESSION_get_ex_data', + '#define SSL_SESSION_get_ex_new_index GRPC_SHADOW_SSL_SESSION_get_ex_new_index', + '#define SSL_SESSION_get_id GRPC_SHADOW_SSL_SESSION_get_id', + '#define SSL_SESSION_get_master_key GRPC_SHADOW_SSL_SESSION_get_master_key', + '#define SSL_SESSION_get_ticket_lifetime_hint GRPC_SHADOW_SSL_SESSION_get_ticket_lifetime_hint', + '#define SSL_SESSION_get_time GRPC_SHADOW_SSL_SESSION_get_time', + '#define SSL_SESSION_get_timeout GRPC_SHADOW_SSL_SESSION_get_timeout', + '#define SSL_SESSION_has_ticket GRPC_SHADOW_SSL_SESSION_has_ticket', + '#define SSL_SESSION_is_resumable GRPC_SHADOW_SSL_SESSION_is_resumable', + '#define SSL_SESSION_new GRPC_SHADOW_SSL_SESSION_new', + '#define SSL_SESSION_set1_id_context GRPC_SHADOW_SSL_SESSION_set1_id_context', + '#define SSL_SESSION_set_ex_data GRPC_SHADOW_SSL_SESSION_set_ex_data', + '#define SSL_SESSION_set_time GRPC_SHADOW_SSL_SESSION_set_time', + '#define SSL_SESSION_set_timeout GRPC_SHADOW_SSL_SESSION_set_timeout', + '#define SSL_SESSION_should_be_single_use GRPC_SHADOW_SSL_SESSION_should_be_single_use', + '#define SSL_SESSION_up_ref GRPC_SHADOW_SSL_SESSION_up_ref', + '#define SSL_get1_session GRPC_SHADOW_SSL_get1_session', + '#define SSL_get_session GRPC_SHADOW_SSL_get_session', + '#define SSL_magic_pending_session_ptr GRPC_SHADOW_SSL_magic_pending_session_ptr', + '#define SSL_set_session GRPC_SHADOW_SSL_set_session', + '#define SSL_alert_desc_string GRPC_SHADOW_SSL_alert_desc_string', + '#define SSL_alert_desc_string_long GRPC_SHADOW_SSL_alert_desc_string_long', + '#define SSL_alert_type_string GRPC_SHADOW_SSL_alert_type_string', + '#define SSL_alert_type_string_long GRPC_SHADOW_SSL_alert_type_string_long', + '#define SSL_state_string GRPC_SHADOW_SSL_state_string', + '#define SSL_state_string_long GRPC_SHADOW_SSL_state_string_long', + '#define SSL_CTX_set_max_proto_version GRPC_SHADOW_SSL_CTX_set_max_proto_version', + '#define SSL_CTX_set_min_proto_version GRPC_SHADOW_SSL_CTX_set_min_proto_version', + '#define SSL_SESSION_get_protocol_version GRPC_SHADOW_SSL_SESSION_get_protocol_version', + '#define SSL_SESSION_get_version GRPC_SHADOW_SSL_SESSION_get_version', + '#define SSL_SESSION_set_protocol_version GRPC_SHADOW_SSL_SESSION_set_protocol_version', + '#define SSL_get_version GRPC_SHADOW_SSL_get_version', + '#define SSL_set_max_proto_version GRPC_SHADOW_SSL_set_max_proto_version', + '#define SSL_set_min_proto_version GRPC_SHADOW_SSL_set_min_proto_version', + '#define SSL_version GRPC_SHADOW_SSL_version', + '#define PEM_read_SSL_SESSION GRPC_SHADOW_PEM_read_SSL_SESSION', + '#define PEM_read_bio_SSL_SESSION GRPC_SHADOW_PEM_read_bio_SSL_SESSION', + '#define PEM_write_SSL_SESSION GRPC_SHADOW_PEM_write_SSL_SESSION', + '#define PEM_write_bio_SSL_SESSION GRPC_SHADOW_PEM_write_bio_SSL_SESSION', + '#define SSL_CTX_add0_chain_cert GRPC_SHADOW_SSL_CTX_add0_chain_cert', + '#define SSL_CTX_add1_chain_cert GRPC_SHADOW_SSL_CTX_add1_chain_cert', + '#define SSL_CTX_add_client_CA GRPC_SHADOW_SSL_CTX_add_client_CA', + '#define SSL_CTX_add_extra_chain_cert GRPC_SHADOW_SSL_CTX_add_extra_chain_cert', + '#define SSL_CTX_clear_chain_certs GRPC_SHADOW_SSL_CTX_clear_chain_certs', + '#define SSL_CTX_clear_extra_chain_certs GRPC_SHADOW_SSL_CTX_clear_extra_chain_certs', + '#define SSL_CTX_get0_certificate GRPC_SHADOW_SSL_CTX_get0_certificate', + '#define SSL_CTX_get0_chain_certs GRPC_SHADOW_SSL_CTX_get0_chain_certs', + '#define SSL_CTX_get0_param GRPC_SHADOW_SSL_CTX_get0_param', + '#define SSL_CTX_get_cert_store GRPC_SHADOW_SSL_CTX_get_cert_store', + '#define SSL_CTX_get_client_CA_list GRPC_SHADOW_SSL_CTX_get_client_CA_list', + '#define SSL_CTX_get_extra_chain_certs GRPC_SHADOW_SSL_CTX_get_extra_chain_certs', + '#define SSL_CTX_get_verify_callback GRPC_SHADOW_SSL_CTX_get_verify_callback', + '#define SSL_CTX_get_verify_depth GRPC_SHADOW_SSL_CTX_get_verify_depth', + '#define SSL_CTX_get_verify_mode GRPC_SHADOW_SSL_CTX_get_verify_mode', + '#define SSL_CTX_load_verify_locations GRPC_SHADOW_SSL_CTX_load_verify_locations', + '#define SSL_CTX_set0_chain GRPC_SHADOW_SSL_CTX_set0_chain', + '#define SSL_CTX_set0_verify_cert_store GRPC_SHADOW_SSL_CTX_set0_verify_cert_store', + '#define SSL_CTX_set1_chain GRPC_SHADOW_SSL_CTX_set1_chain', + '#define SSL_CTX_set1_param GRPC_SHADOW_SSL_CTX_set1_param', + '#define SSL_CTX_set1_verify_cert_store GRPC_SHADOW_SSL_CTX_set1_verify_cert_store', + '#define SSL_CTX_set_cert_store GRPC_SHADOW_SSL_CTX_set_cert_store', + '#define SSL_CTX_set_cert_verify_callback GRPC_SHADOW_SSL_CTX_set_cert_verify_callback', + '#define SSL_CTX_set_client_CA_list GRPC_SHADOW_SSL_CTX_set_client_CA_list', + '#define SSL_CTX_set_client_cert_cb GRPC_SHADOW_SSL_CTX_set_client_cert_cb', + '#define SSL_CTX_set_default_verify_paths GRPC_SHADOW_SSL_CTX_set_default_verify_paths', + '#define SSL_CTX_set_purpose GRPC_SHADOW_SSL_CTX_set_purpose', + '#define SSL_CTX_set_trust GRPC_SHADOW_SSL_CTX_set_trust', + '#define SSL_CTX_set_verify GRPC_SHADOW_SSL_CTX_set_verify', + '#define SSL_CTX_set_verify_depth GRPC_SHADOW_SSL_CTX_set_verify_depth', + '#define SSL_CTX_use_certificate GRPC_SHADOW_SSL_CTX_use_certificate', + '#define SSL_add0_chain_cert GRPC_SHADOW_SSL_add0_chain_cert', + '#define SSL_add1_chain_cert GRPC_SHADOW_SSL_add1_chain_cert', + '#define SSL_add_client_CA GRPC_SHADOW_SSL_add_client_CA', + '#define SSL_alert_from_verify_result GRPC_SHADOW_SSL_alert_from_verify_result', + '#define SSL_clear_chain_certs GRPC_SHADOW_SSL_clear_chain_certs', + '#define SSL_dup_CA_list GRPC_SHADOW_SSL_dup_CA_list', + '#define SSL_get0_chain_certs GRPC_SHADOW_SSL_get0_chain_certs', + '#define SSL_get0_param GRPC_SHADOW_SSL_get0_param', + '#define SSL_get_certificate GRPC_SHADOW_SSL_get_certificate', + '#define SSL_get_client_CA_list GRPC_SHADOW_SSL_get_client_CA_list', + '#define SSL_get_ex_data_X509_STORE_CTX_idx GRPC_SHADOW_SSL_get_ex_data_X509_STORE_CTX_idx', + '#define SSL_get_peer_cert_chain GRPC_SHADOW_SSL_get_peer_cert_chain', + '#define SSL_get_peer_certificate GRPC_SHADOW_SSL_get_peer_certificate', + '#define SSL_get_peer_full_cert_chain GRPC_SHADOW_SSL_get_peer_full_cert_chain', + '#define SSL_get_verify_callback GRPC_SHADOW_SSL_get_verify_callback', + '#define SSL_get_verify_depth GRPC_SHADOW_SSL_get_verify_depth', + '#define SSL_get_verify_result GRPC_SHADOW_SSL_get_verify_result', + '#define SSL_set0_chain GRPC_SHADOW_SSL_set0_chain', + '#define SSL_set0_verify_cert_store GRPC_SHADOW_SSL_set0_verify_cert_store', + '#define SSL_set1_chain GRPC_SHADOW_SSL_set1_chain', + '#define SSL_set1_param GRPC_SHADOW_SSL_set1_param', + '#define SSL_set1_verify_cert_store GRPC_SHADOW_SSL_set1_verify_cert_store', + '#define SSL_set_client_CA_list GRPC_SHADOW_SSL_set_client_CA_list', + '#define SSL_set_purpose GRPC_SHADOW_SSL_set_purpose', + '#define SSL_set_trust GRPC_SHADOW_SSL_set_trust', + '#define SSL_set_verify GRPC_SHADOW_SSL_set_verify', + '#define SSL_set_verify_depth GRPC_SHADOW_SSL_set_verify_depth', + '#define SSL_set_verify_result GRPC_SHADOW_SSL_set_verify_result', + '#define SSL_use_certificate GRPC_SHADOW_SSL_use_certificate', + '#define d2i_SSL_SESSION GRPC_SHADOW_d2i_SSL_SESSION', + '#define d2i_SSL_SESSION_bio GRPC_SHADOW_d2i_SSL_SESSION_bio', + '#define i2d_SSL_SESSION_bio GRPC_SHADOW_i2d_SSL_SESSION_bio', + '#define SSL_export_early_keying_material GRPC_SHADOW_SSL_export_early_keying_material', + '#define SSL_export_keying_material GRPC_SHADOW_SSL_export_keying_material', + '#define SSL_generate_key_block GRPC_SHADOW_SSL_generate_key_block', + '#define SSL_get_key_block_len GRPC_SHADOW_SSL_get_key_block_len', + '#define SSL_CTX_set_ed25519_enabled GRPC_SHADOW_SSL_CTX_set_ed25519_enabled', + '#define SSL_early_callback_ctx_extension_get GRPC_SHADOW_SSL_early_callback_ctx_extension_get', + '#define SSL_extension_supported GRPC_SHADOW_SSL_extension_supported', + '#define SSLv23_client_method GRPC_SHADOW_SSLv23_client_method', + '#define SSLv23_method GRPC_SHADOW_SSLv23_method', + '#define SSLv23_server_method GRPC_SHADOW_SSLv23_server_method', + '#define TLS_client_method GRPC_SHADOW_TLS_client_method', + '#define TLS_method GRPC_SHADOW_TLS_method', + '#define TLS_server_method GRPC_SHADOW_TLS_server_method', + '#define TLS_with_buffers_method GRPC_SHADOW_TLS_with_buffers_method', + '#define TLSv1_1_client_method GRPC_SHADOW_TLSv1_1_client_method', + '#define TLSv1_1_method GRPC_SHADOW_TLSv1_1_method', + '#define TLSv1_1_server_method GRPC_SHADOW_TLSv1_1_server_method', + '#define TLSv1_2_client_method GRPC_SHADOW_TLSv1_2_client_method', + '#define TLSv1_2_method GRPC_SHADOW_TLSv1_2_method', + '#define TLSv1_2_server_method GRPC_SHADOW_TLSv1_2_server_method', + '#define TLSv1_client_method GRPC_SHADOW_TLSv1_client_method', + '#define TLSv1_method GRPC_SHADOW_TLSv1_method', + '#define TLSv1_server_method GRPC_SHADOW_TLSv1_server_method', + '#define SSL_max_seal_overhead GRPC_SHADOW_SSL_max_seal_overhead', + '#define OPENSSL_cpuid_setup GRPC_SHADOW_OPENSSL_cpuid_setup', + '#define CRYPTO_has_asm GRPC_SHADOW_CRYPTO_has_asm', + '#define CRYPTO_is_confidential_build GRPC_SHADOW_CRYPTO_is_confidential_build', + '#define CRYPTO_library_init GRPC_SHADOW_CRYPTO_library_init', + '#define CRYPTO_malloc_init GRPC_SHADOW_CRYPTO_malloc_init', + '#define ENGINE_load_builtin_engines GRPC_SHADOW_ENGINE_load_builtin_engines', + '#define ENGINE_register_all_complete GRPC_SHADOW_ENGINE_register_all_complete', + '#define OPENSSL_ia32cap_P GRPC_SHADOW_OPENSSL_ia32cap_P', + '#define OPENSSL_init_crypto GRPC_SHADOW_OPENSSL_init_crypto', + '#define OPENSSL_load_builtin_modules GRPC_SHADOW_OPENSSL_load_builtin_modules', + '#define OpenSSL_version GRPC_SHADOW_OpenSSL_version', + '#define OpenSSL_version_num GRPC_SHADOW_OpenSSL_version_num', + '#define SSLeay GRPC_SHADOW_SSLeay', + '#define SSLeay_version GRPC_SHADOW_SSLeay_version', + '#define CRYPTO_cleanup_all_ex_data GRPC_SHADOW_CRYPTO_cleanup_all_ex_data', + '#define CRYPTO_free_ex_data GRPC_SHADOW_CRYPTO_free_ex_data', + '#define CRYPTO_get_ex_data GRPC_SHADOW_CRYPTO_get_ex_data', + '#define CRYPTO_get_ex_new_index GRPC_SHADOW_CRYPTO_get_ex_new_index', + '#define CRYPTO_new_ex_data GRPC_SHADOW_CRYPTO_new_ex_data', + '#define CRYPTO_set_ex_data GRPC_SHADOW_CRYPTO_set_ex_data', + '#define BIO_snprintf GRPC_SHADOW_BIO_snprintf', + '#define BIO_vsnprintf GRPC_SHADOW_BIO_vsnprintf', + '#define CRYPTO_memcmp GRPC_SHADOW_CRYPTO_memcmp', + '#define OPENSSL_cleanse GRPC_SHADOW_OPENSSL_cleanse', + '#define OPENSSL_free GRPC_SHADOW_OPENSSL_free', + '#define OPENSSL_hash32 GRPC_SHADOW_OPENSSL_hash32', + '#define OPENSSL_malloc GRPC_SHADOW_OPENSSL_malloc', + '#define OPENSSL_realloc GRPC_SHADOW_OPENSSL_realloc', + '#define OPENSSL_strcasecmp GRPC_SHADOW_OPENSSL_strcasecmp', + '#define OPENSSL_strdup GRPC_SHADOW_OPENSSL_strdup', + '#define OPENSSL_strncasecmp GRPC_SHADOW_OPENSSL_strncasecmp', + '#define OPENSSL_strnlen GRPC_SHADOW_OPENSSL_strnlen', + '#define OPENSSL_tolower GRPC_SHADOW_OPENSSL_tolower', + '#define CRYPTO_refcount_dec_and_test_zero GRPC_SHADOW_CRYPTO_refcount_dec_and_test_zero', + '#define CRYPTO_refcount_inc GRPC_SHADOW_CRYPTO_refcount_inc', + '#define CRYPTO_THREADID_current GRPC_SHADOW_CRYPTO_THREADID_current', + '#define CRYPTO_THREADID_set_callback GRPC_SHADOW_CRYPTO_THREADID_set_callback', + '#define CRYPTO_THREADID_set_numeric GRPC_SHADOW_CRYPTO_THREADID_set_numeric', + '#define CRYPTO_THREADID_set_pointer GRPC_SHADOW_CRYPTO_THREADID_set_pointer', + '#define CRYPTO_get_dynlock_create_callback GRPC_SHADOW_CRYPTO_get_dynlock_create_callback', + '#define CRYPTO_get_dynlock_destroy_callback GRPC_SHADOW_CRYPTO_get_dynlock_destroy_callback', + '#define CRYPTO_get_dynlock_lock_callback GRPC_SHADOW_CRYPTO_get_dynlock_lock_callback', + '#define CRYPTO_get_lock_name GRPC_SHADOW_CRYPTO_get_lock_name', + '#define CRYPTO_get_locking_callback GRPC_SHADOW_CRYPTO_get_locking_callback', + '#define CRYPTO_num_locks GRPC_SHADOW_CRYPTO_num_locks', + '#define CRYPTO_set_add_lock_callback GRPC_SHADOW_CRYPTO_set_add_lock_callback', + '#define CRYPTO_set_dynlock_create_callback GRPC_SHADOW_CRYPTO_set_dynlock_create_callback', + '#define CRYPTO_set_dynlock_destroy_callback GRPC_SHADOW_CRYPTO_set_dynlock_destroy_callback', + '#define CRYPTO_set_dynlock_lock_callback GRPC_SHADOW_CRYPTO_set_dynlock_lock_callback', + '#define CRYPTO_set_id_callback GRPC_SHADOW_CRYPTO_set_id_callback', + '#define CRYPTO_set_locking_callback GRPC_SHADOW_CRYPTO_set_locking_callback', + '#define CRYPTO_MUTEX_cleanup GRPC_SHADOW_CRYPTO_MUTEX_cleanup', + '#define CRYPTO_MUTEX_init GRPC_SHADOW_CRYPTO_MUTEX_init', + '#define CRYPTO_MUTEX_lock_read GRPC_SHADOW_CRYPTO_MUTEX_lock_read', + '#define CRYPTO_MUTEX_lock_write GRPC_SHADOW_CRYPTO_MUTEX_lock_write', + '#define CRYPTO_MUTEX_unlock_read GRPC_SHADOW_CRYPTO_MUTEX_unlock_read', + '#define CRYPTO_MUTEX_unlock_write GRPC_SHADOW_CRYPTO_MUTEX_unlock_write', + '#define CRYPTO_STATIC_MUTEX_lock_read GRPC_SHADOW_CRYPTO_STATIC_MUTEX_lock_read', + '#define CRYPTO_STATIC_MUTEX_lock_write GRPC_SHADOW_CRYPTO_STATIC_MUTEX_lock_write', + '#define CRYPTO_STATIC_MUTEX_unlock_read GRPC_SHADOW_CRYPTO_STATIC_MUTEX_unlock_read', + '#define CRYPTO_STATIC_MUTEX_unlock_write GRPC_SHADOW_CRYPTO_STATIC_MUTEX_unlock_write', + '#define CRYPTO_get_thread_local GRPC_SHADOW_CRYPTO_get_thread_local', + '#define CRYPTO_once GRPC_SHADOW_CRYPTO_once', + '#define CRYPTO_set_thread_local GRPC_SHADOW_CRYPTO_set_thread_local', + '#define sk_deep_copy GRPC_SHADOW_sk_deep_copy', + '#define sk_delete GRPC_SHADOW_sk_delete', + '#define sk_delete_ptr GRPC_SHADOW_sk_delete_ptr', + '#define sk_dup GRPC_SHADOW_sk_dup', + '#define sk_find GRPC_SHADOW_sk_find', + '#define sk_free GRPC_SHADOW_sk_free', + '#define sk_insert GRPC_SHADOW_sk_insert', + '#define sk_is_sorted GRPC_SHADOW_sk_is_sorted', + '#define sk_new GRPC_SHADOW_sk_new', + '#define sk_new_null GRPC_SHADOW_sk_new_null', + '#define sk_num GRPC_SHADOW_sk_num', + '#define sk_pop GRPC_SHADOW_sk_pop', + '#define sk_pop_free GRPC_SHADOW_sk_pop_free', + '#define sk_push GRPC_SHADOW_sk_push', + '#define sk_set GRPC_SHADOW_sk_set', + '#define sk_set_cmp_func GRPC_SHADOW_sk_set_cmp_func', + '#define sk_shift GRPC_SHADOW_sk_shift', + '#define sk_sort GRPC_SHADOW_sk_sort', + '#define sk_value GRPC_SHADOW_sk_value', + '#define sk_zero GRPC_SHADOW_sk_zero', + '#define lh_delete GRPC_SHADOW_lh_delete', + '#define lh_doall GRPC_SHADOW_lh_doall', + '#define lh_doall_arg GRPC_SHADOW_lh_doall_arg', + '#define lh_free GRPC_SHADOW_lh_free', + '#define lh_insert GRPC_SHADOW_lh_insert', + '#define lh_new GRPC_SHADOW_lh_new', + '#define lh_num_items GRPC_SHADOW_lh_num_items', + '#define lh_retrieve GRPC_SHADOW_lh_retrieve', + '#define lh_strhash GRPC_SHADOW_lh_strhash', + '#define ERR_SAVE_STATE_free GRPC_SHADOW_ERR_SAVE_STATE_free', + '#define ERR_add_error_data GRPC_SHADOW_ERR_add_error_data', + '#define ERR_add_error_dataf GRPC_SHADOW_ERR_add_error_dataf', + '#define ERR_clear_error GRPC_SHADOW_ERR_clear_error', + '#define ERR_clear_system_error GRPC_SHADOW_ERR_clear_system_error', + '#define ERR_error_string GRPC_SHADOW_ERR_error_string', + '#define ERR_error_string_n GRPC_SHADOW_ERR_error_string_n', + '#define ERR_free_strings GRPC_SHADOW_ERR_free_strings', + '#define ERR_func_error_string GRPC_SHADOW_ERR_func_error_string', + '#define ERR_get_error GRPC_SHADOW_ERR_get_error', + '#define ERR_get_error_line GRPC_SHADOW_ERR_get_error_line', + '#define ERR_get_error_line_data GRPC_SHADOW_ERR_get_error_line_data', + '#define ERR_get_next_error_library GRPC_SHADOW_ERR_get_next_error_library', + '#define ERR_lib_error_string GRPC_SHADOW_ERR_lib_error_string', + '#define ERR_load_BIO_strings GRPC_SHADOW_ERR_load_BIO_strings', + '#define ERR_load_ERR_strings GRPC_SHADOW_ERR_load_ERR_strings', + '#define ERR_load_crypto_strings GRPC_SHADOW_ERR_load_crypto_strings', + '#define ERR_peek_error GRPC_SHADOW_ERR_peek_error', + '#define ERR_peek_error_line GRPC_SHADOW_ERR_peek_error_line', + '#define ERR_peek_error_line_data GRPC_SHADOW_ERR_peek_error_line_data', + '#define ERR_peek_last_error GRPC_SHADOW_ERR_peek_last_error', + '#define ERR_peek_last_error_line GRPC_SHADOW_ERR_peek_last_error_line', + '#define ERR_peek_last_error_line_data GRPC_SHADOW_ERR_peek_last_error_line_data', + '#define ERR_pop_to_mark GRPC_SHADOW_ERR_pop_to_mark', + '#define ERR_print_errors_cb GRPC_SHADOW_ERR_print_errors_cb', + '#define ERR_print_errors_fp GRPC_SHADOW_ERR_print_errors_fp', + '#define ERR_put_error GRPC_SHADOW_ERR_put_error', + '#define ERR_reason_error_string GRPC_SHADOW_ERR_reason_error_string', + '#define ERR_remove_state GRPC_SHADOW_ERR_remove_state', + '#define ERR_remove_thread_state GRPC_SHADOW_ERR_remove_thread_state', + '#define ERR_restore_state GRPC_SHADOW_ERR_restore_state', + '#define ERR_save_state GRPC_SHADOW_ERR_save_state', + '#define ERR_set_mark GRPC_SHADOW_ERR_set_mark', + '#define kOpenSSLReasonStringData GRPC_SHADOW_kOpenSSLReasonStringData', + '#define kOpenSSLReasonValues GRPC_SHADOW_kOpenSSLReasonValues', + '#define kOpenSSLReasonValuesLen GRPC_SHADOW_kOpenSSLReasonValuesLen', + '#define EVP_DecodeBase64 GRPC_SHADOW_EVP_DecodeBase64', + '#define EVP_DecodeBlock GRPC_SHADOW_EVP_DecodeBlock', + '#define EVP_DecodeFinal GRPC_SHADOW_EVP_DecodeFinal', + '#define EVP_DecodeInit GRPC_SHADOW_EVP_DecodeInit', + '#define EVP_DecodeUpdate GRPC_SHADOW_EVP_DecodeUpdate', + '#define EVP_DecodedLength GRPC_SHADOW_EVP_DecodedLength', + '#define EVP_EncodeBlock GRPC_SHADOW_EVP_EncodeBlock', + '#define EVP_EncodeFinal GRPC_SHADOW_EVP_EncodeFinal', + '#define EVP_EncodeInit GRPC_SHADOW_EVP_EncodeInit', + '#define EVP_EncodeUpdate GRPC_SHADOW_EVP_EncodeUpdate', + '#define EVP_EncodedLength GRPC_SHADOW_EVP_EncodedLength', + '#define CBB_finish_i2d GRPC_SHADOW_CBB_finish_i2d', + '#define CBS_asn1_ber_to_der GRPC_SHADOW_CBS_asn1_ber_to_der', + '#define CBS_get_asn1_implicit_string GRPC_SHADOW_CBS_get_asn1_implicit_string', + '#define CBS_asn1_bitstring_has_bit GRPC_SHADOW_CBS_asn1_bitstring_has_bit', + '#define CBS_asn1_oid_to_text GRPC_SHADOW_CBS_asn1_oid_to_text', + '#define CBS_contains_zero_byte GRPC_SHADOW_CBS_contains_zero_byte', + '#define CBS_copy_bytes GRPC_SHADOW_CBS_copy_bytes', + '#define CBS_data GRPC_SHADOW_CBS_data', + '#define CBS_get_any_asn1 GRPC_SHADOW_CBS_get_any_asn1', + '#define CBS_get_any_asn1_element GRPC_SHADOW_CBS_get_any_asn1_element', + '#define CBS_get_any_ber_asn1_element GRPC_SHADOW_CBS_get_any_ber_asn1_element', + '#define CBS_get_asn1 GRPC_SHADOW_CBS_get_asn1', + '#define CBS_get_asn1_bool GRPC_SHADOW_CBS_get_asn1_bool', + '#define CBS_get_asn1_element GRPC_SHADOW_CBS_get_asn1_element', + '#define CBS_get_asn1_uint64 GRPC_SHADOW_CBS_get_asn1_uint64', + '#define CBS_get_bytes GRPC_SHADOW_CBS_get_bytes', + '#define CBS_get_last_u8 GRPC_SHADOW_CBS_get_last_u8', + '#define CBS_get_optional_asn1 GRPC_SHADOW_CBS_get_optional_asn1', + '#define CBS_get_optional_asn1_bool GRPC_SHADOW_CBS_get_optional_asn1_bool', + '#define CBS_get_optional_asn1_octet_string GRPC_SHADOW_CBS_get_optional_asn1_octet_string', + '#define CBS_get_optional_asn1_uint64 GRPC_SHADOW_CBS_get_optional_asn1_uint64', + '#define CBS_get_u16 GRPC_SHADOW_CBS_get_u16', + '#define CBS_get_u16_length_prefixed GRPC_SHADOW_CBS_get_u16_length_prefixed', + '#define CBS_get_u24 GRPC_SHADOW_CBS_get_u24', + '#define CBS_get_u24_length_prefixed GRPC_SHADOW_CBS_get_u24_length_prefixed', + '#define CBS_get_u32 GRPC_SHADOW_CBS_get_u32', + '#define CBS_get_u8 GRPC_SHADOW_CBS_get_u8', + '#define CBS_get_u8_length_prefixed GRPC_SHADOW_CBS_get_u8_length_prefixed', + '#define CBS_init GRPC_SHADOW_CBS_init', + '#define CBS_is_valid_asn1_bitstring GRPC_SHADOW_CBS_is_valid_asn1_bitstring', + '#define CBS_len GRPC_SHADOW_CBS_len', + '#define CBS_mem_equal GRPC_SHADOW_CBS_mem_equal', + '#define CBS_peek_asn1_tag GRPC_SHADOW_CBS_peek_asn1_tag', + '#define CBS_skip GRPC_SHADOW_CBS_skip', + '#define CBS_stow GRPC_SHADOW_CBS_stow', + '#define CBS_strdup GRPC_SHADOW_CBS_strdup', + '#define CBB_add_asn1 GRPC_SHADOW_CBB_add_asn1', + '#define CBB_add_asn1_bool GRPC_SHADOW_CBB_add_asn1_bool', + '#define CBB_add_asn1_octet_string GRPC_SHADOW_CBB_add_asn1_octet_string', + '#define CBB_add_asn1_oid_from_text GRPC_SHADOW_CBB_add_asn1_oid_from_text', + '#define CBB_add_asn1_uint64 GRPC_SHADOW_CBB_add_asn1_uint64', + '#define CBB_add_bytes GRPC_SHADOW_CBB_add_bytes', + '#define CBB_add_space GRPC_SHADOW_CBB_add_space', + '#define CBB_add_u16 GRPC_SHADOW_CBB_add_u16', + '#define CBB_add_u16_length_prefixed GRPC_SHADOW_CBB_add_u16_length_prefixed', + '#define CBB_add_u24 GRPC_SHADOW_CBB_add_u24', + '#define CBB_add_u24_length_prefixed GRPC_SHADOW_CBB_add_u24_length_prefixed', + '#define CBB_add_u32 GRPC_SHADOW_CBB_add_u32', + '#define CBB_add_u8 GRPC_SHADOW_CBB_add_u8', + '#define CBB_add_u8_length_prefixed GRPC_SHADOW_CBB_add_u8_length_prefixed', + '#define CBB_cleanup GRPC_SHADOW_CBB_cleanup', + '#define CBB_data GRPC_SHADOW_CBB_data', + '#define CBB_did_write GRPC_SHADOW_CBB_did_write', + '#define CBB_discard_child GRPC_SHADOW_CBB_discard_child', + '#define CBB_finish GRPC_SHADOW_CBB_finish', + '#define CBB_flush GRPC_SHADOW_CBB_flush', + '#define CBB_flush_asn1_set_of GRPC_SHADOW_CBB_flush_asn1_set_of', + '#define CBB_init GRPC_SHADOW_CBB_init', + '#define CBB_init_fixed GRPC_SHADOW_CBB_init_fixed', + '#define CBB_len GRPC_SHADOW_CBB_len', + '#define CBB_reserve GRPC_SHADOW_CBB_reserve', + '#define CBB_zero GRPC_SHADOW_CBB_zero', + '#define CRYPTO_BUFFER_POOL_free GRPC_SHADOW_CRYPTO_BUFFER_POOL_free', + '#define CRYPTO_BUFFER_POOL_new GRPC_SHADOW_CRYPTO_BUFFER_POOL_new', + '#define CRYPTO_BUFFER_data GRPC_SHADOW_CRYPTO_BUFFER_data', + '#define CRYPTO_BUFFER_free GRPC_SHADOW_CRYPTO_BUFFER_free', + '#define CRYPTO_BUFFER_init_CBS GRPC_SHADOW_CRYPTO_BUFFER_init_CBS', + '#define CRYPTO_BUFFER_len GRPC_SHADOW_CRYPTO_BUFFER_len', + '#define CRYPTO_BUFFER_new GRPC_SHADOW_CRYPTO_BUFFER_new', + '#define CRYPTO_BUFFER_new_from_CBS GRPC_SHADOW_CRYPTO_BUFFER_new_from_CBS', + '#define CRYPTO_BUFFER_up_ref GRPC_SHADOW_CRYPTO_BUFFER_up_ref', + '#define AES_cbc_encrypt GRPC_SHADOW_AES_cbc_encrypt', + '#define AES_cfb128_encrypt GRPC_SHADOW_AES_cfb128_encrypt', + '#define AES_ctr128_encrypt GRPC_SHADOW_AES_ctr128_encrypt', + '#define AES_decrypt GRPC_SHADOW_AES_decrypt', + '#define AES_ecb_encrypt GRPC_SHADOW_AES_ecb_encrypt', + '#define AES_encrypt GRPC_SHADOW_AES_encrypt', + '#define AES_ofb128_encrypt GRPC_SHADOW_AES_ofb128_encrypt', + '#define AES_set_decrypt_key GRPC_SHADOW_AES_set_decrypt_key', + '#define AES_set_encrypt_key GRPC_SHADOW_AES_set_encrypt_key', + '#define AES_unwrap_key GRPC_SHADOW_AES_unwrap_key', + '#define AES_wrap_key GRPC_SHADOW_AES_wrap_key', + '#define BN_BLINDING_convert GRPC_SHADOW_BN_BLINDING_convert', + '#define BN_BLINDING_free GRPC_SHADOW_BN_BLINDING_free', + '#define BN_BLINDING_invert GRPC_SHADOW_BN_BLINDING_invert', + '#define BN_BLINDING_new GRPC_SHADOW_BN_BLINDING_new', + '#define BN_CTX_end GRPC_SHADOW_BN_CTX_end', + '#define BN_CTX_free GRPC_SHADOW_BN_CTX_free', + '#define BN_CTX_get GRPC_SHADOW_BN_CTX_get', + '#define BN_CTX_new GRPC_SHADOW_BN_CTX_new', + '#define BN_CTX_start GRPC_SHADOW_BN_CTX_start', + '#define BN_GENCB_call GRPC_SHADOW_BN_GENCB_call', + '#define BN_GENCB_set GRPC_SHADOW_BN_GENCB_set', + '#define BN_MONT_CTX_copy GRPC_SHADOW_BN_MONT_CTX_copy', + '#define BN_MONT_CTX_free GRPC_SHADOW_BN_MONT_CTX_free', + '#define BN_MONT_CTX_new GRPC_SHADOW_BN_MONT_CTX_new', + '#define BN_MONT_CTX_new_for_modulus GRPC_SHADOW_BN_MONT_CTX_new_for_modulus', + '#define BN_MONT_CTX_set GRPC_SHADOW_BN_MONT_CTX_set', + '#define BN_MONT_CTX_set_locked GRPC_SHADOW_BN_MONT_CTX_set_locked', + '#define BN_abs_is_word GRPC_SHADOW_BN_abs_is_word', + '#define BN_add GRPC_SHADOW_BN_add', + '#define BN_add_word GRPC_SHADOW_BN_add_word', + '#define BN_bin2bn GRPC_SHADOW_BN_bin2bn', + '#define BN_bn2bin GRPC_SHADOW_BN_bn2bin', + '#define BN_bn2bin_padded GRPC_SHADOW_BN_bn2bin_padded', + '#define BN_bn2le_padded GRPC_SHADOW_BN_bn2le_padded', + '#define BN_clear GRPC_SHADOW_BN_clear', + '#define BN_clear_bit GRPC_SHADOW_BN_clear_bit', + '#define BN_clear_free GRPC_SHADOW_BN_clear_free', + '#define BN_cmp GRPC_SHADOW_BN_cmp', + '#define BN_cmp_word GRPC_SHADOW_BN_cmp_word', + '#define BN_copy GRPC_SHADOW_BN_copy', + '#define BN_count_low_zero_bits GRPC_SHADOW_BN_count_low_zero_bits', + '#define BN_div GRPC_SHADOW_BN_div', + '#define BN_div_word GRPC_SHADOW_BN_div_word', + '#define BN_dup GRPC_SHADOW_BN_dup', + '#define BN_enhanced_miller_rabin_primality_test GRPC_SHADOW_BN_enhanced_miller_rabin_primality_test', + '#define BN_equal_consttime GRPC_SHADOW_BN_equal_consttime', + '#define BN_exp GRPC_SHADOW_BN_exp', + '#define BN_free GRPC_SHADOW_BN_free', + '#define BN_from_montgomery GRPC_SHADOW_BN_from_montgomery', + '#define BN_gcd GRPC_SHADOW_BN_gcd', + '#define BN_generate_prime_ex GRPC_SHADOW_BN_generate_prime_ex', + '#define BN_get_u64 GRPC_SHADOW_BN_get_u64', + '#define BN_get_word GRPC_SHADOW_BN_get_word', + '#define BN_init GRPC_SHADOW_BN_init', + '#define BN_is_bit_set GRPC_SHADOW_BN_is_bit_set', + '#define BN_is_negative GRPC_SHADOW_BN_is_negative', + '#define BN_is_odd GRPC_SHADOW_BN_is_odd', + '#define BN_is_one GRPC_SHADOW_BN_is_one', + '#define BN_is_pow2 GRPC_SHADOW_BN_is_pow2', + '#define BN_is_prime_ex GRPC_SHADOW_BN_is_prime_ex', + '#define BN_is_prime_fasttest_ex GRPC_SHADOW_BN_is_prime_fasttest_ex', + '#define BN_is_word GRPC_SHADOW_BN_is_word', + '#define BN_is_zero GRPC_SHADOW_BN_is_zero', + '#define BN_le2bn GRPC_SHADOW_BN_le2bn', + '#define BN_lshift GRPC_SHADOW_BN_lshift', + '#define BN_lshift1 GRPC_SHADOW_BN_lshift1', + '#define BN_mask_bits GRPC_SHADOW_BN_mask_bits', + '#define BN_mod_add GRPC_SHADOW_BN_mod_add', + '#define BN_mod_add_quick GRPC_SHADOW_BN_mod_add_quick', + '#define BN_mod_exp GRPC_SHADOW_BN_mod_exp', + '#define BN_mod_exp2_mont GRPC_SHADOW_BN_mod_exp2_mont', + '#define BN_mod_exp_mont GRPC_SHADOW_BN_mod_exp_mont', + '#define BN_mod_exp_mont_consttime GRPC_SHADOW_BN_mod_exp_mont_consttime', + '#define BN_mod_exp_mont_word GRPC_SHADOW_BN_mod_exp_mont_word', + '#define BN_mod_inverse GRPC_SHADOW_BN_mod_inverse', + '#define BN_mod_inverse_blinded GRPC_SHADOW_BN_mod_inverse_blinded', + '#define BN_mod_inverse_odd GRPC_SHADOW_BN_mod_inverse_odd', + '#define BN_mod_lshift GRPC_SHADOW_BN_mod_lshift', + '#define BN_mod_lshift1 GRPC_SHADOW_BN_mod_lshift1', + '#define BN_mod_lshift1_quick GRPC_SHADOW_BN_mod_lshift1_quick', + '#define BN_mod_lshift_quick GRPC_SHADOW_BN_mod_lshift_quick', + '#define BN_mod_mul GRPC_SHADOW_BN_mod_mul', + '#define BN_mod_mul_montgomery GRPC_SHADOW_BN_mod_mul_montgomery', + '#define BN_mod_pow2 GRPC_SHADOW_BN_mod_pow2', + '#define BN_mod_sqr GRPC_SHADOW_BN_mod_sqr', + '#define BN_mod_sqrt GRPC_SHADOW_BN_mod_sqrt', + '#define BN_mod_sub GRPC_SHADOW_BN_mod_sub', + '#define BN_mod_sub_quick GRPC_SHADOW_BN_mod_sub_quick', + '#define BN_mod_word GRPC_SHADOW_BN_mod_word', + '#define BN_mul GRPC_SHADOW_BN_mul', + '#define BN_mul_word GRPC_SHADOW_BN_mul_word', + '#define BN_new GRPC_SHADOW_BN_new', + '#define BN_nnmod GRPC_SHADOW_BN_nnmod', + '#define BN_nnmod_pow2 GRPC_SHADOW_BN_nnmod_pow2', + '#define BN_num_bits GRPC_SHADOW_BN_num_bits', + '#define BN_num_bits_word GRPC_SHADOW_BN_num_bits_word', + '#define BN_num_bytes GRPC_SHADOW_BN_num_bytes', + '#define BN_one GRPC_SHADOW_BN_one', + '#define BN_primality_test GRPC_SHADOW_BN_primality_test', + '#define BN_pseudo_rand GRPC_SHADOW_BN_pseudo_rand', + '#define BN_pseudo_rand_range GRPC_SHADOW_BN_pseudo_rand_range', + '#define BN_rand GRPC_SHADOW_BN_rand', + '#define BN_rand_range GRPC_SHADOW_BN_rand_range', + '#define BN_rand_range_ex GRPC_SHADOW_BN_rand_range_ex', + '#define BN_rshift GRPC_SHADOW_BN_rshift', + '#define BN_rshift1 GRPC_SHADOW_BN_rshift1', + '#define BN_set_bit GRPC_SHADOW_BN_set_bit', + '#define BN_set_negative GRPC_SHADOW_BN_set_negative', + '#define BN_set_u64 GRPC_SHADOW_BN_set_u64', + '#define BN_set_word GRPC_SHADOW_BN_set_word', + '#define BN_sqr GRPC_SHADOW_BN_sqr', + '#define BN_sqrt GRPC_SHADOW_BN_sqrt', + '#define BN_sub GRPC_SHADOW_BN_sub', + '#define BN_sub_word GRPC_SHADOW_BN_sub_word', + '#define BN_to_montgomery GRPC_SHADOW_BN_to_montgomery', + '#define BN_uadd GRPC_SHADOW_BN_uadd', + '#define BN_ucmp GRPC_SHADOW_BN_ucmp', + '#define BN_usub GRPC_SHADOW_BN_usub', + '#define BN_value_one GRPC_SHADOW_BN_value_one', + '#define BN_zero GRPC_SHADOW_BN_zero', + '#define BORINGSSL_self_test GRPC_SHADOW_BORINGSSL_self_test', + '#define CRYPTO_POLYVAL_finish GRPC_SHADOW_CRYPTO_POLYVAL_finish', + '#define CRYPTO_POLYVAL_init GRPC_SHADOW_CRYPTO_POLYVAL_init', + '#define CRYPTO_POLYVAL_update_blocks GRPC_SHADOW_CRYPTO_POLYVAL_update_blocks', + '#define CRYPTO_cbc128_decrypt GRPC_SHADOW_CRYPTO_cbc128_decrypt', + '#define CRYPTO_cbc128_encrypt GRPC_SHADOW_CRYPTO_cbc128_encrypt', + '#define CRYPTO_ccm128_decrypt GRPC_SHADOW_CRYPTO_ccm128_decrypt', + '#define CRYPTO_ccm128_encrypt GRPC_SHADOW_CRYPTO_ccm128_encrypt', + '#define CRYPTO_ccm128_init GRPC_SHADOW_CRYPTO_ccm128_init', + '#define CRYPTO_ccm128_max_input GRPC_SHADOW_CRYPTO_ccm128_max_input', + '#define CRYPTO_cfb128_1_encrypt GRPC_SHADOW_CRYPTO_cfb128_1_encrypt', + '#define CRYPTO_cfb128_8_encrypt GRPC_SHADOW_CRYPTO_cfb128_8_encrypt', + '#define CRYPTO_cfb128_encrypt GRPC_SHADOW_CRYPTO_cfb128_encrypt', + '#define CRYPTO_ctr128_encrypt GRPC_SHADOW_CRYPTO_ctr128_encrypt', + '#define CRYPTO_ctr128_encrypt_ctr32 GRPC_SHADOW_CRYPTO_ctr128_encrypt_ctr32', + '#define CRYPTO_gcm128_aad GRPC_SHADOW_CRYPTO_gcm128_aad', + '#define CRYPTO_gcm128_decrypt GRPC_SHADOW_CRYPTO_gcm128_decrypt', + '#define CRYPTO_gcm128_decrypt_ctr32 GRPC_SHADOW_CRYPTO_gcm128_decrypt_ctr32', + '#define CRYPTO_gcm128_encrypt GRPC_SHADOW_CRYPTO_gcm128_encrypt', + '#define CRYPTO_gcm128_encrypt_ctr32 GRPC_SHADOW_CRYPTO_gcm128_encrypt_ctr32', + '#define CRYPTO_gcm128_finish GRPC_SHADOW_CRYPTO_gcm128_finish', + '#define CRYPTO_gcm128_init GRPC_SHADOW_CRYPTO_gcm128_init', + '#define CRYPTO_gcm128_setiv GRPC_SHADOW_CRYPTO_gcm128_setiv', + '#define CRYPTO_gcm128_tag GRPC_SHADOW_CRYPTO_gcm128_tag', + '#define CRYPTO_ghash_init GRPC_SHADOW_CRYPTO_ghash_init', + '#define CRYPTO_ofb128_encrypt GRPC_SHADOW_CRYPTO_ofb128_encrypt', + '#define CRYPTO_sysrand GRPC_SHADOW_CRYPTO_sysrand', + '#define CRYPTO_tls1_prf GRPC_SHADOW_CRYPTO_tls1_prf', + '#define CTR_DRBG_clear GRPC_SHADOW_CTR_DRBG_clear', + '#define CTR_DRBG_generate GRPC_SHADOW_CTR_DRBG_generate', + '#define CTR_DRBG_init GRPC_SHADOW_CTR_DRBG_init', + '#define CTR_DRBG_reseed GRPC_SHADOW_CTR_DRBG_reseed', + '#define DES_decrypt3 GRPC_SHADOW_DES_decrypt3', + '#define DES_ecb3_encrypt GRPC_SHADOW_DES_ecb3_encrypt', + '#define DES_ecb_encrypt GRPC_SHADOW_DES_ecb_encrypt', + '#define DES_ede2_cbc_encrypt GRPC_SHADOW_DES_ede2_cbc_encrypt', + '#define DES_ede3_cbc_encrypt GRPC_SHADOW_DES_ede3_cbc_encrypt', + '#define DES_encrypt3 GRPC_SHADOW_DES_encrypt3', + '#define DES_ncbc_encrypt GRPC_SHADOW_DES_ncbc_encrypt', + '#define DES_set_key GRPC_SHADOW_DES_set_key', + '#define DES_set_key_unchecked GRPC_SHADOW_DES_set_key_unchecked', + '#define DES_set_odd_parity GRPC_SHADOW_DES_set_odd_parity', + '#define ECDSA_SIG_free GRPC_SHADOW_ECDSA_SIG_free', + '#define ECDSA_SIG_get0 GRPC_SHADOW_ECDSA_SIG_get0', + '#define ECDSA_SIG_new GRPC_SHADOW_ECDSA_SIG_new', + '#define ECDSA_SIG_set0 GRPC_SHADOW_ECDSA_SIG_set0', + '#define ECDSA_do_sign GRPC_SHADOW_ECDSA_do_sign', + '#define ECDSA_do_verify GRPC_SHADOW_ECDSA_do_verify', + '#define EC_GFp_mont_method GRPC_SHADOW_EC_GFp_mont_method', + '#define EC_GFp_nistp224_method GRPC_SHADOW_EC_GFp_nistp224_method', + '#define EC_GFp_nistp256_method GRPC_SHADOW_EC_GFp_nistp256_method', + '#define EC_GFp_nistz256_method GRPC_SHADOW_EC_GFp_nistz256_method', + '#define EC_GROUP_cmp GRPC_SHADOW_EC_GROUP_cmp', + '#define EC_GROUP_dup GRPC_SHADOW_EC_GROUP_dup', + '#define EC_GROUP_free GRPC_SHADOW_EC_GROUP_free', + '#define EC_GROUP_get0_generator GRPC_SHADOW_EC_GROUP_get0_generator', + '#define EC_GROUP_get0_order GRPC_SHADOW_EC_GROUP_get0_order', + '#define EC_GROUP_get_cofactor GRPC_SHADOW_EC_GROUP_get_cofactor', + '#define EC_GROUP_get_curve_GFp GRPC_SHADOW_EC_GROUP_get_curve_GFp', + '#define EC_GROUP_get_curve_name GRPC_SHADOW_EC_GROUP_get_curve_name', + '#define EC_GROUP_get_degree GRPC_SHADOW_EC_GROUP_get_degree', + '#define EC_GROUP_get_order GRPC_SHADOW_EC_GROUP_get_order', + '#define EC_GROUP_method_of GRPC_SHADOW_EC_GROUP_method_of', + '#define EC_GROUP_new_by_curve_name GRPC_SHADOW_EC_GROUP_new_by_curve_name', + '#define EC_GROUP_new_curve_GFp GRPC_SHADOW_EC_GROUP_new_curve_GFp', + '#define EC_GROUP_set_asn1_flag GRPC_SHADOW_EC_GROUP_set_asn1_flag', + '#define EC_GROUP_set_generator GRPC_SHADOW_EC_GROUP_set_generator', + '#define EC_GROUP_set_point_conversion_form GRPC_SHADOW_EC_GROUP_set_point_conversion_form', + '#define EC_KEY_check_fips GRPC_SHADOW_EC_KEY_check_fips', + '#define EC_KEY_check_key GRPC_SHADOW_EC_KEY_check_key', + '#define EC_KEY_dup GRPC_SHADOW_EC_KEY_dup', + '#define EC_KEY_free GRPC_SHADOW_EC_KEY_free', + '#define EC_KEY_generate_key GRPC_SHADOW_EC_KEY_generate_key', + '#define EC_KEY_generate_key_fips GRPC_SHADOW_EC_KEY_generate_key_fips', + '#define EC_KEY_get0_group GRPC_SHADOW_EC_KEY_get0_group', + '#define EC_KEY_get0_private_key GRPC_SHADOW_EC_KEY_get0_private_key', + '#define EC_KEY_get0_public_key GRPC_SHADOW_EC_KEY_get0_public_key', + '#define EC_KEY_get_conv_form GRPC_SHADOW_EC_KEY_get_conv_form', + '#define EC_KEY_get_enc_flags GRPC_SHADOW_EC_KEY_get_enc_flags', + '#define EC_KEY_get_ex_data GRPC_SHADOW_EC_KEY_get_ex_data', + '#define EC_KEY_get_ex_new_index GRPC_SHADOW_EC_KEY_get_ex_new_index', + '#define EC_KEY_is_opaque GRPC_SHADOW_EC_KEY_is_opaque', + '#define EC_KEY_new GRPC_SHADOW_EC_KEY_new', + '#define EC_KEY_new_by_curve_name GRPC_SHADOW_EC_KEY_new_by_curve_name', + '#define EC_KEY_new_method GRPC_SHADOW_EC_KEY_new_method', + '#define EC_KEY_set_asn1_flag GRPC_SHADOW_EC_KEY_set_asn1_flag', + '#define EC_KEY_set_conv_form GRPC_SHADOW_EC_KEY_set_conv_form', + '#define EC_KEY_set_enc_flags GRPC_SHADOW_EC_KEY_set_enc_flags', + '#define EC_KEY_set_ex_data GRPC_SHADOW_EC_KEY_set_ex_data', + '#define EC_KEY_set_group GRPC_SHADOW_EC_KEY_set_group', + '#define EC_KEY_set_private_key GRPC_SHADOW_EC_KEY_set_private_key', + '#define EC_KEY_set_public_key GRPC_SHADOW_EC_KEY_set_public_key', + '#define EC_KEY_set_public_key_affine_coordinates GRPC_SHADOW_EC_KEY_set_public_key_affine_coordinates', + '#define EC_KEY_up_ref GRPC_SHADOW_EC_KEY_up_ref', + '#define EC_METHOD_get_field_type GRPC_SHADOW_EC_METHOD_get_field_type', + '#define EC_POINT_add GRPC_SHADOW_EC_POINT_add', + '#define EC_POINT_clear_free GRPC_SHADOW_EC_POINT_clear_free', + '#define EC_POINT_cmp GRPC_SHADOW_EC_POINT_cmp', + '#define EC_POINT_copy GRPC_SHADOW_EC_POINT_copy', + '#define EC_POINT_dbl GRPC_SHADOW_EC_POINT_dbl', + '#define EC_POINT_dup GRPC_SHADOW_EC_POINT_dup', + '#define EC_POINT_free GRPC_SHADOW_EC_POINT_free', + '#define EC_POINT_get_affine_coordinates_GFp GRPC_SHADOW_EC_POINT_get_affine_coordinates_GFp', + '#define EC_POINT_invert GRPC_SHADOW_EC_POINT_invert', + '#define EC_POINT_is_at_infinity GRPC_SHADOW_EC_POINT_is_at_infinity', + '#define EC_POINT_is_on_curve GRPC_SHADOW_EC_POINT_is_on_curve', + '#define EC_POINT_make_affine GRPC_SHADOW_EC_POINT_make_affine', + '#define EC_POINT_mul GRPC_SHADOW_EC_POINT_mul', + '#define EC_POINT_new GRPC_SHADOW_EC_POINT_new', + '#define EC_POINT_oct2point GRPC_SHADOW_EC_POINT_oct2point', + '#define EC_POINT_point2oct GRPC_SHADOW_EC_POINT_point2oct', + '#define EC_POINT_set_affine_coordinates_GFp GRPC_SHADOW_EC_POINT_set_affine_coordinates_GFp', + '#define EC_POINT_set_compressed_coordinates_GFp GRPC_SHADOW_EC_POINT_set_compressed_coordinates_GFp', + '#define EC_POINT_set_to_infinity GRPC_SHADOW_EC_POINT_set_to_infinity', + '#define EC_POINTs_make_affine GRPC_SHADOW_EC_POINTs_make_affine', + '#define EC_get_builtin_curves GRPC_SHADOW_EC_get_builtin_curves', + '#define EVP_AEAD_CTX_aead GRPC_SHADOW_EVP_AEAD_CTX_aead', + '#define EVP_AEAD_CTX_cleanup GRPC_SHADOW_EVP_AEAD_CTX_cleanup', + '#define EVP_AEAD_CTX_free GRPC_SHADOW_EVP_AEAD_CTX_free', + '#define EVP_AEAD_CTX_get_iv GRPC_SHADOW_EVP_AEAD_CTX_get_iv', + '#define EVP_AEAD_CTX_init GRPC_SHADOW_EVP_AEAD_CTX_init', + '#define EVP_AEAD_CTX_init_with_direction GRPC_SHADOW_EVP_AEAD_CTX_init_with_direction', + '#define EVP_AEAD_CTX_new GRPC_SHADOW_EVP_AEAD_CTX_new', + '#define EVP_AEAD_CTX_open GRPC_SHADOW_EVP_AEAD_CTX_open', + '#define EVP_AEAD_CTX_open_gather GRPC_SHADOW_EVP_AEAD_CTX_open_gather', + '#define EVP_AEAD_CTX_seal GRPC_SHADOW_EVP_AEAD_CTX_seal', + '#define EVP_AEAD_CTX_seal_scatter GRPC_SHADOW_EVP_AEAD_CTX_seal_scatter', + '#define EVP_AEAD_CTX_tag_len GRPC_SHADOW_EVP_AEAD_CTX_tag_len', + '#define EVP_AEAD_CTX_zero GRPC_SHADOW_EVP_AEAD_CTX_zero', + '#define EVP_AEAD_key_length GRPC_SHADOW_EVP_AEAD_key_length', + '#define EVP_AEAD_max_overhead GRPC_SHADOW_EVP_AEAD_max_overhead', + '#define EVP_AEAD_max_tag_len GRPC_SHADOW_EVP_AEAD_max_tag_len', + '#define EVP_AEAD_nonce_length GRPC_SHADOW_EVP_AEAD_nonce_length', + '#define EVP_CIPHER_CTX_block_size GRPC_SHADOW_EVP_CIPHER_CTX_block_size', + '#define EVP_CIPHER_CTX_cipher GRPC_SHADOW_EVP_CIPHER_CTX_cipher', + '#define EVP_CIPHER_CTX_cleanup GRPC_SHADOW_EVP_CIPHER_CTX_cleanup', + '#define EVP_CIPHER_CTX_copy GRPC_SHADOW_EVP_CIPHER_CTX_copy', + '#define EVP_CIPHER_CTX_ctrl GRPC_SHADOW_EVP_CIPHER_CTX_ctrl', + '#define EVP_CIPHER_CTX_flags GRPC_SHADOW_EVP_CIPHER_CTX_flags', + '#define EVP_CIPHER_CTX_free GRPC_SHADOW_EVP_CIPHER_CTX_free', + '#define EVP_CIPHER_CTX_get_app_data GRPC_SHADOW_EVP_CIPHER_CTX_get_app_data', + '#define EVP_CIPHER_CTX_init GRPC_SHADOW_EVP_CIPHER_CTX_init', + '#define EVP_CIPHER_CTX_iv_length GRPC_SHADOW_EVP_CIPHER_CTX_iv_length', + '#define EVP_CIPHER_CTX_key_length GRPC_SHADOW_EVP_CIPHER_CTX_key_length', + '#define EVP_CIPHER_CTX_mode GRPC_SHADOW_EVP_CIPHER_CTX_mode', + '#define EVP_CIPHER_CTX_new GRPC_SHADOW_EVP_CIPHER_CTX_new', + '#define EVP_CIPHER_CTX_nid GRPC_SHADOW_EVP_CIPHER_CTX_nid', + '#define EVP_CIPHER_CTX_reset GRPC_SHADOW_EVP_CIPHER_CTX_reset', + '#define EVP_CIPHER_CTX_set_app_data GRPC_SHADOW_EVP_CIPHER_CTX_set_app_data', + '#define EVP_CIPHER_CTX_set_flags GRPC_SHADOW_EVP_CIPHER_CTX_set_flags', + '#define EVP_CIPHER_CTX_set_key_length GRPC_SHADOW_EVP_CIPHER_CTX_set_key_length', + '#define EVP_CIPHER_CTX_set_padding GRPC_SHADOW_EVP_CIPHER_CTX_set_padding', + '#define EVP_CIPHER_block_size GRPC_SHADOW_EVP_CIPHER_block_size', + '#define EVP_CIPHER_flags GRPC_SHADOW_EVP_CIPHER_flags', + '#define EVP_CIPHER_iv_length GRPC_SHADOW_EVP_CIPHER_iv_length', + '#define EVP_CIPHER_key_length GRPC_SHADOW_EVP_CIPHER_key_length', + '#define EVP_CIPHER_mode GRPC_SHADOW_EVP_CIPHER_mode', + '#define EVP_CIPHER_nid GRPC_SHADOW_EVP_CIPHER_nid', + '#define EVP_Cipher GRPC_SHADOW_EVP_Cipher', + '#define EVP_CipherFinal_ex GRPC_SHADOW_EVP_CipherFinal_ex', + '#define EVP_CipherInit GRPC_SHADOW_EVP_CipherInit', + '#define EVP_CipherInit_ex GRPC_SHADOW_EVP_CipherInit_ex', + '#define EVP_CipherUpdate GRPC_SHADOW_EVP_CipherUpdate', + '#define EVP_DecryptFinal_ex GRPC_SHADOW_EVP_DecryptFinal_ex', + '#define EVP_DecryptInit GRPC_SHADOW_EVP_DecryptInit', + '#define EVP_DecryptInit_ex GRPC_SHADOW_EVP_DecryptInit_ex', + '#define EVP_DecryptUpdate GRPC_SHADOW_EVP_DecryptUpdate', + '#define EVP_Digest GRPC_SHADOW_EVP_Digest', + '#define EVP_DigestFinal GRPC_SHADOW_EVP_DigestFinal', + '#define EVP_DigestFinal_ex GRPC_SHADOW_EVP_DigestFinal_ex', + '#define EVP_DigestInit GRPC_SHADOW_EVP_DigestInit', + '#define EVP_DigestInit_ex GRPC_SHADOW_EVP_DigestInit_ex', + '#define EVP_DigestUpdate GRPC_SHADOW_EVP_DigestUpdate', + '#define EVP_EncryptFinal_ex GRPC_SHADOW_EVP_EncryptFinal_ex', + '#define EVP_EncryptInit GRPC_SHADOW_EVP_EncryptInit', + '#define EVP_EncryptInit_ex GRPC_SHADOW_EVP_EncryptInit_ex', + '#define EVP_EncryptUpdate GRPC_SHADOW_EVP_EncryptUpdate', + '#define EVP_MD_CTX_block_size GRPC_SHADOW_EVP_MD_CTX_block_size', + '#define EVP_MD_CTX_cleanup GRPC_SHADOW_EVP_MD_CTX_cleanup', + '#define EVP_MD_CTX_copy GRPC_SHADOW_EVP_MD_CTX_copy', + '#define EVP_MD_CTX_copy_ex GRPC_SHADOW_EVP_MD_CTX_copy_ex', + '#define EVP_MD_CTX_create GRPC_SHADOW_EVP_MD_CTX_create', + '#define EVP_MD_CTX_destroy GRPC_SHADOW_EVP_MD_CTX_destroy', + '#define EVP_MD_CTX_free GRPC_SHADOW_EVP_MD_CTX_free', + '#define EVP_MD_CTX_init GRPC_SHADOW_EVP_MD_CTX_init', + '#define EVP_MD_CTX_md GRPC_SHADOW_EVP_MD_CTX_md', + '#define EVP_MD_CTX_new GRPC_SHADOW_EVP_MD_CTX_new', + '#define EVP_MD_CTX_reset GRPC_SHADOW_EVP_MD_CTX_reset', + '#define EVP_MD_CTX_size GRPC_SHADOW_EVP_MD_CTX_size', + '#define EVP_MD_CTX_type GRPC_SHADOW_EVP_MD_CTX_type', + '#define EVP_MD_block_size GRPC_SHADOW_EVP_MD_block_size', + '#define EVP_MD_flags GRPC_SHADOW_EVP_MD_flags', + '#define EVP_MD_size GRPC_SHADOW_EVP_MD_size', + '#define EVP_MD_type GRPC_SHADOW_EVP_MD_type', + '#define EVP_add_cipher_alias GRPC_SHADOW_EVP_add_cipher_alias', + '#define EVP_add_digest GRPC_SHADOW_EVP_add_digest', + '#define EVP_aead_aes_128_gcm GRPC_SHADOW_EVP_aead_aes_128_gcm', + '#define EVP_aead_aes_128_gcm_tls12 GRPC_SHADOW_EVP_aead_aes_128_gcm_tls12', + '#define EVP_aead_aes_256_gcm GRPC_SHADOW_EVP_aead_aes_256_gcm', + '#define EVP_aead_aes_256_gcm_tls12 GRPC_SHADOW_EVP_aead_aes_256_gcm_tls12', + '#define EVP_aes_128_cbc GRPC_SHADOW_EVP_aes_128_cbc', + '#define EVP_aes_128_ctr GRPC_SHADOW_EVP_aes_128_ctr', + '#define EVP_aes_128_ecb GRPC_SHADOW_EVP_aes_128_ecb', + '#define EVP_aes_128_gcm GRPC_SHADOW_EVP_aes_128_gcm', + '#define EVP_aes_128_ofb GRPC_SHADOW_EVP_aes_128_ofb', + '#define EVP_aes_192_cbc GRPC_SHADOW_EVP_aes_192_cbc', + '#define EVP_aes_192_ctr GRPC_SHADOW_EVP_aes_192_ctr', + '#define EVP_aes_192_ecb GRPC_SHADOW_EVP_aes_192_ecb', + '#define EVP_aes_192_gcm GRPC_SHADOW_EVP_aes_192_gcm', + '#define EVP_aes_256_cbc GRPC_SHADOW_EVP_aes_256_cbc', + '#define EVP_aes_256_ctr GRPC_SHADOW_EVP_aes_256_ctr', + '#define EVP_aes_256_ecb GRPC_SHADOW_EVP_aes_256_ecb', + '#define EVP_aes_256_gcm GRPC_SHADOW_EVP_aes_256_gcm', + '#define EVP_aes_256_ofb GRPC_SHADOW_EVP_aes_256_ofb', + '#define EVP_des_cbc GRPC_SHADOW_EVP_des_cbc', + '#define EVP_des_ecb GRPC_SHADOW_EVP_des_ecb', + '#define EVP_des_ede GRPC_SHADOW_EVP_des_ede', + '#define EVP_des_ede3 GRPC_SHADOW_EVP_des_ede3', + '#define EVP_des_ede3_cbc GRPC_SHADOW_EVP_des_ede3_cbc', + '#define EVP_des_ede_cbc GRPC_SHADOW_EVP_des_ede_cbc', + '#define EVP_has_aes_hardware GRPC_SHADOW_EVP_has_aes_hardware', + '#define EVP_md4 GRPC_SHADOW_EVP_md4', + '#define EVP_md5 GRPC_SHADOW_EVP_md5', + '#define EVP_md5_sha1 GRPC_SHADOW_EVP_md5_sha1', + '#define EVP_sha1 GRPC_SHADOW_EVP_sha1', + '#define EVP_sha224 GRPC_SHADOW_EVP_sha224', + '#define EVP_sha256 GRPC_SHADOW_EVP_sha256', + '#define EVP_sha384 GRPC_SHADOW_EVP_sha384', + '#define EVP_sha512 GRPC_SHADOW_EVP_sha512', + '#define HMAC GRPC_SHADOW_HMAC', + '#define HMAC_CTX_cleanup GRPC_SHADOW_HMAC_CTX_cleanup', + '#define HMAC_CTX_copy GRPC_SHADOW_HMAC_CTX_copy', + '#define HMAC_CTX_copy_ex GRPC_SHADOW_HMAC_CTX_copy_ex', + '#define HMAC_CTX_free GRPC_SHADOW_HMAC_CTX_free', + '#define HMAC_CTX_init GRPC_SHADOW_HMAC_CTX_init', + '#define HMAC_CTX_new GRPC_SHADOW_HMAC_CTX_new', + '#define HMAC_CTX_reset GRPC_SHADOW_HMAC_CTX_reset', + '#define HMAC_Final GRPC_SHADOW_HMAC_Final', + '#define HMAC_Init GRPC_SHADOW_HMAC_Init', + '#define HMAC_Init_ex GRPC_SHADOW_HMAC_Init_ex', + '#define HMAC_Update GRPC_SHADOW_HMAC_Update', + '#define HMAC_size GRPC_SHADOW_HMAC_size', + '#define MD4 GRPC_SHADOW_MD4', + '#define MD4_Final GRPC_SHADOW_MD4_Final', + '#define MD4_Init GRPC_SHADOW_MD4_Init', + '#define MD4_Transform GRPC_SHADOW_MD4_Transform', + '#define MD4_Update GRPC_SHADOW_MD4_Update', + '#define MD5 GRPC_SHADOW_MD5', + '#define MD5_Final GRPC_SHADOW_MD5_Final', + '#define MD5_Init GRPC_SHADOW_MD5_Init', + '#define MD5_Transform GRPC_SHADOW_MD5_Transform', + '#define MD5_Update GRPC_SHADOW_MD5_Update', + '#define OPENSSL_built_in_curves GRPC_SHADOW_OPENSSL_built_in_curves', + '#define RAND_bytes GRPC_SHADOW_RAND_bytes', + '#define RAND_bytes_with_additional_data GRPC_SHADOW_RAND_bytes_with_additional_data', + '#define RAND_pseudo_bytes GRPC_SHADOW_RAND_pseudo_bytes', + '#define RAND_set_urandom_fd GRPC_SHADOW_RAND_set_urandom_fd', + '#define RSAZ_1024_mod_exp_avx2 GRPC_SHADOW_RSAZ_1024_mod_exp_avx2', + '#define RSA_add_pkcs1_prefix GRPC_SHADOW_RSA_add_pkcs1_prefix', + '#define RSA_bits GRPC_SHADOW_RSA_bits', + '#define RSA_blinding_on GRPC_SHADOW_RSA_blinding_on', + '#define RSA_check_fips GRPC_SHADOW_RSA_check_fips', + '#define RSA_check_key GRPC_SHADOW_RSA_check_key', + '#define RSA_decrypt GRPC_SHADOW_RSA_decrypt', + '#define RSA_default_method GRPC_SHADOW_RSA_default_method', + '#define RSA_encrypt GRPC_SHADOW_RSA_encrypt', + '#define RSA_flags GRPC_SHADOW_RSA_flags', + '#define RSA_free GRPC_SHADOW_RSA_free', + '#define RSA_generate_key_ex GRPC_SHADOW_RSA_generate_key_ex', + '#define RSA_generate_key_fips GRPC_SHADOW_RSA_generate_key_fips', + '#define RSA_get0_crt_params GRPC_SHADOW_RSA_get0_crt_params', + '#define RSA_get0_factors GRPC_SHADOW_RSA_get0_factors', + '#define RSA_get0_key GRPC_SHADOW_RSA_get0_key', + '#define RSA_get_ex_data GRPC_SHADOW_RSA_get_ex_data', + '#define RSA_get_ex_new_index GRPC_SHADOW_RSA_get_ex_new_index', + '#define RSA_is_opaque GRPC_SHADOW_RSA_is_opaque', + '#define RSA_new GRPC_SHADOW_RSA_new', + '#define RSA_new_method GRPC_SHADOW_RSA_new_method', + '#define RSA_padding_add_PKCS1_OAEP_mgf1 GRPC_SHADOW_RSA_padding_add_PKCS1_OAEP_mgf1', + '#define RSA_padding_add_PKCS1_PSS_mgf1 GRPC_SHADOW_RSA_padding_add_PKCS1_PSS_mgf1', + '#define RSA_padding_add_PKCS1_type_1 GRPC_SHADOW_RSA_padding_add_PKCS1_type_1', + '#define RSA_padding_add_PKCS1_type_2 GRPC_SHADOW_RSA_padding_add_PKCS1_type_2', + '#define RSA_padding_add_none GRPC_SHADOW_RSA_padding_add_none', + '#define RSA_padding_check_PKCS1_OAEP_mgf1 GRPC_SHADOW_RSA_padding_check_PKCS1_OAEP_mgf1', + '#define RSA_padding_check_PKCS1_type_1 GRPC_SHADOW_RSA_padding_check_PKCS1_type_1', + '#define RSA_padding_check_PKCS1_type_2 GRPC_SHADOW_RSA_padding_check_PKCS1_type_2', + '#define RSA_private_decrypt GRPC_SHADOW_RSA_private_decrypt', + '#define RSA_private_encrypt GRPC_SHADOW_RSA_private_encrypt', + '#define RSA_private_transform GRPC_SHADOW_RSA_private_transform', + '#define RSA_public_decrypt GRPC_SHADOW_RSA_public_decrypt', + '#define RSA_public_encrypt GRPC_SHADOW_RSA_public_encrypt', + '#define RSA_set0_crt_params GRPC_SHADOW_RSA_set0_crt_params', + '#define RSA_set0_factors GRPC_SHADOW_RSA_set0_factors', + '#define RSA_set0_key GRPC_SHADOW_RSA_set0_key', + '#define RSA_set_ex_data GRPC_SHADOW_RSA_set_ex_data', + '#define RSA_sign GRPC_SHADOW_RSA_sign', + '#define RSA_sign_pss_mgf1 GRPC_SHADOW_RSA_sign_pss_mgf1', + '#define RSA_sign_raw GRPC_SHADOW_RSA_sign_raw', + '#define RSA_size GRPC_SHADOW_RSA_size', + '#define RSA_up_ref GRPC_SHADOW_RSA_up_ref', + '#define RSA_verify GRPC_SHADOW_RSA_verify', + '#define RSA_verify_PKCS1_PSS_mgf1 GRPC_SHADOW_RSA_verify_PKCS1_PSS_mgf1', + '#define RSA_verify_pss_mgf1 GRPC_SHADOW_RSA_verify_pss_mgf1', + '#define RSA_verify_raw GRPC_SHADOW_RSA_verify_raw', + '#define SHA1 GRPC_SHADOW_SHA1', + '#define SHA1_Final GRPC_SHADOW_SHA1_Final', + '#define SHA1_Init GRPC_SHADOW_SHA1_Init', + '#define SHA1_Transform GRPC_SHADOW_SHA1_Transform', + '#define SHA1_Update GRPC_SHADOW_SHA1_Update', + '#define SHA224 GRPC_SHADOW_SHA224', + '#define SHA224_Final GRPC_SHADOW_SHA224_Final', + '#define SHA224_Init GRPC_SHADOW_SHA224_Init', + '#define SHA224_Update GRPC_SHADOW_SHA224_Update', + '#define SHA256 GRPC_SHADOW_SHA256', + '#define SHA256_Final GRPC_SHADOW_SHA256_Final', + '#define SHA256_Init GRPC_SHADOW_SHA256_Init', + '#define SHA256_Transform GRPC_SHADOW_SHA256_Transform', + '#define SHA256_Update GRPC_SHADOW_SHA256_Update', + '#define SHA384 GRPC_SHADOW_SHA384', + '#define SHA384_Final GRPC_SHADOW_SHA384_Final', + '#define SHA384_Init GRPC_SHADOW_SHA384_Init', + '#define SHA384_Update GRPC_SHADOW_SHA384_Update', + '#define SHA512 GRPC_SHADOW_SHA512', + '#define SHA512_Final GRPC_SHADOW_SHA512_Final', + '#define SHA512_Init GRPC_SHADOW_SHA512_Init', + '#define SHA512_Transform GRPC_SHADOW_SHA512_Transform', + '#define SHA512_Update GRPC_SHADOW_SHA512_Update', + '#define aes_ctr_set_key GRPC_SHADOW_aes_ctr_set_key', + '#define bn_abs_sub_consttime GRPC_SHADOW_bn_abs_sub_consttime', + '#define bn_add_words GRPC_SHADOW_bn_add_words', + '#define bn_copy_words GRPC_SHADOW_bn_copy_words', + '#define bn_div_consttime GRPC_SHADOW_bn_div_consttime', + '#define bn_expand GRPC_SHADOW_bn_expand', + '#define bn_fits_in_words GRPC_SHADOW_bn_fits_in_words', + '#define bn_from_montgomery_small GRPC_SHADOW_bn_from_montgomery_small', + '#define bn_in_range_words GRPC_SHADOW_bn_in_range_words', + '#define bn_is_bit_set_words GRPC_SHADOW_bn_is_bit_set_words', + '#define bn_is_relatively_prime GRPC_SHADOW_bn_is_relatively_prime', + '#define bn_jacobi GRPC_SHADOW_bn_jacobi', + '#define bn_lcm_consttime GRPC_SHADOW_bn_lcm_consttime', + '#define bn_less_than_montgomery_R GRPC_SHADOW_bn_less_than_montgomery_R', + '#define bn_less_than_words GRPC_SHADOW_bn_less_than_words', + '#define bn_minimal_width GRPC_SHADOW_bn_minimal_width', + '#define bn_mod_add_consttime GRPC_SHADOW_bn_mod_add_consttime', + '#define bn_mod_exp_base_2_consttime GRPC_SHADOW_bn_mod_exp_base_2_consttime', + '#define bn_mod_exp_mont_small GRPC_SHADOW_bn_mod_exp_mont_small', + '#define bn_mod_inverse_consttime GRPC_SHADOW_bn_mod_inverse_consttime', + '#define bn_mod_inverse_prime GRPC_SHADOW_bn_mod_inverse_prime', + '#define bn_mod_inverse_prime_mont_small GRPC_SHADOW_bn_mod_inverse_prime_mont_small', + '#define bn_mod_inverse_secret_prime GRPC_SHADOW_bn_mod_inverse_secret_prime', + '#define bn_mod_lshift1_consttime GRPC_SHADOW_bn_mod_lshift1_consttime', + '#define bn_mod_lshift_consttime GRPC_SHADOW_bn_mod_lshift_consttime', + '#define bn_mod_mul_montgomery_small GRPC_SHADOW_bn_mod_mul_montgomery_small', + '#define bn_mod_sub_consttime GRPC_SHADOW_bn_mod_sub_consttime', + '#define bn_mod_u16_consttime GRPC_SHADOW_bn_mod_u16_consttime', + '#define bn_mont_n0 GRPC_SHADOW_bn_mont_n0', + '#define bn_mul_add_words GRPC_SHADOW_bn_mul_add_words', + '#define bn_mul_comba4 GRPC_SHADOW_bn_mul_comba4', + '#define bn_mul_comba8 GRPC_SHADOW_bn_mul_comba8', + '#define bn_mul_consttime GRPC_SHADOW_bn_mul_consttime', + '#define bn_mul_small GRPC_SHADOW_bn_mul_small', + '#define bn_mul_words GRPC_SHADOW_bn_mul_words', + '#define bn_odd_number_is_obviously_composite GRPC_SHADOW_bn_odd_number_is_obviously_composite', + '#define bn_one_to_montgomery GRPC_SHADOW_bn_one_to_montgomery', + '#define bn_one_to_montgomery_small GRPC_SHADOW_bn_one_to_montgomery_small', + '#define bn_rand_range_words GRPC_SHADOW_bn_rand_range_words', + '#define bn_rand_secret_range GRPC_SHADOW_bn_rand_secret_range', + '#define bn_resize_words GRPC_SHADOW_bn_resize_words', + '#define bn_rshift1_words GRPC_SHADOW_bn_rshift1_words', + '#define bn_rshift_secret_shift GRPC_SHADOW_bn_rshift_secret_shift', + '#define bn_select_words GRPC_SHADOW_bn_select_words', + '#define bn_set_minimal_width GRPC_SHADOW_bn_set_minimal_width', + '#define bn_set_words GRPC_SHADOW_bn_set_words', + '#define bn_sqr_comba4 GRPC_SHADOW_bn_sqr_comba4', + '#define bn_sqr_comba8 GRPC_SHADOW_bn_sqr_comba8', + '#define bn_sqr_consttime GRPC_SHADOW_bn_sqr_consttime', + '#define bn_sqr_small GRPC_SHADOW_bn_sqr_small', + '#define bn_sqr_words GRPC_SHADOW_bn_sqr_words', + '#define bn_sub_words GRPC_SHADOW_bn_sub_words', + '#define bn_to_montgomery_small GRPC_SHADOW_bn_to_montgomery_small', + '#define bn_uadd_consttime GRPC_SHADOW_bn_uadd_consttime', + '#define bn_usub_consttime GRPC_SHADOW_bn_usub_consttime', + '#define bn_wexpand GRPC_SHADOW_bn_wexpand', + '#define crypto_gcm_clmul_enabled GRPC_SHADOW_crypto_gcm_clmul_enabled', + '#define ec_GFp_mont_field_decode GRPC_SHADOW_ec_GFp_mont_field_decode', + '#define ec_GFp_mont_field_encode GRPC_SHADOW_ec_GFp_mont_field_encode', + '#define ec_GFp_mont_field_mul GRPC_SHADOW_ec_GFp_mont_field_mul', + '#define ec_GFp_mont_field_sqr GRPC_SHADOW_ec_GFp_mont_field_sqr', + '#define ec_GFp_mont_group_finish GRPC_SHADOW_ec_GFp_mont_group_finish', + '#define ec_GFp_mont_group_init GRPC_SHADOW_ec_GFp_mont_group_init', + '#define ec_GFp_mont_group_set_curve GRPC_SHADOW_ec_GFp_mont_group_set_curve', + '#define ec_GFp_nistp_recode_scalar_bits GRPC_SHADOW_ec_GFp_nistp_recode_scalar_bits', + '#define ec_GFp_simple_add GRPC_SHADOW_ec_GFp_simple_add', + '#define ec_GFp_simple_cmp GRPC_SHADOW_ec_GFp_simple_cmp', + '#define ec_GFp_simple_dbl GRPC_SHADOW_ec_GFp_simple_dbl', + '#define ec_GFp_simple_field_mul GRPC_SHADOW_ec_GFp_simple_field_mul', + '#define ec_GFp_simple_field_sqr GRPC_SHADOW_ec_GFp_simple_field_sqr', + '#define ec_GFp_simple_group_finish GRPC_SHADOW_ec_GFp_simple_group_finish', + '#define ec_GFp_simple_group_get_curve GRPC_SHADOW_ec_GFp_simple_group_get_curve', + '#define ec_GFp_simple_group_get_degree GRPC_SHADOW_ec_GFp_simple_group_get_degree', + '#define ec_GFp_simple_group_init GRPC_SHADOW_ec_GFp_simple_group_init', + '#define ec_GFp_simple_group_set_curve GRPC_SHADOW_ec_GFp_simple_group_set_curve', + '#define ec_GFp_simple_invert GRPC_SHADOW_ec_GFp_simple_invert', + '#define ec_GFp_simple_is_at_infinity GRPC_SHADOW_ec_GFp_simple_is_at_infinity', + '#define ec_GFp_simple_is_on_curve GRPC_SHADOW_ec_GFp_simple_is_on_curve', + '#define ec_GFp_simple_make_affine GRPC_SHADOW_ec_GFp_simple_make_affine', + '#define ec_GFp_simple_point_copy GRPC_SHADOW_ec_GFp_simple_point_copy', + '#define ec_GFp_simple_point_finish GRPC_SHADOW_ec_GFp_simple_point_finish', + '#define ec_GFp_simple_point_init GRPC_SHADOW_ec_GFp_simple_point_init', + '#define ec_GFp_simple_point_set_affine_coordinates GRPC_SHADOW_ec_GFp_simple_point_set_affine_coordinates', + '#define ec_GFp_simple_point_set_to_infinity GRPC_SHADOW_ec_GFp_simple_point_set_to_infinity', + '#define ec_GFp_simple_points_make_affine GRPC_SHADOW_ec_GFp_simple_points_make_affine', + '#define ec_bignum_to_scalar GRPC_SHADOW_ec_bignum_to_scalar', + '#define ec_bignum_to_scalar_unchecked GRPC_SHADOW_ec_bignum_to_scalar_unchecked', + '#define ec_compute_wNAF GRPC_SHADOW_ec_compute_wNAF', + '#define ec_group_new GRPC_SHADOW_ec_group_new', + '#define ec_point_mul_scalar GRPC_SHADOW_ec_point_mul_scalar', + '#define ec_point_mul_scalar_public GRPC_SHADOW_ec_point_mul_scalar_public', + '#define ec_random_nonzero_scalar GRPC_SHADOW_ec_random_nonzero_scalar', + '#define ec_wNAF_mul GRPC_SHADOW_ec_wNAF_mul', + '#define kBoringSSLRSASqrtTwo GRPC_SHADOW_kBoringSSLRSASqrtTwo', + '#define kBoringSSLRSASqrtTwoLen GRPC_SHADOW_kBoringSSLRSASqrtTwoLen', + '#define md4_block_data_order GRPC_SHADOW_md4_block_data_order', + '#define rsa_default_decrypt GRPC_SHADOW_rsa_default_decrypt', + '#define rsa_default_private_transform GRPC_SHADOW_rsa_default_private_transform', + '#define rsa_default_sign_raw GRPC_SHADOW_rsa_default_sign_raw', + '#define rsa_default_size GRPC_SHADOW_rsa_default_size', + '#define FIPS_mode GRPC_SHADOW_FIPS_mode', + '#define aesni_gcm_decrypt GRPC_SHADOW_aesni_gcm_decrypt', + '#define aesni_gcm_encrypt GRPC_SHADOW_aesni_gcm_encrypt', + '#define aesni_cbc_encrypt GRPC_SHADOW_aesni_cbc_encrypt', + '#define aesni_ccm64_decrypt_blocks GRPC_SHADOW_aesni_ccm64_decrypt_blocks', + '#define aesni_ccm64_encrypt_blocks GRPC_SHADOW_aesni_ccm64_encrypt_blocks', + '#define aesni_ctr32_encrypt_blocks GRPC_SHADOW_aesni_ctr32_encrypt_blocks', + '#define aesni_decrypt GRPC_SHADOW_aesni_decrypt', + '#define aesni_ecb_encrypt GRPC_SHADOW_aesni_ecb_encrypt', + '#define aesni_encrypt GRPC_SHADOW_aesni_encrypt', + '#define aesni_ocb_decrypt GRPC_SHADOW_aesni_ocb_decrypt', + '#define aesni_ocb_encrypt GRPC_SHADOW_aesni_ocb_encrypt', + '#define aesni_set_decrypt_key GRPC_SHADOW_aesni_set_decrypt_key', + '#define aesni_set_encrypt_key GRPC_SHADOW_aesni_set_encrypt_key', + '#define aesni_xts_decrypt GRPC_SHADOW_aesni_xts_decrypt', + '#define aesni_xts_encrypt GRPC_SHADOW_aesni_xts_encrypt', + '#define asm_AES_cbc_encrypt GRPC_SHADOW_asm_AES_cbc_encrypt', + '#define asm_AES_decrypt GRPC_SHADOW_asm_AES_decrypt', + '#define asm_AES_encrypt GRPC_SHADOW_asm_AES_encrypt', + '#define asm_AES_set_decrypt_key GRPC_SHADOW_asm_AES_set_decrypt_key', + '#define asm_AES_set_encrypt_key GRPC_SHADOW_asm_AES_set_encrypt_key', + '#define bsaes_cbc_encrypt GRPC_SHADOW_bsaes_cbc_encrypt', + '#define bsaes_ctr32_encrypt_blocks GRPC_SHADOW_bsaes_ctr32_encrypt_blocks', + '#define bsaes_xts_decrypt GRPC_SHADOW_bsaes_xts_decrypt', + '#define bsaes_xts_encrypt GRPC_SHADOW_bsaes_xts_encrypt', + '#define gcm_ghash_4bit GRPC_SHADOW_gcm_ghash_4bit', + '#define gcm_ghash_avx GRPC_SHADOW_gcm_ghash_avx', + '#define gcm_ghash_clmul GRPC_SHADOW_gcm_ghash_clmul', + '#define gcm_gmult_4bit GRPC_SHADOW_gcm_gmult_4bit', + '#define gcm_gmult_avx GRPC_SHADOW_gcm_gmult_avx', + '#define gcm_gmult_clmul GRPC_SHADOW_gcm_gmult_clmul', + '#define gcm_init_avx GRPC_SHADOW_gcm_init_avx', + '#define gcm_init_clmul GRPC_SHADOW_gcm_init_clmul', + '#define md5_block_asm_data_order GRPC_SHADOW_md5_block_asm_data_order', + '#define ecp_nistz256_avx2_select_w7 GRPC_SHADOW_ecp_nistz256_avx2_select_w7', + '#define ecp_nistz256_mul_mont GRPC_SHADOW_ecp_nistz256_mul_mont', + '#define ecp_nistz256_neg GRPC_SHADOW_ecp_nistz256_neg', + '#define ecp_nistz256_point_add GRPC_SHADOW_ecp_nistz256_point_add', + '#define ecp_nistz256_point_add_affine GRPC_SHADOW_ecp_nistz256_point_add_affine', + '#define ecp_nistz256_point_double GRPC_SHADOW_ecp_nistz256_point_double', + '#define ecp_nistz256_select_w5 GRPC_SHADOW_ecp_nistz256_select_w5', + '#define ecp_nistz256_select_w7 GRPC_SHADOW_ecp_nistz256_select_w7', + '#define ecp_nistz256_sqr_mont GRPC_SHADOW_ecp_nistz256_sqr_mont', + '#define CRYPTO_rdrand GRPC_SHADOW_CRYPTO_rdrand', + '#define CRYPTO_rdrand_multiple8_buf GRPC_SHADOW_CRYPTO_rdrand_multiple8_buf', + '#define rsaz_1024_gather5_avx2 GRPC_SHADOW_rsaz_1024_gather5_avx2', + '#define rsaz_1024_mul_avx2 GRPC_SHADOW_rsaz_1024_mul_avx2', + '#define rsaz_1024_norm2red_avx2 GRPC_SHADOW_rsaz_1024_norm2red_avx2', + '#define rsaz_1024_red2norm_avx2 GRPC_SHADOW_rsaz_1024_red2norm_avx2', + '#define rsaz_1024_scatter5_avx2 GRPC_SHADOW_rsaz_1024_scatter5_avx2', + '#define rsaz_1024_sqr_avx2 GRPC_SHADOW_rsaz_1024_sqr_avx2', + '#define rsaz_avx2_eligible GRPC_SHADOW_rsaz_avx2_eligible', + '#define sha1_block_data_order GRPC_SHADOW_sha1_block_data_order', + '#define sha256_block_data_order GRPC_SHADOW_sha256_block_data_order', + '#define sha512_block_data_order GRPC_SHADOW_sha512_block_data_order', + '#define vpaes_cbc_encrypt GRPC_SHADOW_vpaes_cbc_encrypt', + '#define vpaes_decrypt GRPC_SHADOW_vpaes_decrypt', + '#define vpaes_encrypt GRPC_SHADOW_vpaes_encrypt', + '#define vpaes_set_decrypt_key GRPC_SHADOW_vpaes_set_decrypt_key', + '#define vpaes_set_encrypt_key GRPC_SHADOW_vpaes_set_encrypt_key', + '#define bn_from_montgomery GRPC_SHADOW_bn_from_montgomery', + '#define bn_gather5 GRPC_SHADOW_bn_gather5', + '#define bn_mul_mont_gather5 GRPC_SHADOW_bn_mul_mont_gather5', + '#define bn_power5 GRPC_SHADOW_bn_power5', + '#define bn_scatter5 GRPC_SHADOW_bn_scatter5', + '#define bn_sqr8x_internal GRPC_SHADOW_bn_sqr8x_internal', + '#define bn_mul_mont GRPC_SHADOW_bn_mul_mont', + '#define EVP_get_digestbyname GRPC_SHADOW_EVP_get_digestbyname', + '#define EVP_get_digestbynid GRPC_SHADOW_EVP_get_digestbynid', + '#define EVP_get_digestbyobj GRPC_SHADOW_EVP_get_digestbyobj', + '#define EVP_marshal_digest_algorithm GRPC_SHADOW_EVP_marshal_digest_algorithm', + '#define EVP_parse_digest_algorithm GRPC_SHADOW_EVP_parse_digest_algorithm', + '#define EVP_get_cipherbyname GRPC_SHADOW_EVP_get_cipherbyname', + '#define EVP_get_cipherbynid GRPC_SHADOW_EVP_get_cipherbynid', + '#define EVP_BytesToKey GRPC_SHADOW_EVP_BytesToKey', + '#define EVP_enc_null GRPC_SHADOW_EVP_enc_null', + '#define EVP_rc2_40_cbc GRPC_SHADOW_EVP_rc2_40_cbc', + '#define EVP_rc2_cbc GRPC_SHADOW_EVP_rc2_cbc', + '#define EVP_rc4 GRPC_SHADOW_EVP_rc4', + '#define EVP_aead_aes_128_gcm_siv GRPC_SHADOW_EVP_aead_aes_128_gcm_siv', + '#define EVP_aead_aes_256_gcm_siv GRPC_SHADOW_EVP_aead_aes_256_gcm_siv', + '#define EVP_aead_aes_128_ctr_hmac_sha256 GRPC_SHADOW_EVP_aead_aes_128_ctr_hmac_sha256', + '#define EVP_aead_aes_256_ctr_hmac_sha256 GRPC_SHADOW_EVP_aead_aes_256_ctr_hmac_sha256', + '#define EVP_aead_aes_128_ccm_bluetooth GRPC_SHADOW_EVP_aead_aes_128_ccm_bluetooth', + '#define EVP_aead_aes_128_ccm_bluetooth_8 GRPC_SHADOW_EVP_aead_aes_128_ccm_bluetooth_8', + '#define EVP_aead_chacha20_poly1305 GRPC_SHADOW_EVP_aead_chacha20_poly1305', + '#define EVP_tls_cbc_copy_mac GRPC_SHADOW_EVP_tls_cbc_copy_mac', + '#define EVP_tls_cbc_digest_record GRPC_SHADOW_EVP_tls_cbc_digest_record', + '#define EVP_tls_cbc_record_digest_supported GRPC_SHADOW_EVP_tls_cbc_record_digest_supported', + '#define EVP_tls_cbc_remove_padding GRPC_SHADOW_EVP_tls_cbc_remove_padding', + '#define EVP_aead_aes_128_cbc_sha1_tls GRPC_SHADOW_EVP_aead_aes_128_cbc_sha1_tls', + '#define EVP_aead_aes_128_cbc_sha1_tls_implicit_iv GRPC_SHADOW_EVP_aead_aes_128_cbc_sha1_tls_implicit_iv', + '#define EVP_aead_aes_128_cbc_sha256_tls GRPC_SHADOW_EVP_aead_aes_128_cbc_sha256_tls', + '#define EVP_aead_aes_256_cbc_sha1_tls GRPC_SHADOW_EVP_aead_aes_256_cbc_sha1_tls', + '#define EVP_aead_aes_256_cbc_sha1_tls_implicit_iv GRPC_SHADOW_EVP_aead_aes_256_cbc_sha1_tls_implicit_iv', + '#define EVP_aead_aes_256_cbc_sha256_tls GRPC_SHADOW_EVP_aead_aes_256_cbc_sha256_tls', + '#define EVP_aead_aes_256_cbc_sha384_tls GRPC_SHADOW_EVP_aead_aes_256_cbc_sha384_tls', + '#define EVP_aead_des_ede3_cbc_sha1_tls GRPC_SHADOW_EVP_aead_des_ede3_cbc_sha1_tls', + '#define EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv GRPC_SHADOW_EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv', + '#define EVP_aead_null_sha1_tls GRPC_SHADOW_EVP_aead_null_sha1_tls', + '#define EVP_aead_aes_128_cbc_sha1_ssl3 GRPC_SHADOW_EVP_aead_aes_128_cbc_sha1_ssl3', + '#define EVP_aead_aes_256_cbc_sha1_ssl3 GRPC_SHADOW_EVP_aead_aes_256_cbc_sha1_ssl3', + '#define EVP_aead_des_ede3_cbc_sha1_ssl3 GRPC_SHADOW_EVP_aead_des_ede3_cbc_sha1_ssl3', + '#define EVP_aead_null_sha1_ssl3 GRPC_SHADOW_EVP_aead_null_sha1_ssl3', + '#define aes128gcmsiv_aes_ks GRPC_SHADOW_aes128gcmsiv_aes_ks', + '#define aes128gcmsiv_aes_ks_enc_x1 GRPC_SHADOW_aes128gcmsiv_aes_ks_enc_x1', + '#define aes128gcmsiv_dec GRPC_SHADOW_aes128gcmsiv_dec', + '#define aes128gcmsiv_ecb_enc_block GRPC_SHADOW_aes128gcmsiv_ecb_enc_block', + '#define aes128gcmsiv_enc_msg_x4 GRPC_SHADOW_aes128gcmsiv_enc_msg_x4', + '#define aes128gcmsiv_enc_msg_x8 GRPC_SHADOW_aes128gcmsiv_enc_msg_x8', + '#define aes128gcmsiv_kdf GRPC_SHADOW_aes128gcmsiv_kdf', + '#define aes256gcmsiv_aes_ks GRPC_SHADOW_aes256gcmsiv_aes_ks', + '#define aes256gcmsiv_aes_ks_enc_x1 GRPC_SHADOW_aes256gcmsiv_aes_ks_enc_x1', + '#define aes256gcmsiv_dec GRPC_SHADOW_aes256gcmsiv_dec', + '#define aes256gcmsiv_ecb_enc_block GRPC_SHADOW_aes256gcmsiv_ecb_enc_block', + '#define aes256gcmsiv_enc_msg_x4 GRPC_SHADOW_aes256gcmsiv_enc_msg_x4', + '#define aes256gcmsiv_enc_msg_x8 GRPC_SHADOW_aes256gcmsiv_enc_msg_x8', + '#define aes256gcmsiv_kdf GRPC_SHADOW_aes256gcmsiv_kdf', + '#define aesgcmsiv_htable6_init GRPC_SHADOW_aesgcmsiv_htable6_init', + '#define aesgcmsiv_htable_init GRPC_SHADOW_aesgcmsiv_htable_init', + '#define aesgcmsiv_htable_polyval GRPC_SHADOW_aesgcmsiv_htable_polyval', + '#define aesgcmsiv_polyval_horner GRPC_SHADOW_aesgcmsiv_polyval_horner', + '#define chacha20_poly1305_open GRPC_SHADOW_chacha20_poly1305_open', + '#define chacha20_poly1305_seal GRPC_SHADOW_chacha20_poly1305_seal', + '#define RC4 GRPC_SHADOW_RC4', + '#define RC4_set_key GRPC_SHADOW_RC4_set_key', + '#define CONF_VALUE_new GRPC_SHADOW_CONF_VALUE_new', + '#define CONF_modules_free GRPC_SHADOW_CONF_modules_free', + '#define CONF_modules_load_file GRPC_SHADOW_CONF_modules_load_file', + '#define CONF_parse_list GRPC_SHADOW_CONF_parse_list', + '#define NCONF_free GRPC_SHADOW_NCONF_free', + '#define NCONF_get_section GRPC_SHADOW_NCONF_get_section', + '#define NCONF_get_string GRPC_SHADOW_NCONF_get_string', + '#define NCONF_load GRPC_SHADOW_NCONF_load', + '#define NCONF_load_bio GRPC_SHADOW_NCONF_load_bio', + '#define NCONF_new GRPC_SHADOW_NCONF_new', + '#define OPENSSL_config GRPC_SHADOW_OPENSSL_config', + '#define OPENSSL_no_config GRPC_SHADOW_OPENSSL_no_config', + '#define CRYPTO_chacha_20 GRPC_SHADOW_CRYPTO_chacha_20', + '#define ChaCha20_ctr32 GRPC_SHADOW_ChaCha20_ctr32', + '#define CRYPTO_poly1305_finish GRPC_SHADOW_CRYPTO_poly1305_finish', + '#define CRYPTO_poly1305_init GRPC_SHADOW_CRYPTO_poly1305_init', + '#define CRYPTO_poly1305_update GRPC_SHADOW_CRYPTO_poly1305_update', + '#define SPAKE2_CTX_free GRPC_SHADOW_SPAKE2_CTX_free', + '#define SPAKE2_CTX_new GRPC_SHADOW_SPAKE2_CTX_new', + '#define SPAKE2_generate_msg GRPC_SHADOW_SPAKE2_generate_msg', + '#define SPAKE2_process_msg GRPC_SHADOW_SPAKE2_process_msg', + '#define ED25519_keypair GRPC_SHADOW_ED25519_keypair', + '#define ED25519_keypair_from_seed GRPC_SHADOW_ED25519_keypair_from_seed', + '#define ED25519_sign GRPC_SHADOW_ED25519_sign', + '#define ED25519_verify GRPC_SHADOW_ED25519_verify', + '#define X25519 GRPC_SHADOW_X25519', + '#define X25519_keypair GRPC_SHADOW_X25519_keypair', + '#define X25519_public_from_private GRPC_SHADOW_X25519_public_from_private', + '#define x25519_ge_add GRPC_SHADOW_x25519_ge_add', + '#define x25519_ge_frombytes_vartime GRPC_SHADOW_x25519_ge_frombytes_vartime', + '#define x25519_ge_p1p1_to_p2 GRPC_SHADOW_x25519_ge_p1p1_to_p2', + '#define x25519_ge_p1p1_to_p3 GRPC_SHADOW_x25519_ge_p1p1_to_p3', + '#define x25519_ge_p3_to_cached GRPC_SHADOW_x25519_ge_p3_to_cached', + '#define x25519_ge_scalarmult GRPC_SHADOW_x25519_ge_scalarmult', + '#define x25519_ge_scalarmult_base GRPC_SHADOW_x25519_ge_scalarmult_base', + '#define x25519_ge_scalarmult_small_precomp GRPC_SHADOW_x25519_ge_scalarmult_small_precomp', + '#define x25519_ge_sub GRPC_SHADOW_x25519_ge_sub', + '#define x25519_ge_tobytes GRPC_SHADOW_x25519_ge_tobytes', + '#define x25519_sc_reduce GRPC_SHADOW_x25519_sc_reduce', + '#define BUF_MEM_append GRPC_SHADOW_BUF_MEM_append', + '#define BUF_MEM_free GRPC_SHADOW_BUF_MEM_free', + '#define BUF_MEM_grow GRPC_SHADOW_BUF_MEM_grow', + '#define BUF_MEM_grow_clean GRPC_SHADOW_BUF_MEM_grow_clean', + '#define BUF_MEM_new GRPC_SHADOW_BUF_MEM_new', + '#define BUF_MEM_reserve GRPC_SHADOW_BUF_MEM_reserve', + '#define BUF_memdup GRPC_SHADOW_BUF_memdup', + '#define BUF_strdup GRPC_SHADOW_BUF_strdup', + '#define BUF_strlcat GRPC_SHADOW_BUF_strlcat', + '#define BUF_strlcpy GRPC_SHADOW_BUF_strlcpy', + '#define BUF_strndup GRPC_SHADOW_BUF_strndup', + '#define BUF_strnlen GRPC_SHADOW_BUF_strnlen', + '#define BN_marshal_asn1 GRPC_SHADOW_BN_marshal_asn1', + '#define BN_parse_asn1_unsigned GRPC_SHADOW_BN_parse_asn1_unsigned', + '#define BN_asc2bn GRPC_SHADOW_BN_asc2bn', + '#define BN_bn2cbb_padded GRPC_SHADOW_BN_bn2cbb_padded', + '#define BN_bn2dec GRPC_SHADOW_BN_bn2dec', + '#define BN_bn2hex GRPC_SHADOW_BN_bn2hex', + '#define BN_bn2mpi GRPC_SHADOW_BN_bn2mpi', + '#define BN_dec2bn GRPC_SHADOW_BN_dec2bn', + '#define BN_hex2bn GRPC_SHADOW_BN_hex2bn', + '#define BN_mpi2bn GRPC_SHADOW_BN_mpi2bn', + '#define BN_print GRPC_SHADOW_BN_print', + '#define BN_print_fp GRPC_SHADOW_BN_print_fp', + '#define BIO_callback_ctrl GRPC_SHADOW_BIO_callback_ctrl', + '#define BIO_clear_flags GRPC_SHADOW_BIO_clear_flags', + '#define BIO_clear_retry_flags GRPC_SHADOW_BIO_clear_retry_flags', + '#define BIO_copy_next_retry GRPC_SHADOW_BIO_copy_next_retry', + '#define BIO_ctrl GRPC_SHADOW_BIO_ctrl', + '#define BIO_ctrl_pending GRPC_SHADOW_BIO_ctrl_pending', + '#define BIO_eof GRPC_SHADOW_BIO_eof', + '#define BIO_find_type GRPC_SHADOW_BIO_find_type', + '#define BIO_flush GRPC_SHADOW_BIO_flush', + '#define BIO_free GRPC_SHADOW_BIO_free', + '#define BIO_free_all GRPC_SHADOW_BIO_free_all', + '#define BIO_get_data GRPC_SHADOW_BIO_get_data', + '#define BIO_get_init GRPC_SHADOW_BIO_get_init', + '#define BIO_get_new_index GRPC_SHADOW_BIO_get_new_index', + '#define BIO_get_retry_flags GRPC_SHADOW_BIO_get_retry_flags', + '#define BIO_get_retry_reason GRPC_SHADOW_BIO_get_retry_reason', + '#define BIO_get_shutdown GRPC_SHADOW_BIO_get_shutdown', + '#define BIO_gets GRPC_SHADOW_BIO_gets', + '#define BIO_indent GRPC_SHADOW_BIO_indent', + '#define BIO_int_ctrl GRPC_SHADOW_BIO_int_ctrl', + '#define BIO_meth_free GRPC_SHADOW_BIO_meth_free', + '#define BIO_meth_new GRPC_SHADOW_BIO_meth_new', + '#define BIO_meth_set_create GRPC_SHADOW_BIO_meth_set_create', + '#define BIO_meth_set_ctrl GRPC_SHADOW_BIO_meth_set_ctrl', + '#define BIO_meth_set_destroy GRPC_SHADOW_BIO_meth_set_destroy', + '#define BIO_meth_set_gets GRPC_SHADOW_BIO_meth_set_gets', + '#define BIO_meth_set_puts GRPC_SHADOW_BIO_meth_set_puts', + '#define BIO_meth_set_read GRPC_SHADOW_BIO_meth_set_read', + '#define BIO_meth_set_write GRPC_SHADOW_BIO_meth_set_write', + '#define BIO_method_type GRPC_SHADOW_BIO_method_type', + '#define BIO_new GRPC_SHADOW_BIO_new', + '#define BIO_next GRPC_SHADOW_BIO_next', + '#define BIO_number_read GRPC_SHADOW_BIO_number_read', + '#define BIO_number_written GRPC_SHADOW_BIO_number_written', + '#define BIO_pending GRPC_SHADOW_BIO_pending', + '#define BIO_pop GRPC_SHADOW_BIO_pop', + '#define BIO_ptr_ctrl GRPC_SHADOW_BIO_ptr_ctrl', + '#define BIO_push GRPC_SHADOW_BIO_push', + '#define BIO_puts GRPC_SHADOW_BIO_puts', + '#define BIO_read GRPC_SHADOW_BIO_read', + '#define BIO_read_asn1 GRPC_SHADOW_BIO_read_asn1', + '#define BIO_reset GRPC_SHADOW_BIO_reset', + '#define BIO_set_close GRPC_SHADOW_BIO_set_close', + '#define BIO_set_data GRPC_SHADOW_BIO_set_data', + '#define BIO_set_flags GRPC_SHADOW_BIO_set_flags', + '#define BIO_set_init GRPC_SHADOW_BIO_set_init', + '#define BIO_set_retry_read GRPC_SHADOW_BIO_set_retry_read', + '#define BIO_set_retry_special GRPC_SHADOW_BIO_set_retry_special', + '#define BIO_set_retry_write GRPC_SHADOW_BIO_set_retry_write', + '#define BIO_set_shutdown GRPC_SHADOW_BIO_set_shutdown', + '#define BIO_set_write_buffer_size GRPC_SHADOW_BIO_set_write_buffer_size', + '#define BIO_should_io_special GRPC_SHADOW_BIO_should_io_special', + '#define BIO_should_read GRPC_SHADOW_BIO_should_read', + '#define BIO_should_retry GRPC_SHADOW_BIO_should_retry', + '#define BIO_should_write GRPC_SHADOW_BIO_should_write', + '#define BIO_test_flags GRPC_SHADOW_BIO_test_flags', + '#define BIO_up_ref GRPC_SHADOW_BIO_up_ref', + '#define BIO_vfree GRPC_SHADOW_BIO_vfree', + '#define BIO_wpending GRPC_SHADOW_BIO_wpending', + '#define BIO_write GRPC_SHADOW_BIO_write', + '#define ERR_print_errors GRPC_SHADOW_ERR_print_errors', + '#define BIO_get_mem_data GRPC_SHADOW_BIO_get_mem_data', + '#define BIO_get_mem_ptr GRPC_SHADOW_BIO_get_mem_ptr', + '#define BIO_mem_contents GRPC_SHADOW_BIO_mem_contents', + '#define BIO_new_mem_buf GRPC_SHADOW_BIO_new_mem_buf', + '#define BIO_s_mem GRPC_SHADOW_BIO_s_mem', + '#define BIO_set_mem_buf GRPC_SHADOW_BIO_set_mem_buf', + '#define BIO_set_mem_eof_return GRPC_SHADOW_BIO_set_mem_eof_return', + '#define BIO_do_connect GRPC_SHADOW_BIO_do_connect', + '#define BIO_new_connect GRPC_SHADOW_BIO_new_connect', + '#define BIO_s_connect GRPC_SHADOW_BIO_s_connect', + '#define BIO_set_conn_hostname GRPC_SHADOW_BIO_set_conn_hostname', + '#define BIO_set_conn_int_port GRPC_SHADOW_BIO_set_conn_int_port', + '#define BIO_set_conn_port GRPC_SHADOW_BIO_set_conn_port', + '#define BIO_set_nbio GRPC_SHADOW_BIO_set_nbio', + '#define BIO_get_fd GRPC_SHADOW_BIO_get_fd', + '#define BIO_new_fd GRPC_SHADOW_BIO_new_fd', + '#define BIO_s_fd GRPC_SHADOW_BIO_s_fd', + '#define BIO_set_fd GRPC_SHADOW_BIO_set_fd', + '#define bio_fd_should_retry GRPC_SHADOW_bio_fd_should_retry', + '#define BIO_append_filename GRPC_SHADOW_BIO_append_filename', + '#define BIO_get_fp GRPC_SHADOW_BIO_get_fp', + '#define BIO_new_file GRPC_SHADOW_BIO_new_file', + '#define BIO_new_fp GRPC_SHADOW_BIO_new_fp', + '#define BIO_read_filename GRPC_SHADOW_BIO_read_filename', + '#define BIO_rw_filename GRPC_SHADOW_BIO_rw_filename', + '#define BIO_s_file GRPC_SHADOW_BIO_s_file', + '#define BIO_set_fp GRPC_SHADOW_BIO_set_fp', + '#define BIO_write_filename GRPC_SHADOW_BIO_write_filename', + '#define BIO_hexdump GRPC_SHADOW_BIO_hexdump', + '#define BIO_ctrl_get_read_request GRPC_SHADOW_BIO_ctrl_get_read_request', + '#define BIO_ctrl_get_write_guarantee GRPC_SHADOW_BIO_ctrl_get_write_guarantee', + '#define BIO_new_bio_pair GRPC_SHADOW_BIO_new_bio_pair', + '#define BIO_shutdown_wr GRPC_SHADOW_BIO_shutdown_wr', + '#define BIO_printf GRPC_SHADOW_BIO_printf', + '#define BIO_new_socket GRPC_SHADOW_BIO_new_socket', + '#define BIO_s_socket GRPC_SHADOW_BIO_s_socket', + '#define bio_clear_socket_error GRPC_SHADOW_bio_clear_socket_error', + '#define bio_ip_and_port_to_socket_and_addr GRPC_SHADOW_bio_ip_and_port_to_socket_and_addr', + '#define bio_sock_error GRPC_SHADOW_bio_sock_error', + '#define bio_socket_nbio GRPC_SHADOW_bio_socket_nbio', + '#define RAND_enable_fork_unsafe_buffering GRPC_SHADOW_RAND_enable_fork_unsafe_buffering', + '#define rand_fork_unsafe_buffering_enabled GRPC_SHADOW_rand_fork_unsafe_buffering_enabled', + '#define RAND_SSLeay GRPC_SHADOW_RAND_SSLeay', + '#define RAND_add GRPC_SHADOW_RAND_add', + '#define RAND_cleanup GRPC_SHADOW_RAND_cleanup', + '#define RAND_egd GRPC_SHADOW_RAND_egd', + '#define RAND_file_name GRPC_SHADOW_RAND_file_name', + '#define RAND_get_rand_method GRPC_SHADOW_RAND_get_rand_method', + '#define RAND_load_file GRPC_SHADOW_RAND_load_file', + '#define RAND_poll GRPC_SHADOW_RAND_poll', + '#define RAND_seed GRPC_SHADOW_RAND_seed', + '#define RAND_set_rand_method GRPC_SHADOW_RAND_set_rand_method', + '#define RAND_status GRPC_SHADOW_RAND_status', + '#define OBJ_cbs2nid GRPC_SHADOW_OBJ_cbs2nid', + '#define OBJ_cmp GRPC_SHADOW_OBJ_cmp', + '#define OBJ_create GRPC_SHADOW_OBJ_create', + '#define OBJ_dup GRPC_SHADOW_OBJ_dup', + '#define OBJ_get0_data GRPC_SHADOW_OBJ_get0_data', + '#define OBJ_length GRPC_SHADOW_OBJ_length', + '#define OBJ_ln2nid GRPC_SHADOW_OBJ_ln2nid', + '#define OBJ_nid2cbb GRPC_SHADOW_OBJ_nid2cbb', + '#define OBJ_nid2ln GRPC_SHADOW_OBJ_nid2ln', + '#define OBJ_nid2obj GRPC_SHADOW_OBJ_nid2obj', + '#define OBJ_nid2sn GRPC_SHADOW_OBJ_nid2sn', + '#define OBJ_obj2nid GRPC_SHADOW_OBJ_obj2nid', + '#define OBJ_obj2txt GRPC_SHADOW_OBJ_obj2txt', + '#define OBJ_sn2nid GRPC_SHADOW_OBJ_sn2nid', + '#define OBJ_txt2nid GRPC_SHADOW_OBJ_txt2nid', + '#define OBJ_txt2obj GRPC_SHADOW_OBJ_txt2obj', + '#define OBJ_find_sigid_algs GRPC_SHADOW_OBJ_find_sigid_algs', + '#define OBJ_find_sigid_by_algs GRPC_SHADOW_OBJ_find_sigid_by_algs', + '#define ASN1_BIT_STRING_check GRPC_SHADOW_ASN1_BIT_STRING_check', + '#define ASN1_BIT_STRING_get_bit GRPC_SHADOW_ASN1_BIT_STRING_get_bit', + '#define ASN1_BIT_STRING_set GRPC_SHADOW_ASN1_BIT_STRING_set', + '#define ASN1_BIT_STRING_set_bit GRPC_SHADOW_ASN1_BIT_STRING_set_bit', + '#define c2i_ASN1_BIT_STRING GRPC_SHADOW_c2i_ASN1_BIT_STRING', + '#define i2c_ASN1_BIT_STRING GRPC_SHADOW_i2c_ASN1_BIT_STRING', + '#define d2i_ASN1_BOOLEAN GRPC_SHADOW_d2i_ASN1_BOOLEAN', + '#define i2d_ASN1_BOOLEAN GRPC_SHADOW_i2d_ASN1_BOOLEAN', + '#define ASN1_d2i_bio GRPC_SHADOW_ASN1_d2i_bio', + '#define ASN1_d2i_fp GRPC_SHADOW_ASN1_d2i_fp', + '#define ASN1_item_d2i_bio GRPC_SHADOW_ASN1_item_d2i_bio', + '#define ASN1_item_d2i_fp GRPC_SHADOW_ASN1_item_d2i_fp', + '#define ASN1_dup GRPC_SHADOW_ASN1_dup', + '#define ASN1_item_dup GRPC_SHADOW_ASN1_item_dup', + '#define ASN1_ENUMERATED_get GRPC_SHADOW_ASN1_ENUMERATED_get', + '#define ASN1_ENUMERATED_set GRPC_SHADOW_ASN1_ENUMERATED_set', + '#define ASN1_ENUMERATED_to_BN GRPC_SHADOW_ASN1_ENUMERATED_to_BN', + '#define BN_to_ASN1_ENUMERATED GRPC_SHADOW_BN_to_ASN1_ENUMERATED', + '#define ASN1_GENERALIZEDTIME_adj GRPC_SHADOW_ASN1_GENERALIZEDTIME_adj', + '#define ASN1_GENERALIZEDTIME_check GRPC_SHADOW_ASN1_GENERALIZEDTIME_check', + '#define ASN1_GENERALIZEDTIME_set GRPC_SHADOW_ASN1_GENERALIZEDTIME_set', + '#define ASN1_GENERALIZEDTIME_set_string GRPC_SHADOW_ASN1_GENERALIZEDTIME_set_string', + '#define asn1_generalizedtime_to_tm GRPC_SHADOW_asn1_generalizedtime_to_tm', + '#define ASN1_i2d_bio GRPC_SHADOW_ASN1_i2d_bio', + '#define ASN1_i2d_fp GRPC_SHADOW_ASN1_i2d_fp', + '#define ASN1_item_i2d_bio GRPC_SHADOW_ASN1_item_i2d_bio', + '#define ASN1_item_i2d_fp GRPC_SHADOW_ASN1_item_i2d_fp', + '#define ASN1_INTEGER_cmp GRPC_SHADOW_ASN1_INTEGER_cmp', + '#define ASN1_INTEGER_dup GRPC_SHADOW_ASN1_INTEGER_dup', + '#define ASN1_INTEGER_get GRPC_SHADOW_ASN1_INTEGER_get', + '#define ASN1_INTEGER_set GRPC_SHADOW_ASN1_INTEGER_set', + '#define ASN1_INTEGER_set_uint64 GRPC_SHADOW_ASN1_INTEGER_set_uint64', + '#define ASN1_INTEGER_to_BN GRPC_SHADOW_ASN1_INTEGER_to_BN', + '#define BN_to_ASN1_INTEGER GRPC_SHADOW_BN_to_ASN1_INTEGER', + '#define c2i_ASN1_INTEGER GRPC_SHADOW_c2i_ASN1_INTEGER', + '#define d2i_ASN1_UINTEGER GRPC_SHADOW_d2i_ASN1_UINTEGER', + '#define i2c_ASN1_INTEGER GRPC_SHADOW_i2c_ASN1_INTEGER', + '#define ASN1_mbstring_copy GRPC_SHADOW_ASN1_mbstring_copy', + '#define ASN1_mbstring_ncopy GRPC_SHADOW_ASN1_mbstring_ncopy', + '#define ASN1_OBJECT_create GRPC_SHADOW_ASN1_OBJECT_create', + '#define ASN1_OBJECT_free GRPC_SHADOW_ASN1_OBJECT_free', + '#define ASN1_OBJECT_new GRPC_SHADOW_ASN1_OBJECT_new', + '#define c2i_ASN1_OBJECT GRPC_SHADOW_c2i_ASN1_OBJECT', + '#define d2i_ASN1_OBJECT GRPC_SHADOW_d2i_ASN1_OBJECT', + '#define i2a_ASN1_OBJECT GRPC_SHADOW_i2a_ASN1_OBJECT', + '#define i2d_ASN1_OBJECT GRPC_SHADOW_i2d_ASN1_OBJECT', + '#define i2t_ASN1_OBJECT GRPC_SHADOW_i2t_ASN1_OBJECT', + '#define ASN1_OCTET_STRING_cmp GRPC_SHADOW_ASN1_OCTET_STRING_cmp', + '#define ASN1_OCTET_STRING_dup GRPC_SHADOW_ASN1_OCTET_STRING_dup', + '#define ASN1_OCTET_STRING_set GRPC_SHADOW_ASN1_OCTET_STRING_set', + '#define ASN1_PRINTABLE_type GRPC_SHADOW_ASN1_PRINTABLE_type', + '#define ASN1_STRING_TABLE_add GRPC_SHADOW_ASN1_STRING_TABLE_add', + '#define ASN1_STRING_TABLE_cleanup GRPC_SHADOW_ASN1_STRING_TABLE_cleanup', + '#define ASN1_STRING_TABLE_get GRPC_SHADOW_ASN1_STRING_TABLE_get', + '#define ASN1_STRING_get_default_mask GRPC_SHADOW_ASN1_STRING_get_default_mask', + '#define ASN1_STRING_set_by_NID GRPC_SHADOW_ASN1_STRING_set_by_NID', + '#define ASN1_STRING_set_default_mask GRPC_SHADOW_ASN1_STRING_set_default_mask', + '#define ASN1_STRING_set_default_mask_asc GRPC_SHADOW_ASN1_STRING_set_default_mask_asc', + '#define ASN1_TIME_adj GRPC_SHADOW_ASN1_TIME_adj', + '#define ASN1_TIME_check GRPC_SHADOW_ASN1_TIME_check', + '#define ASN1_TIME_diff GRPC_SHADOW_ASN1_TIME_diff', + '#define ASN1_TIME_free GRPC_SHADOW_ASN1_TIME_free', + '#define ASN1_TIME_it GRPC_SHADOW_ASN1_TIME_it', + '#define ASN1_TIME_new GRPC_SHADOW_ASN1_TIME_new', + '#define ASN1_TIME_set GRPC_SHADOW_ASN1_TIME_set', + '#define ASN1_TIME_set_string GRPC_SHADOW_ASN1_TIME_set_string', + '#define ASN1_TIME_to_generalizedtime GRPC_SHADOW_ASN1_TIME_to_generalizedtime', + '#define d2i_ASN1_TIME GRPC_SHADOW_d2i_ASN1_TIME', + '#define i2d_ASN1_TIME GRPC_SHADOW_i2d_ASN1_TIME', + '#define ASN1_TYPE_cmp GRPC_SHADOW_ASN1_TYPE_cmp', + '#define ASN1_TYPE_get GRPC_SHADOW_ASN1_TYPE_get', + '#define ASN1_TYPE_set GRPC_SHADOW_ASN1_TYPE_set', + '#define ASN1_TYPE_set1 GRPC_SHADOW_ASN1_TYPE_set1', + '#define ASN1_UTCTIME_adj GRPC_SHADOW_ASN1_UTCTIME_adj', + '#define ASN1_UTCTIME_check GRPC_SHADOW_ASN1_UTCTIME_check', + '#define ASN1_UTCTIME_cmp_time_t GRPC_SHADOW_ASN1_UTCTIME_cmp_time_t', + '#define ASN1_UTCTIME_set GRPC_SHADOW_ASN1_UTCTIME_set', + '#define ASN1_UTCTIME_set_string GRPC_SHADOW_ASN1_UTCTIME_set_string', + '#define asn1_utctime_to_tm GRPC_SHADOW_asn1_utctime_to_tm', + '#define UTF8_getc GRPC_SHADOW_UTF8_getc', + '#define UTF8_putc GRPC_SHADOW_UTF8_putc', + '#define ASN1_STRING_cmp GRPC_SHADOW_ASN1_STRING_cmp', + '#define ASN1_STRING_copy GRPC_SHADOW_ASN1_STRING_copy', + '#define ASN1_STRING_data GRPC_SHADOW_ASN1_STRING_data', + '#define ASN1_STRING_dup GRPC_SHADOW_ASN1_STRING_dup', + '#define ASN1_STRING_free GRPC_SHADOW_ASN1_STRING_free', + '#define ASN1_STRING_get0_data GRPC_SHADOW_ASN1_STRING_get0_data', + '#define ASN1_STRING_length GRPC_SHADOW_ASN1_STRING_length', + '#define ASN1_STRING_length_set GRPC_SHADOW_ASN1_STRING_length_set', + '#define ASN1_STRING_new GRPC_SHADOW_ASN1_STRING_new', + '#define ASN1_STRING_set GRPC_SHADOW_ASN1_STRING_set', + '#define ASN1_STRING_set0 GRPC_SHADOW_ASN1_STRING_set0', + '#define ASN1_STRING_type GRPC_SHADOW_ASN1_STRING_type', + '#define ASN1_STRING_type_new GRPC_SHADOW_ASN1_STRING_type_new', + '#define ASN1_get_object GRPC_SHADOW_ASN1_get_object', + '#define ASN1_object_size GRPC_SHADOW_ASN1_object_size', + '#define ASN1_put_eoc GRPC_SHADOW_ASN1_put_eoc', + '#define ASN1_put_object GRPC_SHADOW_ASN1_put_object', + '#define ASN1_tag2str GRPC_SHADOW_ASN1_tag2str', + '#define ASN1_item_pack GRPC_SHADOW_ASN1_item_pack', + '#define ASN1_item_unpack GRPC_SHADOW_ASN1_item_unpack', + '#define i2a_ASN1_ENUMERATED GRPC_SHADOW_i2a_ASN1_ENUMERATED', + '#define i2a_ASN1_INTEGER GRPC_SHADOW_i2a_ASN1_INTEGER', + '#define i2a_ASN1_STRING GRPC_SHADOW_i2a_ASN1_STRING', + '#define ASN1_item_d2i GRPC_SHADOW_ASN1_item_d2i', + '#define ASN1_item_ex_d2i GRPC_SHADOW_ASN1_item_ex_d2i', + '#define ASN1_tag2bit GRPC_SHADOW_ASN1_tag2bit', + '#define asn1_ex_c2i GRPC_SHADOW_asn1_ex_c2i', + '#define ASN1_item_ex_i2d GRPC_SHADOW_ASN1_item_ex_i2d', + '#define ASN1_item_i2d GRPC_SHADOW_ASN1_item_i2d', + '#define ASN1_item_ndef_i2d GRPC_SHADOW_ASN1_item_ndef_i2d', + '#define asn1_ex_i2c GRPC_SHADOW_asn1_ex_i2c', + '#define ASN1_item_ex_free GRPC_SHADOW_ASN1_item_ex_free', + '#define ASN1_item_free GRPC_SHADOW_ASN1_item_free', + '#define ASN1_primitive_free GRPC_SHADOW_ASN1_primitive_free', + '#define ASN1_template_free GRPC_SHADOW_ASN1_template_free', + '#define asn1_item_combine_free GRPC_SHADOW_asn1_item_combine_free', + '#define ASN1_item_ex_new GRPC_SHADOW_ASN1_item_ex_new', + '#define ASN1_item_new GRPC_SHADOW_ASN1_item_new', + '#define ASN1_primitive_new GRPC_SHADOW_ASN1_primitive_new', + '#define ASN1_template_new GRPC_SHADOW_ASN1_template_new', + '#define ASN1_ANY_it GRPC_SHADOW_ASN1_ANY_it', + '#define ASN1_BIT_STRING_free GRPC_SHADOW_ASN1_BIT_STRING_free', + '#define ASN1_BIT_STRING_it GRPC_SHADOW_ASN1_BIT_STRING_it', + '#define ASN1_BIT_STRING_new GRPC_SHADOW_ASN1_BIT_STRING_new', + '#define ASN1_BMPSTRING_free GRPC_SHADOW_ASN1_BMPSTRING_free', + '#define ASN1_BMPSTRING_it GRPC_SHADOW_ASN1_BMPSTRING_it', + '#define ASN1_BMPSTRING_new GRPC_SHADOW_ASN1_BMPSTRING_new', + '#define ASN1_BOOLEAN_it GRPC_SHADOW_ASN1_BOOLEAN_it', + '#define ASN1_ENUMERATED_free GRPC_SHADOW_ASN1_ENUMERATED_free', + '#define ASN1_ENUMERATED_it GRPC_SHADOW_ASN1_ENUMERATED_it', + '#define ASN1_ENUMERATED_new GRPC_SHADOW_ASN1_ENUMERATED_new', + '#define ASN1_FBOOLEAN_it GRPC_SHADOW_ASN1_FBOOLEAN_it', + '#define ASN1_GENERALIZEDTIME_free GRPC_SHADOW_ASN1_GENERALIZEDTIME_free', + '#define ASN1_GENERALIZEDTIME_it GRPC_SHADOW_ASN1_GENERALIZEDTIME_it', + '#define ASN1_GENERALIZEDTIME_new GRPC_SHADOW_ASN1_GENERALIZEDTIME_new', + '#define ASN1_GENERALSTRING_free GRPC_SHADOW_ASN1_GENERALSTRING_free', + '#define ASN1_GENERALSTRING_it GRPC_SHADOW_ASN1_GENERALSTRING_it', + '#define ASN1_GENERALSTRING_new GRPC_SHADOW_ASN1_GENERALSTRING_new', + '#define ASN1_IA5STRING_free GRPC_SHADOW_ASN1_IA5STRING_free', + '#define ASN1_IA5STRING_it GRPC_SHADOW_ASN1_IA5STRING_it', + '#define ASN1_IA5STRING_new GRPC_SHADOW_ASN1_IA5STRING_new', + '#define ASN1_INTEGER_free GRPC_SHADOW_ASN1_INTEGER_free', + '#define ASN1_INTEGER_it GRPC_SHADOW_ASN1_INTEGER_it', + '#define ASN1_INTEGER_new GRPC_SHADOW_ASN1_INTEGER_new', + '#define ASN1_NULL_free GRPC_SHADOW_ASN1_NULL_free', + '#define ASN1_NULL_it GRPC_SHADOW_ASN1_NULL_it', + '#define ASN1_NULL_new GRPC_SHADOW_ASN1_NULL_new', + '#define ASN1_OBJECT_it GRPC_SHADOW_ASN1_OBJECT_it', + '#define ASN1_OCTET_STRING_NDEF_it GRPC_SHADOW_ASN1_OCTET_STRING_NDEF_it', + '#define ASN1_OCTET_STRING_free GRPC_SHADOW_ASN1_OCTET_STRING_free', + '#define ASN1_OCTET_STRING_it GRPC_SHADOW_ASN1_OCTET_STRING_it', + '#define ASN1_OCTET_STRING_new GRPC_SHADOW_ASN1_OCTET_STRING_new', + '#define ASN1_PRINTABLESTRING_free GRPC_SHADOW_ASN1_PRINTABLESTRING_free', + '#define ASN1_PRINTABLESTRING_it GRPC_SHADOW_ASN1_PRINTABLESTRING_it', + '#define ASN1_PRINTABLESTRING_new GRPC_SHADOW_ASN1_PRINTABLESTRING_new', + '#define ASN1_PRINTABLE_free GRPC_SHADOW_ASN1_PRINTABLE_free', + '#define ASN1_PRINTABLE_it GRPC_SHADOW_ASN1_PRINTABLE_it', + '#define ASN1_PRINTABLE_new GRPC_SHADOW_ASN1_PRINTABLE_new', + '#define ASN1_SEQUENCE_ANY_it GRPC_SHADOW_ASN1_SEQUENCE_ANY_it', + '#define ASN1_SEQUENCE_it GRPC_SHADOW_ASN1_SEQUENCE_it', + '#define ASN1_SET_ANY_it GRPC_SHADOW_ASN1_SET_ANY_it', + '#define ASN1_T61STRING_free GRPC_SHADOW_ASN1_T61STRING_free', + '#define ASN1_T61STRING_it GRPC_SHADOW_ASN1_T61STRING_it', + '#define ASN1_T61STRING_new GRPC_SHADOW_ASN1_T61STRING_new', + '#define ASN1_TBOOLEAN_it GRPC_SHADOW_ASN1_TBOOLEAN_it', + '#define ASN1_TYPE_free GRPC_SHADOW_ASN1_TYPE_free', + '#define ASN1_TYPE_new GRPC_SHADOW_ASN1_TYPE_new', + '#define ASN1_UNIVERSALSTRING_free GRPC_SHADOW_ASN1_UNIVERSALSTRING_free', + '#define ASN1_UNIVERSALSTRING_it GRPC_SHADOW_ASN1_UNIVERSALSTRING_it', + '#define ASN1_UNIVERSALSTRING_new GRPC_SHADOW_ASN1_UNIVERSALSTRING_new', + '#define ASN1_UTCTIME_free GRPC_SHADOW_ASN1_UTCTIME_free', + '#define ASN1_UTCTIME_it GRPC_SHADOW_ASN1_UTCTIME_it', + '#define ASN1_UTCTIME_new GRPC_SHADOW_ASN1_UTCTIME_new', + '#define ASN1_UTF8STRING_free GRPC_SHADOW_ASN1_UTF8STRING_free', + '#define ASN1_UTF8STRING_it GRPC_SHADOW_ASN1_UTF8STRING_it', + '#define ASN1_UTF8STRING_new GRPC_SHADOW_ASN1_UTF8STRING_new', + '#define ASN1_VISIBLESTRING_free GRPC_SHADOW_ASN1_VISIBLESTRING_free', + '#define ASN1_VISIBLESTRING_it GRPC_SHADOW_ASN1_VISIBLESTRING_it', + '#define ASN1_VISIBLESTRING_new GRPC_SHADOW_ASN1_VISIBLESTRING_new', + '#define DIRECTORYSTRING_free GRPC_SHADOW_DIRECTORYSTRING_free', + '#define DIRECTORYSTRING_it GRPC_SHADOW_DIRECTORYSTRING_it', + '#define DIRECTORYSTRING_new GRPC_SHADOW_DIRECTORYSTRING_new', + '#define DISPLAYTEXT_free GRPC_SHADOW_DISPLAYTEXT_free', + '#define DISPLAYTEXT_it GRPC_SHADOW_DISPLAYTEXT_it', + '#define DISPLAYTEXT_new GRPC_SHADOW_DISPLAYTEXT_new', + '#define d2i_ASN1_BIT_STRING GRPC_SHADOW_d2i_ASN1_BIT_STRING', + '#define d2i_ASN1_BMPSTRING GRPC_SHADOW_d2i_ASN1_BMPSTRING', + '#define d2i_ASN1_ENUMERATED GRPC_SHADOW_d2i_ASN1_ENUMERATED', + '#define d2i_ASN1_GENERALIZEDTIME GRPC_SHADOW_d2i_ASN1_GENERALIZEDTIME', + '#define d2i_ASN1_GENERALSTRING GRPC_SHADOW_d2i_ASN1_GENERALSTRING', + '#define d2i_ASN1_IA5STRING GRPC_SHADOW_d2i_ASN1_IA5STRING', + '#define d2i_ASN1_INTEGER GRPC_SHADOW_d2i_ASN1_INTEGER', + '#define d2i_ASN1_NULL GRPC_SHADOW_d2i_ASN1_NULL', + '#define d2i_ASN1_OCTET_STRING GRPC_SHADOW_d2i_ASN1_OCTET_STRING', + '#define d2i_ASN1_PRINTABLE GRPC_SHADOW_d2i_ASN1_PRINTABLE', + '#define d2i_ASN1_PRINTABLESTRING GRPC_SHADOW_d2i_ASN1_PRINTABLESTRING', + '#define d2i_ASN1_SEQUENCE_ANY GRPC_SHADOW_d2i_ASN1_SEQUENCE_ANY', + '#define d2i_ASN1_SET_ANY GRPC_SHADOW_d2i_ASN1_SET_ANY', + '#define d2i_ASN1_T61STRING GRPC_SHADOW_d2i_ASN1_T61STRING', + '#define d2i_ASN1_TYPE GRPC_SHADOW_d2i_ASN1_TYPE', + '#define d2i_ASN1_UNIVERSALSTRING GRPC_SHADOW_d2i_ASN1_UNIVERSALSTRING', + '#define d2i_ASN1_UTCTIME GRPC_SHADOW_d2i_ASN1_UTCTIME', + '#define d2i_ASN1_UTF8STRING GRPC_SHADOW_d2i_ASN1_UTF8STRING', + '#define d2i_ASN1_VISIBLESTRING GRPC_SHADOW_d2i_ASN1_VISIBLESTRING', + '#define d2i_DIRECTORYSTRING GRPC_SHADOW_d2i_DIRECTORYSTRING', + '#define d2i_DISPLAYTEXT GRPC_SHADOW_d2i_DISPLAYTEXT', + '#define i2d_ASN1_BIT_STRING GRPC_SHADOW_i2d_ASN1_BIT_STRING', + '#define i2d_ASN1_BMPSTRING GRPC_SHADOW_i2d_ASN1_BMPSTRING', + '#define i2d_ASN1_ENUMERATED GRPC_SHADOW_i2d_ASN1_ENUMERATED', + '#define i2d_ASN1_GENERALIZEDTIME GRPC_SHADOW_i2d_ASN1_GENERALIZEDTIME', + '#define i2d_ASN1_GENERALSTRING GRPC_SHADOW_i2d_ASN1_GENERALSTRING', + '#define i2d_ASN1_IA5STRING GRPC_SHADOW_i2d_ASN1_IA5STRING', + '#define i2d_ASN1_INTEGER GRPC_SHADOW_i2d_ASN1_INTEGER', + '#define i2d_ASN1_NULL GRPC_SHADOW_i2d_ASN1_NULL', + '#define i2d_ASN1_OCTET_STRING GRPC_SHADOW_i2d_ASN1_OCTET_STRING', + '#define i2d_ASN1_PRINTABLE GRPC_SHADOW_i2d_ASN1_PRINTABLE', + '#define i2d_ASN1_PRINTABLESTRING GRPC_SHADOW_i2d_ASN1_PRINTABLESTRING', + '#define i2d_ASN1_SEQUENCE_ANY GRPC_SHADOW_i2d_ASN1_SEQUENCE_ANY', + '#define i2d_ASN1_SET_ANY GRPC_SHADOW_i2d_ASN1_SET_ANY', + '#define i2d_ASN1_T61STRING GRPC_SHADOW_i2d_ASN1_T61STRING', + '#define i2d_ASN1_TYPE GRPC_SHADOW_i2d_ASN1_TYPE', + '#define i2d_ASN1_UNIVERSALSTRING GRPC_SHADOW_i2d_ASN1_UNIVERSALSTRING', + '#define i2d_ASN1_UTCTIME GRPC_SHADOW_i2d_ASN1_UTCTIME', + '#define i2d_ASN1_UTF8STRING GRPC_SHADOW_i2d_ASN1_UTF8STRING', + '#define i2d_ASN1_VISIBLESTRING GRPC_SHADOW_i2d_ASN1_VISIBLESTRING', + '#define i2d_DIRECTORYSTRING GRPC_SHADOW_i2d_DIRECTORYSTRING', + '#define i2d_DISPLAYTEXT GRPC_SHADOW_i2d_DISPLAYTEXT', + '#define asn1_do_adb GRPC_SHADOW_asn1_do_adb', + '#define asn1_enc_free GRPC_SHADOW_asn1_enc_free', + '#define asn1_enc_init GRPC_SHADOW_asn1_enc_init', + '#define asn1_enc_restore GRPC_SHADOW_asn1_enc_restore', + '#define asn1_enc_save GRPC_SHADOW_asn1_enc_save', + '#define asn1_get_choice_selector GRPC_SHADOW_asn1_get_choice_selector', + '#define asn1_get_field_ptr GRPC_SHADOW_asn1_get_field_ptr', + '#define asn1_refcount_dec_and_test_zero GRPC_SHADOW_asn1_refcount_dec_and_test_zero', + '#define asn1_refcount_set_one GRPC_SHADOW_asn1_refcount_set_one', + '#define asn1_set_choice_selector GRPC_SHADOW_asn1_set_choice_selector', + '#define OPENSSL_gmtime GRPC_SHADOW_OPENSSL_gmtime', + '#define OPENSSL_gmtime_adj GRPC_SHADOW_OPENSSL_gmtime_adj', + '#define OPENSSL_gmtime_diff GRPC_SHADOW_OPENSSL_gmtime_diff', + '#define ENGINE_free GRPC_SHADOW_ENGINE_free', + '#define ENGINE_get_ECDSA_method GRPC_SHADOW_ENGINE_get_ECDSA_method', + '#define ENGINE_get_RSA_method GRPC_SHADOW_ENGINE_get_RSA_method', + '#define ENGINE_new GRPC_SHADOW_ENGINE_new', + '#define ENGINE_set_ECDSA_method GRPC_SHADOW_ENGINE_set_ECDSA_method', + '#define ENGINE_set_RSA_method GRPC_SHADOW_ENGINE_set_RSA_method', + '#define METHOD_ref GRPC_SHADOW_METHOD_ref', + '#define METHOD_unref GRPC_SHADOW_METHOD_unref', + '#define DH_compute_key GRPC_SHADOW_DH_compute_key', + '#define DH_free GRPC_SHADOW_DH_free', + '#define DH_generate_key GRPC_SHADOW_DH_generate_key', + '#define DH_generate_parameters_ex GRPC_SHADOW_DH_generate_parameters_ex', + '#define DH_get0_key GRPC_SHADOW_DH_get0_key', + '#define DH_get0_pqg GRPC_SHADOW_DH_get0_pqg', + '#define DH_get_ex_data GRPC_SHADOW_DH_get_ex_data', + '#define DH_get_ex_new_index GRPC_SHADOW_DH_get_ex_new_index', + '#define DH_new GRPC_SHADOW_DH_new', + '#define DH_num_bits GRPC_SHADOW_DH_num_bits', + '#define DH_set0_key GRPC_SHADOW_DH_set0_key', + '#define DH_set0_pqg GRPC_SHADOW_DH_set0_pqg', + '#define DH_set_ex_data GRPC_SHADOW_DH_set_ex_data', + '#define DH_size GRPC_SHADOW_DH_size', + '#define DH_up_ref GRPC_SHADOW_DH_up_ref', + '#define DHparams_dup GRPC_SHADOW_DHparams_dup', + '#define BN_get_rfc3526_prime_1536 GRPC_SHADOW_BN_get_rfc3526_prime_1536', + '#define DH_check GRPC_SHADOW_DH_check', + '#define DH_check_pub_key GRPC_SHADOW_DH_check_pub_key', + '#define DH_marshal_parameters GRPC_SHADOW_DH_marshal_parameters', + '#define DH_parse_parameters GRPC_SHADOW_DH_parse_parameters', + '#define d2i_DHparams GRPC_SHADOW_d2i_DHparams', + '#define i2d_DHparams GRPC_SHADOW_i2d_DHparams', + '#define DSA_SIG_free GRPC_SHADOW_DSA_SIG_free', + '#define DSA_SIG_new GRPC_SHADOW_DSA_SIG_new', + '#define DSA_check_signature GRPC_SHADOW_DSA_check_signature', + '#define DSA_do_check_signature GRPC_SHADOW_DSA_do_check_signature', + '#define DSA_do_sign GRPC_SHADOW_DSA_do_sign', + '#define DSA_do_verify GRPC_SHADOW_DSA_do_verify', + '#define DSA_dup_DH GRPC_SHADOW_DSA_dup_DH', + '#define DSA_free GRPC_SHADOW_DSA_free', + '#define DSA_generate_key GRPC_SHADOW_DSA_generate_key', + '#define DSA_generate_parameters_ex GRPC_SHADOW_DSA_generate_parameters_ex', + '#define DSA_get0_key GRPC_SHADOW_DSA_get0_key', + '#define DSA_get0_pqg GRPC_SHADOW_DSA_get0_pqg', + '#define DSA_get_ex_data GRPC_SHADOW_DSA_get_ex_data', + '#define DSA_get_ex_new_index GRPC_SHADOW_DSA_get_ex_new_index', + '#define DSA_new GRPC_SHADOW_DSA_new', + '#define DSA_set0_key GRPC_SHADOW_DSA_set0_key', + '#define DSA_set0_pqg GRPC_SHADOW_DSA_set0_pqg', + '#define DSA_set_ex_data GRPC_SHADOW_DSA_set_ex_data', + '#define DSA_sign GRPC_SHADOW_DSA_sign', + '#define DSA_size GRPC_SHADOW_DSA_size', + '#define DSA_up_ref GRPC_SHADOW_DSA_up_ref', + '#define DSA_verify GRPC_SHADOW_DSA_verify', + '#define DSAparams_dup GRPC_SHADOW_DSAparams_dup', + '#define DSA_SIG_marshal GRPC_SHADOW_DSA_SIG_marshal', + '#define DSA_SIG_parse GRPC_SHADOW_DSA_SIG_parse', + '#define DSA_marshal_parameters GRPC_SHADOW_DSA_marshal_parameters', + '#define DSA_marshal_private_key GRPC_SHADOW_DSA_marshal_private_key', + '#define DSA_marshal_public_key GRPC_SHADOW_DSA_marshal_public_key', + '#define DSA_parse_parameters GRPC_SHADOW_DSA_parse_parameters', + '#define DSA_parse_private_key GRPC_SHADOW_DSA_parse_private_key', + '#define DSA_parse_public_key GRPC_SHADOW_DSA_parse_public_key', + '#define d2i_DSAPrivateKey GRPC_SHADOW_d2i_DSAPrivateKey', + '#define d2i_DSAPublicKey GRPC_SHADOW_d2i_DSAPublicKey', + '#define d2i_DSA_SIG GRPC_SHADOW_d2i_DSA_SIG', + '#define d2i_DSAparams GRPC_SHADOW_d2i_DSAparams', + '#define i2d_DSAPrivateKey GRPC_SHADOW_i2d_DSAPrivateKey', + '#define i2d_DSAPublicKey GRPC_SHADOW_i2d_DSAPublicKey', + '#define i2d_DSA_SIG GRPC_SHADOW_i2d_DSA_SIG', + '#define i2d_DSAparams GRPC_SHADOW_i2d_DSAparams', + '#define RSAPrivateKey_dup GRPC_SHADOW_RSAPrivateKey_dup', + '#define RSAPublicKey_dup GRPC_SHADOW_RSAPublicKey_dup', + '#define RSA_marshal_private_key GRPC_SHADOW_RSA_marshal_private_key', + '#define RSA_marshal_public_key GRPC_SHADOW_RSA_marshal_public_key', + '#define RSA_parse_private_key GRPC_SHADOW_RSA_parse_private_key', + '#define RSA_parse_public_key GRPC_SHADOW_RSA_parse_public_key', + '#define RSA_private_key_from_bytes GRPC_SHADOW_RSA_private_key_from_bytes', + '#define RSA_private_key_to_bytes GRPC_SHADOW_RSA_private_key_to_bytes', + '#define RSA_public_key_from_bytes GRPC_SHADOW_RSA_public_key_from_bytes', + '#define RSA_public_key_to_bytes GRPC_SHADOW_RSA_public_key_to_bytes', + '#define d2i_RSAPrivateKey GRPC_SHADOW_d2i_RSAPrivateKey', + '#define d2i_RSAPublicKey GRPC_SHADOW_d2i_RSAPublicKey', + '#define i2d_RSAPrivateKey GRPC_SHADOW_i2d_RSAPrivateKey', + '#define i2d_RSAPublicKey GRPC_SHADOW_i2d_RSAPublicKey', + '#define EC_KEY_marshal_curve_name GRPC_SHADOW_EC_KEY_marshal_curve_name', + '#define EC_KEY_marshal_private_key GRPC_SHADOW_EC_KEY_marshal_private_key', + '#define EC_KEY_parse_curve_name GRPC_SHADOW_EC_KEY_parse_curve_name', + '#define EC_KEY_parse_parameters GRPC_SHADOW_EC_KEY_parse_parameters', + '#define EC_KEY_parse_private_key GRPC_SHADOW_EC_KEY_parse_private_key', + '#define EC_POINT_point2cbb GRPC_SHADOW_EC_POINT_point2cbb', + '#define d2i_ECParameters GRPC_SHADOW_d2i_ECParameters', + '#define d2i_ECPrivateKey GRPC_SHADOW_d2i_ECPrivateKey', + '#define i2d_ECParameters GRPC_SHADOW_i2d_ECParameters', + '#define i2d_ECPrivateKey GRPC_SHADOW_i2d_ECPrivateKey', + '#define i2o_ECPublicKey GRPC_SHADOW_i2o_ECPublicKey', + '#define o2i_ECPublicKey GRPC_SHADOW_o2i_ECPublicKey', + '#define ECDH_compute_key GRPC_SHADOW_ECDH_compute_key', + '#define ECDSA_SIG_from_bytes GRPC_SHADOW_ECDSA_SIG_from_bytes', + '#define ECDSA_SIG_marshal GRPC_SHADOW_ECDSA_SIG_marshal', + '#define ECDSA_SIG_max_len GRPC_SHADOW_ECDSA_SIG_max_len', + '#define ECDSA_SIG_parse GRPC_SHADOW_ECDSA_SIG_parse', + '#define ECDSA_SIG_to_bytes GRPC_SHADOW_ECDSA_SIG_to_bytes', + '#define ECDSA_sign GRPC_SHADOW_ECDSA_sign', + '#define ECDSA_size GRPC_SHADOW_ECDSA_size', + '#define ECDSA_verify GRPC_SHADOW_ECDSA_verify', + '#define d2i_ECDSA_SIG GRPC_SHADOW_d2i_ECDSA_SIG', + '#define i2d_ECDSA_SIG GRPC_SHADOW_i2d_ECDSA_SIG', + '#define AES_CMAC GRPC_SHADOW_AES_CMAC', + '#define CMAC_CTX_free GRPC_SHADOW_CMAC_CTX_free', + '#define CMAC_CTX_new GRPC_SHADOW_CMAC_CTX_new', + '#define CMAC_Final GRPC_SHADOW_CMAC_Final', + '#define CMAC_Init GRPC_SHADOW_CMAC_Init', + '#define CMAC_Reset GRPC_SHADOW_CMAC_Reset', + '#define CMAC_Update GRPC_SHADOW_CMAC_Update', + '#define EVP_DigestSign GRPC_SHADOW_EVP_DigestSign', + '#define EVP_DigestSignFinal GRPC_SHADOW_EVP_DigestSignFinal', + '#define EVP_DigestSignInit GRPC_SHADOW_EVP_DigestSignInit', + '#define EVP_DigestSignUpdate GRPC_SHADOW_EVP_DigestSignUpdate', + '#define EVP_DigestVerify GRPC_SHADOW_EVP_DigestVerify', + '#define EVP_DigestVerifyFinal GRPC_SHADOW_EVP_DigestVerifyFinal', + '#define EVP_DigestVerifyInit GRPC_SHADOW_EVP_DigestVerifyInit', + '#define EVP_DigestVerifyUpdate GRPC_SHADOW_EVP_DigestVerifyUpdate', + '#define EVP_PKEY_CTX_get_signature_md GRPC_SHADOW_EVP_PKEY_CTX_get_signature_md', + '#define EVP_PKEY_CTX_set_signature_md GRPC_SHADOW_EVP_PKEY_CTX_set_signature_md', + '#define EVP_PKEY_assign GRPC_SHADOW_EVP_PKEY_assign', + '#define EVP_PKEY_assign_DSA GRPC_SHADOW_EVP_PKEY_assign_DSA', + '#define EVP_PKEY_assign_EC_KEY GRPC_SHADOW_EVP_PKEY_assign_EC_KEY', + '#define EVP_PKEY_assign_RSA GRPC_SHADOW_EVP_PKEY_assign_RSA', + '#define EVP_PKEY_bits GRPC_SHADOW_EVP_PKEY_bits', + '#define EVP_PKEY_cmp GRPC_SHADOW_EVP_PKEY_cmp', + '#define EVP_PKEY_cmp_parameters GRPC_SHADOW_EVP_PKEY_cmp_parameters', + '#define EVP_PKEY_copy_parameters GRPC_SHADOW_EVP_PKEY_copy_parameters', + '#define EVP_PKEY_free GRPC_SHADOW_EVP_PKEY_free', + '#define EVP_PKEY_get0_DH GRPC_SHADOW_EVP_PKEY_get0_DH', + '#define EVP_PKEY_get0_DSA GRPC_SHADOW_EVP_PKEY_get0_DSA', + '#define EVP_PKEY_get0_EC_KEY GRPC_SHADOW_EVP_PKEY_get0_EC_KEY', + '#define EVP_PKEY_get0_RSA GRPC_SHADOW_EVP_PKEY_get0_RSA', + '#define EVP_PKEY_get1_DSA GRPC_SHADOW_EVP_PKEY_get1_DSA', + '#define EVP_PKEY_get1_EC_KEY GRPC_SHADOW_EVP_PKEY_get1_EC_KEY', + '#define EVP_PKEY_get1_RSA GRPC_SHADOW_EVP_PKEY_get1_RSA', + '#define EVP_PKEY_id GRPC_SHADOW_EVP_PKEY_id', + '#define EVP_PKEY_is_opaque GRPC_SHADOW_EVP_PKEY_is_opaque', + '#define EVP_PKEY_missing_parameters GRPC_SHADOW_EVP_PKEY_missing_parameters', + '#define EVP_PKEY_new GRPC_SHADOW_EVP_PKEY_new', + '#define EVP_PKEY_set1_DSA GRPC_SHADOW_EVP_PKEY_set1_DSA', + '#define EVP_PKEY_set1_EC_KEY GRPC_SHADOW_EVP_PKEY_set1_EC_KEY', + '#define EVP_PKEY_set1_RSA GRPC_SHADOW_EVP_PKEY_set1_RSA', + '#define EVP_PKEY_set_type GRPC_SHADOW_EVP_PKEY_set_type', + '#define EVP_PKEY_size GRPC_SHADOW_EVP_PKEY_size', + '#define EVP_PKEY_type GRPC_SHADOW_EVP_PKEY_type', + '#define EVP_PKEY_up_ref GRPC_SHADOW_EVP_PKEY_up_ref', + '#define EVP_cleanup GRPC_SHADOW_EVP_cleanup', + '#define OPENSSL_add_all_algorithms_conf GRPC_SHADOW_OPENSSL_add_all_algorithms_conf', + '#define OpenSSL_add_all_algorithms GRPC_SHADOW_OpenSSL_add_all_algorithms', + '#define OpenSSL_add_all_ciphers GRPC_SHADOW_OpenSSL_add_all_ciphers', + '#define OpenSSL_add_all_digests GRPC_SHADOW_OpenSSL_add_all_digests', + '#define EVP_marshal_private_key GRPC_SHADOW_EVP_marshal_private_key', + '#define EVP_marshal_public_key GRPC_SHADOW_EVP_marshal_public_key', + '#define EVP_parse_private_key GRPC_SHADOW_EVP_parse_private_key', + '#define EVP_parse_public_key GRPC_SHADOW_EVP_parse_public_key', + '#define d2i_AutoPrivateKey GRPC_SHADOW_d2i_AutoPrivateKey', + '#define d2i_PrivateKey GRPC_SHADOW_d2i_PrivateKey', + '#define i2d_PublicKey GRPC_SHADOW_i2d_PublicKey', + '#define EVP_PKEY_CTX_ctrl GRPC_SHADOW_EVP_PKEY_CTX_ctrl', + '#define EVP_PKEY_CTX_dup GRPC_SHADOW_EVP_PKEY_CTX_dup', + '#define EVP_PKEY_CTX_free GRPC_SHADOW_EVP_PKEY_CTX_free', + '#define EVP_PKEY_CTX_get0_pkey GRPC_SHADOW_EVP_PKEY_CTX_get0_pkey', + '#define EVP_PKEY_CTX_new GRPC_SHADOW_EVP_PKEY_CTX_new', + '#define EVP_PKEY_CTX_new_id GRPC_SHADOW_EVP_PKEY_CTX_new_id', + '#define EVP_PKEY_decrypt GRPC_SHADOW_EVP_PKEY_decrypt', + '#define EVP_PKEY_decrypt_init GRPC_SHADOW_EVP_PKEY_decrypt_init', + '#define EVP_PKEY_derive GRPC_SHADOW_EVP_PKEY_derive', + '#define EVP_PKEY_derive_init GRPC_SHADOW_EVP_PKEY_derive_init', + '#define EVP_PKEY_derive_set_peer GRPC_SHADOW_EVP_PKEY_derive_set_peer', + '#define EVP_PKEY_encrypt GRPC_SHADOW_EVP_PKEY_encrypt', + '#define EVP_PKEY_encrypt_init GRPC_SHADOW_EVP_PKEY_encrypt_init', + '#define EVP_PKEY_keygen GRPC_SHADOW_EVP_PKEY_keygen', + '#define EVP_PKEY_keygen_init GRPC_SHADOW_EVP_PKEY_keygen_init', + '#define EVP_PKEY_sign GRPC_SHADOW_EVP_PKEY_sign', + '#define EVP_PKEY_sign_init GRPC_SHADOW_EVP_PKEY_sign_init', + '#define EVP_PKEY_verify GRPC_SHADOW_EVP_PKEY_verify', + '#define EVP_PKEY_verify_init GRPC_SHADOW_EVP_PKEY_verify_init', + '#define EVP_PKEY_verify_recover GRPC_SHADOW_EVP_PKEY_verify_recover', + '#define EVP_PKEY_verify_recover_init GRPC_SHADOW_EVP_PKEY_verify_recover_init', + '#define dsa_asn1_meth GRPC_SHADOW_dsa_asn1_meth', + '#define ec_pkey_meth GRPC_SHADOW_ec_pkey_meth', + '#define ec_asn1_meth GRPC_SHADOW_ec_asn1_meth', + '#define ed25519_pkey_meth GRPC_SHADOW_ed25519_pkey_meth', + '#define EVP_PKEY_new_ed25519_private GRPC_SHADOW_EVP_PKEY_new_ed25519_private', + '#define EVP_PKEY_new_ed25519_public GRPC_SHADOW_EVP_PKEY_new_ed25519_public', + '#define ed25519_asn1_meth GRPC_SHADOW_ed25519_asn1_meth', + '#define EVP_PKEY_CTX_get0_rsa_oaep_label GRPC_SHADOW_EVP_PKEY_CTX_get0_rsa_oaep_label', + '#define EVP_PKEY_CTX_get_rsa_mgf1_md GRPC_SHADOW_EVP_PKEY_CTX_get_rsa_mgf1_md', + '#define EVP_PKEY_CTX_get_rsa_oaep_md GRPC_SHADOW_EVP_PKEY_CTX_get_rsa_oaep_md', + '#define EVP_PKEY_CTX_get_rsa_padding GRPC_SHADOW_EVP_PKEY_CTX_get_rsa_padding', + '#define EVP_PKEY_CTX_get_rsa_pss_saltlen GRPC_SHADOW_EVP_PKEY_CTX_get_rsa_pss_saltlen', + '#define EVP_PKEY_CTX_set0_rsa_oaep_label GRPC_SHADOW_EVP_PKEY_CTX_set0_rsa_oaep_label', + '#define EVP_PKEY_CTX_set_rsa_keygen_bits GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_keygen_bits', + '#define EVP_PKEY_CTX_set_rsa_keygen_pubexp GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_keygen_pubexp', + '#define EVP_PKEY_CTX_set_rsa_mgf1_md GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_mgf1_md', + '#define EVP_PKEY_CTX_set_rsa_oaep_md GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_oaep_md', + '#define EVP_PKEY_CTX_set_rsa_padding GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_padding', + '#define EVP_PKEY_CTX_set_rsa_pss_saltlen GRPC_SHADOW_EVP_PKEY_CTX_set_rsa_pss_saltlen', + '#define rsa_pkey_meth GRPC_SHADOW_rsa_pkey_meth', + '#define rsa_asn1_meth GRPC_SHADOW_rsa_asn1_meth', + '#define PKCS5_PBKDF2_HMAC GRPC_SHADOW_PKCS5_PBKDF2_HMAC', + '#define PKCS5_PBKDF2_HMAC_SHA1 GRPC_SHADOW_PKCS5_PBKDF2_HMAC_SHA1', + '#define EVP_PKEY_print_params GRPC_SHADOW_EVP_PKEY_print_params', + '#define EVP_PKEY_print_private GRPC_SHADOW_EVP_PKEY_print_private', + '#define EVP_PKEY_print_public GRPC_SHADOW_EVP_PKEY_print_public', + '#define EVP_PBE_scrypt GRPC_SHADOW_EVP_PBE_scrypt', + '#define EVP_SignFinal GRPC_SHADOW_EVP_SignFinal', + '#define EVP_SignInit GRPC_SHADOW_EVP_SignInit', + '#define EVP_SignInit_ex GRPC_SHADOW_EVP_SignInit_ex', + '#define EVP_SignUpdate GRPC_SHADOW_EVP_SignUpdate', + '#define EVP_VerifyFinal GRPC_SHADOW_EVP_VerifyFinal', + '#define EVP_VerifyInit GRPC_SHADOW_EVP_VerifyInit', + '#define EVP_VerifyInit_ex GRPC_SHADOW_EVP_VerifyInit_ex', + '#define EVP_VerifyUpdate GRPC_SHADOW_EVP_VerifyUpdate', + '#define HKDF GRPC_SHADOW_HKDF', + '#define HKDF_expand GRPC_SHADOW_HKDF_expand', + '#define HKDF_extract GRPC_SHADOW_HKDF_extract', + '#define PEM_read_DSAPrivateKey GRPC_SHADOW_PEM_read_DSAPrivateKey', + '#define PEM_read_DSA_PUBKEY GRPC_SHADOW_PEM_read_DSA_PUBKEY', + '#define PEM_read_DSAparams GRPC_SHADOW_PEM_read_DSAparams', + '#define PEM_read_ECPrivateKey GRPC_SHADOW_PEM_read_ECPrivateKey', + '#define PEM_read_EC_PUBKEY GRPC_SHADOW_PEM_read_EC_PUBKEY', + '#define PEM_read_PUBKEY GRPC_SHADOW_PEM_read_PUBKEY', + '#define PEM_read_RSAPrivateKey GRPC_SHADOW_PEM_read_RSAPrivateKey', + '#define PEM_read_RSAPublicKey GRPC_SHADOW_PEM_read_RSAPublicKey', + '#define PEM_read_RSA_PUBKEY GRPC_SHADOW_PEM_read_RSA_PUBKEY', + '#define PEM_read_X509_CRL GRPC_SHADOW_PEM_read_X509_CRL', + '#define PEM_read_X509_REQ GRPC_SHADOW_PEM_read_X509_REQ', + '#define PEM_read_bio_DSAPrivateKey GRPC_SHADOW_PEM_read_bio_DSAPrivateKey', + '#define PEM_read_bio_DSA_PUBKEY GRPC_SHADOW_PEM_read_bio_DSA_PUBKEY', + '#define PEM_read_bio_DSAparams GRPC_SHADOW_PEM_read_bio_DSAparams', + '#define PEM_read_bio_ECPrivateKey GRPC_SHADOW_PEM_read_bio_ECPrivateKey', + '#define PEM_read_bio_EC_PUBKEY GRPC_SHADOW_PEM_read_bio_EC_PUBKEY', + '#define PEM_read_bio_PUBKEY GRPC_SHADOW_PEM_read_bio_PUBKEY', + '#define PEM_read_bio_RSAPrivateKey GRPC_SHADOW_PEM_read_bio_RSAPrivateKey', + '#define PEM_read_bio_RSAPublicKey GRPC_SHADOW_PEM_read_bio_RSAPublicKey', + '#define PEM_read_bio_RSA_PUBKEY GRPC_SHADOW_PEM_read_bio_RSA_PUBKEY', + '#define PEM_read_bio_X509_CRL GRPC_SHADOW_PEM_read_bio_X509_CRL', + '#define PEM_read_bio_X509_REQ GRPC_SHADOW_PEM_read_bio_X509_REQ', + '#define PEM_write_DHparams GRPC_SHADOW_PEM_write_DHparams', + '#define PEM_write_DSAPrivateKey GRPC_SHADOW_PEM_write_DSAPrivateKey', + '#define PEM_write_DSA_PUBKEY GRPC_SHADOW_PEM_write_DSA_PUBKEY', + '#define PEM_write_DSAparams GRPC_SHADOW_PEM_write_DSAparams', + '#define PEM_write_ECPrivateKey GRPC_SHADOW_PEM_write_ECPrivateKey', + '#define PEM_write_EC_PUBKEY GRPC_SHADOW_PEM_write_EC_PUBKEY', + '#define PEM_write_PUBKEY GRPC_SHADOW_PEM_write_PUBKEY', + '#define PEM_write_RSAPrivateKey GRPC_SHADOW_PEM_write_RSAPrivateKey', + '#define PEM_write_RSAPublicKey GRPC_SHADOW_PEM_write_RSAPublicKey', + '#define PEM_write_RSA_PUBKEY GRPC_SHADOW_PEM_write_RSA_PUBKEY', + '#define PEM_write_X509_CRL GRPC_SHADOW_PEM_write_X509_CRL', + '#define PEM_write_X509_REQ GRPC_SHADOW_PEM_write_X509_REQ', + '#define PEM_write_X509_REQ_NEW GRPC_SHADOW_PEM_write_X509_REQ_NEW', + '#define PEM_write_bio_DHparams GRPC_SHADOW_PEM_write_bio_DHparams', + '#define PEM_write_bio_DSAPrivateKey GRPC_SHADOW_PEM_write_bio_DSAPrivateKey', + '#define PEM_write_bio_DSA_PUBKEY GRPC_SHADOW_PEM_write_bio_DSA_PUBKEY', + '#define PEM_write_bio_DSAparams GRPC_SHADOW_PEM_write_bio_DSAparams', + '#define PEM_write_bio_ECPrivateKey GRPC_SHADOW_PEM_write_bio_ECPrivateKey', + '#define PEM_write_bio_EC_PUBKEY GRPC_SHADOW_PEM_write_bio_EC_PUBKEY', + '#define PEM_write_bio_PUBKEY GRPC_SHADOW_PEM_write_bio_PUBKEY', + '#define PEM_write_bio_RSAPrivateKey GRPC_SHADOW_PEM_write_bio_RSAPrivateKey', + '#define PEM_write_bio_RSAPublicKey GRPC_SHADOW_PEM_write_bio_RSAPublicKey', + '#define PEM_write_bio_RSA_PUBKEY GRPC_SHADOW_PEM_write_bio_RSA_PUBKEY', + '#define PEM_write_bio_X509_CRL GRPC_SHADOW_PEM_write_bio_X509_CRL', + '#define PEM_write_bio_X509_REQ GRPC_SHADOW_PEM_write_bio_X509_REQ', + '#define PEM_write_bio_X509_REQ_NEW GRPC_SHADOW_PEM_write_bio_X509_REQ_NEW', + '#define PEM_X509_INFO_read GRPC_SHADOW_PEM_X509_INFO_read', + '#define PEM_X509_INFO_read_bio GRPC_SHADOW_PEM_X509_INFO_read_bio', + '#define PEM_X509_INFO_write_bio GRPC_SHADOW_PEM_X509_INFO_write_bio', + '#define PEM_ASN1_read GRPC_SHADOW_PEM_ASN1_read', + '#define PEM_ASN1_write GRPC_SHADOW_PEM_ASN1_write', + '#define PEM_ASN1_write_bio GRPC_SHADOW_PEM_ASN1_write_bio', + '#define PEM_bytes_read_bio GRPC_SHADOW_PEM_bytes_read_bio', + '#define PEM_def_callback GRPC_SHADOW_PEM_def_callback', + '#define PEM_dek_info GRPC_SHADOW_PEM_dek_info', + '#define PEM_do_header GRPC_SHADOW_PEM_do_header', + '#define PEM_get_EVP_CIPHER_INFO GRPC_SHADOW_PEM_get_EVP_CIPHER_INFO', + '#define PEM_proc_type GRPC_SHADOW_PEM_proc_type', + '#define PEM_read GRPC_SHADOW_PEM_read', + '#define PEM_read_bio GRPC_SHADOW_PEM_read_bio', + '#define PEM_write GRPC_SHADOW_PEM_write', + '#define PEM_write_bio GRPC_SHADOW_PEM_write_bio', + '#define PEM_ASN1_read_bio GRPC_SHADOW_PEM_ASN1_read_bio', + '#define PEM_read_PKCS8 GRPC_SHADOW_PEM_read_PKCS8', + '#define PEM_read_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_PEM_read_PKCS8_PRIV_KEY_INFO', + '#define PEM_read_bio_PKCS8 GRPC_SHADOW_PEM_read_bio_PKCS8', + '#define PEM_read_bio_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_PEM_read_bio_PKCS8_PRIV_KEY_INFO', + '#define PEM_write_PKCS8 GRPC_SHADOW_PEM_write_PKCS8', + '#define PEM_write_PKCS8PrivateKey GRPC_SHADOW_PEM_write_PKCS8PrivateKey', + '#define PEM_write_PKCS8PrivateKey_nid GRPC_SHADOW_PEM_write_PKCS8PrivateKey_nid', + '#define PEM_write_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_PEM_write_PKCS8_PRIV_KEY_INFO', + '#define PEM_write_bio_PKCS8 GRPC_SHADOW_PEM_write_bio_PKCS8', + '#define PEM_write_bio_PKCS8PrivateKey GRPC_SHADOW_PEM_write_bio_PKCS8PrivateKey', + '#define PEM_write_bio_PKCS8PrivateKey_nid GRPC_SHADOW_PEM_write_bio_PKCS8PrivateKey_nid', + '#define PEM_write_bio_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_PEM_write_bio_PKCS8_PRIV_KEY_INFO', + '#define d2i_PKCS8PrivateKey_bio GRPC_SHADOW_d2i_PKCS8PrivateKey_bio', + '#define d2i_PKCS8PrivateKey_fp GRPC_SHADOW_d2i_PKCS8PrivateKey_fp', + '#define i2d_PKCS8PrivateKey_bio GRPC_SHADOW_i2d_PKCS8PrivateKey_bio', + '#define i2d_PKCS8PrivateKey_fp GRPC_SHADOW_i2d_PKCS8PrivateKey_fp', + '#define i2d_PKCS8PrivateKey_nid_bio GRPC_SHADOW_i2d_PKCS8PrivateKey_nid_bio', + '#define i2d_PKCS8PrivateKey_nid_fp GRPC_SHADOW_i2d_PKCS8PrivateKey_nid_fp', + '#define PEM_read_DHparams GRPC_SHADOW_PEM_read_DHparams', + '#define PEM_read_PrivateKey GRPC_SHADOW_PEM_read_PrivateKey', + '#define PEM_read_bio_DHparams GRPC_SHADOW_PEM_read_bio_DHparams', + '#define PEM_read_bio_PrivateKey GRPC_SHADOW_PEM_read_bio_PrivateKey', + '#define PEM_write_PrivateKey GRPC_SHADOW_PEM_write_PrivateKey', + '#define PEM_write_bio_PrivateKey GRPC_SHADOW_PEM_write_bio_PrivateKey', + '#define PEM_read_X509 GRPC_SHADOW_PEM_read_X509', + '#define PEM_read_bio_X509 GRPC_SHADOW_PEM_read_bio_X509', + '#define PEM_write_X509 GRPC_SHADOW_PEM_write_X509', + '#define PEM_write_bio_X509 GRPC_SHADOW_PEM_write_bio_X509', + '#define PEM_read_X509_AUX GRPC_SHADOW_PEM_read_X509_AUX', + '#define PEM_read_bio_X509_AUX GRPC_SHADOW_PEM_read_bio_X509_AUX', + '#define PEM_write_X509_AUX GRPC_SHADOW_PEM_write_X509_AUX', + '#define PEM_write_bio_X509_AUX GRPC_SHADOW_PEM_write_bio_X509_AUX', + '#define ASN1_digest GRPC_SHADOW_ASN1_digest', + '#define ASN1_item_digest GRPC_SHADOW_ASN1_item_digest', + '#define ASN1_item_sign GRPC_SHADOW_ASN1_item_sign', + '#define ASN1_item_sign_ctx GRPC_SHADOW_ASN1_item_sign_ctx', + '#define ASN1_STRING_print_ex GRPC_SHADOW_ASN1_STRING_print_ex', + '#define ASN1_STRING_print_ex_fp GRPC_SHADOW_ASN1_STRING_print_ex_fp', + '#define ASN1_STRING_to_UTF8 GRPC_SHADOW_ASN1_STRING_to_UTF8', + '#define X509_NAME_print_ex GRPC_SHADOW_X509_NAME_print_ex', + '#define X509_NAME_print_ex_fp GRPC_SHADOW_X509_NAME_print_ex_fp', + '#define ASN1_item_verify GRPC_SHADOW_ASN1_item_verify', + '#define x509_digest_sign_algorithm GRPC_SHADOW_x509_digest_sign_algorithm', + '#define x509_digest_verify_init GRPC_SHADOW_x509_digest_verify_init', + '#define ASN1_generate_nconf GRPC_SHADOW_ASN1_generate_nconf', + '#define ASN1_generate_v3 GRPC_SHADOW_ASN1_generate_v3', + '#define X509_LOOKUP_hash_dir GRPC_SHADOW_X509_LOOKUP_hash_dir', + '#define X509_LOOKUP_file GRPC_SHADOW_X509_LOOKUP_file', + '#define X509_load_cert_crl_file GRPC_SHADOW_X509_load_cert_crl_file', + '#define X509_load_cert_file GRPC_SHADOW_X509_load_cert_file', + '#define X509_load_crl_file GRPC_SHADOW_X509_load_crl_file', + '#define i2d_PrivateKey GRPC_SHADOW_i2d_PrivateKey', + '#define RSA_PSS_PARAMS_free GRPC_SHADOW_RSA_PSS_PARAMS_free', + '#define RSA_PSS_PARAMS_it GRPC_SHADOW_RSA_PSS_PARAMS_it', + '#define RSA_PSS_PARAMS_new GRPC_SHADOW_RSA_PSS_PARAMS_new', + '#define d2i_RSA_PSS_PARAMS GRPC_SHADOW_d2i_RSA_PSS_PARAMS', + '#define i2d_RSA_PSS_PARAMS GRPC_SHADOW_i2d_RSA_PSS_PARAMS', + '#define x509_print_rsa_pss_params GRPC_SHADOW_x509_print_rsa_pss_params', + '#define x509_rsa_ctx_to_pss GRPC_SHADOW_x509_rsa_ctx_to_pss', + '#define x509_rsa_pss_to_ctx GRPC_SHADOW_x509_rsa_pss_to_ctx', + '#define X509_CRL_print GRPC_SHADOW_X509_CRL_print', + '#define X509_CRL_print_fp GRPC_SHADOW_X509_CRL_print_fp', + '#define X509_REQ_print GRPC_SHADOW_X509_REQ_print', + '#define X509_REQ_print_ex GRPC_SHADOW_X509_REQ_print_ex', + '#define X509_REQ_print_fp GRPC_SHADOW_X509_REQ_print_fp', + '#define ASN1_GENERALIZEDTIME_print GRPC_SHADOW_ASN1_GENERALIZEDTIME_print', + '#define ASN1_STRING_print GRPC_SHADOW_ASN1_STRING_print', + '#define ASN1_TIME_print GRPC_SHADOW_ASN1_TIME_print', + '#define ASN1_UTCTIME_print GRPC_SHADOW_ASN1_UTCTIME_print', + '#define X509_NAME_print GRPC_SHADOW_X509_NAME_print', + '#define X509_ocspid_print GRPC_SHADOW_X509_ocspid_print', + '#define X509_print GRPC_SHADOW_X509_print', + '#define X509_print_ex GRPC_SHADOW_X509_print_ex', + '#define X509_print_ex_fp GRPC_SHADOW_X509_print_ex_fp', + '#define X509_print_fp GRPC_SHADOW_X509_print_fp', + '#define X509_signature_print GRPC_SHADOW_X509_signature_print', + '#define X509_CERT_AUX_print GRPC_SHADOW_X509_CERT_AUX_print', + '#define PKCS8_pkey_get0 GRPC_SHADOW_PKCS8_pkey_get0', + '#define PKCS8_pkey_set0 GRPC_SHADOW_PKCS8_pkey_set0', + '#define X509_signature_dump GRPC_SHADOW_X509_signature_dump', + '#define X509_ATTRIBUTE_count GRPC_SHADOW_X509_ATTRIBUTE_count', + '#define X509_ATTRIBUTE_create_by_NID GRPC_SHADOW_X509_ATTRIBUTE_create_by_NID', + '#define X509_ATTRIBUTE_create_by_OBJ GRPC_SHADOW_X509_ATTRIBUTE_create_by_OBJ', + '#define X509_ATTRIBUTE_create_by_txt GRPC_SHADOW_X509_ATTRIBUTE_create_by_txt', + '#define X509_ATTRIBUTE_get0_data GRPC_SHADOW_X509_ATTRIBUTE_get0_data', + '#define X509_ATTRIBUTE_get0_object GRPC_SHADOW_X509_ATTRIBUTE_get0_object', + '#define X509_ATTRIBUTE_get0_type GRPC_SHADOW_X509_ATTRIBUTE_get0_type', + '#define X509_ATTRIBUTE_set1_data GRPC_SHADOW_X509_ATTRIBUTE_set1_data', + '#define X509_ATTRIBUTE_set1_object GRPC_SHADOW_X509_ATTRIBUTE_set1_object', + '#define X509at_add1_attr GRPC_SHADOW_X509at_add1_attr', + '#define X509at_add1_attr_by_NID GRPC_SHADOW_X509at_add1_attr_by_NID', + '#define X509at_add1_attr_by_OBJ GRPC_SHADOW_X509at_add1_attr_by_OBJ', + '#define X509at_add1_attr_by_txt GRPC_SHADOW_X509at_add1_attr_by_txt', + '#define X509at_delete_attr GRPC_SHADOW_X509at_delete_attr', + '#define X509at_get0_data_by_OBJ GRPC_SHADOW_X509at_get0_data_by_OBJ', + '#define X509at_get_attr GRPC_SHADOW_X509at_get_attr', + '#define X509at_get_attr_by_NID GRPC_SHADOW_X509at_get_attr_by_NID', + '#define X509at_get_attr_by_OBJ GRPC_SHADOW_X509at_get_attr_by_OBJ', + '#define X509at_get_attr_count GRPC_SHADOW_X509at_get_attr_count', + '#define X509_CRL_check_suiteb GRPC_SHADOW_X509_CRL_check_suiteb', + '#define X509_CRL_cmp GRPC_SHADOW_X509_CRL_cmp', + '#define X509_CRL_match GRPC_SHADOW_X509_CRL_match', + '#define X509_NAME_cmp GRPC_SHADOW_X509_NAME_cmp', + '#define X509_NAME_hash GRPC_SHADOW_X509_NAME_hash', + '#define X509_NAME_hash_old GRPC_SHADOW_X509_NAME_hash_old', + '#define X509_chain_check_suiteb GRPC_SHADOW_X509_chain_check_suiteb', + '#define X509_chain_up_ref GRPC_SHADOW_X509_chain_up_ref', + '#define X509_check_private_key GRPC_SHADOW_X509_check_private_key', + '#define X509_cmp GRPC_SHADOW_X509_cmp', + '#define X509_find_by_issuer_and_serial GRPC_SHADOW_X509_find_by_issuer_and_serial', + '#define X509_find_by_subject GRPC_SHADOW_X509_find_by_subject', + '#define X509_get0_pubkey_bitstr GRPC_SHADOW_X509_get0_pubkey_bitstr', + '#define X509_get_issuer_name GRPC_SHADOW_X509_get_issuer_name', + '#define X509_get_pubkey GRPC_SHADOW_X509_get_pubkey', + '#define X509_get_serialNumber GRPC_SHADOW_X509_get_serialNumber', + '#define X509_get_subject_name GRPC_SHADOW_X509_get_subject_name', + '#define X509_issuer_and_serial_cmp GRPC_SHADOW_X509_issuer_and_serial_cmp', + '#define X509_issuer_and_serial_hash GRPC_SHADOW_X509_issuer_and_serial_hash', + '#define X509_issuer_name_cmp GRPC_SHADOW_X509_issuer_name_cmp', + '#define X509_issuer_name_hash GRPC_SHADOW_X509_issuer_name_hash', + '#define X509_issuer_name_hash_old GRPC_SHADOW_X509_issuer_name_hash_old', + '#define X509_subject_name_cmp GRPC_SHADOW_X509_subject_name_cmp', + '#define X509_subject_name_hash GRPC_SHADOW_X509_subject_name_hash', + '#define X509_subject_name_hash_old GRPC_SHADOW_X509_subject_name_hash_old', + '#define X509_STORE_load_locations GRPC_SHADOW_X509_STORE_load_locations', + '#define X509_STORE_set_default_paths GRPC_SHADOW_X509_STORE_set_default_paths', + '#define X509_get_default_cert_area GRPC_SHADOW_X509_get_default_cert_area', + '#define X509_get_default_cert_dir GRPC_SHADOW_X509_get_default_cert_dir', + '#define X509_get_default_cert_dir_env GRPC_SHADOW_X509_get_default_cert_dir_env', + '#define X509_get_default_cert_file GRPC_SHADOW_X509_get_default_cert_file', + '#define X509_get_default_cert_file_env GRPC_SHADOW_X509_get_default_cert_file_env', + '#define X509_get_default_private_dir GRPC_SHADOW_X509_get_default_private_dir', + '#define X509_CRL_add1_ext_i2d GRPC_SHADOW_X509_CRL_add1_ext_i2d', + '#define X509_CRL_add_ext GRPC_SHADOW_X509_CRL_add_ext', + '#define X509_CRL_delete_ext GRPC_SHADOW_X509_CRL_delete_ext', + '#define X509_CRL_get_ext GRPC_SHADOW_X509_CRL_get_ext', + '#define X509_CRL_get_ext_by_NID GRPC_SHADOW_X509_CRL_get_ext_by_NID', + '#define X509_CRL_get_ext_by_OBJ GRPC_SHADOW_X509_CRL_get_ext_by_OBJ', + '#define X509_CRL_get_ext_by_critical GRPC_SHADOW_X509_CRL_get_ext_by_critical', + '#define X509_CRL_get_ext_count GRPC_SHADOW_X509_CRL_get_ext_count', + '#define X509_CRL_get_ext_d2i GRPC_SHADOW_X509_CRL_get_ext_d2i', + '#define X509_REVOKED_add1_ext_i2d GRPC_SHADOW_X509_REVOKED_add1_ext_i2d', + '#define X509_REVOKED_add_ext GRPC_SHADOW_X509_REVOKED_add_ext', + '#define X509_REVOKED_delete_ext GRPC_SHADOW_X509_REVOKED_delete_ext', + '#define X509_REVOKED_get_ext GRPC_SHADOW_X509_REVOKED_get_ext', + '#define X509_REVOKED_get_ext_by_NID GRPC_SHADOW_X509_REVOKED_get_ext_by_NID', + '#define X509_REVOKED_get_ext_by_OBJ GRPC_SHADOW_X509_REVOKED_get_ext_by_OBJ', + '#define X509_REVOKED_get_ext_by_critical GRPC_SHADOW_X509_REVOKED_get_ext_by_critical', + '#define X509_REVOKED_get_ext_count GRPC_SHADOW_X509_REVOKED_get_ext_count', + '#define X509_REVOKED_get_ext_d2i GRPC_SHADOW_X509_REVOKED_get_ext_d2i', + '#define X509_add1_ext_i2d GRPC_SHADOW_X509_add1_ext_i2d', + '#define X509_add_ext GRPC_SHADOW_X509_add_ext', + '#define X509_delete_ext GRPC_SHADOW_X509_delete_ext', + '#define X509_get_ext GRPC_SHADOW_X509_get_ext', + '#define X509_get_ext_by_NID GRPC_SHADOW_X509_get_ext_by_NID', + '#define X509_get_ext_by_OBJ GRPC_SHADOW_X509_get_ext_by_OBJ', + '#define X509_get_ext_by_critical GRPC_SHADOW_X509_get_ext_by_critical', + '#define X509_get_ext_count GRPC_SHADOW_X509_get_ext_count', + '#define X509_get_ext_d2i GRPC_SHADOW_X509_get_ext_d2i', + '#define X509_LOOKUP_by_alias GRPC_SHADOW_X509_LOOKUP_by_alias', + '#define X509_LOOKUP_by_fingerprint GRPC_SHADOW_X509_LOOKUP_by_fingerprint', + '#define X509_LOOKUP_by_issuer_serial GRPC_SHADOW_X509_LOOKUP_by_issuer_serial', + '#define X509_LOOKUP_by_subject GRPC_SHADOW_X509_LOOKUP_by_subject', + '#define X509_LOOKUP_ctrl GRPC_SHADOW_X509_LOOKUP_ctrl', + '#define X509_LOOKUP_free GRPC_SHADOW_X509_LOOKUP_free', + '#define X509_LOOKUP_init GRPC_SHADOW_X509_LOOKUP_init', + '#define X509_LOOKUP_new GRPC_SHADOW_X509_LOOKUP_new', + '#define X509_LOOKUP_shutdown GRPC_SHADOW_X509_LOOKUP_shutdown', + '#define X509_OBJECT_free_contents GRPC_SHADOW_X509_OBJECT_free_contents', + '#define X509_OBJECT_get0_X509 GRPC_SHADOW_X509_OBJECT_get0_X509', + '#define X509_OBJECT_get_type GRPC_SHADOW_X509_OBJECT_get_type', + '#define X509_OBJECT_idx_by_subject GRPC_SHADOW_X509_OBJECT_idx_by_subject', + '#define X509_OBJECT_retrieve_by_subject GRPC_SHADOW_X509_OBJECT_retrieve_by_subject', + '#define X509_OBJECT_retrieve_match GRPC_SHADOW_X509_OBJECT_retrieve_match', + '#define X509_OBJECT_up_ref_count GRPC_SHADOW_X509_OBJECT_up_ref_count', + '#define X509_STORE_CTX_get0_store GRPC_SHADOW_X509_STORE_CTX_get0_store', + '#define X509_STORE_CTX_get1_issuer GRPC_SHADOW_X509_STORE_CTX_get1_issuer', + '#define X509_STORE_add_cert GRPC_SHADOW_X509_STORE_add_cert', + '#define X509_STORE_add_crl GRPC_SHADOW_X509_STORE_add_crl', + '#define X509_STORE_add_lookup GRPC_SHADOW_X509_STORE_add_lookup', + '#define X509_STORE_free GRPC_SHADOW_X509_STORE_free', + '#define X509_STORE_get0_objects GRPC_SHADOW_X509_STORE_get0_objects', + '#define X509_STORE_get0_param GRPC_SHADOW_X509_STORE_get0_param', + '#define X509_STORE_get1_certs GRPC_SHADOW_X509_STORE_get1_certs', + '#define X509_STORE_get1_crls GRPC_SHADOW_X509_STORE_get1_crls', + '#define X509_STORE_get_by_subject GRPC_SHADOW_X509_STORE_get_by_subject', + '#define X509_STORE_new GRPC_SHADOW_X509_STORE_new', + '#define X509_STORE_set0_additional_untrusted GRPC_SHADOW_X509_STORE_set0_additional_untrusted', + '#define X509_STORE_set1_param GRPC_SHADOW_X509_STORE_set1_param', + '#define X509_STORE_set_depth GRPC_SHADOW_X509_STORE_set_depth', + '#define X509_STORE_set_flags GRPC_SHADOW_X509_STORE_set_flags', + '#define X509_STORE_set_lookup_crls_cb GRPC_SHADOW_X509_STORE_set_lookup_crls_cb', + '#define X509_STORE_set_purpose GRPC_SHADOW_X509_STORE_set_purpose', + '#define X509_STORE_set_trust GRPC_SHADOW_X509_STORE_set_trust', + '#define X509_STORE_set_verify_cb GRPC_SHADOW_X509_STORE_set_verify_cb', + '#define X509_STORE_up_ref GRPC_SHADOW_X509_STORE_up_ref', + '#define X509_NAME_oneline GRPC_SHADOW_X509_NAME_oneline', + '#define X509_REQ_to_X509 GRPC_SHADOW_X509_REQ_to_X509', + '#define X509_REQ_add1_attr GRPC_SHADOW_X509_REQ_add1_attr', + '#define X509_REQ_add1_attr_by_NID GRPC_SHADOW_X509_REQ_add1_attr_by_NID', + '#define X509_REQ_add1_attr_by_OBJ GRPC_SHADOW_X509_REQ_add1_attr_by_OBJ', + '#define X509_REQ_add1_attr_by_txt GRPC_SHADOW_X509_REQ_add1_attr_by_txt', + '#define X509_REQ_add_extensions GRPC_SHADOW_X509_REQ_add_extensions', + '#define X509_REQ_add_extensions_nid GRPC_SHADOW_X509_REQ_add_extensions_nid', + '#define X509_REQ_check_private_key GRPC_SHADOW_X509_REQ_check_private_key', + '#define X509_REQ_delete_attr GRPC_SHADOW_X509_REQ_delete_attr', + '#define X509_REQ_extension_nid GRPC_SHADOW_X509_REQ_extension_nid', + '#define X509_REQ_get_attr GRPC_SHADOW_X509_REQ_get_attr', + '#define X509_REQ_get_attr_by_NID GRPC_SHADOW_X509_REQ_get_attr_by_NID', + '#define X509_REQ_get_attr_by_OBJ GRPC_SHADOW_X509_REQ_get_attr_by_OBJ', + '#define X509_REQ_get_attr_count GRPC_SHADOW_X509_REQ_get_attr_count', + '#define X509_REQ_get_extension_nids GRPC_SHADOW_X509_REQ_get_extension_nids', + '#define X509_REQ_get_extensions GRPC_SHADOW_X509_REQ_get_extensions', + '#define X509_REQ_get_pubkey GRPC_SHADOW_X509_REQ_get_pubkey', + '#define X509_REQ_set_extension_nids GRPC_SHADOW_X509_REQ_set_extension_nids', + '#define X509_to_X509_REQ GRPC_SHADOW_X509_to_X509_REQ', + '#define X509_get0_extensions GRPC_SHADOW_X509_get0_extensions', + '#define X509_get0_notAfter GRPC_SHADOW_X509_get0_notAfter', + '#define X509_get0_notBefore GRPC_SHADOW_X509_get0_notBefore', + '#define X509_set_issuer_name GRPC_SHADOW_X509_set_issuer_name', + '#define X509_set_notAfter GRPC_SHADOW_X509_set_notAfter', + '#define X509_set_notBefore GRPC_SHADOW_X509_set_notBefore', + '#define X509_set_pubkey GRPC_SHADOW_X509_set_pubkey', + '#define X509_set_serialNumber GRPC_SHADOW_X509_set_serialNumber', + '#define X509_set_subject_name GRPC_SHADOW_X509_set_subject_name', + '#define X509_set_version GRPC_SHADOW_X509_set_version', + '#define X509_TRUST_add GRPC_SHADOW_X509_TRUST_add', + '#define X509_TRUST_cleanup GRPC_SHADOW_X509_TRUST_cleanup', + '#define X509_TRUST_get0 GRPC_SHADOW_X509_TRUST_get0', + '#define X509_TRUST_get0_name GRPC_SHADOW_X509_TRUST_get0_name', + '#define X509_TRUST_get_by_id GRPC_SHADOW_X509_TRUST_get_by_id', + '#define X509_TRUST_get_count GRPC_SHADOW_X509_TRUST_get_count', + '#define X509_TRUST_get_flags GRPC_SHADOW_X509_TRUST_get_flags', + '#define X509_TRUST_get_trust GRPC_SHADOW_X509_TRUST_get_trust', + '#define X509_TRUST_set GRPC_SHADOW_X509_TRUST_set', + '#define X509_TRUST_set_default GRPC_SHADOW_X509_TRUST_set_default', + '#define X509_check_trust GRPC_SHADOW_X509_check_trust', + '#define X509_verify_cert_error_string GRPC_SHADOW_X509_verify_cert_error_string', + '#define X509_EXTENSION_create_by_NID GRPC_SHADOW_X509_EXTENSION_create_by_NID', + '#define X509_EXTENSION_create_by_OBJ GRPC_SHADOW_X509_EXTENSION_create_by_OBJ', + '#define X509_EXTENSION_get_critical GRPC_SHADOW_X509_EXTENSION_get_critical', + '#define X509_EXTENSION_get_data GRPC_SHADOW_X509_EXTENSION_get_data', + '#define X509_EXTENSION_get_object GRPC_SHADOW_X509_EXTENSION_get_object', + '#define X509_EXTENSION_set_critical GRPC_SHADOW_X509_EXTENSION_set_critical', + '#define X509_EXTENSION_set_data GRPC_SHADOW_X509_EXTENSION_set_data', + '#define X509_EXTENSION_set_object GRPC_SHADOW_X509_EXTENSION_set_object', + '#define X509v3_add_ext GRPC_SHADOW_X509v3_add_ext', + '#define X509v3_delete_ext GRPC_SHADOW_X509v3_delete_ext', + '#define X509v3_get_ext GRPC_SHADOW_X509v3_get_ext', + '#define X509v3_get_ext_by_NID GRPC_SHADOW_X509v3_get_ext_by_NID', + '#define X509v3_get_ext_by_OBJ GRPC_SHADOW_X509v3_get_ext_by_OBJ', + '#define X509v3_get_ext_by_critical GRPC_SHADOW_X509v3_get_ext_by_critical', + '#define X509v3_get_ext_count GRPC_SHADOW_X509v3_get_ext_count', + '#define X509_CRL_diff GRPC_SHADOW_X509_CRL_diff', + '#define X509_STORE_CTX_cleanup GRPC_SHADOW_X509_STORE_CTX_cleanup', + '#define X509_STORE_CTX_free GRPC_SHADOW_X509_STORE_CTX_free', + '#define X509_STORE_CTX_get0_current_crl GRPC_SHADOW_X509_STORE_CTX_get0_current_crl', + '#define X509_STORE_CTX_get0_current_issuer GRPC_SHADOW_X509_STORE_CTX_get0_current_issuer', + '#define X509_STORE_CTX_get0_param GRPC_SHADOW_X509_STORE_CTX_get0_param', + '#define X509_STORE_CTX_get0_parent_ctx GRPC_SHADOW_X509_STORE_CTX_get0_parent_ctx', + '#define X509_STORE_CTX_get0_policy_tree GRPC_SHADOW_X509_STORE_CTX_get0_policy_tree', + '#define X509_STORE_CTX_get0_untrusted GRPC_SHADOW_X509_STORE_CTX_get0_untrusted', + '#define X509_STORE_CTX_get1_chain GRPC_SHADOW_X509_STORE_CTX_get1_chain', + '#define X509_STORE_CTX_get_chain GRPC_SHADOW_X509_STORE_CTX_get_chain', + '#define X509_STORE_CTX_get_current_cert GRPC_SHADOW_X509_STORE_CTX_get_current_cert', + '#define X509_STORE_CTX_get_error GRPC_SHADOW_X509_STORE_CTX_get_error', + '#define X509_STORE_CTX_get_error_depth GRPC_SHADOW_X509_STORE_CTX_get_error_depth', + '#define X509_STORE_CTX_get_ex_data GRPC_SHADOW_X509_STORE_CTX_get_ex_data', + '#define X509_STORE_CTX_get_ex_new_index GRPC_SHADOW_X509_STORE_CTX_get_ex_new_index', + '#define X509_STORE_CTX_get_explicit_policy GRPC_SHADOW_X509_STORE_CTX_get_explicit_policy', + '#define X509_STORE_CTX_init GRPC_SHADOW_X509_STORE_CTX_init', + '#define X509_STORE_CTX_new GRPC_SHADOW_X509_STORE_CTX_new', + '#define X509_STORE_CTX_purpose_inherit GRPC_SHADOW_X509_STORE_CTX_purpose_inherit', + '#define X509_STORE_CTX_set0_crls GRPC_SHADOW_X509_STORE_CTX_set0_crls', + '#define X509_STORE_CTX_set0_param GRPC_SHADOW_X509_STORE_CTX_set0_param', + '#define X509_STORE_CTX_set_cert GRPC_SHADOW_X509_STORE_CTX_set_cert', + '#define X509_STORE_CTX_set_chain GRPC_SHADOW_X509_STORE_CTX_set_chain', + '#define X509_STORE_CTX_set_default GRPC_SHADOW_X509_STORE_CTX_set_default', + '#define X509_STORE_CTX_set_depth GRPC_SHADOW_X509_STORE_CTX_set_depth', + '#define X509_STORE_CTX_set_error GRPC_SHADOW_X509_STORE_CTX_set_error', + '#define X509_STORE_CTX_set_ex_data GRPC_SHADOW_X509_STORE_CTX_set_ex_data', + '#define X509_STORE_CTX_set_flags GRPC_SHADOW_X509_STORE_CTX_set_flags', + '#define X509_STORE_CTX_set_purpose GRPC_SHADOW_X509_STORE_CTX_set_purpose', + '#define X509_STORE_CTX_set_time GRPC_SHADOW_X509_STORE_CTX_set_time', + '#define X509_STORE_CTX_set_trust GRPC_SHADOW_X509_STORE_CTX_set_trust', + '#define X509_STORE_CTX_set_verify_cb GRPC_SHADOW_X509_STORE_CTX_set_verify_cb', + '#define X509_STORE_CTX_trusted_stack GRPC_SHADOW_X509_STORE_CTX_trusted_stack', + '#define X509_STORE_CTX_zero GRPC_SHADOW_X509_STORE_CTX_zero', + '#define X509_cmp_current_time GRPC_SHADOW_X509_cmp_current_time', + '#define X509_cmp_time GRPC_SHADOW_X509_cmp_time', + '#define X509_gmtime_adj GRPC_SHADOW_X509_gmtime_adj', + '#define X509_time_adj GRPC_SHADOW_X509_time_adj', + '#define X509_time_adj_ex GRPC_SHADOW_X509_time_adj_ex', + '#define X509_verify_cert GRPC_SHADOW_X509_verify_cert', + '#define X509_VERIFY_PARAM_add0_policy GRPC_SHADOW_X509_VERIFY_PARAM_add0_policy', + '#define X509_VERIFY_PARAM_add0_table GRPC_SHADOW_X509_VERIFY_PARAM_add0_table', + '#define X509_VERIFY_PARAM_add1_host GRPC_SHADOW_X509_VERIFY_PARAM_add1_host', + '#define X509_VERIFY_PARAM_clear_flags GRPC_SHADOW_X509_VERIFY_PARAM_clear_flags', + '#define X509_VERIFY_PARAM_free GRPC_SHADOW_X509_VERIFY_PARAM_free', + '#define X509_VERIFY_PARAM_get0 GRPC_SHADOW_X509_VERIFY_PARAM_get0', + '#define X509_VERIFY_PARAM_get0_name GRPC_SHADOW_X509_VERIFY_PARAM_get0_name', + '#define X509_VERIFY_PARAM_get0_peername GRPC_SHADOW_X509_VERIFY_PARAM_get0_peername', + '#define X509_VERIFY_PARAM_get_count GRPC_SHADOW_X509_VERIFY_PARAM_get_count', + '#define X509_VERIFY_PARAM_get_depth GRPC_SHADOW_X509_VERIFY_PARAM_get_depth', + '#define X509_VERIFY_PARAM_get_flags GRPC_SHADOW_X509_VERIFY_PARAM_get_flags', + '#define X509_VERIFY_PARAM_inherit GRPC_SHADOW_X509_VERIFY_PARAM_inherit', + '#define X509_VERIFY_PARAM_lookup GRPC_SHADOW_X509_VERIFY_PARAM_lookup', + '#define X509_VERIFY_PARAM_new GRPC_SHADOW_X509_VERIFY_PARAM_new', + '#define X509_VERIFY_PARAM_set1 GRPC_SHADOW_X509_VERIFY_PARAM_set1', + '#define X509_VERIFY_PARAM_set1_email GRPC_SHADOW_X509_VERIFY_PARAM_set1_email', + '#define X509_VERIFY_PARAM_set1_host GRPC_SHADOW_X509_VERIFY_PARAM_set1_host', + '#define X509_VERIFY_PARAM_set1_ip GRPC_SHADOW_X509_VERIFY_PARAM_set1_ip', + '#define X509_VERIFY_PARAM_set1_ip_asc GRPC_SHADOW_X509_VERIFY_PARAM_set1_ip_asc', + '#define X509_VERIFY_PARAM_set1_name GRPC_SHADOW_X509_VERIFY_PARAM_set1_name', + '#define X509_VERIFY_PARAM_set1_policies GRPC_SHADOW_X509_VERIFY_PARAM_set1_policies', + '#define X509_VERIFY_PARAM_set_depth GRPC_SHADOW_X509_VERIFY_PARAM_set_depth', + '#define X509_VERIFY_PARAM_set_flags GRPC_SHADOW_X509_VERIFY_PARAM_set_flags', + '#define X509_VERIFY_PARAM_set_hostflags GRPC_SHADOW_X509_VERIFY_PARAM_set_hostflags', + '#define X509_VERIFY_PARAM_set_purpose GRPC_SHADOW_X509_VERIFY_PARAM_set_purpose', + '#define X509_VERIFY_PARAM_set_time GRPC_SHADOW_X509_VERIFY_PARAM_set_time', + '#define X509_VERIFY_PARAM_set_trust GRPC_SHADOW_X509_VERIFY_PARAM_set_trust', + '#define X509_VERIFY_PARAM_table_cleanup GRPC_SHADOW_X509_VERIFY_PARAM_table_cleanup', + '#define X509_CRL_set_issuer_name GRPC_SHADOW_X509_CRL_set_issuer_name', + '#define X509_CRL_set_lastUpdate GRPC_SHADOW_X509_CRL_set_lastUpdate', + '#define X509_CRL_set_nextUpdate GRPC_SHADOW_X509_CRL_set_nextUpdate', + '#define X509_CRL_set_version GRPC_SHADOW_X509_CRL_set_version', + '#define X509_CRL_sort GRPC_SHADOW_X509_CRL_sort', + '#define X509_CRL_up_ref GRPC_SHADOW_X509_CRL_up_ref', + '#define X509_REVOKED_set_revocationDate GRPC_SHADOW_X509_REVOKED_set_revocationDate', + '#define X509_REVOKED_set_serialNumber GRPC_SHADOW_X509_REVOKED_set_serialNumber', + '#define X509_NAME_ENTRY_create_by_NID GRPC_SHADOW_X509_NAME_ENTRY_create_by_NID', + '#define X509_NAME_ENTRY_create_by_OBJ GRPC_SHADOW_X509_NAME_ENTRY_create_by_OBJ', + '#define X509_NAME_ENTRY_create_by_txt GRPC_SHADOW_X509_NAME_ENTRY_create_by_txt', + '#define X509_NAME_ENTRY_get_data GRPC_SHADOW_X509_NAME_ENTRY_get_data', + '#define X509_NAME_ENTRY_get_object GRPC_SHADOW_X509_NAME_ENTRY_get_object', + '#define X509_NAME_ENTRY_set_data GRPC_SHADOW_X509_NAME_ENTRY_set_data', + '#define X509_NAME_ENTRY_set_object GRPC_SHADOW_X509_NAME_ENTRY_set_object', + '#define X509_NAME_add_entry GRPC_SHADOW_X509_NAME_add_entry', + '#define X509_NAME_add_entry_by_NID GRPC_SHADOW_X509_NAME_add_entry_by_NID', + '#define X509_NAME_add_entry_by_OBJ GRPC_SHADOW_X509_NAME_add_entry_by_OBJ', + '#define X509_NAME_add_entry_by_txt GRPC_SHADOW_X509_NAME_add_entry_by_txt', + '#define X509_NAME_delete_entry GRPC_SHADOW_X509_NAME_delete_entry', + '#define X509_NAME_entry_count GRPC_SHADOW_X509_NAME_entry_count', + '#define X509_NAME_get_entry GRPC_SHADOW_X509_NAME_get_entry', + '#define X509_NAME_get_index_by_NID GRPC_SHADOW_X509_NAME_get_index_by_NID', + '#define X509_NAME_get_index_by_OBJ GRPC_SHADOW_X509_NAME_get_index_by_OBJ', + '#define X509_NAME_get_text_by_NID GRPC_SHADOW_X509_NAME_get_text_by_NID', + '#define X509_NAME_get_text_by_OBJ GRPC_SHADOW_X509_NAME_get_text_by_OBJ', + '#define X509_REQ_set_pubkey GRPC_SHADOW_X509_REQ_set_pubkey', + '#define X509_REQ_set_subject_name GRPC_SHADOW_X509_REQ_set_subject_name', + '#define X509_REQ_set_version GRPC_SHADOW_X509_REQ_set_version', + '#define NETSCAPE_SPKI_b64_decode GRPC_SHADOW_NETSCAPE_SPKI_b64_decode', + '#define NETSCAPE_SPKI_b64_encode GRPC_SHADOW_NETSCAPE_SPKI_b64_encode', + '#define NETSCAPE_SPKI_get_pubkey GRPC_SHADOW_NETSCAPE_SPKI_get_pubkey', + '#define NETSCAPE_SPKI_set_pubkey GRPC_SHADOW_NETSCAPE_SPKI_set_pubkey', + '#define X509_ALGORS_it GRPC_SHADOW_X509_ALGORS_it', + '#define X509_ALGOR_cmp GRPC_SHADOW_X509_ALGOR_cmp', + '#define X509_ALGOR_dup GRPC_SHADOW_X509_ALGOR_dup', + '#define X509_ALGOR_free GRPC_SHADOW_X509_ALGOR_free', + '#define X509_ALGOR_get0 GRPC_SHADOW_X509_ALGOR_get0', + '#define X509_ALGOR_it GRPC_SHADOW_X509_ALGOR_it', + '#define X509_ALGOR_new GRPC_SHADOW_X509_ALGOR_new', + '#define X509_ALGOR_set0 GRPC_SHADOW_X509_ALGOR_set0', + '#define X509_ALGOR_set_md GRPC_SHADOW_X509_ALGOR_set_md', + '#define d2i_X509_ALGOR GRPC_SHADOW_d2i_X509_ALGOR', + '#define d2i_X509_ALGORS GRPC_SHADOW_d2i_X509_ALGORS', + '#define i2d_X509_ALGOR GRPC_SHADOW_i2d_X509_ALGOR', + '#define i2d_X509_ALGORS GRPC_SHADOW_i2d_X509_ALGORS', + '#define NETSCAPE_SPKI_sign GRPC_SHADOW_NETSCAPE_SPKI_sign', + '#define NETSCAPE_SPKI_verify GRPC_SHADOW_NETSCAPE_SPKI_verify', + '#define X509_CRL_digest GRPC_SHADOW_X509_CRL_digest', + '#define X509_CRL_sign GRPC_SHADOW_X509_CRL_sign', + '#define X509_CRL_sign_ctx GRPC_SHADOW_X509_CRL_sign_ctx', + '#define X509_NAME_digest GRPC_SHADOW_X509_NAME_digest', + '#define X509_REQ_digest GRPC_SHADOW_X509_REQ_digest', + '#define X509_REQ_sign GRPC_SHADOW_X509_REQ_sign', + '#define X509_REQ_sign_ctx GRPC_SHADOW_X509_REQ_sign_ctx', + '#define X509_REQ_verify GRPC_SHADOW_X509_REQ_verify', + '#define X509_digest GRPC_SHADOW_X509_digest', + '#define X509_pubkey_digest GRPC_SHADOW_X509_pubkey_digest', + '#define X509_sign GRPC_SHADOW_X509_sign', + '#define X509_sign_ctx GRPC_SHADOW_X509_sign_ctx', + '#define X509_verify GRPC_SHADOW_X509_verify', + '#define d2i_DSAPrivateKey_bio GRPC_SHADOW_d2i_DSAPrivateKey_bio', + '#define d2i_DSAPrivateKey_fp GRPC_SHADOW_d2i_DSAPrivateKey_fp', + '#define d2i_DSA_PUBKEY_bio GRPC_SHADOW_d2i_DSA_PUBKEY_bio', + '#define d2i_DSA_PUBKEY_fp GRPC_SHADOW_d2i_DSA_PUBKEY_fp', + '#define d2i_ECPrivateKey_bio GRPC_SHADOW_d2i_ECPrivateKey_bio', + '#define d2i_ECPrivateKey_fp GRPC_SHADOW_d2i_ECPrivateKey_fp', + '#define d2i_EC_PUBKEY_bio GRPC_SHADOW_d2i_EC_PUBKEY_bio', + '#define d2i_EC_PUBKEY_fp GRPC_SHADOW_d2i_EC_PUBKEY_fp', + '#define d2i_PKCS8_PRIV_KEY_INFO_bio GRPC_SHADOW_d2i_PKCS8_PRIV_KEY_INFO_bio', + '#define d2i_PKCS8_PRIV_KEY_INFO_fp GRPC_SHADOW_d2i_PKCS8_PRIV_KEY_INFO_fp', + '#define d2i_PKCS8_bio GRPC_SHADOW_d2i_PKCS8_bio', + '#define d2i_PKCS8_fp GRPC_SHADOW_d2i_PKCS8_fp', + '#define d2i_PUBKEY_bio GRPC_SHADOW_d2i_PUBKEY_bio', + '#define d2i_PUBKEY_fp GRPC_SHADOW_d2i_PUBKEY_fp', + '#define d2i_PrivateKey_bio GRPC_SHADOW_d2i_PrivateKey_bio', + '#define d2i_PrivateKey_fp GRPC_SHADOW_d2i_PrivateKey_fp', + '#define d2i_RSAPrivateKey_bio GRPC_SHADOW_d2i_RSAPrivateKey_bio', + '#define d2i_RSAPrivateKey_fp GRPC_SHADOW_d2i_RSAPrivateKey_fp', + '#define d2i_RSAPublicKey_bio GRPC_SHADOW_d2i_RSAPublicKey_bio', + '#define d2i_RSAPublicKey_fp GRPC_SHADOW_d2i_RSAPublicKey_fp', + '#define d2i_RSA_PUBKEY_bio GRPC_SHADOW_d2i_RSA_PUBKEY_bio', + '#define d2i_RSA_PUBKEY_fp GRPC_SHADOW_d2i_RSA_PUBKEY_fp', + '#define d2i_X509_CRL_bio GRPC_SHADOW_d2i_X509_CRL_bio', + '#define d2i_X509_CRL_fp GRPC_SHADOW_d2i_X509_CRL_fp', + '#define d2i_X509_REQ_bio GRPC_SHADOW_d2i_X509_REQ_bio', + '#define d2i_X509_REQ_fp GRPC_SHADOW_d2i_X509_REQ_fp', + '#define d2i_X509_bio GRPC_SHADOW_d2i_X509_bio', + '#define d2i_X509_fp GRPC_SHADOW_d2i_X509_fp', + '#define i2d_DSAPrivateKey_bio GRPC_SHADOW_i2d_DSAPrivateKey_bio', + '#define i2d_DSAPrivateKey_fp GRPC_SHADOW_i2d_DSAPrivateKey_fp', + '#define i2d_DSA_PUBKEY_bio GRPC_SHADOW_i2d_DSA_PUBKEY_bio', + '#define i2d_DSA_PUBKEY_fp GRPC_SHADOW_i2d_DSA_PUBKEY_fp', + '#define i2d_ECPrivateKey_bio GRPC_SHADOW_i2d_ECPrivateKey_bio', + '#define i2d_ECPrivateKey_fp GRPC_SHADOW_i2d_ECPrivateKey_fp', + '#define i2d_EC_PUBKEY_bio GRPC_SHADOW_i2d_EC_PUBKEY_bio', + '#define i2d_EC_PUBKEY_fp GRPC_SHADOW_i2d_EC_PUBKEY_fp', + '#define i2d_PKCS8PrivateKeyInfo_bio GRPC_SHADOW_i2d_PKCS8PrivateKeyInfo_bio', + '#define i2d_PKCS8PrivateKeyInfo_fp GRPC_SHADOW_i2d_PKCS8PrivateKeyInfo_fp', + '#define i2d_PKCS8_PRIV_KEY_INFO_bio GRPC_SHADOW_i2d_PKCS8_PRIV_KEY_INFO_bio', + '#define i2d_PKCS8_PRIV_KEY_INFO_fp GRPC_SHADOW_i2d_PKCS8_PRIV_KEY_INFO_fp', + '#define i2d_PKCS8_bio GRPC_SHADOW_i2d_PKCS8_bio', + '#define i2d_PKCS8_fp GRPC_SHADOW_i2d_PKCS8_fp', + '#define i2d_PUBKEY_bio GRPC_SHADOW_i2d_PUBKEY_bio', + '#define i2d_PUBKEY_fp GRPC_SHADOW_i2d_PUBKEY_fp', + '#define i2d_PrivateKey_bio GRPC_SHADOW_i2d_PrivateKey_bio', + '#define i2d_PrivateKey_fp GRPC_SHADOW_i2d_PrivateKey_fp', + '#define i2d_RSAPrivateKey_bio GRPC_SHADOW_i2d_RSAPrivateKey_bio', + '#define i2d_RSAPrivateKey_fp GRPC_SHADOW_i2d_RSAPrivateKey_fp', + '#define i2d_RSAPublicKey_bio GRPC_SHADOW_i2d_RSAPublicKey_bio', + '#define i2d_RSAPublicKey_fp GRPC_SHADOW_i2d_RSAPublicKey_fp', + '#define i2d_RSA_PUBKEY_bio GRPC_SHADOW_i2d_RSA_PUBKEY_bio', + '#define i2d_RSA_PUBKEY_fp GRPC_SHADOW_i2d_RSA_PUBKEY_fp', + '#define i2d_X509_CRL_bio GRPC_SHADOW_i2d_X509_CRL_bio', + '#define i2d_X509_CRL_fp GRPC_SHADOW_i2d_X509_CRL_fp', + '#define i2d_X509_REQ_bio GRPC_SHADOW_i2d_X509_REQ_bio', + '#define i2d_X509_REQ_fp GRPC_SHADOW_i2d_X509_REQ_fp', + '#define i2d_X509_bio GRPC_SHADOW_i2d_X509_bio', + '#define i2d_X509_fp GRPC_SHADOW_i2d_X509_fp', + '#define X509_ATTRIBUTE_SET_it GRPC_SHADOW_X509_ATTRIBUTE_SET_it', + '#define X509_ATTRIBUTE_create GRPC_SHADOW_X509_ATTRIBUTE_create', + '#define X509_ATTRIBUTE_dup GRPC_SHADOW_X509_ATTRIBUTE_dup', + '#define X509_ATTRIBUTE_free GRPC_SHADOW_X509_ATTRIBUTE_free', + '#define X509_ATTRIBUTE_it GRPC_SHADOW_X509_ATTRIBUTE_it', + '#define X509_ATTRIBUTE_new GRPC_SHADOW_X509_ATTRIBUTE_new', + '#define d2i_X509_ATTRIBUTE GRPC_SHADOW_d2i_X509_ATTRIBUTE', + '#define i2d_X509_ATTRIBUTE GRPC_SHADOW_i2d_X509_ATTRIBUTE', + '#define X509_CRL_INFO_free GRPC_SHADOW_X509_CRL_INFO_free', + '#define X509_CRL_INFO_it GRPC_SHADOW_X509_CRL_INFO_it', + '#define X509_CRL_INFO_new GRPC_SHADOW_X509_CRL_INFO_new', + '#define X509_CRL_METHOD_free GRPC_SHADOW_X509_CRL_METHOD_free', + '#define X509_CRL_METHOD_new GRPC_SHADOW_X509_CRL_METHOD_new', + '#define X509_CRL_add0_revoked GRPC_SHADOW_X509_CRL_add0_revoked', + '#define X509_CRL_dup GRPC_SHADOW_X509_CRL_dup', + '#define X509_CRL_free GRPC_SHADOW_X509_CRL_free', + '#define X509_CRL_get0_by_cert GRPC_SHADOW_X509_CRL_get0_by_cert', + '#define X509_CRL_get0_by_serial GRPC_SHADOW_X509_CRL_get0_by_serial', + '#define X509_CRL_get_meth_data GRPC_SHADOW_X509_CRL_get_meth_data', + '#define X509_CRL_it GRPC_SHADOW_X509_CRL_it', + '#define X509_CRL_new GRPC_SHADOW_X509_CRL_new', + '#define X509_CRL_set_default_method GRPC_SHADOW_X509_CRL_set_default_method', + '#define X509_CRL_set_meth_data GRPC_SHADOW_X509_CRL_set_meth_data', + '#define X509_CRL_verify GRPC_SHADOW_X509_CRL_verify', + '#define X509_REVOKED_dup GRPC_SHADOW_X509_REVOKED_dup', + '#define X509_REVOKED_free GRPC_SHADOW_X509_REVOKED_free', + '#define X509_REVOKED_it GRPC_SHADOW_X509_REVOKED_it', + '#define X509_REVOKED_new GRPC_SHADOW_X509_REVOKED_new', + '#define d2i_X509_CRL GRPC_SHADOW_d2i_X509_CRL', + '#define d2i_X509_CRL_INFO GRPC_SHADOW_d2i_X509_CRL_INFO', + '#define d2i_X509_REVOKED GRPC_SHADOW_d2i_X509_REVOKED', + '#define i2d_X509_CRL GRPC_SHADOW_i2d_X509_CRL', + '#define i2d_X509_CRL_INFO GRPC_SHADOW_i2d_X509_CRL_INFO', + '#define i2d_X509_REVOKED GRPC_SHADOW_i2d_X509_REVOKED', + '#define X509_EXTENSIONS_it GRPC_SHADOW_X509_EXTENSIONS_it', + '#define X509_EXTENSION_dup GRPC_SHADOW_X509_EXTENSION_dup', + '#define X509_EXTENSION_free GRPC_SHADOW_X509_EXTENSION_free', + '#define X509_EXTENSION_it GRPC_SHADOW_X509_EXTENSION_it', + '#define X509_EXTENSION_new GRPC_SHADOW_X509_EXTENSION_new', + '#define d2i_X509_EXTENSION GRPC_SHADOW_d2i_X509_EXTENSION', + '#define d2i_X509_EXTENSIONS GRPC_SHADOW_d2i_X509_EXTENSIONS', + '#define i2d_X509_EXTENSION GRPC_SHADOW_i2d_X509_EXTENSION', + '#define i2d_X509_EXTENSIONS GRPC_SHADOW_i2d_X509_EXTENSIONS', + '#define X509_INFO_free GRPC_SHADOW_X509_INFO_free', + '#define X509_INFO_new GRPC_SHADOW_X509_INFO_new', + '#define X509_NAME_ENTRIES_it GRPC_SHADOW_X509_NAME_ENTRIES_it', + '#define X509_NAME_ENTRY_dup GRPC_SHADOW_X509_NAME_ENTRY_dup', + '#define X509_NAME_ENTRY_free GRPC_SHADOW_X509_NAME_ENTRY_free', + '#define X509_NAME_ENTRY_it GRPC_SHADOW_X509_NAME_ENTRY_it', + '#define X509_NAME_ENTRY_new GRPC_SHADOW_X509_NAME_ENTRY_new', + '#define X509_NAME_ENTRY_set GRPC_SHADOW_X509_NAME_ENTRY_set', + '#define X509_NAME_INTERNAL_it GRPC_SHADOW_X509_NAME_INTERNAL_it', + '#define X509_NAME_dup GRPC_SHADOW_X509_NAME_dup', + '#define X509_NAME_free GRPC_SHADOW_X509_NAME_free', + '#define X509_NAME_get0_der GRPC_SHADOW_X509_NAME_get0_der', + '#define X509_NAME_it GRPC_SHADOW_X509_NAME_it', + '#define X509_NAME_new GRPC_SHADOW_X509_NAME_new', + '#define X509_NAME_set GRPC_SHADOW_X509_NAME_set', + '#define d2i_X509_NAME GRPC_SHADOW_d2i_X509_NAME', + '#define d2i_X509_NAME_ENTRY GRPC_SHADOW_d2i_X509_NAME_ENTRY', + '#define i2d_X509_NAME GRPC_SHADOW_i2d_X509_NAME', + '#define i2d_X509_NAME_ENTRY GRPC_SHADOW_i2d_X509_NAME_ENTRY', + '#define X509_PKEY_free GRPC_SHADOW_X509_PKEY_free', + '#define X509_PKEY_new GRPC_SHADOW_X509_PKEY_new', + '#define X509_PUBKEY_free GRPC_SHADOW_X509_PUBKEY_free', + '#define X509_PUBKEY_get GRPC_SHADOW_X509_PUBKEY_get', + '#define X509_PUBKEY_get0_param GRPC_SHADOW_X509_PUBKEY_get0_param', + '#define X509_PUBKEY_it GRPC_SHADOW_X509_PUBKEY_it', + '#define X509_PUBKEY_new GRPC_SHADOW_X509_PUBKEY_new', + '#define X509_PUBKEY_set GRPC_SHADOW_X509_PUBKEY_set', + '#define X509_PUBKEY_set0_param GRPC_SHADOW_X509_PUBKEY_set0_param', + '#define d2i_DSA_PUBKEY GRPC_SHADOW_d2i_DSA_PUBKEY', + '#define d2i_EC_PUBKEY GRPC_SHADOW_d2i_EC_PUBKEY', + '#define d2i_PUBKEY GRPC_SHADOW_d2i_PUBKEY', + '#define d2i_RSA_PUBKEY GRPC_SHADOW_d2i_RSA_PUBKEY', + '#define d2i_X509_PUBKEY GRPC_SHADOW_d2i_X509_PUBKEY', + '#define i2d_DSA_PUBKEY GRPC_SHADOW_i2d_DSA_PUBKEY', + '#define i2d_EC_PUBKEY GRPC_SHADOW_i2d_EC_PUBKEY', + '#define i2d_PUBKEY GRPC_SHADOW_i2d_PUBKEY', + '#define i2d_RSA_PUBKEY GRPC_SHADOW_i2d_RSA_PUBKEY', + '#define i2d_X509_PUBKEY GRPC_SHADOW_i2d_X509_PUBKEY', + '#define X509_REQ_INFO_free GRPC_SHADOW_X509_REQ_INFO_free', + '#define X509_REQ_INFO_it GRPC_SHADOW_X509_REQ_INFO_it', + '#define X509_REQ_INFO_new GRPC_SHADOW_X509_REQ_INFO_new', + '#define X509_REQ_dup GRPC_SHADOW_X509_REQ_dup', + '#define X509_REQ_free GRPC_SHADOW_X509_REQ_free', + '#define X509_REQ_it GRPC_SHADOW_X509_REQ_it', + '#define X509_REQ_new GRPC_SHADOW_X509_REQ_new', + '#define d2i_X509_REQ GRPC_SHADOW_d2i_X509_REQ', + '#define d2i_X509_REQ_INFO GRPC_SHADOW_d2i_X509_REQ_INFO', + '#define i2d_X509_REQ GRPC_SHADOW_i2d_X509_REQ', + '#define i2d_X509_REQ_INFO GRPC_SHADOW_i2d_X509_REQ_INFO', + '#define X509_SIG_free GRPC_SHADOW_X509_SIG_free', + '#define X509_SIG_it GRPC_SHADOW_X509_SIG_it', + '#define X509_SIG_new GRPC_SHADOW_X509_SIG_new', + '#define d2i_X509_SIG GRPC_SHADOW_d2i_X509_SIG', + '#define i2d_X509_SIG GRPC_SHADOW_i2d_X509_SIG', + '#define NETSCAPE_SPKAC_free GRPC_SHADOW_NETSCAPE_SPKAC_free', + '#define NETSCAPE_SPKAC_it GRPC_SHADOW_NETSCAPE_SPKAC_it', + '#define NETSCAPE_SPKAC_new GRPC_SHADOW_NETSCAPE_SPKAC_new', + '#define NETSCAPE_SPKI_free GRPC_SHADOW_NETSCAPE_SPKI_free', + '#define NETSCAPE_SPKI_it GRPC_SHADOW_NETSCAPE_SPKI_it', + '#define NETSCAPE_SPKI_new GRPC_SHADOW_NETSCAPE_SPKI_new', + '#define d2i_NETSCAPE_SPKAC GRPC_SHADOW_d2i_NETSCAPE_SPKAC', + '#define d2i_NETSCAPE_SPKI GRPC_SHADOW_d2i_NETSCAPE_SPKI', + '#define i2d_NETSCAPE_SPKAC GRPC_SHADOW_i2d_NETSCAPE_SPKAC', + '#define i2d_NETSCAPE_SPKI GRPC_SHADOW_i2d_NETSCAPE_SPKI', + '#define X509_VAL_free GRPC_SHADOW_X509_VAL_free', + '#define X509_VAL_it GRPC_SHADOW_X509_VAL_it', + '#define X509_VAL_new GRPC_SHADOW_X509_VAL_new', + '#define d2i_X509_VAL GRPC_SHADOW_d2i_X509_VAL', + '#define i2d_X509_VAL GRPC_SHADOW_i2d_X509_VAL', + '#define X509_CINF_free GRPC_SHADOW_X509_CINF_free', + '#define X509_CINF_it GRPC_SHADOW_X509_CINF_it', + '#define X509_CINF_new GRPC_SHADOW_X509_CINF_new', + '#define X509_dup GRPC_SHADOW_X509_dup', + '#define X509_free GRPC_SHADOW_X509_free', + '#define X509_get0_signature GRPC_SHADOW_X509_get0_signature', + '#define X509_get_ex_data GRPC_SHADOW_X509_get_ex_data', + '#define X509_get_ex_new_index GRPC_SHADOW_X509_get_ex_new_index', + '#define X509_get_signature_nid GRPC_SHADOW_X509_get_signature_nid', + '#define X509_it GRPC_SHADOW_X509_it', + '#define X509_new GRPC_SHADOW_X509_new', + '#define X509_parse_from_buffer GRPC_SHADOW_X509_parse_from_buffer', + '#define X509_set_ex_data GRPC_SHADOW_X509_set_ex_data', + '#define X509_up_ref GRPC_SHADOW_X509_up_ref', + '#define d2i_X509 GRPC_SHADOW_d2i_X509', + '#define d2i_X509_AUX GRPC_SHADOW_d2i_X509_AUX', + '#define d2i_X509_CINF GRPC_SHADOW_d2i_X509_CINF', + '#define i2d_X509 GRPC_SHADOW_i2d_X509', + '#define i2d_X509_AUX GRPC_SHADOW_i2d_X509_AUX', + '#define i2d_X509_CINF GRPC_SHADOW_i2d_X509_CINF', + '#define X509_CERT_AUX_free GRPC_SHADOW_X509_CERT_AUX_free', + '#define X509_CERT_AUX_it GRPC_SHADOW_X509_CERT_AUX_it', + '#define X509_CERT_AUX_new GRPC_SHADOW_X509_CERT_AUX_new', + '#define X509_add1_reject_object GRPC_SHADOW_X509_add1_reject_object', + '#define X509_add1_trust_object GRPC_SHADOW_X509_add1_trust_object', + '#define X509_alias_get0 GRPC_SHADOW_X509_alias_get0', + '#define X509_alias_set1 GRPC_SHADOW_X509_alias_set1', + '#define X509_keyid_get0 GRPC_SHADOW_X509_keyid_get0', + '#define X509_keyid_set1 GRPC_SHADOW_X509_keyid_set1', + '#define X509_reject_clear GRPC_SHADOW_X509_reject_clear', + '#define X509_trust_clear GRPC_SHADOW_X509_trust_clear', + '#define d2i_X509_CERT_AUX GRPC_SHADOW_d2i_X509_CERT_AUX', + '#define i2d_X509_CERT_AUX GRPC_SHADOW_i2d_X509_CERT_AUX', + '#define policy_cache_find_data GRPC_SHADOW_policy_cache_find_data', + '#define policy_cache_free GRPC_SHADOW_policy_cache_free', + '#define policy_cache_set GRPC_SHADOW_policy_cache_set', + '#define policy_data_free GRPC_SHADOW_policy_data_free', + '#define policy_data_new GRPC_SHADOW_policy_data_new', + '#define X509_policy_level_get0_node GRPC_SHADOW_X509_policy_level_get0_node', + '#define X509_policy_level_node_count GRPC_SHADOW_X509_policy_level_node_count', + '#define X509_policy_node_get0_parent GRPC_SHADOW_X509_policy_node_get0_parent', + '#define X509_policy_node_get0_policy GRPC_SHADOW_X509_policy_node_get0_policy', + '#define X509_policy_node_get0_qualifiers GRPC_SHADOW_X509_policy_node_get0_qualifiers', + '#define X509_policy_tree_get0_level GRPC_SHADOW_X509_policy_tree_get0_level', + '#define X509_policy_tree_get0_policies GRPC_SHADOW_X509_policy_tree_get0_policies', + '#define X509_policy_tree_get0_user_policies GRPC_SHADOW_X509_policy_tree_get0_user_policies', + '#define X509_policy_tree_level_count GRPC_SHADOW_X509_policy_tree_level_count', + '#define policy_cache_set_mapping GRPC_SHADOW_policy_cache_set_mapping', + '#define level_add_node GRPC_SHADOW_level_add_node', + '#define level_find_node GRPC_SHADOW_level_find_node', + '#define policy_node_cmp_new GRPC_SHADOW_policy_node_cmp_new', + '#define policy_node_free GRPC_SHADOW_policy_node_free', + '#define policy_node_match GRPC_SHADOW_policy_node_match', + '#define tree_find_sk GRPC_SHADOW_tree_find_sk', + '#define X509_policy_check GRPC_SHADOW_X509_policy_check', + '#define X509_policy_tree_free GRPC_SHADOW_X509_policy_tree_free', + '#define v3_akey_id GRPC_SHADOW_v3_akey_id', + '#define AUTHORITY_KEYID_free GRPC_SHADOW_AUTHORITY_KEYID_free', + '#define AUTHORITY_KEYID_it GRPC_SHADOW_AUTHORITY_KEYID_it', + '#define AUTHORITY_KEYID_new GRPC_SHADOW_AUTHORITY_KEYID_new', + '#define d2i_AUTHORITY_KEYID GRPC_SHADOW_d2i_AUTHORITY_KEYID', + '#define i2d_AUTHORITY_KEYID GRPC_SHADOW_i2d_AUTHORITY_KEYID', + '#define GENERAL_NAME_print GRPC_SHADOW_GENERAL_NAME_print', + '#define a2i_GENERAL_NAME GRPC_SHADOW_a2i_GENERAL_NAME', + '#define i2v_GENERAL_NAME GRPC_SHADOW_i2v_GENERAL_NAME', + '#define i2v_GENERAL_NAMES GRPC_SHADOW_i2v_GENERAL_NAMES', + '#define v2i_GENERAL_NAME GRPC_SHADOW_v2i_GENERAL_NAME', + '#define v2i_GENERAL_NAMES GRPC_SHADOW_v2i_GENERAL_NAMES', + '#define v2i_GENERAL_NAME_ex GRPC_SHADOW_v2i_GENERAL_NAME_ex', + '#define v3_alt GRPC_SHADOW_v3_alt', + '#define BASIC_CONSTRAINTS_free GRPC_SHADOW_BASIC_CONSTRAINTS_free', + '#define BASIC_CONSTRAINTS_it GRPC_SHADOW_BASIC_CONSTRAINTS_it', + '#define BASIC_CONSTRAINTS_new GRPC_SHADOW_BASIC_CONSTRAINTS_new', + '#define d2i_BASIC_CONSTRAINTS GRPC_SHADOW_d2i_BASIC_CONSTRAINTS', + '#define i2d_BASIC_CONSTRAINTS GRPC_SHADOW_i2d_BASIC_CONSTRAINTS', + '#define v3_bcons GRPC_SHADOW_v3_bcons', + '#define i2v_ASN1_BIT_STRING GRPC_SHADOW_i2v_ASN1_BIT_STRING', + '#define v2i_ASN1_BIT_STRING GRPC_SHADOW_v2i_ASN1_BIT_STRING', + '#define v3_key_usage GRPC_SHADOW_v3_key_usage', + '#define v3_nscert GRPC_SHADOW_v3_nscert', + '#define X509V3_EXT_CRL_add_nconf GRPC_SHADOW_X509V3_EXT_CRL_add_nconf', + '#define X509V3_EXT_REQ_add_nconf GRPC_SHADOW_X509V3_EXT_REQ_add_nconf', + '#define X509V3_EXT_add_nconf GRPC_SHADOW_X509V3_EXT_add_nconf', + '#define X509V3_EXT_add_nconf_sk GRPC_SHADOW_X509V3_EXT_add_nconf_sk', + '#define X509V3_EXT_i2d GRPC_SHADOW_X509V3_EXT_i2d', + '#define X509V3_EXT_nconf GRPC_SHADOW_X509V3_EXT_nconf', + '#define X509V3_EXT_nconf_nid GRPC_SHADOW_X509V3_EXT_nconf_nid', + '#define X509V3_get_section GRPC_SHADOW_X509V3_get_section', + '#define X509V3_get_string GRPC_SHADOW_X509V3_get_string', + '#define X509V3_section_free GRPC_SHADOW_X509V3_section_free', + '#define X509V3_set_ctx GRPC_SHADOW_X509V3_set_ctx', + '#define X509V3_set_nconf GRPC_SHADOW_X509V3_set_nconf', + '#define X509V3_string_free GRPC_SHADOW_X509V3_string_free', + '#define CERTIFICATEPOLICIES_free GRPC_SHADOW_CERTIFICATEPOLICIES_free', + '#define CERTIFICATEPOLICIES_it GRPC_SHADOW_CERTIFICATEPOLICIES_it', + '#define CERTIFICATEPOLICIES_new GRPC_SHADOW_CERTIFICATEPOLICIES_new', + '#define NOTICEREF_free GRPC_SHADOW_NOTICEREF_free', + '#define NOTICEREF_it GRPC_SHADOW_NOTICEREF_it', + '#define NOTICEREF_new GRPC_SHADOW_NOTICEREF_new', + '#define POLICYINFO_free GRPC_SHADOW_POLICYINFO_free', + '#define POLICYINFO_it GRPC_SHADOW_POLICYINFO_it', + '#define POLICYINFO_new GRPC_SHADOW_POLICYINFO_new', + '#define POLICYQUALINFO_free GRPC_SHADOW_POLICYQUALINFO_free', + '#define POLICYQUALINFO_it GRPC_SHADOW_POLICYQUALINFO_it', + '#define POLICYQUALINFO_new GRPC_SHADOW_POLICYQUALINFO_new', + '#define USERNOTICE_free GRPC_SHADOW_USERNOTICE_free', + '#define USERNOTICE_it GRPC_SHADOW_USERNOTICE_it', + '#define USERNOTICE_new GRPC_SHADOW_USERNOTICE_new', + '#define X509_POLICY_NODE_print GRPC_SHADOW_X509_POLICY_NODE_print', + '#define d2i_CERTIFICATEPOLICIES GRPC_SHADOW_d2i_CERTIFICATEPOLICIES', + '#define d2i_NOTICEREF GRPC_SHADOW_d2i_NOTICEREF', + '#define d2i_POLICYINFO GRPC_SHADOW_d2i_POLICYINFO', + '#define d2i_POLICYQUALINFO GRPC_SHADOW_d2i_POLICYQUALINFO', + '#define d2i_USERNOTICE GRPC_SHADOW_d2i_USERNOTICE', + '#define i2d_CERTIFICATEPOLICIES GRPC_SHADOW_i2d_CERTIFICATEPOLICIES', + '#define i2d_NOTICEREF GRPC_SHADOW_i2d_NOTICEREF', + '#define i2d_POLICYINFO GRPC_SHADOW_i2d_POLICYINFO', + '#define i2d_POLICYQUALINFO GRPC_SHADOW_i2d_POLICYQUALINFO', + '#define i2d_USERNOTICE GRPC_SHADOW_i2d_USERNOTICE', + '#define v3_cpols GRPC_SHADOW_v3_cpols', + '#define CRL_DIST_POINTS_free GRPC_SHADOW_CRL_DIST_POINTS_free', + '#define CRL_DIST_POINTS_it GRPC_SHADOW_CRL_DIST_POINTS_it', + '#define CRL_DIST_POINTS_new GRPC_SHADOW_CRL_DIST_POINTS_new', + '#define DIST_POINT_NAME_free GRPC_SHADOW_DIST_POINT_NAME_free', + '#define DIST_POINT_NAME_it GRPC_SHADOW_DIST_POINT_NAME_it', + '#define DIST_POINT_NAME_new GRPC_SHADOW_DIST_POINT_NAME_new', + '#define DIST_POINT_free GRPC_SHADOW_DIST_POINT_free', + '#define DIST_POINT_it GRPC_SHADOW_DIST_POINT_it', + '#define DIST_POINT_new GRPC_SHADOW_DIST_POINT_new', + '#define DIST_POINT_set_dpname GRPC_SHADOW_DIST_POINT_set_dpname', + '#define ISSUING_DIST_POINT_free GRPC_SHADOW_ISSUING_DIST_POINT_free', + '#define ISSUING_DIST_POINT_it GRPC_SHADOW_ISSUING_DIST_POINT_it', + '#define ISSUING_DIST_POINT_new GRPC_SHADOW_ISSUING_DIST_POINT_new', + '#define d2i_CRL_DIST_POINTS GRPC_SHADOW_d2i_CRL_DIST_POINTS', + '#define d2i_DIST_POINT GRPC_SHADOW_d2i_DIST_POINT', + '#define d2i_DIST_POINT_NAME GRPC_SHADOW_d2i_DIST_POINT_NAME', + '#define d2i_ISSUING_DIST_POINT GRPC_SHADOW_d2i_ISSUING_DIST_POINT', + '#define i2d_CRL_DIST_POINTS GRPC_SHADOW_i2d_CRL_DIST_POINTS', + '#define i2d_DIST_POINT GRPC_SHADOW_i2d_DIST_POINT', + '#define i2d_DIST_POINT_NAME GRPC_SHADOW_i2d_DIST_POINT_NAME', + '#define i2d_ISSUING_DIST_POINT GRPC_SHADOW_i2d_ISSUING_DIST_POINT', + '#define v3_crld GRPC_SHADOW_v3_crld', + '#define v3_freshest_crl GRPC_SHADOW_v3_freshest_crl', + '#define v3_idp GRPC_SHADOW_v3_idp', + '#define i2s_ASN1_ENUMERATED_TABLE GRPC_SHADOW_i2s_ASN1_ENUMERATED_TABLE', + '#define v3_crl_reason GRPC_SHADOW_v3_crl_reason', + '#define EXTENDED_KEY_USAGE_free GRPC_SHADOW_EXTENDED_KEY_USAGE_free', + '#define EXTENDED_KEY_USAGE_it GRPC_SHADOW_EXTENDED_KEY_USAGE_it', + '#define EXTENDED_KEY_USAGE_new GRPC_SHADOW_EXTENDED_KEY_USAGE_new', + '#define d2i_EXTENDED_KEY_USAGE GRPC_SHADOW_d2i_EXTENDED_KEY_USAGE', + '#define i2d_EXTENDED_KEY_USAGE GRPC_SHADOW_i2d_EXTENDED_KEY_USAGE', + '#define v3_ext_ku GRPC_SHADOW_v3_ext_ku', + '#define v3_ocsp_accresp GRPC_SHADOW_v3_ocsp_accresp', + '#define EDIPARTYNAME_free GRPC_SHADOW_EDIPARTYNAME_free', + '#define EDIPARTYNAME_it GRPC_SHADOW_EDIPARTYNAME_it', + '#define EDIPARTYNAME_new GRPC_SHADOW_EDIPARTYNAME_new', + '#define GENERAL_NAMES_free GRPC_SHADOW_GENERAL_NAMES_free', + '#define GENERAL_NAMES_it GRPC_SHADOW_GENERAL_NAMES_it', + '#define GENERAL_NAMES_new GRPC_SHADOW_GENERAL_NAMES_new', + '#define GENERAL_NAME_cmp GRPC_SHADOW_GENERAL_NAME_cmp', + '#define GENERAL_NAME_dup GRPC_SHADOW_GENERAL_NAME_dup', + '#define GENERAL_NAME_free GRPC_SHADOW_GENERAL_NAME_free', + '#define GENERAL_NAME_get0_otherName GRPC_SHADOW_GENERAL_NAME_get0_otherName', + '#define GENERAL_NAME_get0_value GRPC_SHADOW_GENERAL_NAME_get0_value', + '#define GENERAL_NAME_it GRPC_SHADOW_GENERAL_NAME_it', + '#define GENERAL_NAME_new GRPC_SHADOW_GENERAL_NAME_new', + '#define GENERAL_NAME_set0_othername GRPC_SHADOW_GENERAL_NAME_set0_othername', + '#define GENERAL_NAME_set0_value GRPC_SHADOW_GENERAL_NAME_set0_value', + '#define OTHERNAME_cmp GRPC_SHADOW_OTHERNAME_cmp', + '#define OTHERNAME_free GRPC_SHADOW_OTHERNAME_free', + '#define OTHERNAME_it GRPC_SHADOW_OTHERNAME_it', + '#define OTHERNAME_new GRPC_SHADOW_OTHERNAME_new', + '#define d2i_EDIPARTYNAME GRPC_SHADOW_d2i_EDIPARTYNAME', + '#define d2i_GENERAL_NAME GRPC_SHADOW_d2i_GENERAL_NAME', + '#define d2i_GENERAL_NAMES GRPC_SHADOW_d2i_GENERAL_NAMES', + '#define d2i_OTHERNAME GRPC_SHADOW_d2i_OTHERNAME', + '#define i2d_EDIPARTYNAME GRPC_SHADOW_i2d_EDIPARTYNAME', + '#define i2d_GENERAL_NAME GRPC_SHADOW_i2d_GENERAL_NAME', + '#define i2d_GENERAL_NAMES GRPC_SHADOW_i2d_GENERAL_NAMES', + '#define i2d_OTHERNAME GRPC_SHADOW_i2d_OTHERNAME', + '#define v3_ns_ia5_list GRPC_SHADOW_v3_ns_ia5_list', + '#define ACCESS_DESCRIPTION_free GRPC_SHADOW_ACCESS_DESCRIPTION_free', + '#define ACCESS_DESCRIPTION_it GRPC_SHADOW_ACCESS_DESCRIPTION_it', + '#define ACCESS_DESCRIPTION_new GRPC_SHADOW_ACCESS_DESCRIPTION_new', + '#define AUTHORITY_INFO_ACCESS_free GRPC_SHADOW_AUTHORITY_INFO_ACCESS_free', + '#define AUTHORITY_INFO_ACCESS_it GRPC_SHADOW_AUTHORITY_INFO_ACCESS_it', + '#define AUTHORITY_INFO_ACCESS_new GRPC_SHADOW_AUTHORITY_INFO_ACCESS_new', + '#define d2i_ACCESS_DESCRIPTION GRPC_SHADOW_d2i_ACCESS_DESCRIPTION', + '#define d2i_AUTHORITY_INFO_ACCESS GRPC_SHADOW_d2i_AUTHORITY_INFO_ACCESS', + '#define i2a_ACCESS_DESCRIPTION GRPC_SHADOW_i2a_ACCESS_DESCRIPTION', + '#define i2d_ACCESS_DESCRIPTION GRPC_SHADOW_i2d_ACCESS_DESCRIPTION', + '#define i2d_AUTHORITY_INFO_ACCESS GRPC_SHADOW_i2d_AUTHORITY_INFO_ACCESS', + '#define v3_info GRPC_SHADOW_v3_info', + '#define v3_sinfo GRPC_SHADOW_v3_sinfo', + '#define v3_crl_num GRPC_SHADOW_v3_crl_num', + '#define v3_delta_crl GRPC_SHADOW_v3_delta_crl', + '#define v3_inhibit_anyp GRPC_SHADOW_v3_inhibit_anyp', + '#define X509V3_EXT_add GRPC_SHADOW_X509V3_EXT_add', + '#define X509V3_EXT_add_alias GRPC_SHADOW_X509V3_EXT_add_alias', + '#define X509V3_EXT_add_list GRPC_SHADOW_X509V3_EXT_add_list', + '#define X509V3_EXT_cleanup GRPC_SHADOW_X509V3_EXT_cleanup', + '#define X509V3_EXT_d2i GRPC_SHADOW_X509V3_EXT_d2i', + '#define X509V3_EXT_free GRPC_SHADOW_X509V3_EXT_free', + '#define X509V3_EXT_get GRPC_SHADOW_X509V3_EXT_get', + '#define X509V3_EXT_get_nid GRPC_SHADOW_X509V3_EXT_get_nid', + '#define X509V3_add1_i2d GRPC_SHADOW_X509V3_add1_i2d', + '#define X509V3_add_standard_extensions GRPC_SHADOW_X509V3_add_standard_extensions', + '#define X509V3_get_d2i GRPC_SHADOW_X509V3_get_d2i', + '#define GENERAL_SUBTREE_free GRPC_SHADOW_GENERAL_SUBTREE_free', + '#define GENERAL_SUBTREE_it GRPC_SHADOW_GENERAL_SUBTREE_it', + '#define GENERAL_SUBTREE_new GRPC_SHADOW_GENERAL_SUBTREE_new', + '#define NAME_CONSTRAINTS_check GRPC_SHADOW_NAME_CONSTRAINTS_check', + '#define NAME_CONSTRAINTS_free GRPC_SHADOW_NAME_CONSTRAINTS_free', + '#define NAME_CONSTRAINTS_it GRPC_SHADOW_NAME_CONSTRAINTS_it', + '#define NAME_CONSTRAINTS_new GRPC_SHADOW_NAME_CONSTRAINTS_new', + '#define v3_name_constraints GRPC_SHADOW_v3_name_constraints', + '#define v3_pci GRPC_SHADOW_v3_pci', + '#define PROXY_CERT_INFO_EXTENSION_free GRPC_SHADOW_PROXY_CERT_INFO_EXTENSION_free', + '#define PROXY_CERT_INFO_EXTENSION_it GRPC_SHADOW_PROXY_CERT_INFO_EXTENSION_it', + '#define PROXY_CERT_INFO_EXTENSION_new GRPC_SHADOW_PROXY_CERT_INFO_EXTENSION_new', + '#define PROXY_POLICY_free GRPC_SHADOW_PROXY_POLICY_free', + '#define PROXY_POLICY_it GRPC_SHADOW_PROXY_POLICY_it', + '#define PROXY_POLICY_new GRPC_SHADOW_PROXY_POLICY_new', + '#define d2i_PROXY_CERT_INFO_EXTENSION GRPC_SHADOW_d2i_PROXY_CERT_INFO_EXTENSION', + '#define d2i_PROXY_POLICY GRPC_SHADOW_d2i_PROXY_POLICY', + '#define i2d_PROXY_CERT_INFO_EXTENSION GRPC_SHADOW_i2d_PROXY_CERT_INFO_EXTENSION', + '#define i2d_PROXY_POLICY GRPC_SHADOW_i2d_PROXY_POLICY', + '#define POLICY_CONSTRAINTS_free GRPC_SHADOW_POLICY_CONSTRAINTS_free', + '#define POLICY_CONSTRAINTS_it GRPC_SHADOW_POLICY_CONSTRAINTS_it', + '#define POLICY_CONSTRAINTS_new GRPC_SHADOW_POLICY_CONSTRAINTS_new', + '#define v3_policy_constraints GRPC_SHADOW_v3_policy_constraints', + '#define PKEY_USAGE_PERIOD_free GRPC_SHADOW_PKEY_USAGE_PERIOD_free', + '#define PKEY_USAGE_PERIOD_it GRPC_SHADOW_PKEY_USAGE_PERIOD_it', + '#define PKEY_USAGE_PERIOD_new GRPC_SHADOW_PKEY_USAGE_PERIOD_new', + '#define d2i_PKEY_USAGE_PERIOD GRPC_SHADOW_d2i_PKEY_USAGE_PERIOD', + '#define i2d_PKEY_USAGE_PERIOD GRPC_SHADOW_i2d_PKEY_USAGE_PERIOD', + '#define v3_pkey_usage_period GRPC_SHADOW_v3_pkey_usage_period', + '#define POLICY_MAPPINGS_it GRPC_SHADOW_POLICY_MAPPINGS_it', + '#define POLICY_MAPPING_free GRPC_SHADOW_POLICY_MAPPING_free', + '#define POLICY_MAPPING_it GRPC_SHADOW_POLICY_MAPPING_it', + '#define POLICY_MAPPING_new GRPC_SHADOW_POLICY_MAPPING_new', + '#define v3_policy_mappings GRPC_SHADOW_v3_policy_mappings', + '#define X509V3_EXT_print GRPC_SHADOW_X509V3_EXT_print', + '#define X509V3_EXT_print_fp GRPC_SHADOW_X509V3_EXT_print_fp', + '#define X509V3_EXT_val_prn GRPC_SHADOW_X509V3_EXT_val_prn', + '#define X509V3_extensions_print GRPC_SHADOW_X509V3_extensions_print', + '#define X509_PURPOSE_add GRPC_SHADOW_X509_PURPOSE_add', + '#define X509_PURPOSE_cleanup GRPC_SHADOW_X509_PURPOSE_cleanup', + '#define X509_PURPOSE_get0 GRPC_SHADOW_X509_PURPOSE_get0', + '#define X509_PURPOSE_get0_name GRPC_SHADOW_X509_PURPOSE_get0_name', + '#define X509_PURPOSE_get0_sname GRPC_SHADOW_X509_PURPOSE_get0_sname', + '#define X509_PURPOSE_get_by_id GRPC_SHADOW_X509_PURPOSE_get_by_id', + '#define X509_PURPOSE_get_by_sname GRPC_SHADOW_X509_PURPOSE_get_by_sname', + '#define X509_PURPOSE_get_count GRPC_SHADOW_X509_PURPOSE_get_count', + '#define X509_PURPOSE_get_id GRPC_SHADOW_X509_PURPOSE_get_id', + '#define X509_PURPOSE_get_trust GRPC_SHADOW_X509_PURPOSE_get_trust', + '#define X509_PURPOSE_set GRPC_SHADOW_X509_PURPOSE_set', + '#define X509_check_akid GRPC_SHADOW_X509_check_akid', + '#define X509_check_ca GRPC_SHADOW_X509_check_ca', + '#define X509_check_issued GRPC_SHADOW_X509_check_issued', + '#define X509_check_purpose GRPC_SHADOW_X509_check_purpose', + '#define X509_supported_extension GRPC_SHADOW_X509_supported_extension', + '#define i2s_ASN1_OCTET_STRING GRPC_SHADOW_i2s_ASN1_OCTET_STRING', + '#define s2i_ASN1_OCTET_STRING GRPC_SHADOW_s2i_ASN1_OCTET_STRING', + '#define v3_skey_id GRPC_SHADOW_v3_skey_id', + '#define SXNETID_free GRPC_SHADOW_SXNETID_free', + '#define SXNETID_it GRPC_SHADOW_SXNETID_it', + '#define SXNETID_new GRPC_SHADOW_SXNETID_new', + '#define SXNET_add_id_INTEGER GRPC_SHADOW_SXNET_add_id_INTEGER', + '#define SXNET_add_id_asc GRPC_SHADOW_SXNET_add_id_asc', + '#define SXNET_add_id_ulong GRPC_SHADOW_SXNET_add_id_ulong', + '#define SXNET_free GRPC_SHADOW_SXNET_free', + '#define SXNET_get_id_INTEGER GRPC_SHADOW_SXNET_get_id_INTEGER', + '#define SXNET_get_id_asc GRPC_SHADOW_SXNET_get_id_asc', + '#define SXNET_get_id_ulong GRPC_SHADOW_SXNET_get_id_ulong', + '#define SXNET_it GRPC_SHADOW_SXNET_it', + '#define SXNET_new GRPC_SHADOW_SXNET_new', + '#define d2i_SXNET GRPC_SHADOW_d2i_SXNET', + '#define d2i_SXNETID GRPC_SHADOW_d2i_SXNETID', + '#define i2d_SXNET GRPC_SHADOW_i2d_SXNET', + '#define i2d_SXNETID GRPC_SHADOW_i2d_SXNETID', + '#define v3_sxnet GRPC_SHADOW_v3_sxnet', + '#define X509V3_NAME_from_section GRPC_SHADOW_X509V3_NAME_from_section', + '#define X509V3_add_value GRPC_SHADOW_X509V3_add_value', + '#define X509V3_add_value_bool GRPC_SHADOW_X509V3_add_value_bool', + '#define X509V3_add_value_bool_nf GRPC_SHADOW_X509V3_add_value_bool_nf', + '#define X509V3_add_value_int GRPC_SHADOW_X509V3_add_value_int', + '#define X509V3_add_value_uchar GRPC_SHADOW_X509V3_add_value_uchar', + '#define X509V3_conf_free GRPC_SHADOW_X509V3_conf_free', + '#define X509V3_get_value_bool GRPC_SHADOW_X509V3_get_value_bool', + '#define X509V3_get_value_int GRPC_SHADOW_X509V3_get_value_int', + '#define X509V3_parse_list GRPC_SHADOW_X509V3_parse_list', + '#define X509_REQ_get1_email GRPC_SHADOW_X509_REQ_get1_email', + '#define X509_check_email GRPC_SHADOW_X509_check_email', + '#define X509_check_host GRPC_SHADOW_X509_check_host', + '#define X509_check_ip GRPC_SHADOW_X509_check_ip', + '#define X509_check_ip_asc GRPC_SHADOW_X509_check_ip_asc', + '#define X509_email_free GRPC_SHADOW_X509_email_free', + '#define X509_get1_email GRPC_SHADOW_X509_get1_email', + '#define X509_get1_ocsp GRPC_SHADOW_X509_get1_ocsp', + '#define a2i_IPADDRESS GRPC_SHADOW_a2i_IPADDRESS', + '#define a2i_IPADDRESS_NC GRPC_SHADOW_a2i_IPADDRESS_NC', + '#define a2i_ipadd GRPC_SHADOW_a2i_ipadd', + '#define hex_to_string GRPC_SHADOW_hex_to_string', + '#define i2s_ASN1_ENUMERATED GRPC_SHADOW_i2s_ASN1_ENUMERATED', + '#define i2s_ASN1_INTEGER GRPC_SHADOW_i2s_ASN1_INTEGER', + '#define name_cmp GRPC_SHADOW_name_cmp', + '#define s2i_ASN1_INTEGER GRPC_SHADOW_s2i_ASN1_INTEGER', + '#define string_to_hex GRPC_SHADOW_string_to_hex', + '#define PKCS7_get_raw_certificates GRPC_SHADOW_PKCS7_get_raw_certificates', + '#define pkcs7_bundle GRPC_SHADOW_pkcs7_bundle', + '#define pkcs7_parse_header GRPC_SHADOW_pkcs7_parse_header', + '#define PKCS7_bundle_CRLs GRPC_SHADOW_PKCS7_bundle_CRLs', + '#define PKCS7_bundle_certificates GRPC_SHADOW_PKCS7_bundle_certificates', + '#define PKCS7_get_CRLs GRPC_SHADOW_PKCS7_get_CRLs', + '#define PKCS7_get_PEM_CRLs GRPC_SHADOW_PKCS7_get_PEM_CRLs', + '#define PKCS7_get_PEM_certificates GRPC_SHADOW_PKCS7_get_PEM_certificates', + '#define PKCS7_get_certificates GRPC_SHADOW_PKCS7_get_certificates', + '#define PKCS8_marshal_encrypted_private_key GRPC_SHADOW_PKCS8_marshal_encrypted_private_key', + '#define PKCS8_parse_encrypted_private_key GRPC_SHADOW_PKCS8_parse_encrypted_private_key', + '#define pkcs12_key_gen GRPC_SHADOW_pkcs12_key_gen', + '#define pkcs8_pbe_decrypt GRPC_SHADOW_pkcs8_pbe_decrypt', + '#define EVP_PKCS82PKEY GRPC_SHADOW_EVP_PKCS82PKEY', + '#define EVP_PKEY2PKCS8 GRPC_SHADOW_EVP_PKEY2PKCS8', + '#define PKCS12_PBE_add GRPC_SHADOW_PKCS12_PBE_add', + '#define PKCS12_free GRPC_SHADOW_PKCS12_free', + '#define PKCS12_get_key_and_certs GRPC_SHADOW_PKCS12_get_key_and_certs', + '#define PKCS12_parse GRPC_SHADOW_PKCS12_parse', + '#define PKCS12_verify_mac GRPC_SHADOW_PKCS12_verify_mac', + '#define PKCS8_PRIV_KEY_INFO_free GRPC_SHADOW_PKCS8_PRIV_KEY_INFO_free', + '#define PKCS8_PRIV_KEY_INFO_it GRPC_SHADOW_PKCS8_PRIV_KEY_INFO_it', + '#define PKCS8_PRIV_KEY_INFO_new GRPC_SHADOW_PKCS8_PRIV_KEY_INFO_new', + '#define PKCS8_decrypt GRPC_SHADOW_PKCS8_decrypt', + '#define PKCS8_encrypt GRPC_SHADOW_PKCS8_encrypt', + '#define d2i_PKCS12 GRPC_SHADOW_d2i_PKCS12', + '#define d2i_PKCS12_bio GRPC_SHADOW_d2i_PKCS12_bio', + '#define d2i_PKCS12_fp GRPC_SHADOW_d2i_PKCS12_fp', + '#define d2i_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_d2i_PKCS8_PRIV_KEY_INFO', + '#define i2d_PKCS8_PRIV_KEY_INFO GRPC_SHADOW_i2d_PKCS8_PRIV_KEY_INFO', + '#define PKCS5_pbe2_decrypt_init GRPC_SHADOW_PKCS5_pbe2_decrypt_init', + '#define PKCS5_pbe2_encrypt_init GRPC_SHADOW_PKCS5_pbe2_encrypt_init' +end diff --git a/src/objective-c/BoringSSL.podspec b/src/objective-c/BoringSSL.podspec deleted file mode 100644 index dc566803930..00000000000 --- a/src/objective-c/BoringSSL.podspec +++ /dev/null @@ -1,1539 +0,0 @@ -# BoringSSL CocoaPods podspec - -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Pod::Spec.new do |s| - s.name = 'BoringSSL' - version = '10.0.6' - s.version = version - s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google’s needs.' - # Adapted from the homepage: - s.description = <<-DESC - BoringSSL is a fork of OpenSSL that is designed to meet Google’s needs. - - Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. - We don’t recommend that third parties depend upon it. Doing so is likely to be frustrating - because there are no guarantees of API stability. Only the latest version of this pod is - supported, and every new version is a new major version. - - We update Google libraries and programs that use BoringSSL as needed when deciding to make API - changes. This allows us to mostly avoid compromises in the name of compatibility. It works for - us, but it may not work for you. - - As a Cocoapods pod, it has the advantage over OpenSSL's pods that the library doesn't need to - be precompiled. This eliminates the 10 - 20 minutes of wait the first time a user does "pod - install", lets it be used as a dynamic framework (pending solution of Cocoapods' issue #4605), - and works with bitcode automatically. It's also thought to be smaller than OpenSSL (which takes - 1MB - 2MB per ARM architecture), but we don't have specific numbers yet. - - BoringSSL arose because Google used OpenSSL for many years in various ways and, over time, built - up a large number of patches that were maintained while tracking upstream OpenSSL. As Google’s - product portfolio became more complex, more copies of OpenSSL sprung up and the effort involved - in maintaining all these patches in multiple places was growing steadily. - - Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it’s not part of the - NDK) and a number of other apps/programs. - DESC - s.homepage = 'https://github.com/google/boringssl' - s.license = { :type => 'Mixed', :file => 'LICENSE' } - # "The name and email addresses of the library maintainers, not the Podspec maintainer." - s.authors = 'Adam Langley', 'David Benjamin', 'Matt Braithwaite' - - s.source = { - :git => 'https://github.com/google/boringssl.git', - :commit => "b29b21a81b32ec273f118f589f46d56ad3332420", - } - - s.ios.deployment_target = '5.0' - s.osx.deployment_target = '10.7' - - name = 'openssl' - - # When creating a dynamic framework, name it openssl.framework instead of BoringSSL.framework. - # This lets users write their includes like `#include ` as opposed to `#include - # `. - s.module_name = name - - # When creating a dynamic framework, copy the headers under `include/openssl/` into the root of - # the `Headers/` directory of the framework (i.e., not under `Headers/include/openssl`). - # - # TODO(jcanizales): Debug why this doesn't work on macOS. - s.header_mappings_dir = 'include/openssl' - - # The above has an undesired effect when creating a static library: It forces users to write - # includes like `#include `. `s.header_dir` adds a path prefix to that, and - # because Cocoapods lets omit the pod name when including headers of static libraries, the - # following lets users write `#include `. - s.header_dir = name - - # The module map and umbrella header created automatically by Cocoapods don't work for C libraries - # like this one. The following file, and a correct umbrella header, are created on the fly by the - # `prepare_command` of this pod. - s.module_map = 'include/openssl/BoringSSL.modulemap' - - # We don't need to inhibit all warnings; only -Wno-shorten-64-to-32. But Cocoapods' linter doesn't - # want that for some reason. - s.compiler_flags = '-DOPENSSL_NO_ASM', '-GCC_WARN_INHIBIT_ALL_WARNINGS', '-w' - s.requires_arc = false - - # Like many other C libraries, BoringSSL has its public headers under `include//` and its - # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't - # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in - # practice). Because we need our `header_mappings_dir` to be `include/openssl/` for the reason - # mentioned above, we work around the linter limitation by dividing the pod into two subspecs, one - # for public headers and the other for implementation. Each gets its own `header_mappings_dir`, - # making the linter happy. - s.subspec 'Interface' do |ss| - ss.header_mappings_dir = 'include/openssl' - ss.source_files = 'include/openssl/*.h' - end - s.subspec 'Implementation' do |ss| - ss.header_mappings_dir = '.' - ss.source_files = 'ssl/*.{h,cc}', - 'ssl/**/*.{h,cc}', - '*.{h,c}', - 'crypto/*.{h,c}', - 'crypto/**/*.{h,c}', - 'third_party/fiat/*.{h,c}' - ss.private_header_files = 'ssl/*.h', - 'ssl/**/*.h', - '*.h', - 'crypto/*.h', - 'crypto/**/*.h' - # bcm.c includes other source files, creating duplicated symbols. Since it is not used, we - # explicitly exclude it from the pod. - # TODO (mxyan): Work with BoringSSL team to remove this hack. - ss.exclude_files = 'crypto/fipsmodule/bcm.c', - '**/*_test.*', - '**/test_*.*', - '**/test/*.*' - - ss.dependency "#{s.name}/Interface", version - end - - s.prepare_command = <<-END_OF_COMMAND - # Add a module map and an umbrella header - cat > include/openssl/umbrella.h < include/openssl/BoringSSL.modulemap < err_data.c < - #include - #include - - - OPENSSL_COMPILE_ASSERT(ERR_LIB_NONE == 1, library_values_changed_1); - OPENSSL_COMPILE_ASSERT(ERR_LIB_SYS == 2, library_values_changed_2); - OPENSSL_COMPILE_ASSERT(ERR_LIB_BN == 3, library_values_changed_3); - OPENSSL_COMPILE_ASSERT(ERR_LIB_RSA == 4, library_values_changed_4); - OPENSSL_COMPILE_ASSERT(ERR_LIB_DH == 5, library_values_changed_5); - OPENSSL_COMPILE_ASSERT(ERR_LIB_EVP == 6, library_values_changed_6); - OPENSSL_COMPILE_ASSERT(ERR_LIB_BUF == 7, library_values_changed_7); - OPENSSL_COMPILE_ASSERT(ERR_LIB_OBJ == 8, library_values_changed_8); - OPENSSL_COMPILE_ASSERT(ERR_LIB_PEM == 9, library_values_changed_9); - OPENSSL_COMPILE_ASSERT(ERR_LIB_DSA == 10, library_values_changed_10); - OPENSSL_COMPILE_ASSERT(ERR_LIB_X509 == 11, library_values_changed_11); - OPENSSL_COMPILE_ASSERT(ERR_LIB_ASN1 == 12, library_values_changed_12); - OPENSSL_COMPILE_ASSERT(ERR_LIB_CONF == 13, library_values_changed_13); - OPENSSL_COMPILE_ASSERT(ERR_LIB_CRYPTO == 14, library_values_changed_14); - OPENSSL_COMPILE_ASSERT(ERR_LIB_EC == 15, library_values_changed_15); - OPENSSL_COMPILE_ASSERT(ERR_LIB_SSL == 16, library_values_changed_16); - OPENSSL_COMPILE_ASSERT(ERR_LIB_BIO == 17, library_values_changed_17); - OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS7 == 18, library_values_changed_18); - OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS8 == 19, library_values_changed_19); - OPENSSL_COMPILE_ASSERT(ERR_LIB_X509V3 == 20, library_values_changed_20); - OPENSSL_COMPILE_ASSERT(ERR_LIB_RAND == 21, library_values_changed_21); - OPENSSL_COMPILE_ASSERT(ERR_LIB_ENGINE == 22, library_values_changed_22); - OPENSSL_COMPILE_ASSERT(ERR_LIB_OCSP == 23, library_values_changed_23); - OPENSSL_COMPILE_ASSERT(ERR_LIB_UI == 24, library_values_changed_24); - OPENSSL_COMPILE_ASSERT(ERR_LIB_COMP == 25, library_values_changed_25); - OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDSA == 26, library_values_changed_26); - OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDH == 27, library_values_changed_27); - OPENSSL_COMPILE_ASSERT(ERR_LIB_HMAC == 28, library_values_changed_28); - OPENSSL_COMPILE_ASSERT(ERR_LIB_DIGEST == 29, library_values_changed_29); - OPENSSL_COMPILE_ASSERT(ERR_LIB_CIPHER == 30, library_values_changed_30); - OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 31, library_values_changed_31); - OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32); - OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num); - - const uint32_t kOpenSSLReasonValues[] = { - 0xc320838, - 0xc328852, - 0xc330861, - 0xc338871, - 0xc340880, - 0xc348899, - 0xc3508a5, - 0xc3588c2, - 0xc3608e2, - 0xc3688f0, - 0xc370900, - 0xc37890d, - 0xc38091d, - 0xc388928, - 0xc39093e, - 0xc39894d, - 0xc3a0961, - 0xc3a8845, - 0xc3b00ea, - 0xc3b88d4, - 0x10320845, - 0x10329513, - 0x1033151f, - 0x10339538, - 0x1034154b, - 0x10348eed, - 0x10350c5e, - 0x1035955e, - 0x10361573, - 0x10369586, - 0x103715a5, - 0x103795be, - 0x103815d3, - 0x103895f1, - 0x10391600, - 0x1039961c, - 0x103a1637, - 0x103a9646, - 0x103b1662, - 0x103b967d, - 0x103c1694, - 0x103c80ea, - 0x103d16a5, - 0x103d96b9, - 0x103e16d8, - 0x103e96e7, - 0x103f16fe, - 0x103f9711, - 0x10400c22, - 0x10409724, - 0x10411742, - 0x10419755, - 0x1042176f, - 0x1042977f, - 0x10431793, - 0x104397a9, - 0x104417c1, - 0x104497d6, - 0x104517ea, - 0x104597fc, - 0x104605fb, - 0x1046894d, - 0x10471811, - 0x10479828, - 0x1048183d, - 0x1048984b, - 0x10490e4f, - 0x14320c05, - 0x14328c13, - 0x14330c22, - 0x14338c34, - 0x143400ac, - 0x143480ea, - 0x18320083, - 0x18328f43, - 0x183300ac, - 0x18338f59, - 0x18340f6d, - 0x183480ea, - 0x18350f82, - 0x18358f9a, - 0x18360faf, - 0x18368fc3, - 0x18370fe7, - 0x18378ffd, - 0x18381011, - 0x18389021, - 0x18390a73, - 0x18399031, - 0x183a1059, - 0x183a907f, - 0x183b0c6a, - 0x183b90b4, - 0x183c10c6, - 0x183c90d1, - 0x183d10e1, - 0x183d90f2, - 0x183e1103, - 0x183e9115, - 0x183f113e, - 0x183f9157, - 0x1840116f, - 0x184086d3, - 0x184110a2, - 0x1841906d, - 0x1842108c, - 0x18429046, - 0x20321196, - 0x243211a2, - 0x24328993, - 0x243311b4, - 0x243391c1, - 0x243411ce, - 0x243491e0, - 0x243511ef, - 0x2435920c, - 0x24361219, - 0x24369227, - 0x24371235, - 0x24379243, - 0x2438124c, - 0x24389259, - 0x2439126c, - 0x28320c52, - 0x28328c6a, - 0x28330c22, - 0x28338c7d, - 0x28340c5e, - 0x283480ac, - 0x283500ea, - 0x2c322c30, - 0x2c329283, - 0x2c332c3e, - 0x2c33ac50, - 0x2c342c64, - 0x2c34ac76, - 0x2c352c91, - 0x2c35aca3, - 0x2c362cb6, - 0x2c36832d, - 0x2c372cc3, - 0x2c37acd5, - 0x2c382cfa, - 0x2c38ad11, - 0x2c392d1f, - 0x2c39ad2f, - 0x2c3a2d41, - 0x2c3aad55, - 0x2c3b2d66, - 0x2c3bad85, - 0x2c3c1295, - 0x2c3c92ab, - 0x2c3d2d99, - 0x2c3d92c4, - 0x2c3e2db6, - 0x2c3eadc4, - 0x2c3f2ddc, - 0x2c3fadf4, - 0x2c402e01, - 0x2c409196, - 0x2c412e12, - 0x2c41ae25, - 0x2c42116f, - 0x2c42ae36, - 0x2c430720, - 0x2c43ad77, - 0x2c442ce8, - 0x30320000, - 0x30328015, - 0x3033001f, - 0x30338038, - 0x3034004a, - 0x30348064, - 0x3035006b, - 0x30358083, - 0x30360094, - 0x303680ac, - 0x303700b9, - 0x303780c8, - 0x303800ea, - 0x303880f7, - 0x3039010a, - 0x30398125, - 0x303a013a, - 0x303a814e, - 0x303b0162, - 0x303b8173, - 0x303c018c, - 0x303c81a9, - 0x303d01b7, - 0x303d81cb, - 0x303e01db, - 0x303e81f4, - 0x303f0204, - 0x303f8217, - 0x30400226, - 0x30408232, - 0x30410247, - 0x30418257, - 0x3042026e, - 0x3042827b, - 0x3043028e, - 0x3043829d, - 0x304402b2, - 0x304482d3, - 0x304502e6, - 0x304582f9, - 0x30460312, - 0x3046832d, - 0x3047034a, - 0x30478363, - 0x30480371, - 0x30488382, - 0x30490391, - 0x304983a9, - 0x304a03bb, - 0x304a83cf, - 0x304b03ee, - 0x304b8401, - 0x304c040c, - 0x304c841d, - 0x304d0429, - 0x304d843f, - 0x304e044d, - 0x304e8463, - 0x304f0475, - 0x304f8487, - 0x3050049a, - 0x305084ad, - 0x305104be, - 0x305184ce, - 0x305204e6, - 0x305284fb, - 0x30530513, - 0x30538527, - 0x3054053f, - 0x30548558, - 0x30550571, - 0x3055858e, - 0x30560599, - 0x305685b1, - 0x305705c1, - 0x305785d2, - 0x305805e5, - 0x305885fb, - 0x30590604, - 0x30598619, - 0x305a062c, - 0x305a863b, - 0x305b065b, - 0x305b866a, - 0x305c068b, - 0x305c86a7, - 0x305d06b3, - 0x305d86d3, - 0x305e06ef, - 0x305e8700, - 0x305f0716, - 0x305f8720, - 0x34320b63, - 0x34328b77, - 0x34330b94, - 0x34338ba7, - 0x34340bb6, - 0x34348bef, - 0x34350bd3, - 0x3c320083, - 0x3c328ca7, - 0x3c330cc0, - 0x3c338cdb, - 0x3c340cf8, - 0x3c348d22, - 0x3c350d3d, - 0x3c358d63, - 0x3c360d7c, - 0x3c368d94, - 0x3c370da5, - 0x3c378db3, - 0x3c380dc0, - 0x3c388dd4, - 0x3c390c6a, - 0x3c398de8, - 0x3c3a0dfc, - 0x3c3a890d, - 0x3c3b0e0c, - 0x3c3b8e27, - 0x3c3c0e39, - 0x3c3c8e6c, - 0x3c3d0e76, - 0x3c3d8e8a, - 0x3c3e0e98, - 0x3c3e8ebd, - 0x3c3f0c93, - 0x3c3f8ea6, - 0x3c4000ac, - 0x3c4080ea, - 0x3c410d13, - 0x3c418d52, - 0x3c420e4f, - 0x403218a4, - 0x403298ba, - 0x403318e8, - 0x403398f2, - 0x40341909, - 0x40349927, - 0x40351937, - 0x40359949, - 0x40361956, - 0x40369962, - 0x40371977, - 0x40379989, - 0x40381994, - 0x403899a6, - 0x40390eed, - 0x403999b6, - 0x403a19c9, - 0x403a99ea, - 0x403b19fb, - 0x403b9a0b, - 0x403c0064, - 0x403c8083, - 0x403d1a8f, - 0x403d9aa5, - 0x403e1ab4, - 0x403e9aec, - 0x403f1b06, - 0x403f9b14, - 0x40401b29, - 0x40409b3d, - 0x40411b5a, - 0x40419b75, - 0x40421b8e, - 0x40429ba1, - 0x40431bb5, - 0x40439bcd, - 0x40441be4, - 0x404480ac, - 0x40451bf9, - 0x40459c0b, - 0x40461c2f, - 0x40469c4f, - 0x40471c5d, - 0x40479c84, - 0x40481cc1, - 0x40489cda, - 0x40491cf1, - 0x40499d0b, - 0x404a1d22, - 0x404a9d40, - 0x404b1d58, - 0x404b9d6f, - 0x404c1d85, - 0x404c9d97, - 0x404d1db8, - 0x404d9dda, - 0x404e1dee, - 0x404e9dfb, - 0x404f1e28, - 0x404f9e51, - 0x40501e8c, - 0x40509ea0, - 0x40511ebb, - 0x40521ecb, - 0x40529eef, - 0x40531f07, - 0x40539f1a, - 0x40541f2f, - 0x40549f52, - 0x40551f60, - 0x40559f7d, - 0x40561f8a, - 0x40569fa3, - 0x40571fbb, - 0x40579fce, - 0x40581fe3, - 0x4058a00a, - 0x40592039, - 0x4059a066, - 0x405a207a, - 0x405aa08a, - 0x405b20a2, - 0x405ba0b3, - 0x405c20c6, - 0x405ca105, - 0x405d2112, - 0x405da129, - 0x405e2167, - 0x405e8ab1, - 0x405f2188, - 0x405fa195, - 0x406021a3, - 0x4060a1c5, - 0x40612209, - 0x4061a241, - 0x40622258, - 0x4062a269, - 0x4063227a, - 0x4063a28f, - 0x406422a6, - 0x4064a2d2, - 0x406522ed, - 0x4065a304, - 0x4066231c, - 0x4066a346, - 0x40672371, - 0x4067a392, - 0x406823b9, - 0x4068a3da, - 0x4069240c, - 0x4069a43a, - 0x406a245b, - 0x406aa47b, - 0x406b2603, - 0x406ba626, - 0x406c263c, - 0x406ca8b7, - 0x406d28e6, - 0x406da90e, - 0x406e293c, - 0x406ea989, - 0x406f29a8, - 0x406fa9e0, - 0x407029f3, - 0x4070aa10, - 0x40710800, - 0x4071aa22, - 0x40722a35, - 0x4072aa4e, - 0x40732a66, - 0x40739482, - 0x40742a7a, - 0x4074aa94, - 0x40752aa5, - 0x4075aab9, - 0x40762ac7, - 0x40769259, - 0x40772aec, - 0x4077ab0e, - 0x40782b29, - 0x4078ab62, - 0x40792b79, - 0x4079ab8f, - 0x407a2b9b, - 0x407aabae, - 0x407b2bc3, - 0x407babd5, - 0x407c2c06, - 0x407cac0f, - 0x407d23f5, - 0x407d9e61, - 0x407e2b3e, - 0x407ea01a, - 0x407f1c71, - 0x407f9a31, - 0x40801e38, - 0x40809c99, - 0x40811edd, - 0x40819e12, - 0x40822927, - 0x40829a17, - 0x40831ff5, - 0x4083a2b7, - 0x40841cad, - 0x4084a052, - 0x408520d7, - 0x4085a1ed, - 0x40862149, - 0x40869e7b, - 0x4087296d, - 0x4087a21e, - 0x40881a78, - 0x4088a3a5, - 0x40891ac7, - 0x40899a54, - 0x408a265c, - 0x408a9862, - 0x408b2bea, - 0x408ba9bd, - 0x408c20e7, - 0x408c987e, - 0x41f4252e, - 0x41f925c0, - 0x41fe24b3, - 0x41fea6a8, - 0x41ff2799, - 0x42032547, - 0x42082569, - 0x4208a5a5, - 0x42092497, - 0x4209a5df, - 0x420a24ee, - 0x420aa4ce, - 0x420b250e, - 0x420ba587, - 0x420c27b5, - 0x420ca675, - 0x420d268f, - 0x420da6c6, - 0x421226e0, - 0x4217277c, - 0x4217a722, - 0x421c2744, - 0x421f26ff, - 0x422127cc, - 0x4226275f, - 0x422b289b, - 0x422ba849, - 0x422c2883, - 0x422ca808, - 0x422d27e7, - 0x422da868, - 0x422e282e, - 0x422ea954, - 0x4432072b, - 0x4432873a, - 0x44330746, - 0x44338754, - 0x44340767, - 0x44348778, - 0x4435077f, - 0x44358789, - 0x4436079c, - 0x443687b2, - 0x443707c4, - 0x443787d1, - 0x443807e0, - 0x443887e8, - 0x44390800, - 0x4439880e, - 0x443a0821, - 0x48321283, - 0x48329295, - 0x483312ab, - 0x483392c4, - 0x4c3212e9, - 0x4c3292f9, - 0x4c33130c, - 0x4c33932c, - 0x4c3400ac, - 0x4c3480ea, - 0x4c351338, - 0x4c359346, - 0x4c361362, - 0x4c369375, - 0x4c371384, - 0x4c379392, - 0x4c3813a7, - 0x4c3893b3, - 0x4c3913d3, - 0x4c3993fd, - 0x4c3a1416, - 0x4c3a942f, - 0x4c3b05fb, - 0x4c3b9448, - 0x4c3c145a, - 0x4c3c9469, - 0x4c3d1482, - 0x4c3d8c45, - 0x4c3e14db, - 0x4c3e9491, - 0x4c3f14fd, - 0x4c3f9259, - 0x4c4014a7, - 0x4c4092d5, - 0x4c4114cb, - 0x50322e48, - 0x5032ae57, - 0x50332e62, - 0x5033ae72, - 0x50342e8b, - 0x5034aea5, - 0x50352eb3, - 0x5035aec9, - 0x50362edb, - 0x5036aef1, - 0x50372f0a, - 0x5037af1d, - 0x50382f35, - 0x5038af46, - 0x50392f5b, - 0x5039af6f, - 0x503a2f8f, - 0x503aafa5, - 0x503b2fbd, - 0x503bafcf, - 0x503c2feb, - 0x503cb002, - 0x503d301b, - 0x503db031, - 0x503e303e, - 0x503eb054, - 0x503f3066, - 0x503f8382, - 0x50403079, - 0x5040b089, - 0x504130a3, - 0x5041b0b2, - 0x504230cc, - 0x5042b0e9, - 0x504330f9, - 0x5043b109, - 0x50443118, - 0x5044843f, - 0x5045312c, - 0x5045b14a, - 0x5046315d, - 0x5046b173, - 0x50473185, - 0x5047b19a, - 0x504831c0, - 0x5048b1ce, - 0x504931e1, - 0x5049b1f6, - 0x504a320c, - 0x504ab21c, - 0x504b323c, - 0x504bb24f, - 0x504c3272, - 0x504cb2a0, - 0x504d32b2, - 0x504db2cf, - 0x504e32ea, - 0x504eb306, - 0x504f3318, - 0x504fb32f, - 0x5050333e, - 0x505086ef, - 0x50513351, - 0x58320f2b, - 0x68320eed, - 0x68328c6a, - 0x68330c7d, - 0x68338efb, - 0x68340f0b, - 0x683480ea, - 0x6c320ec9, - 0x6c328c34, - 0x6c330ed4, - 0x74320a19, - 0x743280ac, - 0x74330c45, - 0x7832097e, - 0x78328993, - 0x7833099f, - 0x78338083, - 0x783409ae, - 0x783489c3, - 0x783509e2, - 0x78358a04, - 0x78360a19, - 0x78368a2f, - 0x78370a3f, - 0x78378a60, - 0x78380a73, - 0x78388a85, - 0x78390a92, - 0x78398ab1, - 0x783a0ac6, - 0x783a8ad4, - 0x783b0ade, - 0x783b8af2, - 0x783c0b09, - 0x783c8b1e, - 0x783d0b35, - 0x783d8b4a, - 0x783e0aa0, - 0x783e8a52, - 0x7c321185, - }; - - const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); - - const char kOpenSSLReasonStringData[] = - "ASN1_LENGTH_MISMATCH\\0" - "AUX_ERROR\\0" - "BAD_GET_ASN1_OBJECT_CALL\\0" - "BAD_OBJECT_HEADER\\0" - "BMPSTRING_IS_WRONG_LENGTH\\0" - "BN_LIB\\0" - "BOOLEAN_IS_WRONG_LENGTH\\0" - "BUFFER_TOO_SMALL\\0" - "CONTEXT_NOT_INITIALISED\\0" - "DECODE_ERROR\\0" - "DEPTH_EXCEEDED\\0" - "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\\0" - "ENCODE_ERROR\\0" - "ERROR_GETTING_TIME\\0" - "EXPECTING_AN_ASN1_SEQUENCE\\0" - "EXPECTING_AN_INTEGER\\0" - "EXPECTING_AN_OBJECT\\0" - "EXPECTING_A_BOOLEAN\\0" - "EXPECTING_A_TIME\\0" - "EXPLICIT_LENGTH_MISMATCH\\0" - "EXPLICIT_TAG_NOT_CONSTRUCTED\\0" - "FIELD_MISSING\\0" - "FIRST_NUM_TOO_LARGE\\0" - "HEADER_TOO_LONG\\0" - "ILLEGAL_BITSTRING_FORMAT\\0" - "ILLEGAL_BOOLEAN\\0" - "ILLEGAL_CHARACTERS\\0" - "ILLEGAL_FORMAT\\0" - "ILLEGAL_HEX\\0" - "ILLEGAL_IMPLICIT_TAG\\0" - "ILLEGAL_INTEGER\\0" - "ILLEGAL_NESTED_TAGGING\\0" - "ILLEGAL_NULL\\0" - "ILLEGAL_NULL_VALUE\\0" - "ILLEGAL_OBJECT\\0" - "ILLEGAL_OPTIONAL_ANY\\0" - "ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE\\0" - "ILLEGAL_TAGGED_ANY\\0" - "ILLEGAL_TIME_VALUE\\0" - "INTEGER_NOT_ASCII_FORMAT\\0" - "INTEGER_TOO_LARGE_FOR_LONG\\0" - "INVALID_BIT_STRING_BITS_LEFT\\0" - "INVALID_BMPSTRING_LENGTH\\0" - "INVALID_DIGIT\\0" - "INVALID_MODIFIER\\0" - "INVALID_NUMBER\\0" - "INVALID_OBJECT_ENCODING\\0" - "INVALID_SEPARATOR\\0" - "INVALID_TIME_FORMAT\\0" - "INVALID_UNIVERSALSTRING_LENGTH\\0" - "INVALID_UTF8STRING\\0" - "LIST_ERROR\\0" - "MISSING_ASN1_EOS\\0" - "MISSING_EOC\\0" - "MISSING_SECOND_NUMBER\\0" - "MISSING_VALUE\\0" - "MSTRING_NOT_UNIVERSAL\\0" - "MSTRING_WRONG_TAG\\0" - "NESTED_ASN1_ERROR\\0" - "NESTED_ASN1_STRING\\0" - "NON_HEX_CHARACTERS\\0" - "NOT_ASCII_FORMAT\\0" - "NOT_ENOUGH_DATA\\0" - "NO_MATCHING_CHOICE_TYPE\\0" - "NULL_IS_WRONG_LENGTH\\0" - "OBJECT_NOT_ASCII_FORMAT\\0" - "ODD_NUMBER_OF_CHARS\\0" - "SECOND_NUMBER_TOO_LARGE\\0" - "SEQUENCE_LENGTH_MISMATCH\\0" - "SEQUENCE_NOT_CONSTRUCTED\\0" - "SEQUENCE_OR_SET_NEEDS_CONFIG\\0" - "SHORT_LINE\\0" - "STREAMING_NOT_SUPPORTED\\0" - "STRING_TOO_LONG\\0" - "STRING_TOO_SHORT\\0" - "TAG_VALUE_TOO_HIGH\\0" - "TIME_NOT_ASCII_FORMAT\\0" - "TOO_LONG\\0" - "TYPE_NOT_CONSTRUCTED\\0" - "TYPE_NOT_PRIMITIVE\\0" - "UNEXPECTED_EOC\\0" - "UNIVERSALSTRING_IS_WRONG_LENGTH\\0" - "UNKNOWN_FORMAT\\0" - "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\\0" - "UNKNOWN_SIGNATURE_ALGORITHM\\0" - "UNKNOWN_TAG\\0" - "UNSUPPORTED_ANY_DEFINED_BY_TYPE\\0" - "UNSUPPORTED_PUBLIC_KEY_TYPE\\0" - "UNSUPPORTED_TYPE\\0" - "WRONG_PUBLIC_KEY_TYPE\\0" - "WRONG_TAG\\0" - "WRONG_TYPE\\0" - "BAD_FOPEN_MODE\\0" - "BROKEN_PIPE\\0" - "CONNECT_ERROR\\0" - "ERROR_SETTING_NBIO\\0" - "INVALID_ARGUMENT\\0" - "IN_USE\\0" - "KEEPALIVE\\0" - "NBIO_CONNECT_ERROR\\0" - "NO_HOSTNAME_SPECIFIED\\0" - "NO_PORT_SPECIFIED\\0" - "NO_SUCH_FILE\\0" - "NULL_PARAMETER\\0" - "SYS_LIB\\0" - "UNABLE_TO_CREATE_SOCKET\\0" - "UNINITIALIZED\\0" - "UNSUPPORTED_METHOD\\0" - "WRITE_TO_READ_ONLY_BIO\\0" - "ARG2_LT_ARG3\\0" - "BAD_ENCODING\\0" - "BAD_RECIPROCAL\\0" - "BIGNUM_TOO_LONG\\0" - "BITS_TOO_SMALL\\0" - "CALLED_WITH_EVEN_MODULUS\\0" - "DIV_BY_ZERO\\0" - "EXPAND_ON_STATIC_BIGNUM_DATA\\0" - "INPUT_NOT_REDUCED\\0" - "INVALID_INPUT\\0" - "INVALID_RANGE\\0" - "NEGATIVE_NUMBER\\0" - "NOT_A_SQUARE\\0" - "NOT_INITIALIZED\\0" - "NO_INVERSE\\0" - "PRIVATE_KEY_TOO_LARGE\\0" - "P_IS_NOT_PRIME\\0" - "TOO_MANY_ITERATIONS\\0" - "TOO_MANY_TEMPORARY_VARIABLES\\0" - "AES_KEY_SETUP_FAILED\\0" - "BAD_DECRYPT\\0" - "BAD_KEY_LENGTH\\0" - "CTRL_NOT_IMPLEMENTED\\0" - "CTRL_OPERATION_NOT_IMPLEMENTED\\0" - "DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH\\0" - "INITIALIZATION_ERROR\\0" - "INPUT_NOT_INITIALIZED\\0" - "INVALID_AD_SIZE\\0" - "INVALID_KEY_LENGTH\\0" - "INVALID_NONCE\\0" - "INVALID_NONCE_SIZE\\0" - "INVALID_OPERATION\\0" - "IV_TOO_LARGE\\0" - "NO_CIPHER_SET\\0" - "NO_DIRECTION_SET\\0" - "OUTPUT_ALIASES_INPUT\\0" - "TAG_TOO_LARGE\\0" - "TOO_LARGE\\0" - "UNSUPPORTED_AD_SIZE\\0" - "UNSUPPORTED_INPUT_SIZE\\0" - "UNSUPPORTED_KEY_SIZE\\0" - "UNSUPPORTED_NONCE_SIZE\\0" - "UNSUPPORTED_TAG_SIZE\\0" - "WRONG_FINAL_BLOCK_LENGTH\\0" - "LIST_CANNOT_BE_NULL\\0" - "MISSING_CLOSE_SQUARE_BRACKET\\0" - "MISSING_EQUAL_SIGN\\0" - "NO_CLOSE_BRACE\\0" - "UNABLE_TO_CREATE_NEW_SECTION\\0" - "VARIABLE_EXPANSION_TOO_LONG\\0" - "VARIABLE_HAS_NO_VALUE\\0" - "BAD_GENERATOR\\0" - "INVALID_PUBKEY\\0" - "MODULUS_TOO_LARGE\\0" - "NO_PRIVATE_VALUE\\0" - "UNKNOWN_HASH\\0" - "BAD_Q_VALUE\\0" - "BAD_VERSION\\0" - "MISSING_PARAMETERS\\0" - "NEED_NEW_SETUP_VALUES\\0" - "BIGNUM_OUT_OF_RANGE\\0" - "COORDINATES_OUT_OF_RANGE\\0" - "D2I_ECPKPARAMETERS_FAILURE\\0" - "EC_GROUP_NEW_BY_NAME_FAILURE\\0" - "GROUP2PKPARAMETERS_FAILURE\\0" - "GROUP_MISMATCH\\0" - "I2D_ECPKPARAMETERS_FAILURE\\0" - "INCOMPATIBLE_OBJECTS\\0" - "INVALID_COFACTOR\\0" - "INVALID_COMPRESSED_POINT\\0" - "INVALID_COMPRESSION_BIT\\0" - "INVALID_ENCODING\\0" - "INVALID_FIELD\\0" - "INVALID_FORM\\0" - "INVALID_GROUP_ORDER\\0" - "INVALID_PRIVATE_KEY\\0" - "MISSING_PRIVATE_KEY\\0" - "NON_NAMED_CURVE\\0" - "PKPARAMETERS2GROUP_FAILURE\\0" - "POINT_AT_INFINITY\\0" - "POINT_IS_NOT_ON_CURVE\\0" - "PUBLIC_KEY_VALIDATION_FAILED\\0" - "SLOT_FULL\\0" - "UNDEFINED_GENERATOR\\0" - "UNKNOWN_GROUP\\0" - "UNKNOWN_ORDER\\0" - "WRONG_CURVE_PARAMETERS\\0" - "WRONG_ORDER\\0" - "KDF_FAILED\\0" - "POINT_ARITHMETIC_FAILURE\\0" - "BAD_SIGNATURE\\0" - "NOT_IMPLEMENTED\\0" - "RANDOM_NUMBER_GENERATION_FAILED\\0" - "OPERATION_NOT_SUPPORTED\\0" - "COMMAND_NOT_SUPPORTED\\0" - "DIFFERENT_KEY_TYPES\\0" - "DIFFERENT_PARAMETERS\\0" - "EXPECTING_AN_EC_KEY_KEY\\0" - "EXPECTING_AN_RSA_KEY\\0" - "EXPECTING_A_DSA_KEY\\0" - "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\\0" - "INVALID_DIGEST_LENGTH\\0" - "INVALID_DIGEST_TYPE\\0" - "INVALID_KEYBITS\\0" - "INVALID_MGF1_MD\\0" - "INVALID_PADDING_MODE\\0" - "INVALID_PARAMETERS\\0" - "INVALID_PSS_SALTLEN\\0" - "INVALID_SIGNATURE\\0" - "KEYS_NOT_SET\\0" - "MEMORY_LIMIT_EXCEEDED\\0" - "NOT_A_PRIVATE_KEY\\0" - "NO_DEFAULT_DIGEST\\0" - "NO_KEY_SET\\0" - "NO_MDC2_SUPPORT\\0" - "NO_NID_FOR_CURVE\\0" - "NO_OPERATION_SET\\0" - "NO_PARAMETERS_SET\\0" - "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\\0" - "OPERATON_NOT_INITIALIZED\\0" - "UNKNOWN_PUBLIC_KEY_TYPE\\0" - "UNSUPPORTED_ALGORITHM\\0" - "OUTPUT_TOO_LARGE\\0" - "UNKNOWN_NID\\0" - "BAD_BASE64_DECODE\\0" - "BAD_END_LINE\\0" - "BAD_IV_CHARS\\0" - "BAD_PASSWORD_READ\\0" - "CIPHER_IS_NULL\\0" - "ERROR_CONVERTING_PRIVATE_KEY\\0" - "NOT_DEK_INFO\\0" - "NOT_ENCRYPTED\\0" - "NOT_PROC_TYPE\\0" - "NO_START_LINE\\0" - "READ_KEY\\0" - "SHORT_HEADER\\0" - "UNSUPPORTED_CIPHER\\0" - "UNSUPPORTED_ENCRYPTION\\0" - "BAD_PKCS7_VERSION\\0" - "NOT_PKCS7_SIGNED_DATA\\0" - "NO_CERTIFICATES_INCLUDED\\0" - "NO_CRLS_INCLUDED\\0" - "BAD_ITERATION_COUNT\\0" - "BAD_PKCS12_DATA\\0" - "BAD_PKCS12_VERSION\\0" - "CIPHER_HAS_NO_OBJECT_IDENTIFIER\\0" - "CRYPT_ERROR\\0" - "ENCRYPT_ERROR\\0" - "ERROR_SETTING_CIPHER_PARAMS\\0" - "INCORRECT_PASSWORD\\0" - "KEYGEN_FAILURE\\0" - "KEY_GEN_ERROR\\0" - "METHOD_NOT_SUPPORTED\\0" - "MISSING_MAC\\0" - "MULTIPLE_PRIVATE_KEYS_IN_PKCS12\\0" - "PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED\\0" - "PKCS12_TOO_DEEPLY_NESTED\\0" - "PRIVATE_KEY_DECODE_ERROR\\0" - "PRIVATE_KEY_ENCODE_ERROR\\0" - "UNKNOWN_ALGORITHM\\0" - "UNKNOWN_CIPHER\\0" - "UNKNOWN_CIPHER_ALGORITHM\\0" - "UNKNOWN_DIGEST\\0" - "UNSUPPORTED_KEYLENGTH\\0" - "UNSUPPORTED_KEY_DERIVATION_FUNCTION\\0" - "UNSUPPORTED_PRF\\0" - "UNSUPPORTED_PRIVATE_KEY_ALGORITHM\\0" - "UNSUPPORTED_SALT_TYPE\\0" - "BAD_E_VALUE\\0" - "BAD_FIXED_HEADER_DECRYPT\\0" - "BAD_PAD_BYTE_COUNT\\0" - "BAD_RSA_PARAMETERS\\0" - "BLOCK_TYPE_IS_NOT_01\\0" - "BN_NOT_INITIALIZED\\0" - "CANNOT_RECOVER_MULTI_PRIME_KEY\\0" - "CRT_PARAMS_ALREADY_GIVEN\\0" - "CRT_VALUES_INCORRECT\\0" - "DATA_LEN_NOT_EQUAL_TO_MOD_LEN\\0" - "DATA_TOO_LARGE\\0" - "DATA_TOO_LARGE_FOR_KEY_SIZE\\0" - "DATA_TOO_LARGE_FOR_MODULUS\\0" - "DATA_TOO_SMALL\\0" - "DATA_TOO_SMALL_FOR_KEY_SIZE\\0" - "DIGEST_TOO_BIG_FOR_RSA_KEY\\0" - "D_E_NOT_CONGRUENT_TO_1\\0" - "EMPTY_PUBLIC_KEY\\0" - "FIRST_OCTET_INVALID\\0" - "INCONSISTENT_SET_OF_CRT_VALUES\\0" - "INTERNAL_ERROR\\0" - "INVALID_MESSAGE_LENGTH\\0" - "KEY_SIZE_TOO_SMALL\\0" - "LAST_OCTET_INVALID\\0" - "MUST_HAVE_AT_LEAST_TWO_PRIMES\\0" - "NO_PUBLIC_EXPONENT\\0" - "NULL_BEFORE_BLOCK_MISSING\\0" - "N_NOT_EQUAL_P_Q\\0" - "OAEP_DECODING_ERROR\\0" - "ONLY_ONE_OF_P_Q_GIVEN\\0" - "OUTPUT_BUFFER_TOO_SMALL\\0" - "PADDING_CHECK_FAILED\\0" - "PKCS_DECODING_ERROR\\0" - "SLEN_CHECK_FAILED\\0" - "SLEN_RECOVERY_FAILED\\0" - "UNKNOWN_ALGORITHM_TYPE\\0" - "UNKNOWN_PADDING_TYPE\\0" - "VALUE_MISSING\\0" - "WRONG_SIGNATURE_LENGTH\\0" - "ALPN_MISMATCH_ON_EARLY_DATA\\0" - "APPLICATION_DATA_INSTEAD_OF_HANDSHAKE\\0" - "APP_DATA_IN_HANDSHAKE\\0" - "ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT\\0" - "BAD_ALERT\\0" - "BAD_CHANGE_CIPHER_SPEC\\0" - "BAD_DATA_RETURNED_BY_CALLBACK\\0" - "BAD_DH_P_LENGTH\\0" - "BAD_DIGEST_LENGTH\\0" - "BAD_ECC_CERT\\0" - "BAD_ECPOINT\\0" - "BAD_HANDSHAKE_RECORD\\0" - "BAD_HELLO_REQUEST\\0" - "BAD_LENGTH\\0" - "BAD_PACKET_LENGTH\\0" - "BAD_RSA_ENCRYPT\\0" - "BAD_SRTP_MKI_VALUE\\0" - "BAD_SRTP_PROTECTION_PROFILE_LIST\\0" - "BAD_SSL_FILETYPE\\0" - "BAD_WRITE_RETRY\\0" - "BIO_NOT_SET\\0" - "BLOCK_CIPHER_PAD_IS_WRONG\\0" - "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\\0" - "CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD\\0" - "CANNOT_PARSE_LEAF_CERT\\0" - "CA_DN_LENGTH_MISMATCH\\0" - "CA_DN_TOO_LONG\\0" - "CCS_RECEIVED_EARLY\\0" - "CERTIFICATE_AND_PRIVATE_KEY_MISMATCH\\0" - "CERTIFICATE_VERIFY_FAILED\\0" - "CERT_CB_ERROR\\0" - "CERT_LENGTH_MISMATCH\\0" - "CHANNEL_ID_NOT_P256\\0" - "CHANNEL_ID_SIGNATURE_INVALID\\0" - "CIPHER_OR_HASH_UNAVAILABLE\\0" - "CLIENTHELLO_PARSE_FAILED\\0" - "CLIENTHELLO_TLSEXT\\0" - "CONNECTION_REJECTED\\0" - "CONNECTION_TYPE_NOT_SET\\0" - "CUSTOM_EXTENSION_ERROR\\0" - "DATA_LENGTH_TOO_LONG\\0" - "DECRYPTION_FAILED\\0" - "DECRYPTION_FAILED_OR_BAD_RECORD_MAC\\0" - "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\\0" - "DH_P_TOO_LONG\\0" - "DIGEST_CHECK_FAILED\\0" - "DOWNGRADE_DETECTED\\0" - "DTLS_MESSAGE_TOO_BIG\\0" - "DUPLICATE_EXTENSION\\0" - "DUPLICATE_KEY_SHARE\\0" - "ECC_CERT_NOT_FOR_SIGNING\\0" - "EMS_STATE_INCONSISTENT\\0" - "ENCRYPTED_LENGTH_TOO_LONG\\0" - "ERROR_ADDING_EXTENSION\\0" - "ERROR_IN_RECEIVED_CIPHER_LIST\\0" - "ERROR_PARSING_EXTENSION\\0" - "EXCESSIVE_MESSAGE_SIZE\\0" - "EXTRA_DATA_IN_MESSAGE\\0" - "FRAGMENT_MISMATCH\\0" - "GOT_NEXT_PROTO_WITHOUT_EXTENSION\\0" - "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\\0" - "HTTPS_PROXY_REQUEST\\0" - "HTTP_REQUEST\\0" - "INAPPROPRIATE_FALLBACK\\0" - "INVALID_ALPN_PROTOCOL\\0" - "INVALID_COMMAND\\0" - "INVALID_COMPRESSION_LIST\\0" - "INVALID_MESSAGE\\0" - "INVALID_OUTER_RECORD_TYPE\\0" - "INVALID_SCT_LIST\\0" - "INVALID_SSL_SESSION\\0" - "INVALID_TICKET_KEYS_LENGTH\\0" - "LENGTH_MISMATCH\\0" - "MISSING_EXTENSION\\0" - "MISSING_KEY_SHARE\\0" - "MISSING_RSA_CERTIFICATE\\0" - "MISSING_TMP_DH_KEY\\0" - "MISSING_TMP_ECDH_KEY\\0" - "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\\0" - "MTU_TOO_SMALL\\0" - "NEGOTIATED_BOTH_NPN_AND_ALPN\\0" - "NESTED_GROUP\\0" - "NO_CERTIFICATES_RETURNED\\0" - "NO_CERTIFICATE_ASSIGNED\\0" - "NO_CERTIFICATE_SET\\0" - "NO_CIPHERS_AVAILABLE\\0" - "NO_CIPHERS_PASSED\\0" - "NO_CIPHERS_SPECIFIED\\0" - "NO_CIPHER_MATCH\\0" - "NO_COMMON_SIGNATURE_ALGORITHMS\\0" - "NO_COMPRESSION_SPECIFIED\\0" - "NO_GROUPS_SPECIFIED\\0" - "NO_METHOD_SPECIFIED\\0" - "NO_P256_SUPPORT\\0" - "NO_PRIVATE_KEY_ASSIGNED\\0" - "NO_RENEGOTIATION\\0" - "NO_REQUIRED_DIGEST\\0" - "NO_SHARED_CIPHER\\0" - "NO_SHARED_GROUP\\0" - "NO_SUPPORTED_VERSIONS_ENABLED\\0" - "NULL_SSL_CTX\\0" - "NULL_SSL_METHOD_PASSED\\0" - "OLD_SESSION_CIPHER_NOT_RETURNED\\0" - "OLD_SESSION_PRF_HASH_MISMATCH\\0" - "OLD_SESSION_VERSION_NOT_RETURNED\\0" - "PARSE_TLSEXT\\0" - "PATH_TOO_LONG\\0" - "PEER_DID_NOT_RETURN_A_CERTIFICATE\\0" - "PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\\0" - "PRE_SHARED_KEY_MUST_BE_LAST\\0" - "PROTOCOL_IS_SHUTDOWN\\0" - "PSK_IDENTITY_BINDER_COUNT_MISMATCH\\0" - "PSK_IDENTITY_NOT_FOUND\\0" - "PSK_NO_CLIENT_CB\\0" - "PSK_NO_SERVER_CB\\0" - "READ_TIMEOUT_EXPIRED\\0" - "RECORD_LENGTH_MISMATCH\\0" - "RECORD_TOO_LARGE\\0" - "RENEGOTIATION_EMS_MISMATCH\\0" - "RENEGOTIATION_ENCODING_ERR\\0" - "RENEGOTIATION_MISMATCH\\0" - "REQUIRED_CIPHER_MISSING\\0" - "RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION\\0" - "RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION\\0" - "SCSV_RECEIVED_WHEN_RENEGOTIATING\\0" - "SERVERHELLO_TLSEXT\\0" - "SERVER_CERT_CHANGED\\0" - "SESSION_ID_CONTEXT_UNINITIALIZED\\0" - "SESSION_MAY_NOT_BE_CREATED\\0" - "SHUTDOWN_WHILE_IN_INIT\\0" - "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\\0" - "SRTP_COULD_NOT_ALLOCATE_PROFILES\\0" - "SRTP_UNKNOWN_PROTECTION_PROFILE\\0" - "SSL3_EXT_INVALID_SERVERNAME\\0" - "SSLV3_ALERT_BAD_CERTIFICATE\\0" - "SSLV3_ALERT_BAD_RECORD_MAC\\0" - "SSLV3_ALERT_CERTIFICATE_EXPIRED\\0" - "SSLV3_ALERT_CERTIFICATE_REVOKED\\0" - "SSLV3_ALERT_CERTIFICATE_UNKNOWN\\0" - "SSLV3_ALERT_CLOSE_NOTIFY\\0" - "SSLV3_ALERT_DECOMPRESSION_FAILURE\\0" - "SSLV3_ALERT_HANDSHAKE_FAILURE\\0" - "SSLV3_ALERT_ILLEGAL_PARAMETER\\0" - "SSLV3_ALERT_NO_CERTIFICATE\\0" - "SSLV3_ALERT_UNEXPECTED_MESSAGE\\0" - "SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\\0" - "SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\\0" - "SSL_HANDSHAKE_FAILURE\\0" - "SSL_SESSION_ID_CONTEXT_TOO_LONG\\0" - "TICKET_ENCRYPTION_FAILED\\0" - "TLSV1_ALERT_ACCESS_DENIED\\0" - "TLSV1_ALERT_DECODE_ERROR\\0" - "TLSV1_ALERT_DECRYPTION_FAILED\\0" - "TLSV1_ALERT_DECRYPT_ERROR\\0" - "TLSV1_ALERT_EXPORT_RESTRICTION\\0" - "TLSV1_ALERT_INAPPROPRIATE_FALLBACK\\0" - "TLSV1_ALERT_INSUFFICIENT_SECURITY\\0" - "TLSV1_ALERT_INTERNAL_ERROR\\0" - "TLSV1_ALERT_NO_RENEGOTIATION\\0" - "TLSV1_ALERT_PROTOCOL_VERSION\\0" - "TLSV1_ALERT_RECORD_OVERFLOW\\0" - "TLSV1_ALERT_UNKNOWN_CA\\0" - "TLSV1_ALERT_USER_CANCELLED\\0" - "TLSV1_BAD_CERTIFICATE_HASH_VALUE\\0" - "TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\\0" - "TLSV1_CERTIFICATE_REQUIRED\\0" - "TLSV1_CERTIFICATE_UNOBTAINABLE\\0" - "TLSV1_UNKNOWN_PSK_IDENTITY\\0" - "TLSV1_UNRECOGNIZED_NAME\\0" - "TLSV1_UNSUPPORTED_EXTENSION\\0" - "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\\0" - "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\\0" - "TOO_MANY_EMPTY_FRAGMENTS\\0" - "TOO_MANY_KEY_UPDATES\\0" - "TOO_MANY_WARNING_ALERTS\\0" - "TOO_MUCH_READ_EARLY_DATA\\0" - "TOO_MUCH_SKIPPED_EARLY_DATA\\0" - "UNABLE_TO_FIND_ECDH_PARAMETERS\\0" - "UNEXPECTED_EXTENSION\\0" - "UNEXPECTED_EXTENSION_ON_EARLY_DATA\\0" - "UNEXPECTED_MESSAGE\\0" - "UNEXPECTED_OPERATOR_IN_GROUP\\0" - "UNEXPECTED_RECORD\\0" - "UNKNOWN_ALERT_TYPE\\0" - "UNKNOWN_CERTIFICATE_TYPE\\0" - "UNKNOWN_CIPHER_RETURNED\\0" - "UNKNOWN_CIPHER_TYPE\\0" - "UNKNOWN_KEY_EXCHANGE_TYPE\\0" - "UNKNOWN_PROTOCOL\\0" - "UNKNOWN_SSL_VERSION\\0" - "UNKNOWN_STATE\\0" - "UNSAFE_LEGACY_RENEGOTIATION_DISABLED\\0" - "UNSUPPORTED_COMPRESSION_ALGORITHM\\0" - "UNSUPPORTED_ELLIPTIC_CURVE\\0" - "UNSUPPORTED_PROTOCOL\\0" - "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\\0" - "WRONG_CERTIFICATE_TYPE\\0" - "WRONG_CIPHER_RETURNED\\0" - "WRONG_CURVE\\0" - "WRONG_MESSAGE_TYPE\\0" - "WRONG_SIGNATURE_TYPE\\0" - "WRONG_SSL_VERSION\\0" - "WRONG_VERSION_NUMBER\\0" - "WRONG_VERSION_ON_EARLY_DATA\\0" - "X509_LIB\\0" - "X509_VERIFICATION_SETUP_PROBLEMS\\0" - "AKID_MISMATCH\\0" - "BAD_X509_FILETYPE\\0" - "BASE64_DECODE_ERROR\\0" - "CANT_CHECK_DH_KEY\\0" - "CERT_ALREADY_IN_HASH_TABLE\\0" - "CRL_ALREADY_DELTA\\0" - "CRL_VERIFY_FAILURE\\0" - "IDP_MISMATCH\\0" - "INVALID_DIRECTORY\\0" - "INVALID_FIELD_NAME\\0" - "INVALID_PARAMETER\\0" - "INVALID_PSS_PARAMETERS\\0" - "INVALID_TRUST\\0" - "ISSUER_MISMATCH\\0" - "KEY_TYPE_MISMATCH\\0" - "KEY_VALUES_MISMATCH\\0" - "LOADING_CERT_DIR\\0" - "LOADING_DEFAULTS\\0" - "NAME_TOO_LONG\\0" - "NEWER_CRL_NOT_NEWER\\0" - "NO_CERT_SET_FOR_US_TO_VERIFY\\0" - "NO_CRL_NUMBER\\0" - "PUBLIC_KEY_DECODE_ERROR\\0" - "PUBLIC_KEY_ENCODE_ERROR\\0" - "SHOULD_RETRY\\0" - "UNKNOWN_KEY_TYPE\\0" - "UNKNOWN_PURPOSE_ID\\0" - "UNKNOWN_TRUST_ID\\0" - "WRONG_LOOKUP_TYPE\\0" - "BAD_IP_ADDRESS\\0" - "BAD_OBJECT\\0" - "BN_DEC2BN_ERROR\\0" - "BN_TO_ASN1_INTEGER_ERROR\\0" - "CANNOT_FIND_FREE_FUNCTION\\0" - "DIRNAME_ERROR\\0" - "DISTPOINT_ALREADY_SET\\0" - "DUPLICATE_ZONE_ID\\0" - "ERROR_CONVERTING_ZONE\\0" - "ERROR_CREATING_EXTENSION\\0" - "ERROR_IN_EXTENSION\\0" - "EXPECTED_A_SECTION_NAME\\0" - "EXTENSION_EXISTS\\0" - "EXTENSION_NAME_ERROR\\0" - "EXTENSION_NOT_FOUND\\0" - "EXTENSION_SETTING_NOT_SUPPORTED\\0" - "EXTENSION_VALUE_ERROR\\0" - "ILLEGAL_EMPTY_EXTENSION\\0" - "ILLEGAL_HEX_DIGIT\\0" - "INCORRECT_POLICY_SYNTAX_TAG\\0" - "INVALID_BOOLEAN_STRING\\0" - "INVALID_EXTENSION_STRING\\0" - "INVALID_MULTIPLE_RDNS\\0" - "INVALID_NAME\\0" - "INVALID_NULL_ARGUMENT\\0" - "INVALID_NULL_NAME\\0" - "INVALID_NULL_VALUE\\0" - "INVALID_NUMBERS\\0" - "INVALID_OBJECT_IDENTIFIER\\0" - "INVALID_OPTION\\0" - "INVALID_POLICY_IDENTIFIER\\0" - "INVALID_PROXY_POLICY_SETTING\\0" - "INVALID_PURPOSE\\0" - "INVALID_SECTION\\0" - "INVALID_SYNTAX\\0" - "ISSUER_DECODE_ERROR\\0" - "NEED_ORGANIZATION_AND_NUMBERS\\0" - "NO_CONFIG_DATABASE\\0" - "NO_ISSUER_CERTIFICATE\\0" - "NO_ISSUER_DETAILS\\0" - "NO_POLICY_IDENTIFIER\\0" - "NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED\\0" - "NO_PUBLIC_KEY\\0" - "NO_SUBJECT_DETAILS\\0" - "ODD_NUMBER_OF_DIGITS\\0" - "OPERATION_NOT_DEFINED\\0" - "OTHERNAME_ERROR\\0" - "POLICY_LANGUAGE_ALREADY_DEFINED\\0" - "POLICY_PATH_LENGTH\\0" - "POLICY_PATH_LENGTH_ALREADY_DEFINED\\0" - "POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY\\0" - "SECTION_NOT_FOUND\\0" - "UNABLE_TO_GET_ISSUER_DETAILS\\0" - "UNABLE_TO_GET_ISSUER_KEYID\\0" - "UNKNOWN_BIT_STRING_ARGUMENT\\0" - "UNKNOWN_EXTENSION\\0" - "UNKNOWN_EXTENSION_NAME\\0" - "UNKNOWN_OPTION\\0" - "UNSUPPORTED_OPTION\\0" - "USER_TOO_LONG\\0" - ""; - EOF - END_OF_COMMAND -end diff --git a/src/objective-c/examples/Sample/Podfile b/src/objective-c/examples/Sample/Podfile index 9ea2f61927c..bebd55bd628 100644 --- a/src/objective-c/examples/Sample/Podfile +++ b/src/objective-c/examples/Sample/Podfile @@ -19,7 +19,7 @@ target 'Sample' do pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf" - pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" pod 'gRPC', :path => GRPC_LOCAL_SRC pod 'gRPC-Core', :path => GRPC_LOCAL_SRC diff --git a/src/objective-c/examples/SwiftSample/Podfile b/src/objective-c/examples/SwiftSample/Podfile index a2c2b82cc9c..8214371bc59 100644 --- a/src/objective-c/examples/SwiftSample/Podfile +++ b/src/objective-c/examples/SwiftSample/Podfile @@ -19,7 +19,7 @@ target 'SwiftSample' do pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf" - pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" pod 'gRPC', :path => GRPC_LOCAL_SRC pod 'gRPC-Core', :path => GRPC_LOCAL_SRC diff --git a/src/objective-c/grpc_shadow_boringssl_symbol_list b/src/objective-c/grpc_shadow_boringssl_symbol_list new file mode 100644 index 00000000000..33a6ed0e25e --- /dev/null +++ b/src/objective-c/grpc_shadow_boringssl_symbol_list @@ -0,0 +1,2974 @@ +# Automatically generated by tools/distrib/generate_grpc_shadow_boringssl_symbol_list.sh +b29b21a81b32ec273f118f589f46d56ad3332420 +BIO_f_ssl +BIO_set_ssl +SSL_CTX_add_client_custom_ext +SSL_CTX_add_server_custom_ext +DTLSv1_get_timeout +DTLSv1_handle_timeout +DTLSv1_set_initial_timeout_duration +SSL_CTX_set_srtp_profiles +SSL_CTX_set_tlsext_use_srtp +SSL_get_selected_srtp_profile +SSL_get_srtp_profiles +SSL_set_srtp_profiles +SSL_set_tlsext_use_srtp +DTLS_client_method +DTLS_method +DTLS_server_method +DTLS_with_buffers_method +DTLSv1_2_client_method +DTLSv1_2_method +DTLSv1_2_server_method +DTLSv1_client_method +DTLSv1_method +DTLSv1_server_method +SSL_SESSION_from_bytes +SSL_SESSION_to_bytes +SSL_SESSION_to_bytes_for_ticket +i2d_SSL_SESSION +SSL_CTX_set0_client_CAs +SSL_CTX_set_cert_cb +SSL_CTX_set_chain_and_key +SSL_CTX_set_ocsp_response +SSL_CTX_set_signed_cert_timestamp_list +SSL_CTX_use_certificate_ASN1 +SSL_get0_peer_certificates +SSL_get0_server_requested_CAs +SSL_set0_client_CAs +SSL_set_cert_cb +SSL_set_chain_and_key +SSL_set_ocsp_response +SSL_set_signed_cert_timestamp_list +SSL_use_certificate_ASN1 +SSL_CIPHER_description +SSL_CIPHER_get_auth_nid +SSL_CIPHER_get_bits +SSL_CIPHER_get_cipher_nid +SSL_CIPHER_get_digest_nid +SSL_CIPHER_get_id +SSL_CIPHER_get_kx_name +SSL_CIPHER_get_kx_nid +SSL_CIPHER_get_max_version +SSL_CIPHER_get_min_version +SSL_CIPHER_get_name +SSL_CIPHER_get_prf_nid +SSL_CIPHER_get_rfc_name +SSL_CIPHER_get_version +SSL_CIPHER_is_aead +SSL_CIPHER_is_block_cipher +SSL_CIPHER_standard_name +SSL_COMP_add_compression_method +SSL_COMP_free_compression_methods +SSL_COMP_get0_name +SSL_COMP_get_compression_methods +SSL_COMP_get_id +SSL_COMP_get_name +SSL_get_cipher_by_value +SSL_CTX_get_default_passwd_cb +SSL_CTX_get_default_passwd_cb_userdata +SSL_CTX_set_default_passwd_cb +SSL_CTX_set_default_passwd_cb_userdata +SSL_CTX_use_PrivateKey_file +SSL_CTX_use_RSAPrivateKey_file +SSL_CTX_use_certificate_chain_file +SSL_CTX_use_certificate_file +SSL_add_file_cert_subjects_to_stack +SSL_load_client_CA_file +SSL_use_PrivateKey_file +SSL_use_RSAPrivateKey_file +SSL_use_certificate_file +SSL_get_curve_name +ERR_load_SSL_strings +OPENSSL_init_ssl +SSL_CTX_check_private_key +SSL_CTX_cipher_in_group +SSL_CTX_clear_mode +SSL_CTX_clear_options +SSL_CTX_enable_ocsp_stapling +SSL_CTX_enable_signed_cert_timestamps +SSL_CTX_enable_tls_channel_id +SSL_CTX_free +SSL_CTX_get0_privatekey +SSL_CTX_get_ciphers +SSL_CTX_get_ex_data +SSL_CTX_get_ex_new_index +SSL_CTX_get_keylog_callback +SSL_CTX_get_max_cert_list +SSL_CTX_get_mode +SSL_CTX_get_options +SSL_CTX_get_quiet_shutdown +SSL_CTX_get_read_ahead +SSL_CTX_get_session_cache_mode +SSL_CTX_get_tlsext_ticket_keys +SSL_CTX_need_tmp_RSA +SSL_CTX_new +SSL_CTX_sess_accept +SSL_CTX_sess_accept_good +SSL_CTX_sess_accept_renegotiate +SSL_CTX_sess_cache_full +SSL_CTX_sess_cb_hits +SSL_CTX_sess_connect +SSL_CTX_sess_connect_good +SSL_CTX_sess_connect_renegotiate +SSL_CTX_sess_get_cache_size +SSL_CTX_sess_hits +SSL_CTX_sess_misses +SSL_CTX_sess_number +SSL_CTX_sess_set_cache_size +SSL_CTX_sess_timeouts +SSL_CTX_set0_buffer_pool +SSL_CTX_set1_curves +SSL_CTX_set1_curves_list +SSL_CTX_set1_tls_channel_id +SSL_CTX_set_allow_unknown_alpn_protos +SSL_CTX_set_alpn_protos +SSL_CTX_set_alpn_select_cb +SSL_CTX_set_cipher_list +SSL_CTX_set_current_time_cb +SSL_CTX_set_custom_verify +SSL_CTX_set_dos_protection_cb +SSL_CTX_set_early_data_enabled +SSL_CTX_set_ex_data +SSL_CTX_set_false_start_allowed_without_alpn +SSL_CTX_set_grease_enabled +SSL_CTX_set_keylog_callback +SSL_CTX_set_max_cert_list +SSL_CTX_set_max_send_fragment +SSL_CTX_set_mode +SSL_CTX_set_msg_callback +SSL_CTX_set_msg_callback_arg +SSL_CTX_set_next_proto_select_cb +SSL_CTX_set_next_protos_advertised_cb +SSL_CTX_set_options +SSL_CTX_set_psk_client_callback +SSL_CTX_set_psk_server_callback +SSL_CTX_set_quiet_shutdown +SSL_CTX_set_read_ahead +SSL_CTX_set_retain_only_sha256_of_client_certs +SSL_CTX_set_select_certificate_cb +SSL_CTX_set_session_cache_mode +SSL_CTX_set_session_id_context +SSL_CTX_set_strict_cipher_list +SSL_CTX_set_ticket_aead_method +SSL_CTX_set_tls13_variant +SSL_CTX_set_tls_channel_id_enabled +SSL_CTX_set_tlsext_servername_arg +SSL_CTX_set_tlsext_servername_callback +SSL_CTX_set_tlsext_ticket_key_cb +SSL_CTX_set_tlsext_ticket_keys +SSL_CTX_set_tmp_dh +SSL_CTX_set_tmp_dh_callback +SSL_CTX_set_tmp_ecdh +SSL_CTX_set_tmp_rsa +SSL_CTX_set_tmp_rsa_callback +SSL_CTX_up_ref +SSL_CTX_use_psk_identity_hint +SSL_accept +SSL_cache_hit +SSL_certs_clear +SSL_check_private_key +SSL_clear +SSL_clear_mode +SSL_clear_options +SSL_connect +SSL_cutthrough_complete +SSL_do_handshake +SSL_dummy_pq_padding_used +SSL_early_data_accepted +SSL_enable_ocsp_stapling +SSL_enable_signed_cert_timestamps +SSL_enable_tls_channel_id +SSL_free +SSL_get0_alpn_selected +SSL_get0_certificate_types +SSL_get0_next_proto_negotiated +SSL_get0_ocsp_response +SSL_get0_session_id_context +SSL_get0_signed_cert_timestamp_list +SSL_get_SSL_CTX +SSL_get_cipher_list +SSL_get_ciphers +SSL_get_client_random +SSL_get_current_cipher +SSL_get_current_compression +SSL_get_current_expansion +SSL_get_curve_id +SSL_get_default_timeout +SSL_get_error +SSL_get_ex_data +SSL_get_ex_new_index +SSL_get_extms_support +SSL_get_fd +SSL_get_finished +SSL_get_info_callback +SSL_get_ivs +SSL_get_max_cert_list +SSL_get_mode +SSL_get_negotiated_token_binding_param +SSL_get_options +SSL_get_peer_finished +SSL_get_peer_quic_transport_params +SSL_get_peer_signature_algorithm +SSL_get_pending_cipher +SSL_get_privatekey +SSL_get_psk_identity +SSL_get_psk_identity_hint +SSL_get_quiet_shutdown +SSL_get_rbio +SSL_get_read_ahead +SSL_get_read_sequence +SSL_get_rfd +SSL_get_secure_renegotiation_support +SSL_get_server_random +SSL_get_server_tmp_key +SSL_get_servername +SSL_get_servername_type +SSL_get_shared_ciphers +SSL_get_shutdown +SSL_get_structure_sizes +SSL_get_ticket_age_skew +SSL_get_tls_channel_id +SSL_get_tls_unique +SSL_get_verify_mode +SSL_get_wbio +SSL_get_wfd +SSL_get_write_sequence +SSL_in_early_data +SSL_in_false_start +SSL_in_init +SSL_is_draft_downgrade +SSL_is_dtls +SSL_is_init_finished +SSL_is_server +SSL_is_token_binding_negotiated +SSL_library_init +SSL_load_error_strings +SSL_need_tmp_RSA +SSL_new +SSL_num_renegotiations +SSL_peek +SSL_pending +SSL_read +SSL_renegotiate +SSL_renegotiate_pending +SSL_reset_early_data_reject +SSL_select_next_proto +SSL_send_fatal_alert +SSL_session_reused +SSL_set0_rbio +SSL_set0_wbio +SSL_set1_curves +SSL_set1_curves_list +SSL_set1_tls_channel_id +SSL_set_SSL_CTX +SSL_set_accept_state +SSL_set_alpn_protos +SSL_set_bio +SSL_set_cipher_list +SSL_set_connect_state +SSL_set_custom_verify +SSL_set_dummy_pq_padding_size +SSL_set_early_data_enabled +SSL_set_ex_data +SSL_set_fd +SSL_set_info_callback +SSL_set_max_cert_list +SSL_set_max_send_fragment +SSL_set_mode +SSL_set_msg_callback +SSL_set_msg_callback_arg +SSL_set_mtu +SSL_set_options +SSL_set_psk_client_callback +SSL_set_psk_server_callback +SSL_set_quic_transport_params +SSL_set_quiet_shutdown +SSL_set_read_ahead +SSL_set_renegotiate_mode +SSL_set_retain_only_sha256_of_client_certs +SSL_set_rfd +SSL_set_session_id_context +SSL_set_shutdown +SSL_set_state +SSL_set_strict_cipher_list +SSL_set_tls13_variant +SSL_set_tls_channel_id_enabled +SSL_set_tlsext_host_name +SSL_set_tmp_dh +SSL_set_tmp_dh_callback +SSL_set_tmp_ecdh +SSL_set_tmp_rsa +SSL_set_tmp_rsa_callback +SSL_set_token_binding_params +SSL_set_wfd +SSL_shutdown +SSL_state +SSL_total_renegotiations +SSL_use_psk_identity_hint +SSL_want +SSL_write +SSL_CTX_set_private_key_method +SSL_CTX_set_signing_algorithm_prefs +SSL_CTX_set_verify_algorithm_prefs +SSL_CTX_use_PrivateKey +SSL_CTX_use_PrivateKey_ASN1 +SSL_CTX_use_RSAPrivateKey +SSL_CTX_use_RSAPrivateKey_ASN1 +SSL_get_signature_algorithm_digest +SSL_get_signature_algorithm_key_type +SSL_get_signature_algorithm_name +SSL_is_signature_algorithm_rsa_pss +SSL_set_private_key_method +SSL_set_signing_algorithm_prefs +SSL_use_PrivateKey +SSL_use_PrivateKey_ASN1 +SSL_use_RSAPrivateKey +SSL_use_RSAPrivateKey_ASN1 +SSL_CTX_add_session +SSL_CTX_flush_sessions +SSL_CTX_get_channel_id_cb +SSL_CTX_get_info_callback +SSL_CTX_get_timeout +SSL_CTX_remove_session +SSL_CTX_sess_get_get_cb +SSL_CTX_sess_get_new_cb +SSL_CTX_sess_get_remove_cb +SSL_CTX_sess_set_get_cb +SSL_CTX_sess_set_new_cb +SSL_CTX_sess_set_remove_cb +SSL_CTX_set_channel_id_cb +SSL_CTX_set_info_callback +SSL_CTX_set_session_psk_dhe_timeout +SSL_CTX_set_timeout +SSL_SESSION_free +SSL_SESSION_get0_peer +SSL_SESSION_get0_ticket +SSL_SESSION_get_ex_data +SSL_SESSION_get_ex_new_index +SSL_SESSION_get_id +SSL_SESSION_get_master_key +SSL_SESSION_get_ticket_lifetime_hint +SSL_SESSION_get_time +SSL_SESSION_get_timeout +SSL_SESSION_has_ticket +SSL_SESSION_is_resumable +SSL_SESSION_new +SSL_SESSION_set1_id_context +SSL_SESSION_set_ex_data +SSL_SESSION_set_time +SSL_SESSION_set_timeout +SSL_SESSION_should_be_single_use +SSL_SESSION_up_ref +SSL_get1_session +SSL_get_session +SSL_magic_pending_session_ptr +SSL_set_session +SSL_alert_desc_string +SSL_alert_desc_string_long +SSL_alert_type_string +SSL_alert_type_string_long +SSL_state_string +SSL_state_string_long +SSL_CTX_set_max_proto_version +SSL_CTX_set_min_proto_version +SSL_SESSION_get_protocol_version +SSL_SESSION_get_version +SSL_SESSION_set_protocol_version +SSL_get_version +SSL_set_max_proto_version +SSL_set_min_proto_version +SSL_version +PEM_read_SSL_SESSION +PEM_read_bio_SSL_SESSION +PEM_write_SSL_SESSION +PEM_write_bio_SSL_SESSION +SSL_CTX_add0_chain_cert +SSL_CTX_add1_chain_cert +SSL_CTX_add_client_CA +SSL_CTX_add_extra_chain_cert +SSL_CTX_clear_chain_certs +SSL_CTX_clear_extra_chain_certs +SSL_CTX_get0_certificate +SSL_CTX_get0_chain_certs +SSL_CTX_get0_param +SSL_CTX_get_cert_store +SSL_CTX_get_client_CA_list +SSL_CTX_get_extra_chain_certs +SSL_CTX_get_verify_callback +SSL_CTX_get_verify_depth +SSL_CTX_get_verify_mode +SSL_CTX_load_verify_locations +SSL_CTX_set0_chain +SSL_CTX_set0_verify_cert_store +SSL_CTX_set1_chain +SSL_CTX_set1_param +SSL_CTX_set1_verify_cert_store +SSL_CTX_set_cert_store +SSL_CTX_set_cert_verify_callback +SSL_CTX_set_client_CA_list +SSL_CTX_set_client_cert_cb +SSL_CTX_set_default_verify_paths +SSL_CTX_set_purpose +SSL_CTX_set_trust +SSL_CTX_set_verify +SSL_CTX_set_verify_depth +SSL_CTX_use_certificate +SSL_add0_chain_cert +SSL_add1_chain_cert +SSL_add_client_CA +SSL_alert_from_verify_result +SSL_clear_chain_certs +SSL_dup_CA_list +SSL_get0_chain_certs +SSL_get0_param +SSL_get_certificate +SSL_get_client_CA_list +SSL_get_ex_data_X509_STORE_CTX_idx +SSL_get_peer_cert_chain +SSL_get_peer_certificate +SSL_get_peer_full_cert_chain +SSL_get_verify_callback +SSL_get_verify_depth +SSL_get_verify_result +SSL_set0_chain +SSL_set0_verify_cert_store +SSL_set1_chain +SSL_set1_param +SSL_set1_verify_cert_store +SSL_set_client_CA_list +SSL_set_purpose +SSL_set_trust +SSL_set_verify +SSL_set_verify_depth +SSL_set_verify_result +SSL_use_certificate +d2i_SSL_SESSION +d2i_SSL_SESSION_bio +i2d_SSL_SESSION_bio +SSL_export_early_keying_material +SSL_export_keying_material +SSL_generate_key_block +SSL_get_key_block_len +SSL_CTX_set_ed25519_enabled +SSL_early_callback_ctx_extension_get +SSL_extension_supported +SSLv23_client_method +SSLv23_method +SSLv23_server_method +TLS_client_method +TLS_method +TLS_server_method +TLS_with_buffers_method +TLSv1_1_client_method +TLSv1_1_method +TLSv1_1_server_method +TLSv1_2_client_method +TLSv1_2_method +TLSv1_2_server_method +TLSv1_client_method +TLSv1_method +TLSv1_server_method +SSL_max_seal_overhead +OPENSSL_cpuid_setup +CRYPTO_has_asm +CRYPTO_is_confidential_build +CRYPTO_library_init +CRYPTO_malloc_init +ENGINE_load_builtin_engines +ENGINE_register_all_complete +OPENSSL_ia32cap_P +OPENSSL_init_crypto +OPENSSL_load_builtin_modules +OpenSSL_version +OpenSSL_version_num +SSLeay +SSLeay_version +CRYPTO_cleanup_all_ex_data +CRYPTO_free_ex_data +CRYPTO_get_ex_data +CRYPTO_get_ex_new_index +CRYPTO_new_ex_data +CRYPTO_set_ex_data +BIO_snprintf +BIO_vsnprintf +CRYPTO_memcmp +OPENSSL_cleanse +OPENSSL_free +OPENSSL_hash32 +OPENSSL_malloc +OPENSSL_realloc +OPENSSL_strcasecmp +OPENSSL_strdup +OPENSSL_strncasecmp +OPENSSL_strnlen +OPENSSL_tolower +CRYPTO_refcount_dec_and_test_zero +CRYPTO_refcount_inc +CRYPTO_THREADID_current +CRYPTO_THREADID_set_callback +CRYPTO_THREADID_set_numeric +CRYPTO_THREADID_set_pointer +CRYPTO_get_dynlock_create_callback +CRYPTO_get_dynlock_destroy_callback +CRYPTO_get_dynlock_lock_callback +CRYPTO_get_lock_name +CRYPTO_get_locking_callback +CRYPTO_num_locks +CRYPTO_set_add_lock_callback +CRYPTO_set_dynlock_create_callback +CRYPTO_set_dynlock_destroy_callback +CRYPTO_set_dynlock_lock_callback +CRYPTO_set_id_callback +CRYPTO_set_locking_callback +CRYPTO_MUTEX_cleanup +CRYPTO_MUTEX_init +CRYPTO_MUTEX_lock_read +CRYPTO_MUTEX_lock_write +CRYPTO_MUTEX_unlock_read +CRYPTO_MUTEX_unlock_write +CRYPTO_STATIC_MUTEX_lock_read +CRYPTO_STATIC_MUTEX_lock_write +CRYPTO_STATIC_MUTEX_unlock_read +CRYPTO_STATIC_MUTEX_unlock_write +CRYPTO_get_thread_local +CRYPTO_once +CRYPTO_set_thread_local +sk_deep_copy +sk_delete +sk_delete_ptr +sk_dup +sk_find +sk_free +sk_insert +sk_is_sorted +sk_new +sk_new_null +sk_num +sk_pop +sk_pop_free +sk_push +sk_set +sk_set_cmp_func +sk_shift +sk_sort +sk_value +sk_zero +lh_delete +lh_doall +lh_doall_arg +lh_free +lh_insert +lh_new +lh_num_items +lh_retrieve +lh_strhash +ERR_SAVE_STATE_free +ERR_add_error_data +ERR_add_error_dataf +ERR_clear_error +ERR_clear_system_error +ERR_error_string +ERR_error_string_n +ERR_free_strings +ERR_func_error_string +ERR_get_error +ERR_get_error_line +ERR_get_error_line_data +ERR_get_next_error_library +ERR_lib_error_string +ERR_load_BIO_strings +ERR_load_ERR_strings +ERR_load_crypto_strings +ERR_peek_error +ERR_peek_error_line +ERR_peek_error_line_data +ERR_peek_last_error +ERR_peek_last_error_line +ERR_peek_last_error_line_data +ERR_pop_to_mark +ERR_print_errors_cb +ERR_print_errors_fp +ERR_put_error +ERR_reason_error_string +ERR_remove_state +ERR_remove_thread_state +ERR_restore_state +ERR_save_state +ERR_set_mark +kOpenSSLReasonStringData +kOpenSSLReasonValues +kOpenSSLReasonValuesLen +EVP_DecodeBase64 +EVP_DecodeBlock +EVP_DecodeFinal +EVP_DecodeInit +EVP_DecodeUpdate +EVP_DecodedLength +EVP_EncodeBlock +EVP_EncodeFinal +EVP_EncodeInit +EVP_EncodeUpdate +EVP_EncodedLength +CBB_finish_i2d +CBS_asn1_ber_to_der +CBS_get_asn1_implicit_string +CBS_asn1_bitstring_has_bit +CBS_asn1_oid_to_text +CBS_contains_zero_byte +CBS_copy_bytes +CBS_data +CBS_get_any_asn1 +CBS_get_any_asn1_element +CBS_get_any_ber_asn1_element +CBS_get_asn1 +CBS_get_asn1_bool +CBS_get_asn1_element +CBS_get_asn1_uint64 +CBS_get_bytes +CBS_get_last_u8 +CBS_get_optional_asn1 +CBS_get_optional_asn1_bool +CBS_get_optional_asn1_octet_string +CBS_get_optional_asn1_uint64 +CBS_get_u16 +CBS_get_u16_length_prefixed +CBS_get_u24 +CBS_get_u24_length_prefixed +CBS_get_u32 +CBS_get_u8 +CBS_get_u8_length_prefixed +CBS_init +CBS_is_valid_asn1_bitstring +CBS_len +CBS_mem_equal +CBS_peek_asn1_tag +CBS_skip +CBS_stow +CBS_strdup +CBB_add_asn1 +CBB_add_asn1_bool +CBB_add_asn1_octet_string +CBB_add_asn1_oid_from_text +CBB_add_asn1_uint64 +CBB_add_bytes +CBB_add_space +CBB_add_u16 +CBB_add_u16_length_prefixed +CBB_add_u24 +CBB_add_u24_length_prefixed +CBB_add_u32 +CBB_add_u8 +CBB_add_u8_length_prefixed +CBB_cleanup +CBB_data +CBB_did_write +CBB_discard_child +CBB_finish +CBB_flush +CBB_flush_asn1_set_of +CBB_init +CBB_init_fixed +CBB_len +CBB_reserve +CBB_zero +CRYPTO_BUFFER_POOL_free +CRYPTO_BUFFER_POOL_new +CRYPTO_BUFFER_data +CRYPTO_BUFFER_free +CRYPTO_BUFFER_init_CBS +CRYPTO_BUFFER_len +CRYPTO_BUFFER_new +CRYPTO_BUFFER_new_from_CBS +CRYPTO_BUFFER_up_ref +AES_cbc_encrypt +AES_cfb128_encrypt +AES_ctr128_encrypt +AES_decrypt +AES_ecb_encrypt +AES_encrypt +AES_ofb128_encrypt +AES_set_decrypt_key +AES_set_encrypt_key +AES_unwrap_key +AES_wrap_key +BN_BLINDING_convert +BN_BLINDING_free +BN_BLINDING_invert +BN_BLINDING_new +BN_CTX_end +BN_CTX_free +BN_CTX_get +BN_CTX_new +BN_CTX_start +BN_GENCB_call +BN_GENCB_set +BN_MONT_CTX_copy +BN_MONT_CTX_free +BN_MONT_CTX_new +BN_MONT_CTX_new_for_modulus +BN_MONT_CTX_set +BN_MONT_CTX_set_locked +BN_abs_is_word +BN_add +BN_add_word +BN_bin2bn +BN_bn2bin +BN_bn2bin_padded +BN_bn2le_padded +BN_clear +BN_clear_bit +BN_clear_free +BN_cmp +BN_cmp_word +BN_copy +BN_count_low_zero_bits +BN_div +BN_div_word +BN_dup +BN_enhanced_miller_rabin_primality_test +BN_equal_consttime +BN_exp +BN_free +BN_from_montgomery +BN_gcd +BN_generate_prime_ex +BN_get_u64 +BN_get_word +BN_init +BN_is_bit_set +BN_is_negative +BN_is_odd +BN_is_one +BN_is_pow2 +BN_is_prime_ex +BN_is_prime_fasttest_ex +BN_is_word +BN_is_zero +BN_le2bn +BN_lshift +BN_lshift1 +BN_mask_bits +BN_mod_add +BN_mod_add_quick +BN_mod_exp +BN_mod_exp2_mont +BN_mod_exp_mont +BN_mod_exp_mont_consttime +BN_mod_exp_mont_word +BN_mod_inverse +BN_mod_inverse_blinded +BN_mod_inverse_odd +BN_mod_lshift +BN_mod_lshift1 +BN_mod_lshift1_quick +BN_mod_lshift_quick +BN_mod_mul +BN_mod_mul_montgomery +BN_mod_pow2 +BN_mod_sqr +BN_mod_sqrt +BN_mod_sub +BN_mod_sub_quick +BN_mod_word +BN_mul +BN_mul_word +BN_new +BN_nnmod +BN_nnmod_pow2 +BN_num_bits +BN_num_bits_word +BN_num_bytes +BN_one +BN_primality_test +BN_pseudo_rand +BN_pseudo_rand_range +BN_rand +BN_rand_range +BN_rand_range_ex +BN_rshift +BN_rshift1 +BN_set_bit +BN_set_negative +BN_set_u64 +BN_set_word +BN_sqr +BN_sqrt +BN_sub +BN_sub_word +BN_to_montgomery +BN_uadd +BN_ucmp +BN_usub +BN_value_one +BN_zero +BORINGSSL_self_test +CRYPTO_POLYVAL_finish +CRYPTO_POLYVAL_init +CRYPTO_POLYVAL_update_blocks +CRYPTO_cbc128_decrypt +CRYPTO_cbc128_encrypt +CRYPTO_ccm128_decrypt +CRYPTO_ccm128_encrypt +CRYPTO_ccm128_init +CRYPTO_ccm128_max_input +CRYPTO_cfb128_1_encrypt +CRYPTO_cfb128_8_encrypt +CRYPTO_cfb128_encrypt +CRYPTO_ctr128_encrypt +CRYPTO_ctr128_encrypt_ctr32 +CRYPTO_gcm128_aad +CRYPTO_gcm128_decrypt +CRYPTO_gcm128_decrypt_ctr32 +CRYPTO_gcm128_encrypt +CRYPTO_gcm128_encrypt_ctr32 +CRYPTO_gcm128_finish +CRYPTO_gcm128_init +CRYPTO_gcm128_setiv +CRYPTO_gcm128_tag +CRYPTO_ghash_init +CRYPTO_ofb128_encrypt +CRYPTO_sysrand +CRYPTO_tls1_prf +CTR_DRBG_clear +CTR_DRBG_generate +CTR_DRBG_init +CTR_DRBG_reseed +DES_decrypt3 +DES_ecb3_encrypt +DES_ecb_encrypt +DES_ede2_cbc_encrypt +DES_ede3_cbc_encrypt +DES_encrypt3 +DES_ncbc_encrypt +DES_set_key +DES_set_key_unchecked +DES_set_odd_parity +ECDSA_SIG_free +ECDSA_SIG_get0 +ECDSA_SIG_new +ECDSA_SIG_set0 +ECDSA_do_sign +ECDSA_do_verify +EC_GFp_mont_method +EC_GFp_nistp224_method +EC_GFp_nistp256_method +EC_GFp_nistz256_method +EC_GROUP_cmp +EC_GROUP_dup +EC_GROUP_free +EC_GROUP_get0_generator +EC_GROUP_get0_order +EC_GROUP_get_cofactor +EC_GROUP_get_curve_GFp +EC_GROUP_get_curve_name +EC_GROUP_get_degree +EC_GROUP_get_order +EC_GROUP_method_of +EC_GROUP_new_by_curve_name +EC_GROUP_new_curve_GFp +EC_GROUP_set_asn1_flag +EC_GROUP_set_generator +EC_GROUP_set_point_conversion_form +EC_KEY_check_fips +EC_KEY_check_key +EC_KEY_dup +EC_KEY_free +EC_KEY_generate_key +EC_KEY_generate_key_fips +EC_KEY_get0_group +EC_KEY_get0_private_key +EC_KEY_get0_public_key +EC_KEY_get_conv_form +EC_KEY_get_enc_flags +EC_KEY_get_ex_data +EC_KEY_get_ex_new_index +EC_KEY_is_opaque +EC_KEY_new +EC_KEY_new_by_curve_name +EC_KEY_new_method +EC_KEY_set_asn1_flag +EC_KEY_set_conv_form +EC_KEY_set_enc_flags +EC_KEY_set_ex_data +EC_KEY_set_group +EC_KEY_set_private_key +EC_KEY_set_public_key +EC_KEY_set_public_key_affine_coordinates +EC_KEY_up_ref +EC_METHOD_get_field_type +EC_POINT_add +EC_POINT_clear_free +EC_POINT_cmp +EC_POINT_copy +EC_POINT_dbl +EC_POINT_dup +EC_POINT_free +EC_POINT_get_affine_coordinates_GFp +EC_POINT_invert +EC_POINT_is_at_infinity +EC_POINT_is_on_curve +EC_POINT_make_affine +EC_POINT_mul +EC_POINT_new +EC_POINT_oct2point +EC_POINT_point2oct +EC_POINT_set_affine_coordinates_GFp +EC_POINT_set_compressed_coordinates_GFp +EC_POINT_set_to_infinity +EC_POINTs_make_affine +EC_get_builtin_curves +EVP_AEAD_CTX_aead +EVP_AEAD_CTX_cleanup +EVP_AEAD_CTX_free +EVP_AEAD_CTX_get_iv +EVP_AEAD_CTX_init +EVP_AEAD_CTX_init_with_direction +EVP_AEAD_CTX_new +EVP_AEAD_CTX_open +EVP_AEAD_CTX_open_gather +EVP_AEAD_CTX_seal +EVP_AEAD_CTX_seal_scatter +EVP_AEAD_CTX_tag_len +EVP_AEAD_CTX_zero +EVP_AEAD_key_length +EVP_AEAD_max_overhead +EVP_AEAD_max_tag_len +EVP_AEAD_nonce_length +EVP_CIPHER_CTX_block_size +EVP_CIPHER_CTX_cipher +EVP_CIPHER_CTX_cleanup +EVP_CIPHER_CTX_copy +EVP_CIPHER_CTX_ctrl +EVP_CIPHER_CTX_flags +EVP_CIPHER_CTX_free +EVP_CIPHER_CTX_get_app_data +EVP_CIPHER_CTX_init +EVP_CIPHER_CTX_iv_length +EVP_CIPHER_CTX_key_length +EVP_CIPHER_CTX_mode +EVP_CIPHER_CTX_new +EVP_CIPHER_CTX_nid +EVP_CIPHER_CTX_reset +EVP_CIPHER_CTX_set_app_data +EVP_CIPHER_CTX_set_flags +EVP_CIPHER_CTX_set_key_length +EVP_CIPHER_CTX_set_padding +EVP_CIPHER_block_size +EVP_CIPHER_flags +EVP_CIPHER_iv_length +EVP_CIPHER_key_length +EVP_CIPHER_mode +EVP_CIPHER_nid +EVP_Cipher +EVP_CipherFinal_ex +EVP_CipherInit +EVP_CipherInit_ex +EVP_CipherUpdate +EVP_DecryptFinal_ex +EVP_DecryptInit +EVP_DecryptInit_ex +EVP_DecryptUpdate +EVP_Digest +EVP_DigestFinal +EVP_DigestFinal_ex +EVP_DigestInit +EVP_DigestInit_ex +EVP_DigestUpdate +EVP_EncryptFinal_ex +EVP_EncryptInit +EVP_EncryptInit_ex +EVP_EncryptUpdate +EVP_MD_CTX_block_size +EVP_MD_CTX_cleanup +EVP_MD_CTX_copy +EVP_MD_CTX_copy_ex +EVP_MD_CTX_create +EVP_MD_CTX_destroy +EVP_MD_CTX_free +EVP_MD_CTX_init +EVP_MD_CTX_md +EVP_MD_CTX_new +EVP_MD_CTX_reset +EVP_MD_CTX_size +EVP_MD_CTX_type +EVP_MD_block_size +EVP_MD_flags +EVP_MD_size +EVP_MD_type +EVP_add_cipher_alias +EVP_add_digest +EVP_aead_aes_128_gcm +EVP_aead_aes_128_gcm_tls12 +EVP_aead_aes_256_gcm +EVP_aead_aes_256_gcm_tls12 +EVP_aes_128_cbc +EVP_aes_128_ctr +EVP_aes_128_ecb +EVP_aes_128_gcm +EVP_aes_128_ofb +EVP_aes_192_cbc +EVP_aes_192_ctr +EVP_aes_192_ecb +EVP_aes_192_gcm +EVP_aes_256_cbc +EVP_aes_256_ctr +EVP_aes_256_ecb +EVP_aes_256_gcm +EVP_aes_256_ofb +EVP_des_cbc +EVP_des_ecb +EVP_des_ede +EVP_des_ede3 +EVP_des_ede3_cbc +EVP_des_ede_cbc +EVP_has_aes_hardware +EVP_md4 +EVP_md5 +EVP_md5_sha1 +EVP_sha1 +EVP_sha224 +EVP_sha256 +EVP_sha384 +EVP_sha512 +HMAC +HMAC_CTX_cleanup +HMAC_CTX_copy +HMAC_CTX_copy_ex +HMAC_CTX_free +HMAC_CTX_init +HMAC_CTX_new +HMAC_CTX_reset +HMAC_Final +HMAC_Init +HMAC_Init_ex +HMAC_Update +HMAC_size +MD4 +MD4_Final +MD4_Init +MD4_Transform +MD4_Update +MD5 +MD5_Final +MD5_Init +MD5_Transform +MD5_Update +OPENSSL_built_in_curves +RAND_bytes +RAND_bytes_with_additional_data +RAND_pseudo_bytes +RAND_set_urandom_fd +RSAZ_1024_mod_exp_avx2 +RSA_add_pkcs1_prefix +RSA_bits +RSA_blinding_on +RSA_check_fips +RSA_check_key +RSA_decrypt +RSA_default_method +RSA_encrypt +RSA_flags +RSA_free +RSA_generate_key_ex +RSA_generate_key_fips +RSA_get0_crt_params +RSA_get0_factors +RSA_get0_key +RSA_get_ex_data +RSA_get_ex_new_index +RSA_is_opaque +RSA_new +RSA_new_method +RSA_padding_add_PKCS1_OAEP_mgf1 +RSA_padding_add_PKCS1_PSS_mgf1 +RSA_padding_add_PKCS1_type_1 +RSA_padding_add_PKCS1_type_2 +RSA_padding_add_none +RSA_padding_check_PKCS1_OAEP_mgf1 +RSA_padding_check_PKCS1_type_1 +RSA_padding_check_PKCS1_type_2 +RSA_private_decrypt +RSA_private_encrypt +RSA_private_transform +RSA_public_decrypt +RSA_public_encrypt +RSA_set0_crt_params +RSA_set0_factors +RSA_set0_key +RSA_set_ex_data +RSA_sign +RSA_sign_pss_mgf1 +RSA_sign_raw +RSA_size +RSA_up_ref +RSA_verify +RSA_verify_PKCS1_PSS_mgf1 +RSA_verify_pss_mgf1 +RSA_verify_raw +SHA1 +SHA1_Final +SHA1_Init +SHA1_Transform +SHA1_Update +SHA224 +SHA224_Final +SHA224_Init +SHA224_Update +SHA256 +SHA256_Final +SHA256_Init +SHA256_Transform +SHA256_Update +SHA384 +SHA384_Final +SHA384_Init +SHA384_Update +SHA512 +SHA512_Final +SHA512_Init +SHA512_Transform +SHA512_Update +aes_ctr_set_key +bn_abs_sub_consttime +bn_add_words +bn_copy_words +bn_div_consttime +bn_expand +bn_fits_in_words +bn_from_montgomery_small +bn_in_range_words +bn_is_bit_set_words +bn_is_relatively_prime +bn_jacobi +bn_lcm_consttime +bn_less_than_montgomery_R +bn_less_than_words +bn_minimal_width +bn_mod_add_consttime +bn_mod_exp_base_2_consttime +bn_mod_exp_mont_small +bn_mod_inverse_consttime +bn_mod_inverse_prime +bn_mod_inverse_prime_mont_small +bn_mod_inverse_secret_prime +bn_mod_lshift1_consttime +bn_mod_lshift_consttime +bn_mod_mul_montgomery_small +bn_mod_sub_consttime +bn_mod_u16_consttime +bn_mont_n0 +bn_mul_add_words +bn_mul_comba4 +bn_mul_comba8 +bn_mul_consttime +bn_mul_small +bn_mul_words +bn_odd_number_is_obviously_composite +bn_one_to_montgomery +bn_one_to_montgomery_small +bn_rand_range_words +bn_rand_secret_range +bn_resize_words +bn_rshift1_words +bn_rshift_secret_shift +bn_select_words +bn_set_minimal_width +bn_set_words +bn_sqr_comba4 +bn_sqr_comba8 +bn_sqr_consttime +bn_sqr_small +bn_sqr_words +bn_sub_words +bn_to_montgomery_small +bn_uadd_consttime +bn_usub_consttime +bn_wexpand +crypto_gcm_clmul_enabled +ec_GFp_mont_field_decode +ec_GFp_mont_field_encode +ec_GFp_mont_field_mul +ec_GFp_mont_field_sqr +ec_GFp_mont_group_finish +ec_GFp_mont_group_init +ec_GFp_mont_group_set_curve +ec_GFp_nistp_recode_scalar_bits +ec_GFp_simple_add +ec_GFp_simple_cmp +ec_GFp_simple_dbl +ec_GFp_simple_field_mul +ec_GFp_simple_field_sqr +ec_GFp_simple_group_finish +ec_GFp_simple_group_get_curve +ec_GFp_simple_group_get_degree +ec_GFp_simple_group_init +ec_GFp_simple_group_set_curve +ec_GFp_simple_invert +ec_GFp_simple_is_at_infinity +ec_GFp_simple_is_on_curve +ec_GFp_simple_make_affine +ec_GFp_simple_point_copy +ec_GFp_simple_point_finish +ec_GFp_simple_point_init +ec_GFp_simple_point_set_affine_coordinates +ec_GFp_simple_point_set_to_infinity +ec_GFp_simple_points_make_affine +ec_bignum_to_scalar +ec_bignum_to_scalar_unchecked +ec_compute_wNAF +ec_group_new +ec_point_mul_scalar +ec_point_mul_scalar_public +ec_random_nonzero_scalar +ec_wNAF_mul +kBoringSSLRSASqrtTwo +kBoringSSLRSASqrtTwoLen +md4_block_data_order +rsa_default_decrypt +rsa_default_private_transform +rsa_default_sign_raw +rsa_default_size +FIPS_mode +aesni_gcm_decrypt +aesni_gcm_encrypt +aesni_cbc_encrypt +aesni_ccm64_decrypt_blocks +aesni_ccm64_encrypt_blocks +aesni_ctr32_encrypt_blocks +aesni_decrypt +aesni_ecb_encrypt +aesni_encrypt +aesni_ocb_decrypt +aesni_ocb_encrypt +aesni_set_decrypt_key +aesni_set_encrypt_key +aesni_xts_decrypt +aesni_xts_encrypt +asm_AES_cbc_encrypt +asm_AES_decrypt +asm_AES_encrypt +asm_AES_set_decrypt_key +asm_AES_set_encrypt_key +bsaes_cbc_encrypt +bsaes_ctr32_encrypt_blocks +bsaes_xts_decrypt +bsaes_xts_encrypt +gcm_ghash_4bit +gcm_ghash_avx +gcm_ghash_clmul +gcm_gmult_4bit +gcm_gmult_avx +gcm_gmult_clmul +gcm_init_avx +gcm_init_clmul +md5_block_asm_data_order +ecp_nistz256_avx2_select_w7 +ecp_nistz256_mul_mont +ecp_nistz256_neg +ecp_nistz256_point_add +ecp_nistz256_point_add_affine +ecp_nistz256_point_double +ecp_nistz256_select_w5 +ecp_nistz256_select_w7 +ecp_nistz256_sqr_mont +CRYPTO_rdrand +CRYPTO_rdrand_multiple8_buf +rsaz_1024_gather5_avx2 +rsaz_1024_mul_avx2 +rsaz_1024_norm2red_avx2 +rsaz_1024_red2norm_avx2 +rsaz_1024_scatter5_avx2 +rsaz_1024_sqr_avx2 +rsaz_avx2_eligible +sha1_block_data_order +sha256_block_data_order +sha512_block_data_order +vpaes_cbc_encrypt +vpaes_decrypt +vpaes_encrypt +vpaes_set_decrypt_key +vpaes_set_encrypt_key +bn_from_montgomery +bn_gather5 +bn_mul_mont_gather5 +bn_power5 +bn_scatter5 +bn_sqr8x_internal +bn_mul_mont +EVP_get_digestbyname +EVP_get_digestbynid +EVP_get_digestbyobj +EVP_marshal_digest_algorithm +EVP_parse_digest_algorithm +EVP_get_cipherbyname +EVP_get_cipherbynid +EVP_BytesToKey +EVP_enc_null +EVP_rc2_40_cbc +EVP_rc2_cbc +EVP_rc4 +EVP_aead_aes_128_gcm_siv +EVP_aead_aes_256_gcm_siv +EVP_aead_aes_128_ctr_hmac_sha256 +EVP_aead_aes_256_ctr_hmac_sha256 +EVP_aead_aes_128_ccm_bluetooth +EVP_aead_aes_128_ccm_bluetooth_8 +EVP_aead_chacha20_poly1305 +EVP_tls_cbc_copy_mac +EVP_tls_cbc_digest_record +EVP_tls_cbc_record_digest_supported +EVP_tls_cbc_remove_padding +EVP_aead_aes_128_cbc_sha1_tls +EVP_aead_aes_128_cbc_sha1_tls_implicit_iv +EVP_aead_aes_128_cbc_sha256_tls +EVP_aead_aes_256_cbc_sha1_tls +EVP_aead_aes_256_cbc_sha1_tls_implicit_iv +EVP_aead_aes_256_cbc_sha256_tls +EVP_aead_aes_256_cbc_sha384_tls +EVP_aead_des_ede3_cbc_sha1_tls +EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv +EVP_aead_null_sha1_tls +EVP_aead_aes_128_cbc_sha1_ssl3 +EVP_aead_aes_256_cbc_sha1_ssl3 +EVP_aead_des_ede3_cbc_sha1_ssl3 +EVP_aead_null_sha1_ssl3 +aes128gcmsiv_aes_ks +aes128gcmsiv_aes_ks_enc_x1 +aes128gcmsiv_dec +aes128gcmsiv_ecb_enc_block +aes128gcmsiv_enc_msg_x4 +aes128gcmsiv_enc_msg_x8 +aes128gcmsiv_kdf +aes256gcmsiv_aes_ks +aes256gcmsiv_aes_ks_enc_x1 +aes256gcmsiv_dec +aes256gcmsiv_ecb_enc_block +aes256gcmsiv_enc_msg_x4 +aes256gcmsiv_enc_msg_x8 +aes256gcmsiv_kdf +aesgcmsiv_htable6_init +aesgcmsiv_htable_init +aesgcmsiv_htable_polyval +aesgcmsiv_polyval_horner +chacha20_poly1305_open +chacha20_poly1305_seal +RC4 +RC4_set_key +CONF_VALUE_new +CONF_modules_free +CONF_modules_load_file +CONF_parse_list +NCONF_free +NCONF_get_section +NCONF_get_string +NCONF_load +NCONF_load_bio +NCONF_new +OPENSSL_config +OPENSSL_no_config +CRYPTO_chacha_20 +ChaCha20_ctr32 +CRYPTO_poly1305_finish +CRYPTO_poly1305_init +CRYPTO_poly1305_update +SPAKE2_CTX_free +SPAKE2_CTX_new +SPAKE2_generate_msg +SPAKE2_process_msg +ED25519_keypair +ED25519_keypair_from_seed +ED25519_sign +ED25519_verify +X25519 +X25519_keypair +X25519_public_from_private +x25519_ge_add +x25519_ge_frombytes_vartime +x25519_ge_p1p1_to_p2 +x25519_ge_p1p1_to_p3 +x25519_ge_p3_to_cached +x25519_ge_scalarmult +x25519_ge_scalarmult_base +x25519_ge_scalarmult_small_precomp +x25519_ge_sub +x25519_ge_tobytes +x25519_sc_reduce +BUF_MEM_append +BUF_MEM_free +BUF_MEM_grow +BUF_MEM_grow_clean +BUF_MEM_new +BUF_MEM_reserve +BUF_memdup +BUF_strdup +BUF_strlcat +BUF_strlcpy +BUF_strndup +BUF_strnlen +BN_marshal_asn1 +BN_parse_asn1_unsigned +BN_asc2bn +BN_bn2cbb_padded +BN_bn2dec +BN_bn2hex +BN_bn2mpi +BN_dec2bn +BN_hex2bn +BN_mpi2bn +BN_print +BN_print_fp +BIO_callback_ctrl +BIO_clear_flags +BIO_clear_retry_flags +BIO_copy_next_retry +BIO_ctrl +BIO_ctrl_pending +BIO_eof +BIO_find_type +BIO_flush +BIO_free +BIO_free_all +BIO_get_data +BIO_get_init +BIO_get_new_index +BIO_get_retry_flags +BIO_get_retry_reason +BIO_get_shutdown +BIO_gets +BIO_indent +BIO_int_ctrl +BIO_meth_free +BIO_meth_new +BIO_meth_set_create +BIO_meth_set_ctrl +BIO_meth_set_destroy +BIO_meth_set_gets +BIO_meth_set_puts +BIO_meth_set_read +BIO_meth_set_write +BIO_method_type +BIO_new +BIO_next +BIO_number_read +BIO_number_written +BIO_pending +BIO_pop +BIO_ptr_ctrl +BIO_push +BIO_puts +BIO_read +BIO_read_asn1 +BIO_reset +BIO_set_close +BIO_set_data +BIO_set_flags +BIO_set_init +BIO_set_retry_read +BIO_set_retry_special +BIO_set_retry_write +BIO_set_shutdown +BIO_set_write_buffer_size +BIO_should_io_special +BIO_should_read +BIO_should_retry +BIO_should_write +BIO_test_flags +BIO_up_ref +BIO_vfree +BIO_wpending +BIO_write +ERR_print_errors +BIO_get_mem_data +BIO_get_mem_ptr +BIO_mem_contents +BIO_new_mem_buf +BIO_s_mem +BIO_set_mem_buf +BIO_set_mem_eof_return +BIO_do_connect +BIO_new_connect +BIO_s_connect +BIO_set_conn_hostname +BIO_set_conn_int_port +BIO_set_conn_port +BIO_set_nbio +BIO_get_fd +BIO_new_fd +BIO_s_fd +BIO_set_fd +bio_fd_should_retry +BIO_append_filename +BIO_get_fp +BIO_new_file +BIO_new_fp +BIO_read_filename +BIO_rw_filename +BIO_s_file +BIO_set_fp +BIO_write_filename +BIO_hexdump +BIO_ctrl_get_read_request +BIO_ctrl_get_write_guarantee +BIO_new_bio_pair +BIO_shutdown_wr +BIO_printf +BIO_new_socket +BIO_s_socket +bio_clear_socket_error +bio_ip_and_port_to_socket_and_addr +bio_sock_error +bio_socket_nbio +RAND_enable_fork_unsafe_buffering +rand_fork_unsafe_buffering_enabled +RAND_SSLeay +RAND_add +RAND_cleanup +RAND_egd +RAND_file_name +RAND_get_rand_method +RAND_load_file +RAND_poll +RAND_seed +RAND_set_rand_method +RAND_status +OBJ_cbs2nid +OBJ_cmp +OBJ_create +OBJ_dup +OBJ_get0_data +OBJ_length +OBJ_ln2nid +OBJ_nid2cbb +OBJ_nid2ln +OBJ_nid2obj +OBJ_nid2sn +OBJ_obj2nid +OBJ_obj2txt +OBJ_sn2nid +OBJ_txt2nid +OBJ_txt2obj +OBJ_find_sigid_algs +OBJ_find_sigid_by_algs +ASN1_BIT_STRING_check +ASN1_BIT_STRING_get_bit +ASN1_BIT_STRING_set +ASN1_BIT_STRING_set_bit +c2i_ASN1_BIT_STRING +i2c_ASN1_BIT_STRING +d2i_ASN1_BOOLEAN +i2d_ASN1_BOOLEAN +ASN1_d2i_bio +ASN1_d2i_fp +ASN1_item_d2i_bio +ASN1_item_d2i_fp +ASN1_dup +ASN1_item_dup +ASN1_ENUMERATED_get +ASN1_ENUMERATED_set +ASN1_ENUMERATED_to_BN +BN_to_ASN1_ENUMERATED +ASN1_GENERALIZEDTIME_adj +ASN1_GENERALIZEDTIME_check +ASN1_GENERALIZEDTIME_set +ASN1_GENERALIZEDTIME_set_string +asn1_generalizedtime_to_tm +ASN1_i2d_bio +ASN1_i2d_fp +ASN1_item_i2d_bio +ASN1_item_i2d_fp +ASN1_INTEGER_cmp +ASN1_INTEGER_dup +ASN1_INTEGER_get +ASN1_INTEGER_set +ASN1_INTEGER_set_uint64 +ASN1_INTEGER_to_BN +BN_to_ASN1_INTEGER +c2i_ASN1_INTEGER +d2i_ASN1_UINTEGER +i2c_ASN1_INTEGER +ASN1_mbstring_copy +ASN1_mbstring_ncopy +ASN1_OBJECT_create +ASN1_OBJECT_free +ASN1_OBJECT_new +c2i_ASN1_OBJECT +d2i_ASN1_OBJECT +i2a_ASN1_OBJECT +i2d_ASN1_OBJECT +i2t_ASN1_OBJECT +ASN1_OCTET_STRING_cmp +ASN1_OCTET_STRING_dup +ASN1_OCTET_STRING_set +ASN1_PRINTABLE_type +ASN1_STRING_TABLE_add +ASN1_STRING_TABLE_cleanup +ASN1_STRING_TABLE_get +ASN1_STRING_get_default_mask +ASN1_STRING_set_by_NID +ASN1_STRING_set_default_mask +ASN1_STRING_set_default_mask_asc +ASN1_TIME_adj +ASN1_TIME_check +ASN1_TIME_diff +ASN1_TIME_free +ASN1_TIME_it +ASN1_TIME_new +ASN1_TIME_set +ASN1_TIME_set_string +ASN1_TIME_to_generalizedtime +d2i_ASN1_TIME +i2d_ASN1_TIME +ASN1_TYPE_cmp +ASN1_TYPE_get +ASN1_TYPE_set +ASN1_TYPE_set1 +ASN1_UTCTIME_adj +ASN1_UTCTIME_check +ASN1_UTCTIME_cmp_time_t +ASN1_UTCTIME_set +ASN1_UTCTIME_set_string +asn1_utctime_to_tm +UTF8_getc +UTF8_putc +ASN1_STRING_cmp +ASN1_STRING_copy +ASN1_STRING_data +ASN1_STRING_dup +ASN1_STRING_free +ASN1_STRING_get0_data +ASN1_STRING_length +ASN1_STRING_length_set +ASN1_STRING_new +ASN1_STRING_set +ASN1_STRING_set0 +ASN1_STRING_type +ASN1_STRING_type_new +ASN1_get_object +ASN1_object_size +ASN1_put_eoc +ASN1_put_object +ASN1_tag2str +ASN1_item_pack +ASN1_item_unpack +i2a_ASN1_ENUMERATED +i2a_ASN1_INTEGER +i2a_ASN1_STRING +ASN1_item_d2i +ASN1_item_ex_d2i +ASN1_tag2bit +asn1_ex_c2i +ASN1_item_ex_i2d +ASN1_item_i2d +ASN1_item_ndef_i2d +asn1_ex_i2c +ASN1_item_ex_free +ASN1_item_free +ASN1_primitive_free +ASN1_template_free +asn1_item_combine_free +ASN1_item_ex_new +ASN1_item_new +ASN1_primitive_new +ASN1_template_new +ASN1_ANY_it +ASN1_BIT_STRING_free +ASN1_BIT_STRING_it +ASN1_BIT_STRING_new +ASN1_BMPSTRING_free +ASN1_BMPSTRING_it +ASN1_BMPSTRING_new +ASN1_BOOLEAN_it +ASN1_ENUMERATED_free +ASN1_ENUMERATED_it +ASN1_ENUMERATED_new +ASN1_FBOOLEAN_it +ASN1_GENERALIZEDTIME_free +ASN1_GENERALIZEDTIME_it +ASN1_GENERALIZEDTIME_new +ASN1_GENERALSTRING_free +ASN1_GENERALSTRING_it +ASN1_GENERALSTRING_new +ASN1_IA5STRING_free +ASN1_IA5STRING_it +ASN1_IA5STRING_new +ASN1_INTEGER_free +ASN1_INTEGER_it +ASN1_INTEGER_new +ASN1_NULL_free +ASN1_NULL_it +ASN1_NULL_new +ASN1_OBJECT_it +ASN1_OCTET_STRING_NDEF_it +ASN1_OCTET_STRING_free +ASN1_OCTET_STRING_it +ASN1_OCTET_STRING_new +ASN1_PRINTABLESTRING_free +ASN1_PRINTABLESTRING_it +ASN1_PRINTABLESTRING_new +ASN1_PRINTABLE_free +ASN1_PRINTABLE_it +ASN1_PRINTABLE_new +ASN1_SEQUENCE_ANY_it +ASN1_SEQUENCE_it +ASN1_SET_ANY_it +ASN1_T61STRING_free +ASN1_T61STRING_it +ASN1_T61STRING_new +ASN1_TBOOLEAN_it +ASN1_TYPE_free +ASN1_TYPE_new +ASN1_UNIVERSALSTRING_free +ASN1_UNIVERSALSTRING_it +ASN1_UNIVERSALSTRING_new +ASN1_UTCTIME_free +ASN1_UTCTIME_it +ASN1_UTCTIME_new +ASN1_UTF8STRING_free +ASN1_UTF8STRING_it +ASN1_UTF8STRING_new +ASN1_VISIBLESTRING_free +ASN1_VISIBLESTRING_it +ASN1_VISIBLESTRING_new +DIRECTORYSTRING_free +DIRECTORYSTRING_it +DIRECTORYSTRING_new +DISPLAYTEXT_free +DISPLAYTEXT_it +DISPLAYTEXT_new +d2i_ASN1_BIT_STRING +d2i_ASN1_BMPSTRING +d2i_ASN1_ENUMERATED +d2i_ASN1_GENERALIZEDTIME +d2i_ASN1_GENERALSTRING +d2i_ASN1_IA5STRING +d2i_ASN1_INTEGER +d2i_ASN1_NULL +d2i_ASN1_OCTET_STRING +d2i_ASN1_PRINTABLE +d2i_ASN1_PRINTABLESTRING +d2i_ASN1_SEQUENCE_ANY +d2i_ASN1_SET_ANY +d2i_ASN1_T61STRING +d2i_ASN1_TYPE +d2i_ASN1_UNIVERSALSTRING +d2i_ASN1_UTCTIME +d2i_ASN1_UTF8STRING +d2i_ASN1_VISIBLESTRING +d2i_DIRECTORYSTRING +d2i_DISPLAYTEXT +i2d_ASN1_BIT_STRING +i2d_ASN1_BMPSTRING +i2d_ASN1_ENUMERATED +i2d_ASN1_GENERALIZEDTIME +i2d_ASN1_GENERALSTRING +i2d_ASN1_IA5STRING +i2d_ASN1_INTEGER +i2d_ASN1_NULL +i2d_ASN1_OCTET_STRING +i2d_ASN1_PRINTABLE +i2d_ASN1_PRINTABLESTRING +i2d_ASN1_SEQUENCE_ANY +i2d_ASN1_SET_ANY +i2d_ASN1_T61STRING +i2d_ASN1_TYPE +i2d_ASN1_UNIVERSALSTRING +i2d_ASN1_UTCTIME +i2d_ASN1_UTF8STRING +i2d_ASN1_VISIBLESTRING +i2d_DIRECTORYSTRING +i2d_DISPLAYTEXT +asn1_do_adb +asn1_enc_free +asn1_enc_init +asn1_enc_restore +asn1_enc_save +asn1_get_choice_selector +asn1_get_field_ptr +asn1_refcount_dec_and_test_zero +asn1_refcount_set_one +asn1_set_choice_selector +OPENSSL_gmtime +OPENSSL_gmtime_adj +OPENSSL_gmtime_diff +ENGINE_free +ENGINE_get_ECDSA_method +ENGINE_get_RSA_method +ENGINE_new +ENGINE_set_ECDSA_method +ENGINE_set_RSA_method +METHOD_ref +METHOD_unref +DH_compute_key +DH_free +DH_generate_key +DH_generate_parameters_ex +DH_get0_key +DH_get0_pqg +DH_get_ex_data +DH_get_ex_new_index +DH_new +DH_num_bits +DH_set0_key +DH_set0_pqg +DH_set_ex_data +DH_size +DH_up_ref +DHparams_dup +BN_get_rfc3526_prime_1536 +DH_check +DH_check_pub_key +DH_marshal_parameters +DH_parse_parameters +d2i_DHparams +i2d_DHparams +DSA_SIG_free +DSA_SIG_new +DSA_check_signature +DSA_do_check_signature +DSA_do_sign +DSA_do_verify +DSA_dup_DH +DSA_free +DSA_generate_key +DSA_generate_parameters_ex +DSA_get0_key +DSA_get0_pqg +DSA_get_ex_data +DSA_get_ex_new_index +DSA_new +DSA_set0_key +DSA_set0_pqg +DSA_set_ex_data +DSA_sign +DSA_size +DSA_up_ref +DSA_verify +DSAparams_dup +DSA_SIG_marshal +DSA_SIG_parse +DSA_marshal_parameters +DSA_marshal_private_key +DSA_marshal_public_key +DSA_parse_parameters +DSA_parse_private_key +DSA_parse_public_key +d2i_DSAPrivateKey +d2i_DSAPublicKey +d2i_DSA_SIG +d2i_DSAparams +i2d_DSAPrivateKey +i2d_DSAPublicKey +i2d_DSA_SIG +i2d_DSAparams +RSAPrivateKey_dup +RSAPublicKey_dup +RSA_marshal_private_key +RSA_marshal_public_key +RSA_parse_private_key +RSA_parse_public_key +RSA_private_key_from_bytes +RSA_private_key_to_bytes +RSA_public_key_from_bytes +RSA_public_key_to_bytes +d2i_RSAPrivateKey +d2i_RSAPublicKey +i2d_RSAPrivateKey +i2d_RSAPublicKey +EC_KEY_marshal_curve_name +EC_KEY_marshal_private_key +EC_KEY_parse_curve_name +EC_KEY_parse_parameters +EC_KEY_parse_private_key +EC_POINT_point2cbb +d2i_ECParameters +d2i_ECPrivateKey +i2d_ECParameters +i2d_ECPrivateKey +i2o_ECPublicKey +o2i_ECPublicKey +ECDH_compute_key +ECDSA_SIG_from_bytes +ECDSA_SIG_marshal +ECDSA_SIG_max_len +ECDSA_SIG_parse +ECDSA_SIG_to_bytes +ECDSA_sign +ECDSA_size +ECDSA_verify +d2i_ECDSA_SIG +i2d_ECDSA_SIG +AES_CMAC +CMAC_CTX_free +CMAC_CTX_new +CMAC_Final +CMAC_Init +CMAC_Reset +CMAC_Update +EVP_DigestSign +EVP_DigestSignFinal +EVP_DigestSignInit +EVP_DigestSignUpdate +EVP_DigestVerify +EVP_DigestVerifyFinal +EVP_DigestVerifyInit +EVP_DigestVerifyUpdate +EVP_PKEY_CTX_get_signature_md +EVP_PKEY_CTX_set_signature_md +EVP_PKEY_assign +EVP_PKEY_assign_DSA +EVP_PKEY_assign_EC_KEY +EVP_PKEY_assign_RSA +EVP_PKEY_bits +EVP_PKEY_cmp +EVP_PKEY_cmp_parameters +EVP_PKEY_copy_parameters +EVP_PKEY_free +EVP_PKEY_get0_DH +EVP_PKEY_get0_DSA +EVP_PKEY_get0_EC_KEY +EVP_PKEY_get0_RSA +EVP_PKEY_get1_DSA +EVP_PKEY_get1_EC_KEY +EVP_PKEY_get1_RSA +EVP_PKEY_id +EVP_PKEY_is_opaque +EVP_PKEY_missing_parameters +EVP_PKEY_new +EVP_PKEY_set1_DSA +EVP_PKEY_set1_EC_KEY +EVP_PKEY_set1_RSA +EVP_PKEY_set_type +EVP_PKEY_size +EVP_PKEY_type +EVP_PKEY_up_ref +EVP_cleanup +OPENSSL_add_all_algorithms_conf +OpenSSL_add_all_algorithms +OpenSSL_add_all_ciphers +OpenSSL_add_all_digests +EVP_marshal_private_key +EVP_marshal_public_key +EVP_parse_private_key +EVP_parse_public_key +d2i_AutoPrivateKey +d2i_PrivateKey +i2d_PublicKey +EVP_PKEY_CTX_ctrl +EVP_PKEY_CTX_dup +EVP_PKEY_CTX_free +EVP_PKEY_CTX_get0_pkey +EVP_PKEY_CTX_new +EVP_PKEY_CTX_new_id +EVP_PKEY_decrypt +EVP_PKEY_decrypt_init +EVP_PKEY_derive +EVP_PKEY_derive_init +EVP_PKEY_derive_set_peer +EVP_PKEY_encrypt +EVP_PKEY_encrypt_init +EVP_PKEY_keygen +EVP_PKEY_keygen_init +EVP_PKEY_sign +EVP_PKEY_sign_init +EVP_PKEY_verify +EVP_PKEY_verify_init +EVP_PKEY_verify_recover +EVP_PKEY_verify_recover_init +dsa_asn1_meth +ec_pkey_meth +ec_asn1_meth +ed25519_pkey_meth +EVP_PKEY_new_ed25519_private +EVP_PKEY_new_ed25519_public +ed25519_asn1_meth +EVP_PKEY_CTX_get0_rsa_oaep_label +EVP_PKEY_CTX_get_rsa_mgf1_md +EVP_PKEY_CTX_get_rsa_oaep_md +EVP_PKEY_CTX_get_rsa_padding +EVP_PKEY_CTX_get_rsa_pss_saltlen +EVP_PKEY_CTX_set0_rsa_oaep_label +EVP_PKEY_CTX_set_rsa_keygen_bits +EVP_PKEY_CTX_set_rsa_keygen_pubexp +EVP_PKEY_CTX_set_rsa_mgf1_md +EVP_PKEY_CTX_set_rsa_oaep_md +EVP_PKEY_CTX_set_rsa_padding +EVP_PKEY_CTX_set_rsa_pss_saltlen +rsa_pkey_meth +rsa_asn1_meth +PKCS5_PBKDF2_HMAC +PKCS5_PBKDF2_HMAC_SHA1 +EVP_PKEY_print_params +EVP_PKEY_print_private +EVP_PKEY_print_public +EVP_PBE_scrypt +EVP_SignFinal +EVP_SignInit +EVP_SignInit_ex +EVP_SignUpdate +EVP_VerifyFinal +EVP_VerifyInit +EVP_VerifyInit_ex +EVP_VerifyUpdate +HKDF +HKDF_expand +HKDF_extract +PEM_read_DSAPrivateKey +PEM_read_DSA_PUBKEY +PEM_read_DSAparams +PEM_read_ECPrivateKey +PEM_read_EC_PUBKEY +PEM_read_PUBKEY +PEM_read_RSAPrivateKey +PEM_read_RSAPublicKey +PEM_read_RSA_PUBKEY +PEM_read_X509_CRL +PEM_read_X509_REQ +PEM_read_bio_DSAPrivateKey +PEM_read_bio_DSA_PUBKEY +PEM_read_bio_DSAparams +PEM_read_bio_ECPrivateKey +PEM_read_bio_EC_PUBKEY +PEM_read_bio_PUBKEY +PEM_read_bio_RSAPrivateKey +PEM_read_bio_RSAPublicKey +PEM_read_bio_RSA_PUBKEY +PEM_read_bio_X509_CRL +PEM_read_bio_X509_REQ +PEM_write_DHparams +PEM_write_DSAPrivateKey +PEM_write_DSA_PUBKEY +PEM_write_DSAparams +PEM_write_ECPrivateKey +PEM_write_EC_PUBKEY +PEM_write_PUBKEY +PEM_write_RSAPrivateKey +PEM_write_RSAPublicKey +PEM_write_RSA_PUBKEY +PEM_write_X509_CRL +PEM_write_X509_REQ +PEM_write_X509_REQ_NEW +PEM_write_bio_DHparams +PEM_write_bio_DSAPrivateKey +PEM_write_bio_DSA_PUBKEY +PEM_write_bio_DSAparams +PEM_write_bio_ECPrivateKey +PEM_write_bio_EC_PUBKEY +PEM_write_bio_PUBKEY +PEM_write_bio_RSAPrivateKey +PEM_write_bio_RSAPublicKey +PEM_write_bio_RSA_PUBKEY +PEM_write_bio_X509_CRL +PEM_write_bio_X509_REQ +PEM_write_bio_X509_REQ_NEW +PEM_X509_INFO_read +PEM_X509_INFO_read_bio +PEM_X509_INFO_write_bio +PEM_ASN1_read +PEM_ASN1_write +PEM_ASN1_write_bio +PEM_bytes_read_bio +PEM_def_callback +PEM_dek_info +PEM_do_header +PEM_get_EVP_CIPHER_INFO +PEM_proc_type +PEM_read +PEM_read_bio +PEM_write +PEM_write_bio +PEM_ASN1_read_bio +PEM_read_PKCS8 +PEM_read_PKCS8_PRIV_KEY_INFO +PEM_read_bio_PKCS8 +PEM_read_bio_PKCS8_PRIV_KEY_INFO +PEM_write_PKCS8 +PEM_write_PKCS8PrivateKey +PEM_write_PKCS8PrivateKey_nid +PEM_write_PKCS8_PRIV_KEY_INFO +PEM_write_bio_PKCS8 +PEM_write_bio_PKCS8PrivateKey +PEM_write_bio_PKCS8PrivateKey_nid +PEM_write_bio_PKCS8_PRIV_KEY_INFO +d2i_PKCS8PrivateKey_bio +d2i_PKCS8PrivateKey_fp +i2d_PKCS8PrivateKey_bio +i2d_PKCS8PrivateKey_fp +i2d_PKCS8PrivateKey_nid_bio +i2d_PKCS8PrivateKey_nid_fp +PEM_read_DHparams +PEM_read_PrivateKey +PEM_read_bio_DHparams +PEM_read_bio_PrivateKey +PEM_write_PrivateKey +PEM_write_bio_PrivateKey +PEM_read_X509 +PEM_read_bio_X509 +PEM_write_X509 +PEM_write_bio_X509 +PEM_read_X509_AUX +PEM_read_bio_X509_AUX +PEM_write_X509_AUX +PEM_write_bio_X509_AUX +ASN1_digest +ASN1_item_digest +ASN1_item_sign +ASN1_item_sign_ctx +ASN1_STRING_print_ex +ASN1_STRING_print_ex_fp +ASN1_STRING_to_UTF8 +X509_NAME_print_ex +X509_NAME_print_ex_fp +ASN1_item_verify +x509_digest_sign_algorithm +x509_digest_verify_init +ASN1_generate_nconf +ASN1_generate_v3 +X509_LOOKUP_hash_dir +X509_LOOKUP_file +X509_load_cert_crl_file +X509_load_cert_file +X509_load_crl_file +i2d_PrivateKey +RSA_PSS_PARAMS_free +RSA_PSS_PARAMS_it +RSA_PSS_PARAMS_new +d2i_RSA_PSS_PARAMS +i2d_RSA_PSS_PARAMS +x509_print_rsa_pss_params +x509_rsa_ctx_to_pss +x509_rsa_pss_to_ctx +X509_CRL_print +X509_CRL_print_fp +X509_REQ_print +X509_REQ_print_ex +X509_REQ_print_fp +ASN1_GENERALIZEDTIME_print +ASN1_STRING_print +ASN1_TIME_print +ASN1_UTCTIME_print +X509_NAME_print +X509_ocspid_print +X509_print +X509_print_ex +X509_print_ex_fp +X509_print_fp +X509_signature_print +X509_CERT_AUX_print +PKCS8_pkey_get0 +PKCS8_pkey_set0 +X509_signature_dump +X509_ATTRIBUTE_count +X509_ATTRIBUTE_create_by_NID +X509_ATTRIBUTE_create_by_OBJ +X509_ATTRIBUTE_create_by_txt +X509_ATTRIBUTE_get0_data +X509_ATTRIBUTE_get0_object +X509_ATTRIBUTE_get0_type +X509_ATTRIBUTE_set1_data +X509_ATTRIBUTE_set1_object +X509at_add1_attr +X509at_add1_attr_by_NID +X509at_add1_attr_by_OBJ +X509at_add1_attr_by_txt +X509at_delete_attr +X509at_get0_data_by_OBJ +X509at_get_attr +X509at_get_attr_by_NID +X509at_get_attr_by_OBJ +X509at_get_attr_count +X509_CRL_check_suiteb +X509_CRL_cmp +X509_CRL_match +X509_NAME_cmp +X509_NAME_hash +X509_NAME_hash_old +X509_chain_check_suiteb +X509_chain_up_ref +X509_check_private_key +X509_cmp +X509_find_by_issuer_and_serial +X509_find_by_subject +X509_get0_pubkey_bitstr +X509_get_issuer_name +X509_get_pubkey +X509_get_serialNumber +X509_get_subject_name +X509_issuer_and_serial_cmp +X509_issuer_and_serial_hash +X509_issuer_name_cmp +X509_issuer_name_hash +X509_issuer_name_hash_old +X509_subject_name_cmp +X509_subject_name_hash +X509_subject_name_hash_old +X509_STORE_load_locations +X509_STORE_set_default_paths +X509_get_default_cert_area +X509_get_default_cert_dir +X509_get_default_cert_dir_env +X509_get_default_cert_file +X509_get_default_cert_file_env +X509_get_default_private_dir +X509_CRL_add1_ext_i2d +X509_CRL_add_ext +X509_CRL_delete_ext +X509_CRL_get_ext +X509_CRL_get_ext_by_NID +X509_CRL_get_ext_by_OBJ +X509_CRL_get_ext_by_critical +X509_CRL_get_ext_count +X509_CRL_get_ext_d2i +X509_REVOKED_add1_ext_i2d +X509_REVOKED_add_ext +X509_REVOKED_delete_ext +X509_REVOKED_get_ext +X509_REVOKED_get_ext_by_NID +X509_REVOKED_get_ext_by_OBJ +X509_REVOKED_get_ext_by_critical +X509_REVOKED_get_ext_count +X509_REVOKED_get_ext_d2i +X509_add1_ext_i2d +X509_add_ext +X509_delete_ext +X509_get_ext +X509_get_ext_by_NID +X509_get_ext_by_OBJ +X509_get_ext_by_critical +X509_get_ext_count +X509_get_ext_d2i +X509_LOOKUP_by_alias +X509_LOOKUP_by_fingerprint +X509_LOOKUP_by_issuer_serial +X509_LOOKUP_by_subject +X509_LOOKUP_ctrl +X509_LOOKUP_free +X509_LOOKUP_init +X509_LOOKUP_new +X509_LOOKUP_shutdown +X509_OBJECT_free_contents +X509_OBJECT_get0_X509 +X509_OBJECT_get_type +X509_OBJECT_idx_by_subject +X509_OBJECT_retrieve_by_subject +X509_OBJECT_retrieve_match +X509_OBJECT_up_ref_count +X509_STORE_CTX_get0_store +X509_STORE_CTX_get1_issuer +X509_STORE_add_cert +X509_STORE_add_crl +X509_STORE_add_lookup +X509_STORE_free +X509_STORE_get0_objects +X509_STORE_get0_param +X509_STORE_get1_certs +X509_STORE_get1_crls +X509_STORE_get_by_subject +X509_STORE_new +X509_STORE_set0_additional_untrusted +X509_STORE_set1_param +X509_STORE_set_depth +X509_STORE_set_flags +X509_STORE_set_lookup_crls_cb +X509_STORE_set_purpose +X509_STORE_set_trust +X509_STORE_set_verify_cb +X509_STORE_up_ref +X509_NAME_oneline +X509_REQ_to_X509 +X509_REQ_add1_attr +X509_REQ_add1_attr_by_NID +X509_REQ_add1_attr_by_OBJ +X509_REQ_add1_attr_by_txt +X509_REQ_add_extensions +X509_REQ_add_extensions_nid +X509_REQ_check_private_key +X509_REQ_delete_attr +X509_REQ_extension_nid +X509_REQ_get_attr +X509_REQ_get_attr_by_NID +X509_REQ_get_attr_by_OBJ +X509_REQ_get_attr_count +X509_REQ_get_extension_nids +X509_REQ_get_extensions +X509_REQ_get_pubkey +X509_REQ_set_extension_nids +X509_to_X509_REQ +X509_get0_extensions +X509_get0_notAfter +X509_get0_notBefore +X509_set_issuer_name +X509_set_notAfter +X509_set_notBefore +X509_set_pubkey +X509_set_serialNumber +X509_set_subject_name +X509_set_version +X509_TRUST_add +X509_TRUST_cleanup +X509_TRUST_get0 +X509_TRUST_get0_name +X509_TRUST_get_by_id +X509_TRUST_get_count +X509_TRUST_get_flags +X509_TRUST_get_trust +X509_TRUST_set +X509_TRUST_set_default +X509_check_trust +X509_verify_cert_error_string +X509_EXTENSION_create_by_NID +X509_EXTENSION_create_by_OBJ +X509_EXTENSION_get_critical +X509_EXTENSION_get_data +X509_EXTENSION_get_object +X509_EXTENSION_set_critical +X509_EXTENSION_set_data +X509_EXTENSION_set_object +X509v3_add_ext +X509v3_delete_ext +X509v3_get_ext +X509v3_get_ext_by_NID +X509v3_get_ext_by_OBJ +X509v3_get_ext_by_critical +X509v3_get_ext_count +X509_CRL_diff +X509_STORE_CTX_cleanup +X509_STORE_CTX_free +X509_STORE_CTX_get0_current_crl +X509_STORE_CTX_get0_current_issuer +X509_STORE_CTX_get0_param +X509_STORE_CTX_get0_parent_ctx +X509_STORE_CTX_get0_policy_tree +X509_STORE_CTX_get0_untrusted +X509_STORE_CTX_get1_chain +X509_STORE_CTX_get_chain +X509_STORE_CTX_get_current_cert +X509_STORE_CTX_get_error +X509_STORE_CTX_get_error_depth +X509_STORE_CTX_get_ex_data +X509_STORE_CTX_get_ex_new_index +X509_STORE_CTX_get_explicit_policy +X509_STORE_CTX_init +X509_STORE_CTX_new +X509_STORE_CTX_purpose_inherit +X509_STORE_CTX_set0_crls +X509_STORE_CTX_set0_param +X509_STORE_CTX_set_cert +X509_STORE_CTX_set_chain +X509_STORE_CTX_set_default +X509_STORE_CTX_set_depth +X509_STORE_CTX_set_error +X509_STORE_CTX_set_ex_data +X509_STORE_CTX_set_flags +X509_STORE_CTX_set_purpose +X509_STORE_CTX_set_time +X509_STORE_CTX_set_trust +X509_STORE_CTX_set_verify_cb +X509_STORE_CTX_trusted_stack +X509_STORE_CTX_zero +X509_cmp_current_time +X509_cmp_time +X509_gmtime_adj +X509_time_adj +X509_time_adj_ex +X509_verify_cert +X509_VERIFY_PARAM_add0_policy +X509_VERIFY_PARAM_add0_table +X509_VERIFY_PARAM_add1_host +X509_VERIFY_PARAM_clear_flags +X509_VERIFY_PARAM_free +X509_VERIFY_PARAM_get0 +X509_VERIFY_PARAM_get0_name +X509_VERIFY_PARAM_get0_peername +X509_VERIFY_PARAM_get_count +X509_VERIFY_PARAM_get_depth +X509_VERIFY_PARAM_get_flags +X509_VERIFY_PARAM_inherit +X509_VERIFY_PARAM_lookup +X509_VERIFY_PARAM_new +X509_VERIFY_PARAM_set1 +X509_VERIFY_PARAM_set1_email +X509_VERIFY_PARAM_set1_host +X509_VERIFY_PARAM_set1_ip +X509_VERIFY_PARAM_set1_ip_asc +X509_VERIFY_PARAM_set1_name +X509_VERIFY_PARAM_set1_policies +X509_VERIFY_PARAM_set_depth +X509_VERIFY_PARAM_set_flags +X509_VERIFY_PARAM_set_hostflags +X509_VERIFY_PARAM_set_purpose +X509_VERIFY_PARAM_set_time +X509_VERIFY_PARAM_set_trust +X509_VERIFY_PARAM_table_cleanup +X509_CRL_set_issuer_name +X509_CRL_set_lastUpdate +X509_CRL_set_nextUpdate +X509_CRL_set_version +X509_CRL_sort +X509_CRL_up_ref +X509_REVOKED_set_revocationDate +X509_REVOKED_set_serialNumber +X509_NAME_ENTRY_create_by_NID +X509_NAME_ENTRY_create_by_OBJ +X509_NAME_ENTRY_create_by_txt +X509_NAME_ENTRY_get_data +X509_NAME_ENTRY_get_object +X509_NAME_ENTRY_set_data +X509_NAME_ENTRY_set_object +X509_NAME_add_entry +X509_NAME_add_entry_by_NID +X509_NAME_add_entry_by_OBJ +X509_NAME_add_entry_by_txt +X509_NAME_delete_entry +X509_NAME_entry_count +X509_NAME_get_entry +X509_NAME_get_index_by_NID +X509_NAME_get_index_by_OBJ +X509_NAME_get_text_by_NID +X509_NAME_get_text_by_OBJ +X509_REQ_set_pubkey +X509_REQ_set_subject_name +X509_REQ_set_version +NETSCAPE_SPKI_b64_decode +NETSCAPE_SPKI_b64_encode +NETSCAPE_SPKI_get_pubkey +NETSCAPE_SPKI_set_pubkey +X509_ALGORS_it +X509_ALGOR_cmp +X509_ALGOR_dup +X509_ALGOR_free +X509_ALGOR_get0 +X509_ALGOR_it +X509_ALGOR_new +X509_ALGOR_set0 +X509_ALGOR_set_md +d2i_X509_ALGOR +d2i_X509_ALGORS +i2d_X509_ALGOR +i2d_X509_ALGORS +NETSCAPE_SPKI_sign +NETSCAPE_SPKI_verify +X509_CRL_digest +X509_CRL_sign +X509_CRL_sign_ctx +X509_NAME_digest +X509_REQ_digest +X509_REQ_sign +X509_REQ_sign_ctx +X509_REQ_verify +X509_digest +X509_pubkey_digest +X509_sign +X509_sign_ctx +X509_verify +d2i_DSAPrivateKey_bio +d2i_DSAPrivateKey_fp +d2i_DSA_PUBKEY_bio +d2i_DSA_PUBKEY_fp +d2i_ECPrivateKey_bio +d2i_ECPrivateKey_fp +d2i_EC_PUBKEY_bio +d2i_EC_PUBKEY_fp +d2i_PKCS8_PRIV_KEY_INFO_bio +d2i_PKCS8_PRIV_KEY_INFO_fp +d2i_PKCS8_bio +d2i_PKCS8_fp +d2i_PUBKEY_bio +d2i_PUBKEY_fp +d2i_PrivateKey_bio +d2i_PrivateKey_fp +d2i_RSAPrivateKey_bio +d2i_RSAPrivateKey_fp +d2i_RSAPublicKey_bio +d2i_RSAPublicKey_fp +d2i_RSA_PUBKEY_bio +d2i_RSA_PUBKEY_fp +d2i_X509_CRL_bio +d2i_X509_CRL_fp +d2i_X509_REQ_bio +d2i_X509_REQ_fp +d2i_X509_bio +d2i_X509_fp +i2d_DSAPrivateKey_bio +i2d_DSAPrivateKey_fp +i2d_DSA_PUBKEY_bio +i2d_DSA_PUBKEY_fp +i2d_ECPrivateKey_bio +i2d_ECPrivateKey_fp +i2d_EC_PUBKEY_bio +i2d_EC_PUBKEY_fp +i2d_PKCS8PrivateKeyInfo_bio +i2d_PKCS8PrivateKeyInfo_fp +i2d_PKCS8_PRIV_KEY_INFO_bio +i2d_PKCS8_PRIV_KEY_INFO_fp +i2d_PKCS8_bio +i2d_PKCS8_fp +i2d_PUBKEY_bio +i2d_PUBKEY_fp +i2d_PrivateKey_bio +i2d_PrivateKey_fp +i2d_RSAPrivateKey_bio +i2d_RSAPrivateKey_fp +i2d_RSAPublicKey_bio +i2d_RSAPublicKey_fp +i2d_RSA_PUBKEY_bio +i2d_RSA_PUBKEY_fp +i2d_X509_CRL_bio +i2d_X509_CRL_fp +i2d_X509_REQ_bio +i2d_X509_REQ_fp +i2d_X509_bio +i2d_X509_fp +X509_ATTRIBUTE_SET_it +X509_ATTRIBUTE_create +X509_ATTRIBUTE_dup +X509_ATTRIBUTE_free +X509_ATTRIBUTE_it +X509_ATTRIBUTE_new +d2i_X509_ATTRIBUTE +i2d_X509_ATTRIBUTE +X509_CRL_INFO_free +X509_CRL_INFO_it +X509_CRL_INFO_new +X509_CRL_METHOD_free +X509_CRL_METHOD_new +X509_CRL_add0_revoked +X509_CRL_dup +X509_CRL_free +X509_CRL_get0_by_cert +X509_CRL_get0_by_serial +X509_CRL_get_meth_data +X509_CRL_it +X509_CRL_new +X509_CRL_set_default_method +X509_CRL_set_meth_data +X509_CRL_verify +X509_REVOKED_dup +X509_REVOKED_free +X509_REVOKED_it +X509_REVOKED_new +d2i_X509_CRL +d2i_X509_CRL_INFO +d2i_X509_REVOKED +i2d_X509_CRL +i2d_X509_CRL_INFO +i2d_X509_REVOKED +X509_EXTENSIONS_it +X509_EXTENSION_dup +X509_EXTENSION_free +X509_EXTENSION_it +X509_EXTENSION_new +d2i_X509_EXTENSION +d2i_X509_EXTENSIONS +i2d_X509_EXTENSION +i2d_X509_EXTENSIONS +X509_INFO_free +X509_INFO_new +X509_NAME_ENTRIES_it +X509_NAME_ENTRY_dup +X509_NAME_ENTRY_free +X509_NAME_ENTRY_it +X509_NAME_ENTRY_new +X509_NAME_ENTRY_set +X509_NAME_INTERNAL_it +X509_NAME_dup +X509_NAME_free +X509_NAME_get0_der +X509_NAME_it +X509_NAME_new +X509_NAME_set +d2i_X509_NAME +d2i_X509_NAME_ENTRY +i2d_X509_NAME +i2d_X509_NAME_ENTRY +X509_PKEY_free +X509_PKEY_new +X509_PUBKEY_free +X509_PUBKEY_get +X509_PUBKEY_get0_param +X509_PUBKEY_it +X509_PUBKEY_new +X509_PUBKEY_set +X509_PUBKEY_set0_param +d2i_DSA_PUBKEY +d2i_EC_PUBKEY +d2i_PUBKEY +d2i_RSA_PUBKEY +d2i_X509_PUBKEY +i2d_DSA_PUBKEY +i2d_EC_PUBKEY +i2d_PUBKEY +i2d_RSA_PUBKEY +i2d_X509_PUBKEY +X509_REQ_INFO_free +X509_REQ_INFO_it +X509_REQ_INFO_new +X509_REQ_dup +X509_REQ_free +X509_REQ_it +X509_REQ_new +d2i_X509_REQ +d2i_X509_REQ_INFO +i2d_X509_REQ +i2d_X509_REQ_INFO +X509_SIG_free +X509_SIG_it +X509_SIG_new +d2i_X509_SIG +i2d_X509_SIG +NETSCAPE_SPKAC_free +NETSCAPE_SPKAC_it +NETSCAPE_SPKAC_new +NETSCAPE_SPKI_free +NETSCAPE_SPKI_it +NETSCAPE_SPKI_new +d2i_NETSCAPE_SPKAC +d2i_NETSCAPE_SPKI +i2d_NETSCAPE_SPKAC +i2d_NETSCAPE_SPKI +X509_VAL_free +X509_VAL_it +X509_VAL_new +d2i_X509_VAL +i2d_X509_VAL +X509_CINF_free +X509_CINF_it +X509_CINF_new +X509_dup +X509_free +X509_get0_signature +X509_get_ex_data +X509_get_ex_new_index +X509_get_signature_nid +X509_it +X509_new +X509_parse_from_buffer +X509_set_ex_data +X509_up_ref +d2i_X509 +d2i_X509_AUX +d2i_X509_CINF +i2d_X509 +i2d_X509_AUX +i2d_X509_CINF +X509_CERT_AUX_free +X509_CERT_AUX_it +X509_CERT_AUX_new +X509_add1_reject_object +X509_add1_trust_object +X509_alias_get0 +X509_alias_set1 +X509_keyid_get0 +X509_keyid_set1 +X509_reject_clear +X509_trust_clear +d2i_X509_CERT_AUX +i2d_X509_CERT_AUX +policy_cache_find_data +policy_cache_free +policy_cache_set +policy_data_free +policy_data_new +X509_policy_level_get0_node +X509_policy_level_node_count +X509_policy_node_get0_parent +X509_policy_node_get0_policy +X509_policy_node_get0_qualifiers +X509_policy_tree_get0_level +X509_policy_tree_get0_policies +X509_policy_tree_get0_user_policies +X509_policy_tree_level_count +policy_cache_set_mapping +level_add_node +level_find_node +policy_node_cmp_new +policy_node_free +policy_node_match +tree_find_sk +X509_policy_check +X509_policy_tree_free +v3_akey_id +AUTHORITY_KEYID_free +AUTHORITY_KEYID_it +AUTHORITY_KEYID_new +d2i_AUTHORITY_KEYID +i2d_AUTHORITY_KEYID +GENERAL_NAME_print +a2i_GENERAL_NAME +i2v_GENERAL_NAME +i2v_GENERAL_NAMES +v2i_GENERAL_NAME +v2i_GENERAL_NAMES +v2i_GENERAL_NAME_ex +v3_alt +BASIC_CONSTRAINTS_free +BASIC_CONSTRAINTS_it +BASIC_CONSTRAINTS_new +d2i_BASIC_CONSTRAINTS +i2d_BASIC_CONSTRAINTS +v3_bcons +i2v_ASN1_BIT_STRING +v2i_ASN1_BIT_STRING +v3_key_usage +v3_nscert +X509V3_EXT_CRL_add_nconf +X509V3_EXT_REQ_add_nconf +X509V3_EXT_add_nconf +X509V3_EXT_add_nconf_sk +X509V3_EXT_i2d +X509V3_EXT_nconf +X509V3_EXT_nconf_nid +X509V3_get_section +X509V3_get_string +X509V3_section_free +X509V3_set_ctx +X509V3_set_nconf +X509V3_string_free +CERTIFICATEPOLICIES_free +CERTIFICATEPOLICIES_it +CERTIFICATEPOLICIES_new +NOTICEREF_free +NOTICEREF_it +NOTICEREF_new +POLICYINFO_free +POLICYINFO_it +POLICYINFO_new +POLICYQUALINFO_free +POLICYQUALINFO_it +POLICYQUALINFO_new +USERNOTICE_free +USERNOTICE_it +USERNOTICE_new +X509_POLICY_NODE_print +d2i_CERTIFICATEPOLICIES +d2i_NOTICEREF +d2i_POLICYINFO +d2i_POLICYQUALINFO +d2i_USERNOTICE +i2d_CERTIFICATEPOLICIES +i2d_NOTICEREF +i2d_POLICYINFO +i2d_POLICYQUALINFO +i2d_USERNOTICE +v3_cpols +CRL_DIST_POINTS_free +CRL_DIST_POINTS_it +CRL_DIST_POINTS_new +DIST_POINT_NAME_free +DIST_POINT_NAME_it +DIST_POINT_NAME_new +DIST_POINT_free +DIST_POINT_it +DIST_POINT_new +DIST_POINT_set_dpname +ISSUING_DIST_POINT_free +ISSUING_DIST_POINT_it +ISSUING_DIST_POINT_new +d2i_CRL_DIST_POINTS +d2i_DIST_POINT +d2i_DIST_POINT_NAME +d2i_ISSUING_DIST_POINT +i2d_CRL_DIST_POINTS +i2d_DIST_POINT +i2d_DIST_POINT_NAME +i2d_ISSUING_DIST_POINT +v3_crld +v3_freshest_crl +v3_idp +i2s_ASN1_ENUMERATED_TABLE +v3_crl_reason +EXTENDED_KEY_USAGE_free +EXTENDED_KEY_USAGE_it +EXTENDED_KEY_USAGE_new +d2i_EXTENDED_KEY_USAGE +i2d_EXTENDED_KEY_USAGE +v3_ext_ku +v3_ocsp_accresp +EDIPARTYNAME_free +EDIPARTYNAME_it +EDIPARTYNAME_new +GENERAL_NAMES_free +GENERAL_NAMES_it +GENERAL_NAMES_new +GENERAL_NAME_cmp +GENERAL_NAME_dup +GENERAL_NAME_free +GENERAL_NAME_get0_otherName +GENERAL_NAME_get0_value +GENERAL_NAME_it +GENERAL_NAME_new +GENERAL_NAME_set0_othername +GENERAL_NAME_set0_value +OTHERNAME_cmp +OTHERNAME_free +OTHERNAME_it +OTHERNAME_new +d2i_EDIPARTYNAME +d2i_GENERAL_NAME +d2i_GENERAL_NAMES +d2i_OTHERNAME +i2d_EDIPARTYNAME +i2d_GENERAL_NAME +i2d_GENERAL_NAMES +i2d_OTHERNAME +v3_ns_ia5_list +ACCESS_DESCRIPTION_free +ACCESS_DESCRIPTION_it +ACCESS_DESCRIPTION_new +AUTHORITY_INFO_ACCESS_free +AUTHORITY_INFO_ACCESS_it +AUTHORITY_INFO_ACCESS_new +d2i_ACCESS_DESCRIPTION +d2i_AUTHORITY_INFO_ACCESS +i2a_ACCESS_DESCRIPTION +i2d_ACCESS_DESCRIPTION +i2d_AUTHORITY_INFO_ACCESS +v3_info +v3_sinfo +v3_crl_num +v3_delta_crl +v3_inhibit_anyp +X509V3_EXT_add +X509V3_EXT_add_alias +X509V3_EXT_add_list +X509V3_EXT_cleanup +X509V3_EXT_d2i +X509V3_EXT_free +X509V3_EXT_get +X509V3_EXT_get_nid +X509V3_add1_i2d +X509V3_add_standard_extensions +X509V3_get_d2i +GENERAL_SUBTREE_free +GENERAL_SUBTREE_it +GENERAL_SUBTREE_new +NAME_CONSTRAINTS_check +NAME_CONSTRAINTS_free +NAME_CONSTRAINTS_it +NAME_CONSTRAINTS_new +v3_name_constraints +v3_pci +PROXY_CERT_INFO_EXTENSION_free +PROXY_CERT_INFO_EXTENSION_it +PROXY_CERT_INFO_EXTENSION_new +PROXY_POLICY_free +PROXY_POLICY_it +PROXY_POLICY_new +d2i_PROXY_CERT_INFO_EXTENSION +d2i_PROXY_POLICY +i2d_PROXY_CERT_INFO_EXTENSION +i2d_PROXY_POLICY +POLICY_CONSTRAINTS_free +POLICY_CONSTRAINTS_it +POLICY_CONSTRAINTS_new +v3_policy_constraints +PKEY_USAGE_PERIOD_free +PKEY_USAGE_PERIOD_it +PKEY_USAGE_PERIOD_new +d2i_PKEY_USAGE_PERIOD +i2d_PKEY_USAGE_PERIOD +v3_pkey_usage_period +POLICY_MAPPINGS_it +POLICY_MAPPING_free +POLICY_MAPPING_it +POLICY_MAPPING_new +v3_policy_mappings +X509V3_EXT_print +X509V3_EXT_print_fp +X509V3_EXT_val_prn +X509V3_extensions_print +X509_PURPOSE_add +X509_PURPOSE_cleanup +X509_PURPOSE_get0 +X509_PURPOSE_get0_name +X509_PURPOSE_get0_sname +X509_PURPOSE_get_by_id +X509_PURPOSE_get_by_sname +X509_PURPOSE_get_count +X509_PURPOSE_get_id +X509_PURPOSE_get_trust +X509_PURPOSE_set +X509_check_akid +X509_check_ca +X509_check_issued +X509_check_purpose +X509_supported_extension +i2s_ASN1_OCTET_STRING +s2i_ASN1_OCTET_STRING +v3_skey_id +SXNETID_free +SXNETID_it +SXNETID_new +SXNET_add_id_INTEGER +SXNET_add_id_asc +SXNET_add_id_ulong +SXNET_free +SXNET_get_id_INTEGER +SXNET_get_id_asc +SXNET_get_id_ulong +SXNET_it +SXNET_new +d2i_SXNET +d2i_SXNETID +i2d_SXNET +i2d_SXNETID +v3_sxnet +X509V3_NAME_from_section +X509V3_add_value +X509V3_add_value_bool +X509V3_add_value_bool_nf +X509V3_add_value_int +X509V3_add_value_uchar +X509V3_conf_free +X509V3_get_value_bool +X509V3_get_value_int +X509V3_parse_list +X509_REQ_get1_email +X509_check_email +X509_check_host +X509_check_ip +X509_check_ip_asc +X509_email_free +X509_get1_email +X509_get1_ocsp +a2i_IPADDRESS +a2i_IPADDRESS_NC +a2i_ipadd +hex_to_string +i2s_ASN1_ENUMERATED +i2s_ASN1_INTEGER +name_cmp +s2i_ASN1_INTEGER +string_to_hex +PKCS7_get_raw_certificates +pkcs7_bundle +pkcs7_parse_header +PKCS7_bundle_CRLs +PKCS7_bundle_certificates +PKCS7_get_CRLs +PKCS7_get_PEM_CRLs +PKCS7_get_PEM_certificates +PKCS7_get_certificates +PKCS8_marshal_encrypted_private_key +PKCS8_parse_encrypted_private_key +pkcs12_key_gen +pkcs8_pbe_decrypt +EVP_PKCS82PKEY +EVP_PKEY2PKCS8 +PKCS12_PBE_add +PKCS12_free +PKCS12_get_key_and_certs +PKCS12_parse +PKCS12_verify_mac +PKCS8_PRIV_KEY_INFO_free +PKCS8_PRIV_KEY_INFO_it +PKCS8_PRIV_KEY_INFO_new +PKCS8_decrypt +PKCS8_encrypt +d2i_PKCS12 +d2i_PKCS12_bio +d2i_PKCS12_fp +d2i_PKCS8_PRIV_KEY_INFO +i2d_PKCS8_PRIV_KEY_INFO +PKCS5_pbe2_decrypt_init +PKCS5_pbe2_encrypt_init diff --git a/src/objective-c/tests/Connectivity/Podfile b/src/objective-c/tests/Connectivity/Podfile index c7127b3e78b..2c2344334c9 100644 --- a/src/objective-c/tests/Connectivity/Podfile +++ b/src/objective-c/tests/Connectivity/Podfile @@ -10,7 +10,7 @@ target 'ConnectivityTestingApp' do pod 'gRPC-ProtoRPC/CFStream', :path => GRPC_LOCAL_SRC pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf" - pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" end pre_install do |installer| diff --git a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m index a6dfb154a43..75a669da4d4 100644 --- a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m +++ b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m @@ -37,7 +37,9 @@ #import "test/core/end2end/data/ssl_test_data.h" #import "test/core/util/test_config.h" -#import +#import "src/core/tsi/grpc_shadow_boringssl.h" + +#import static void drain_cq(grpc_completion_queue *cq) { grpc_event ev; diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 3c2a34fb499..507d251b481 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -21,7 +21,7 @@ GRPC_LOCAL_SRC = '../../..' pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" - pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true pod 'gRPC', :path => GRPC_LOCAL_SRC pod 'gRPC-Core', :path => GRPC_LOCAL_SRC @@ -47,7 +47,7 @@ end pod '!ProtoCompiler', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" - pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true pod 'gRPC/CFStream', :path => GRPC_LOCAL_SRC pod 'gRPC-Core/CFStream-Implementation', :path => GRPC_LOCAL_SRC @@ -62,7 +62,7 @@ end CronetUnitTests ).each do |target_name| target target_name do - pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" pod 'gRPC-Core', :path => GRPC_LOCAL_SRC pod 'gRPC-Core/Cronet-Interface', :path => GRPC_LOCAL_SRC diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 8ff46335826..204fb7de374 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -1716,6 +1716,14 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_TESTABILITY = YES; GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + "$(inherited)", + "PB_FIELD_32BIT=1", + "PB_NO_PACKED_STRUCTS=1", + "GRPC_SHADOW_BORINGSSL_SYMBOLS=1", + ); INFOPLIST_FILE = CronetUnitTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index 5098f351db4..f912154301f 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -174,8 +174,9 @@ ss.header_mappings_dir = '.' ss.libraries = 'z' ss.dependency "#{s.name}/Interface", version - ss.dependency 'BoringSSL', '~> 10.0' + ss.dependency 'BoringSSL-GRPC', '0.0.1' ss.dependency 'nanopb', '~> 0.3' + ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS' # To save you from scrolling, this is the last part of the podspec. ss.source_files = ${ruby_multiline_list(grpc_private_files(libs), 22)} diff --git a/templates/src/core/tsi/grpc_shadow_boringssl.h.template b/templates/src/core/tsi/grpc_shadow_boringssl.h.template new file mode 100644 index 00000000000..0b5e6128810 --- /dev/null +++ b/templates/src/core/tsi/grpc_shadow_boringssl.h.template @@ -0,0 +1,40 @@ +%YAML 1.2 +--- | + <%! + def expand_symbol_list(symbol_list): + return '\n'.join('#define %s GRPC_SHADOW_%s' % (symbol, symbol) for symbol in symbol_list) + %> + /* + * + * 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. + * + */ + + // This file is autogenerated from a template file. Please make + // modifications to + // `templates/src/objective-c/tsi/grpc_shadow_boringssl.h.template` + // instead. This file can be regenerated from the template by running + // `tools/buildgen/generate_projects.sh`. + + #ifndef GRPC_CORE_TSI_GRPC_SHADOW_BORINGSSL_H + #define GRPC_CORE_TSI_GRPC_SHADOW_BORINGSSL_H + + #ifdef GRPC_SHADOW_BORINGSSL_SYMBOLS + + ${expand_symbol_list(settings.grpc_shadow_boringssl_symbols)} + + #endif /* GRPC_SHADOW_BORINGSSL_SYMBOLS */ + + #endif /* GRPC_CORE_TSI_GRPC_SHADOW_BORINGSSL_H */ diff --git a/templates/src/objective-c/BoringSSL-GRPC.podspec.template b/templates/src/objective-c/BoringSSL-GRPC.podspec.template new file mode 100644 index 00000000000..986216fdbfa --- /dev/null +++ b/templates/src/objective-c/BoringSSL-GRPC.podspec.template @@ -0,0 +1,1561 @@ +%YAML 1.2 +--- | + <%! + def expand_symbol_list(symbol_list): + return ',\n '.join("'#define %s GRPC_SHADOW_%s'" % (symbol, symbol) for symbol in symbol_list) + %> + # This file has been automatically generated from a template file. + # Please make modifications to + # `templates/src/objective-c/BoringSSL-GRPC.podspec.template` instead. This + # file can be regenerated from the template by running + # `tools/buildgen/generate_projects.sh`. + + # BoringSSL CocoaPods podspec + + # Copyright 2015, Google Inc. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are + # met: + # + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above + # copyright notice, this list of conditions and the following disclaimer + # in the documentation and/or other materials provided with the + # distribution. + # * Neither the name of Google Inc. nor the names of its + # contributors may be used to endorse or promote products derived from + # this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Pod::Spec.new do |s| + s.name = 'BoringSSL-GRPC' + version = '0.0.1' + s.version = version + s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.' + # Adapted from the homepage: + s.description = <<-DESC + BoringSSL is a fork of OpenSSL that is designed to meet Google's needs. + + Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. + We don't recommend that third parties depend upon it. Doing so is likely to be frustrating + because there are no guarantees of API stability. Only the latest version of this pod is + supported, and every new version is a new major version. + + We update Google libraries and programs that use BoringSSL as needed when deciding to make API + changes. This allows us to mostly avoid compromises in the name of compatibility. It works for + us, but it may not work for you. + + As a Cocoapods pod, it has the advantage over OpenSSL's pods that the library doesn't need to + be precompiled. This eliminates the 10 - 20 minutes of wait the first time a user does "pod + install", lets it be used as a dynamic framework (pending solution of Cocoapods' issue #4605), + and works with bitcode automatically. It's also thought to be smaller than OpenSSL (which takes + 1MB - 2MB per ARM architecture), but we don't have specific numbers yet. + + BoringSSL arose because Google used OpenSSL for many years in various ways and, over time, built + up a large number of patches that were maintained while tracking upstream OpenSSL. As Google's + product portfolio became more complex, more copies of OpenSSL sprung up and the effort involved + in maintaining all these patches in multiple places was growing steadily. + + Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's not part of the + NDK) and a number of other apps/programs. + DESC + s.homepage = 'https://github.com/google/boringssl' + s.license = { :type => 'Mixed', :file => 'LICENSE' } + # "The name and email addresses of the library maintainers, not the Podspec maintainer." + s.authors = 'Adam Langley', 'David Benjamin', 'Matt Braithwaite' + + s.source = { + :git => 'https://github.com/google/boringssl.git', + :commit => "b29b21a81b32ec273f118f589f46d56ad3332420", + } + + s.ios.deployment_target = '5.0' + s.osx.deployment_target = '10.7' + + name = 'openssl' + + # When creating a dynamic framework, name it openssl.framework instead of BoringSSL.framework. + # This lets users write their includes like `#include ` as opposed to `#include + # `. + s.module_name = name + + # When creating a dynamic framework, copy the headers under `include/openssl/` into the root of + # the `Headers/` directory of the framework (i.e., not under `Headers/include/openssl`). + # + # TODO(jcanizales): Debug why this doesn't work on macOS. + s.header_mappings_dir = 'include/openssl' + + # The above has an undesired effect when creating a static library: It forces users to write + # includes like `#include `. `s.header_dir` adds a path prefix to that, and + # because Cocoapods lets omit the pod name when including headers of static libraries, the + # following lets users write `#include `. + s.header_dir = name + + # The module map and umbrella header created automatically by Cocoapods don't work for C libraries + # like this one. The following file, and a correct umbrella header, are created on the fly by the + # `prepare_command` of this pod. + s.module_map = 'include/openssl/BoringSSL.modulemap' + + # We don't need to inhibit all warnings; only -Wno-shorten-64-to-32. But Cocoapods' linter doesn't + # want that for some reason. + s.compiler_flags = '-DOPENSSL_NO_ASM', '-GCC_WARN_INHIBIT_ALL_WARNINGS', '-w' + s.requires_arc = false + + # Like many other C libraries, BoringSSL has its public headers under `include//` and its + # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't + # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in + # practice). Because we need our `header_mappings_dir` to be `include/openssl/` for the reason + # mentioned above, we work around the linter limitation by dividing the pod into two subspecs, one + # for public headers and the other for implementation. Each gets its own `header_mappings_dir`, + # making the linter happy. + s.subspec 'Interface' do |ss| + ss.header_mappings_dir = 'include/openssl' + ss.source_files = 'include/openssl/*.h' + end + s.subspec 'Implementation' do |ss| + ss.header_mappings_dir = '.' + ss.source_files = 'ssl/*.{h,cc}', + 'ssl/**/*.{h,cc}', + '*.{h,c}', + 'crypto/*.{h,c}', + 'crypto/**/*.{h,c}', + 'third_party/fiat/*.{h,c}' + ss.private_header_files = 'ssl/*.h', + 'ssl/**/*.h', + '*.h', + 'crypto/*.h', + 'crypto/**/*.h' + # bcm.c includes other source files, creating duplicated symbols. Since it is not used, we + # explicitly exclude it from the pod. + # TODO (mxyan): Work with BoringSSL team to remove this hack. + ss.exclude_files = 'crypto/fipsmodule/bcm.c', + '**/*_test.*', + '**/test_*.*', + '**/test/*.*' + + ss.dependency "#{s.name}/Interface", version + end + + s.prepare_command = <<-END_OF_COMMAND + # Add a module map and an umbrella header + cat > include/openssl/umbrella.h < include/openssl/BoringSSL.modulemap < err_data.c < + #include + #include + + + OPENSSL_COMPILE_ASSERT(ERR_LIB_NONE == 1, library_values_changed_1); + OPENSSL_COMPILE_ASSERT(ERR_LIB_SYS == 2, library_values_changed_2); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BN == 3, library_values_changed_3); + OPENSSL_COMPILE_ASSERT(ERR_LIB_RSA == 4, library_values_changed_4); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DH == 5, library_values_changed_5); + OPENSSL_COMPILE_ASSERT(ERR_LIB_EVP == 6, library_values_changed_6); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BUF == 7, library_values_changed_7); + OPENSSL_COMPILE_ASSERT(ERR_LIB_OBJ == 8, library_values_changed_8); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PEM == 9, library_values_changed_9); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DSA == 10, library_values_changed_10); + OPENSSL_COMPILE_ASSERT(ERR_LIB_X509 == 11, library_values_changed_11); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ASN1 == 12, library_values_changed_12); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CONF == 13, library_values_changed_13); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CRYPTO == 14, library_values_changed_14); + OPENSSL_COMPILE_ASSERT(ERR_LIB_EC == 15, library_values_changed_15); + OPENSSL_COMPILE_ASSERT(ERR_LIB_SSL == 16, library_values_changed_16); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BIO == 17, library_values_changed_17); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS7 == 18, library_values_changed_18); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS8 == 19, library_values_changed_19); + OPENSSL_COMPILE_ASSERT(ERR_LIB_X509V3 == 20, library_values_changed_20); + OPENSSL_COMPILE_ASSERT(ERR_LIB_RAND == 21, library_values_changed_21); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ENGINE == 22, library_values_changed_22); + OPENSSL_COMPILE_ASSERT(ERR_LIB_OCSP == 23, library_values_changed_23); + OPENSSL_COMPILE_ASSERT(ERR_LIB_UI == 24, library_values_changed_24); + OPENSSL_COMPILE_ASSERT(ERR_LIB_COMP == 25, library_values_changed_25); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDSA == 26, library_values_changed_26); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDH == 27, library_values_changed_27); + OPENSSL_COMPILE_ASSERT(ERR_LIB_HMAC == 28, library_values_changed_28); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DIGEST == 29, library_values_changed_29); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CIPHER == 30, library_values_changed_30); + OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 31, library_values_changed_31); + OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32); + OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num); + + const uint32_t kOpenSSLReasonValues[] = { + 0xc320838, + 0xc328852, + 0xc330861, + 0xc338871, + 0xc340880, + 0xc348899, + 0xc3508a5, + 0xc3588c2, + 0xc3608e2, + 0xc3688f0, + 0xc370900, + 0xc37890d, + 0xc38091d, + 0xc388928, + 0xc39093e, + 0xc39894d, + 0xc3a0961, + 0xc3a8845, + 0xc3b00ea, + 0xc3b88d4, + 0x10320845, + 0x10329513, + 0x1033151f, + 0x10339538, + 0x1034154b, + 0x10348eed, + 0x10350c5e, + 0x1035955e, + 0x10361573, + 0x10369586, + 0x103715a5, + 0x103795be, + 0x103815d3, + 0x103895f1, + 0x10391600, + 0x1039961c, + 0x103a1637, + 0x103a9646, + 0x103b1662, + 0x103b967d, + 0x103c1694, + 0x103c80ea, + 0x103d16a5, + 0x103d96b9, + 0x103e16d8, + 0x103e96e7, + 0x103f16fe, + 0x103f9711, + 0x10400c22, + 0x10409724, + 0x10411742, + 0x10419755, + 0x1042176f, + 0x1042977f, + 0x10431793, + 0x104397a9, + 0x104417c1, + 0x104497d6, + 0x104517ea, + 0x104597fc, + 0x104605fb, + 0x1046894d, + 0x10471811, + 0x10479828, + 0x1048183d, + 0x1048984b, + 0x10490e4f, + 0x14320c05, + 0x14328c13, + 0x14330c22, + 0x14338c34, + 0x143400ac, + 0x143480ea, + 0x18320083, + 0x18328f43, + 0x183300ac, + 0x18338f59, + 0x18340f6d, + 0x183480ea, + 0x18350f82, + 0x18358f9a, + 0x18360faf, + 0x18368fc3, + 0x18370fe7, + 0x18378ffd, + 0x18381011, + 0x18389021, + 0x18390a73, + 0x18399031, + 0x183a1059, + 0x183a907f, + 0x183b0c6a, + 0x183b90b4, + 0x183c10c6, + 0x183c90d1, + 0x183d10e1, + 0x183d90f2, + 0x183e1103, + 0x183e9115, + 0x183f113e, + 0x183f9157, + 0x1840116f, + 0x184086d3, + 0x184110a2, + 0x1841906d, + 0x1842108c, + 0x18429046, + 0x20321196, + 0x243211a2, + 0x24328993, + 0x243311b4, + 0x243391c1, + 0x243411ce, + 0x243491e0, + 0x243511ef, + 0x2435920c, + 0x24361219, + 0x24369227, + 0x24371235, + 0x24379243, + 0x2438124c, + 0x24389259, + 0x2439126c, + 0x28320c52, + 0x28328c6a, + 0x28330c22, + 0x28338c7d, + 0x28340c5e, + 0x283480ac, + 0x283500ea, + 0x2c322c30, + 0x2c329283, + 0x2c332c3e, + 0x2c33ac50, + 0x2c342c64, + 0x2c34ac76, + 0x2c352c91, + 0x2c35aca3, + 0x2c362cb6, + 0x2c36832d, + 0x2c372cc3, + 0x2c37acd5, + 0x2c382cfa, + 0x2c38ad11, + 0x2c392d1f, + 0x2c39ad2f, + 0x2c3a2d41, + 0x2c3aad55, + 0x2c3b2d66, + 0x2c3bad85, + 0x2c3c1295, + 0x2c3c92ab, + 0x2c3d2d99, + 0x2c3d92c4, + 0x2c3e2db6, + 0x2c3eadc4, + 0x2c3f2ddc, + 0x2c3fadf4, + 0x2c402e01, + 0x2c409196, + 0x2c412e12, + 0x2c41ae25, + 0x2c42116f, + 0x2c42ae36, + 0x2c430720, + 0x2c43ad77, + 0x2c442ce8, + 0x30320000, + 0x30328015, + 0x3033001f, + 0x30338038, + 0x3034004a, + 0x30348064, + 0x3035006b, + 0x30358083, + 0x30360094, + 0x303680ac, + 0x303700b9, + 0x303780c8, + 0x303800ea, + 0x303880f7, + 0x3039010a, + 0x30398125, + 0x303a013a, + 0x303a814e, + 0x303b0162, + 0x303b8173, + 0x303c018c, + 0x303c81a9, + 0x303d01b7, + 0x303d81cb, + 0x303e01db, + 0x303e81f4, + 0x303f0204, + 0x303f8217, + 0x30400226, + 0x30408232, + 0x30410247, + 0x30418257, + 0x3042026e, + 0x3042827b, + 0x3043028e, + 0x3043829d, + 0x304402b2, + 0x304482d3, + 0x304502e6, + 0x304582f9, + 0x30460312, + 0x3046832d, + 0x3047034a, + 0x30478363, + 0x30480371, + 0x30488382, + 0x30490391, + 0x304983a9, + 0x304a03bb, + 0x304a83cf, + 0x304b03ee, + 0x304b8401, + 0x304c040c, + 0x304c841d, + 0x304d0429, + 0x304d843f, + 0x304e044d, + 0x304e8463, + 0x304f0475, + 0x304f8487, + 0x3050049a, + 0x305084ad, + 0x305104be, + 0x305184ce, + 0x305204e6, + 0x305284fb, + 0x30530513, + 0x30538527, + 0x3054053f, + 0x30548558, + 0x30550571, + 0x3055858e, + 0x30560599, + 0x305685b1, + 0x305705c1, + 0x305785d2, + 0x305805e5, + 0x305885fb, + 0x30590604, + 0x30598619, + 0x305a062c, + 0x305a863b, + 0x305b065b, + 0x305b866a, + 0x305c068b, + 0x305c86a7, + 0x305d06b3, + 0x305d86d3, + 0x305e06ef, + 0x305e8700, + 0x305f0716, + 0x305f8720, + 0x34320b63, + 0x34328b77, + 0x34330b94, + 0x34338ba7, + 0x34340bb6, + 0x34348bef, + 0x34350bd3, + 0x3c320083, + 0x3c328ca7, + 0x3c330cc0, + 0x3c338cdb, + 0x3c340cf8, + 0x3c348d22, + 0x3c350d3d, + 0x3c358d63, + 0x3c360d7c, + 0x3c368d94, + 0x3c370da5, + 0x3c378db3, + 0x3c380dc0, + 0x3c388dd4, + 0x3c390c6a, + 0x3c398de8, + 0x3c3a0dfc, + 0x3c3a890d, + 0x3c3b0e0c, + 0x3c3b8e27, + 0x3c3c0e39, + 0x3c3c8e6c, + 0x3c3d0e76, + 0x3c3d8e8a, + 0x3c3e0e98, + 0x3c3e8ebd, + 0x3c3f0c93, + 0x3c3f8ea6, + 0x3c4000ac, + 0x3c4080ea, + 0x3c410d13, + 0x3c418d52, + 0x3c420e4f, + 0x403218a4, + 0x403298ba, + 0x403318e8, + 0x403398f2, + 0x40341909, + 0x40349927, + 0x40351937, + 0x40359949, + 0x40361956, + 0x40369962, + 0x40371977, + 0x40379989, + 0x40381994, + 0x403899a6, + 0x40390eed, + 0x403999b6, + 0x403a19c9, + 0x403a99ea, + 0x403b19fb, + 0x403b9a0b, + 0x403c0064, + 0x403c8083, + 0x403d1a8f, + 0x403d9aa5, + 0x403e1ab4, + 0x403e9aec, + 0x403f1b06, + 0x403f9b14, + 0x40401b29, + 0x40409b3d, + 0x40411b5a, + 0x40419b75, + 0x40421b8e, + 0x40429ba1, + 0x40431bb5, + 0x40439bcd, + 0x40441be4, + 0x404480ac, + 0x40451bf9, + 0x40459c0b, + 0x40461c2f, + 0x40469c4f, + 0x40471c5d, + 0x40479c84, + 0x40481cc1, + 0x40489cda, + 0x40491cf1, + 0x40499d0b, + 0x404a1d22, + 0x404a9d40, + 0x404b1d58, + 0x404b9d6f, + 0x404c1d85, + 0x404c9d97, + 0x404d1db8, + 0x404d9dda, + 0x404e1dee, + 0x404e9dfb, + 0x404f1e28, + 0x404f9e51, + 0x40501e8c, + 0x40509ea0, + 0x40511ebb, + 0x40521ecb, + 0x40529eef, + 0x40531f07, + 0x40539f1a, + 0x40541f2f, + 0x40549f52, + 0x40551f60, + 0x40559f7d, + 0x40561f8a, + 0x40569fa3, + 0x40571fbb, + 0x40579fce, + 0x40581fe3, + 0x4058a00a, + 0x40592039, + 0x4059a066, + 0x405a207a, + 0x405aa08a, + 0x405b20a2, + 0x405ba0b3, + 0x405c20c6, + 0x405ca105, + 0x405d2112, + 0x405da129, + 0x405e2167, + 0x405e8ab1, + 0x405f2188, + 0x405fa195, + 0x406021a3, + 0x4060a1c5, + 0x40612209, + 0x4061a241, + 0x40622258, + 0x4062a269, + 0x4063227a, + 0x4063a28f, + 0x406422a6, + 0x4064a2d2, + 0x406522ed, + 0x4065a304, + 0x4066231c, + 0x4066a346, + 0x40672371, + 0x4067a392, + 0x406823b9, + 0x4068a3da, + 0x4069240c, + 0x4069a43a, + 0x406a245b, + 0x406aa47b, + 0x406b2603, + 0x406ba626, + 0x406c263c, + 0x406ca8b7, + 0x406d28e6, + 0x406da90e, + 0x406e293c, + 0x406ea989, + 0x406f29a8, + 0x406fa9e0, + 0x407029f3, + 0x4070aa10, + 0x40710800, + 0x4071aa22, + 0x40722a35, + 0x4072aa4e, + 0x40732a66, + 0x40739482, + 0x40742a7a, + 0x4074aa94, + 0x40752aa5, + 0x4075aab9, + 0x40762ac7, + 0x40769259, + 0x40772aec, + 0x4077ab0e, + 0x40782b29, + 0x4078ab62, + 0x40792b79, + 0x4079ab8f, + 0x407a2b9b, + 0x407aabae, + 0x407b2bc3, + 0x407babd5, + 0x407c2c06, + 0x407cac0f, + 0x407d23f5, + 0x407d9e61, + 0x407e2b3e, + 0x407ea01a, + 0x407f1c71, + 0x407f9a31, + 0x40801e38, + 0x40809c99, + 0x40811edd, + 0x40819e12, + 0x40822927, + 0x40829a17, + 0x40831ff5, + 0x4083a2b7, + 0x40841cad, + 0x4084a052, + 0x408520d7, + 0x4085a1ed, + 0x40862149, + 0x40869e7b, + 0x4087296d, + 0x4087a21e, + 0x40881a78, + 0x4088a3a5, + 0x40891ac7, + 0x40899a54, + 0x408a265c, + 0x408a9862, + 0x408b2bea, + 0x408ba9bd, + 0x408c20e7, + 0x408c987e, + 0x41f4252e, + 0x41f925c0, + 0x41fe24b3, + 0x41fea6a8, + 0x41ff2799, + 0x42032547, + 0x42082569, + 0x4208a5a5, + 0x42092497, + 0x4209a5df, + 0x420a24ee, + 0x420aa4ce, + 0x420b250e, + 0x420ba587, + 0x420c27b5, + 0x420ca675, + 0x420d268f, + 0x420da6c6, + 0x421226e0, + 0x4217277c, + 0x4217a722, + 0x421c2744, + 0x421f26ff, + 0x422127cc, + 0x4226275f, + 0x422b289b, + 0x422ba849, + 0x422c2883, + 0x422ca808, + 0x422d27e7, + 0x422da868, + 0x422e282e, + 0x422ea954, + 0x4432072b, + 0x4432873a, + 0x44330746, + 0x44338754, + 0x44340767, + 0x44348778, + 0x4435077f, + 0x44358789, + 0x4436079c, + 0x443687b2, + 0x443707c4, + 0x443787d1, + 0x443807e0, + 0x443887e8, + 0x44390800, + 0x4439880e, + 0x443a0821, + 0x48321283, + 0x48329295, + 0x483312ab, + 0x483392c4, + 0x4c3212e9, + 0x4c3292f9, + 0x4c33130c, + 0x4c33932c, + 0x4c3400ac, + 0x4c3480ea, + 0x4c351338, + 0x4c359346, + 0x4c361362, + 0x4c369375, + 0x4c371384, + 0x4c379392, + 0x4c3813a7, + 0x4c3893b3, + 0x4c3913d3, + 0x4c3993fd, + 0x4c3a1416, + 0x4c3a942f, + 0x4c3b05fb, + 0x4c3b9448, + 0x4c3c145a, + 0x4c3c9469, + 0x4c3d1482, + 0x4c3d8c45, + 0x4c3e14db, + 0x4c3e9491, + 0x4c3f14fd, + 0x4c3f9259, + 0x4c4014a7, + 0x4c4092d5, + 0x4c4114cb, + 0x50322e48, + 0x5032ae57, + 0x50332e62, + 0x5033ae72, + 0x50342e8b, + 0x5034aea5, + 0x50352eb3, + 0x5035aec9, + 0x50362edb, + 0x5036aef1, + 0x50372f0a, + 0x5037af1d, + 0x50382f35, + 0x5038af46, + 0x50392f5b, + 0x5039af6f, + 0x503a2f8f, + 0x503aafa5, + 0x503b2fbd, + 0x503bafcf, + 0x503c2feb, + 0x503cb002, + 0x503d301b, + 0x503db031, + 0x503e303e, + 0x503eb054, + 0x503f3066, + 0x503f8382, + 0x50403079, + 0x5040b089, + 0x504130a3, + 0x5041b0b2, + 0x504230cc, + 0x5042b0e9, + 0x504330f9, + 0x5043b109, + 0x50443118, + 0x5044843f, + 0x5045312c, + 0x5045b14a, + 0x5046315d, + 0x5046b173, + 0x50473185, + 0x5047b19a, + 0x504831c0, + 0x5048b1ce, + 0x504931e1, + 0x5049b1f6, + 0x504a320c, + 0x504ab21c, + 0x504b323c, + 0x504bb24f, + 0x504c3272, + 0x504cb2a0, + 0x504d32b2, + 0x504db2cf, + 0x504e32ea, + 0x504eb306, + 0x504f3318, + 0x504fb32f, + 0x5050333e, + 0x505086ef, + 0x50513351, + 0x58320f2b, + 0x68320eed, + 0x68328c6a, + 0x68330c7d, + 0x68338efb, + 0x68340f0b, + 0x683480ea, + 0x6c320ec9, + 0x6c328c34, + 0x6c330ed4, + 0x74320a19, + 0x743280ac, + 0x74330c45, + 0x7832097e, + 0x78328993, + 0x7833099f, + 0x78338083, + 0x783409ae, + 0x783489c3, + 0x783509e2, + 0x78358a04, + 0x78360a19, + 0x78368a2f, + 0x78370a3f, + 0x78378a60, + 0x78380a73, + 0x78388a85, + 0x78390a92, + 0x78398ab1, + 0x783a0ac6, + 0x783a8ad4, + 0x783b0ade, + 0x783b8af2, + 0x783c0b09, + 0x783c8b1e, + 0x783d0b35, + 0x783d8b4a, + 0x783e0aa0, + 0x783e8a52, + 0x7c321185, + }; + + const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); + + const char kOpenSSLReasonStringData[] = + "ASN1_LENGTH_MISMATCH\\0" + "AUX_ERROR\\0" + "BAD_GET_ASN1_OBJECT_CALL\\0" + "BAD_OBJECT_HEADER\\0" + "BMPSTRING_IS_WRONG_LENGTH\\0" + "BN_LIB\\0" + "BOOLEAN_IS_WRONG_LENGTH\\0" + "BUFFER_TOO_SMALL\\0" + "CONTEXT_NOT_INITIALISED\\0" + "DECODE_ERROR\\0" + "DEPTH_EXCEEDED\\0" + "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\\0" + "ENCODE_ERROR\\0" + "ERROR_GETTING_TIME\\0" + "EXPECTING_AN_ASN1_SEQUENCE\\0" + "EXPECTING_AN_INTEGER\\0" + "EXPECTING_AN_OBJECT\\0" + "EXPECTING_A_BOOLEAN\\0" + "EXPECTING_A_TIME\\0" + "EXPLICIT_LENGTH_MISMATCH\\0" + "EXPLICIT_TAG_NOT_CONSTRUCTED\\0" + "FIELD_MISSING\\0" + "FIRST_NUM_TOO_LARGE\\0" + "HEADER_TOO_LONG\\0" + "ILLEGAL_BITSTRING_FORMAT\\0" + "ILLEGAL_BOOLEAN\\0" + "ILLEGAL_CHARACTERS\\0" + "ILLEGAL_FORMAT\\0" + "ILLEGAL_HEX\\0" + "ILLEGAL_IMPLICIT_TAG\\0" + "ILLEGAL_INTEGER\\0" + "ILLEGAL_NESTED_TAGGING\\0" + "ILLEGAL_NULL\\0" + "ILLEGAL_NULL_VALUE\\0" + "ILLEGAL_OBJECT\\0" + "ILLEGAL_OPTIONAL_ANY\\0" + "ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE\\0" + "ILLEGAL_TAGGED_ANY\\0" + "ILLEGAL_TIME_VALUE\\0" + "INTEGER_NOT_ASCII_FORMAT\\0" + "INTEGER_TOO_LARGE_FOR_LONG\\0" + "INVALID_BIT_STRING_BITS_LEFT\\0" + "INVALID_BMPSTRING_LENGTH\\0" + "INVALID_DIGIT\\0" + "INVALID_MODIFIER\\0" + "INVALID_NUMBER\\0" + "INVALID_OBJECT_ENCODING\\0" + "INVALID_SEPARATOR\\0" + "INVALID_TIME_FORMAT\\0" + "INVALID_UNIVERSALSTRING_LENGTH\\0" + "INVALID_UTF8STRING\\0" + "LIST_ERROR\\0" + "MISSING_ASN1_EOS\\0" + "MISSING_EOC\\0" + "MISSING_SECOND_NUMBER\\0" + "MISSING_VALUE\\0" + "MSTRING_NOT_UNIVERSAL\\0" + "MSTRING_WRONG_TAG\\0" + "NESTED_ASN1_ERROR\\0" + "NESTED_ASN1_STRING\\0" + "NON_HEX_CHARACTERS\\0" + "NOT_ASCII_FORMAT\\0" + "NOT_ENOUGH_DATA\\0" + "NO_MATCHING_CHOICE_TYPE\\0" + "NULL_IS_WRONG_LENGTH\\0" + "OBJECT_NOT_ASCII_FORMAT\\0" + "ODD_NUMBER_OF_CHARS\\0" + "SECOND_NUMBER_TOO_LARGE\\0" + "SEQUENCE_LENGTH_MISMATCH\\0" + "SEQUENCE_NOT_CONSTRUCTED\\0" + "SEQUENCE_OR_SET_NEEDS_CONFIG\\0" + "SHORT_LINE\\0" + "STREAMING_NOT_SUPPORTED\\0" + "STRING_TOO_LONG\\0" + "STRING_TOO_SHORT\\0" + "TAG_VALUE_TOO_HIGH\\0" + "TIME_NOT_ASCII_FORMAT\\0" + "TOO_LONG\\0" + "TYPE_NOT_CONSTRUCTED\\0" + "TYPE_NOT_PRIMITIVE\\0" + "UNEXPECTED_EOC\\0" + "UNIVERSALSTRING_IS_WRONG_LENGTH\\0" + "UNKNOWN_FORMAT\\0" + "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\\0" + "UNKNOWN_SIGNATURE_ALGORITHM\\0" + "UNKNOWN_TAG\\0" + "UNSUPPORTED_ANY_DEFINED_BY_TYPE\\0" + "UNSUPPORTED_PUBLIC_KEY_TYPE\\0" + "UNSUPPORTED_TYPE\\0" + "WRONG_PUBLIC_KEY_TYPE\\0" + "WRONG_TAG\\0" + "WRONG_TYPE\\0" + "BAD_FOPEN_MODE\\0" + "BROKEN_PIPE\\0" + "CONNECT_ERROR\\0" + "ERROR_SETTING_NBIO\\0" + "INVALID_ARGUMENT\\0" + "IN_USE\\0" + "KEEPALIVE\\0" + "NBIO_CONNECT_ERROR\\0" + "NO_HOSTNAME_SPECIFIED\\0" + "NO_PORT_SPECIFIED\\0" + "NO_SUCH_FILE\\0" + "NULL_PARAMETER\\0" + "SYS_LIB\\0" + "UNABLE_TO_CREATE_SOCKET\\0" + "UNINITIALIZED\\0" + "UNSUPPORTED_METHOD\\0" + "WRITE_TO_READ_ONLY_BIO\\0" + "ARG2_LT_ARG3\\0" + "BAD_ENCODING\\0" + "BAD_RECIPROCAL\\0" + "BIGNUM_TOO_LONG\\0" + "BITS_TOO_SMALL\\0" + "CALLED_WITH_EVEN_MODULUS\\0" + "DIV_BY_ZERO\\0" + "EXPAND_ON_STATIC_BIGNUM_DATA\\0" + "INPUT_NOT_REDUCED\\0" + "INVALID_INPUT\\0" + "INVALID_RANGE\\0" + "NEGATIVE_NUMBER\\0" + "NOT_A_SQUARE\\0" + "NOT_INITIALIZED\\0" + "NO_INVERSE\\0" + "PRIVATE_KEY_TOO_LARGE\\0" + "P_IS_NOT_PRIME\\0" + "TOO_MANY_ITERATIONS\\0" + "TOO_MANY_TEMPORARY_VARIABLES\\0" + "AES_KEY_SETUP_FAILED\\0" + "BAD_DECRYPT\\0" + "BAD_KEY_LENGTH\\0" + "CTRL_NOT_IMPLEMENTED\\0" + "CTRL_OPERATION_NOT_IMPLEMENTED\\0" + "DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH\\0" + "INITIALIZATION_ERROR\\0" + "INPUT_NOT_INITIALIZED\\0" + "INVALID_AD_SIZE\\0" + "INVALID_KEY_LENGTH\\0" + "INVALID_NONCE\\0" + "INVALID_NONCE_SIZE\\0" + "INVALID_OPERATION\\0" + "IV_TOO_LARGE\\0" + "NO_CIPHER_SET\\0" + "NO_DIRECTION_SET\\0" + "OUTPUT_ALIASES_INPUT\\0" + "TAG_TOO_LARGE\\0" + "TOO_LARGE\\0" + "UNSUPPORTED_AD_SIZE\\0" + "UNSUPPORTED_INPUT_SIZE\\0" + "UNSUPPORTED_KEY_SIZE\\0" + "UNSUPPORTED_NONCE_SIZE\\0" + "UNSUPPORTED_TAG_SIZE\\0" + "WRONG_FINAL_BLOCK_LENGTH\\0" + "LIST_CANNOT_BE_NULL\\0" + "MISSING_CLOSE_SQUARE_BRACKET\\0" + "MISSING_EQUAL_SIGN\\0" + "NO_CLOSE_BRACE\\0" + "UNABLE_TO_CREATE_NEW_SECTION\\0" + "VARIABLE_EXPANSION_TOO_LONG\\0" + "VARIABLE_HAS_NO_VALUE\\0" + "BAD_GENERATOR\\0" + "INVALID_PUBKEY\\0" + "MODULUS_TOO_LARGE\\0" + "NO_PRIVATE_VALUE\\0" + "UNKNOWN_HASH\\0" + "BAD_Q_VALUE\\0" + "BAD_VERSION\\0" + "MISSING_PARAMETERS\\0" + "NEED_NEW_SETUP_VALUES\\0" + "BIGNUM_OUT_OF_RANGE\\0" + "COORDINATES_OUT_OF_RANGE\\0" + "D2I_ECPKPARAMETERS_FAILURE\\0" + "EC_GROUP_NEW_BY_NAME_FAILURE\\0" + "GROUP2PKPARAMETERS_FAILURE\\0" + "GROUP_MISMATCH\\0" + "I2D_ECPKPARAMETERS_FAILURE\\0" + "INCOMPATIBLE_OBJECTS\\0" + "INVALID_COFACTOR\\0" + "INVALID_COMPRESSED_POINT\\0" + "INVALID_COMPRESSION_BIT\\0" + "INVALID_ENCODING\\0" + "INVALID_FIELD\\0" + "INVALID_FORM\\0" + "INVALID_GROUP_ORDER\\0" + "INVALID_PRIVATE_KEY\\0" + "MISSING_PRIVATE_KEY\\0" + "NON_NAMED_CURVE\\0" + "PKPARAMETERS2GROUP_FAILURE\\0" + "POINT_AT_INFINITY\\0" + "POINT_IS_NOT_ON_CURVE\\0" + "PUBLIC_KEY_VALIDATION_FAILED\\0" + "SLOT_FULL\\0" + "UNDEFINED_GENERATOR\\0" + "UNKNOWN_GROUP\\0" + "UNKNOWN_ORDER\\0" + "WRONG_CURVE_PARAMETERS\\0" + "WRONG_ORDER\\0" + "KDF_FAILED\\0" + "POINT_ARITHMETIC_FAILURE\\0" + "BAD_SIGNATURE\\0" + "NOT_IMPLEMENTED\\0" + "RANDOM_NUMBER_GENERATION_FAILED\\0" + "OPERATION_NOT_SUPPORTED\\0" + "COMMAND_NOT_SUPPORTED\\0" + "DIFFERENT_KEY_TYPES\\0" + "DIFFERENT_PARAMETERS\\0" + "EXPECTING_AN_EC_KEY_KEY\\0" + "EXPECTING_AN_RSA_KEY\\0" + "EXPECTING_A_DSA_KEY\\0" + "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\\0" + "INVALID_DIGEST_LENGTH\\0" + "INVALID_DIGEST_TYPE\\0" + "INVALID_KEYBITS\\0" + "INVALID_MGF1_MD\\0" + "INVALID_PADDING_MODE\\0" + "INVALID_PARAMETERS\\0" + "INVALID_PSS_SALTLEN\\0" + "INVALID_SIGNATURE\\0" + "KEYS_NOT_SET\\0" + "MEMORY_LIMIT_EXCEEDED\\0" + "NOT_A_PRIVATE_KEY\\0" + "NO_DEFAULT_DIGEST\\0" + "NO_KEY_SET\\0" + "NO_MDC2_SUPPORT\\0" + "NO_NID_FOR_CURVE\\0" + "NO_OPERATION_SET\\0" + "NO_PARAMETERS_SET\\0" + "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\\0" + "OPERATON_NOT_INITIALIZED\\0" + "UNKNOWN_PUBLIC_KEY_TYPE\\0" + "UNSUPPORTED_ALGORITHM\\0" + "OUTPUT_TOO_LARGE\\0" + "UNKNOWN_NID\\0" + "BAD_BASE64_DECODE\\0" + "BAD_END_LINE\\0" + "BAD_IV_CHARS\\0" + "BAD_PASSWORD_READ\\0" + "CIPHER_IS_NULL\\0" + "ERROR_CONVERTING_PRIVATE_KEY\\0" + "NOT_DEK_INFO\\0" + "NOT_ENCRYPTED\\0" + "NOT_PROC_TYPE\\0" + "NO_START_LINE\\0" + "READ_KEY\\0" + "SHORT_HEADER\\0" + "UNSUPPORTED_CIPHER\\0" + "UNSUPPORTED_ENCRYPTION\\0" + "BAD_PKCS7_VERSION\\0" + "NOT_PKCS7_SIGNED_DATA\\0" + "NO_CERTIFICATES_INCLUDED\\0" + "NO_CRLS_INCLUDED\\0" + "BAD_ITERATION_COUNT\\0" + "BAD_PKCS12_DATA\\0" + "BAD_PKCS12_VERSION\\0" + "CIPHER_HAS_NO_OBJECT_IDENTIFIER\\0" + "CRYPT_ERROR\\0" + "ENCRYPT_ERROR\\0" + "ERROR_SETTING_CIPHER_PARAMS\\0" + "INCORRECT_PASSWORD\\0" + "KEYGEN_FAILURE\\0" + "KEY_GEN_ERROR\\0" + "METHOD_NOT_SUPPORTED\\0" + "MISSING_MAC\\0" + "MULTIPLE_PRIVATE_KEYS_IN_PKCS12\\0" + "PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED\\0" + "PKCS12_TOO_DEEPLY_NESTED\\0" + "PRIVATE_KEY_DECODE_ERROR\\0" + "PRIVATE_KEY_ENCODE_ERROR\\0" + "UNKNOWN_ALGORITHM\\0" + "UNKNOWN_CIPHER\\0" + "UNKNOWN_CIPHER_ALGORITHM\\0" + "UNKNOWN_DIGEST\\0" + "UNSUPPORTED_KEYLENGTH\\0" + "UNSUPPORTED_KEY_DERIVATION_FUNCTION\\0" + "UNSUPPORTED_PRF\\0" + "UNSUPPORTED_PRIVATE_KEY_ALGORITHM\\0" + "UNSUPPORTED_SALT_TYPE\\0" + "BAD_E_VALUE\\0" + "BAD_FIXED_HEADER_DECRYPT\\0" + "BAD_PAD_BYTE_COUNT\\0" + "BAD_RSA_PARAMETERS\\0" + "BLOCK_TYPE_IS_NOT_01\\0" + "BN_NOT_INITIALIZED\\0" + "CANNOT_RECOVER_MULTI_PRIME_KEY\\0" + "CRT_PARAMS_ALREADY_GIVEN\\0" + "CRT_VALUES_INCORRECT\\0" + "DATA_LEN_NOT_EQUAL_TO_MOD_LEN\\0" + "DATA_TOO_LARGE\\0" + "DATA_TOO_LARGE_FOR_KEY_SIZE\\0" + "DATA_TOO_LARGE_FOR_MODULUS\\0" + "DATA_TOO_SMALL\\0" + "DATA_TOO_SMALL_FOR_KEY_SIZE\\0" + "DIGEST_TOO_BIG_FOR_RSA_KEY\\0" + "D_E_NOT_CONGRUENT_TO_1\\0" + "EMPTY_PUBLIC_KEY\\0" + "FIRST_OCTET_INVALID\\0" + "INCONSISTENT_SET_OF_CRT_VALUES\\0" + "INTERNAL_ERROR\\0" + "INVALID_MESSAGE_LENGTH\\0" + "KEY_SIZE_TOO_SMALL\\0" + "LAST_OCTET_INVALID\\0" + "MUST_HAVE_AT_LEAST_TWO_PRIMES\\0" + "NO_PUBLIC_EXPONENT\\0" + "NULL_BEFORE_BLOCK_MISSING\\0" + "N_NOT_EQUAL_P_Q\\0" + "OAEP_DECODING_ERROR\\0" + "ONLY_ONE_OF_P_Q_GIVEN\\0" + "OUTPUT_BUFFER_TOO_SMALL\\0" + "PADDING_CHECK_FAILED\\0" + "PKCS_DECODING_ERROR\\0" + "SLEN_CHECK_FAILED\\0" + "SLEN_RECOVERY_FAILED\\0" + "UNKNOWN_ALGORITHM_TYPE\\0" + "UNKNOWN_PADDING_TYPE\\0" + "VALUE_MISSING\\0" + "WRONG_SIGNATURE_LENGTH\\0" + "ALPN_MISMATCH_ON_EARLY_DATA\\0" + "APPLICATION_DATA_INSTEAD_OF_HANDSHAKE\\0" + "APP_DATA_IN_HANDSHAKE\\0" + "ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT\\0" + "BAD_ALERT\\0" + "BAD_CHANGE_CIPHER_SPEC\\0" + "BAD_DATA_RETURNED_BY_CALLBACK\\0" + "BAD_DH_P_LENGTH\\0" + "BAD_DIGEST_LENGTH\\0" + "BAD_ECC_CERT\\0" + "BAD_ECPOINT\\0" + "BAD_HANDSHAKE_RECORD\\0" + "BAD_HELLO_REQUEST\\0" + "BAD_LENGTH\\0" + "BAD_PACKET_LENGTH\\0" + "BAD_RSA_ENCRYPT\\0" + "BAD_SRTP_MKI_VALUE\\0" + "BAD_SRTP_PROTECTION_PROFILE_LIST\\0" + "BAD_SSL_FILETYPE\\0" + "BAD_WRITE_RETRY\\0" + "BIO_NOT_SET\\0" + "BLOCK_CIPHER_PAD_IS_WRONG\\0" + "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\\0" + "CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD\\0" + "CANNOT_PARSE_LEAF_CERT\\0" + "CA_DN_LENGTH_MISMATCH\\0" + "CA_DN_TOO_LONG\\0" + "CCS_RECEIVED_EARLY\\0" + "CERTIFICATE_AND_PRIVATE_KEY_MISMATCH\\0" + "CERTIFICATE_VERIFY_FAILED\\0" + "CERT_CB_ERROR\\0" + "CERT_LENGTH_MISMATCH\\0" + "CHANNEL_ID_NOT_P256\\0" + "CHANNEL_ID_SIGNATURE_INVALID\\0" + "CIPHER_OR_HASH_UNAVAILABLE\\0" + "CLIENTHELLO_PARSE_FAILED\\0" + "CLIENTHELLO_TLSEXT\\0" + "CONNECTION_REJECTED\\0" + "CONNECTION_TYPE_NOT_SET\\0" + "CUSTOM_EXTENSION_ERROR\\0" + "DATA_LENGTH_TOO_LONG\\0" + "DECRYPTION_FAILED\\0" + "DECRYPTION_FAILED_OR_BAD_RECORD_MAC\\0" + "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\\0" + "DH_P_TOO_LONG\\0" + "DIGEST_CHECK_FAILED\\0" + "DOWNGRADE_DETECTED\\0" + "DTLS_MESSAGE_TOO_BIG\\0" + "DUPLICATE_EXTENSION\\0" + "DUPLICATE_KEY_SHARE\\0" + "ECC_CERT_NOT_FOR_SIGNING\\0" + "EMS_STATE_INCONSISTENT\\0" + "ENCRYPTED_LENGTH_TOO_LONG\\0" + "ERROR_ADDING_EXTENSION\\0" + "ERROR_IN_RECEIVED_CIPHER_LIST\\0" + "ERROR_PARSING_EXTENSION\\0" + "EXCESSIVE_MESSAGE_SIZE\\0" + "EXTRA_DATA_IN_MESSAGE\\0" + "FRAGMENT_MISMATCH\\0" + "GOT_NEXT_PROTO_WITHOUT_EXTENSION\\0" + "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\\0" + "HTTPS_PROXY_REQUEST\\0" + "HTTP_REQUEST\\0" + "INAPPROPRIATE_FALLBACK\\0" + "INVALID_ALPN_PROTOCOL\\0" + "INVALID_COMMAND\\0" + "INVALID_COMPRESSION_LIST\\0" + "INVALID_MESSAGE\\0" + "INVALID_OUTER_RECORD_TYPE\\0" + "INVALID_SCT_LIST\\0" + "INVALID_SSL_SESSION\\0" + "INVALID_TICKET_KEYS_LENGTH\\0" + "LENGTH_MISMATCH\\0" + "MISSING_EXTENSION\\0" + "MISSING_KEY_SHARE\\0" + "MISSING_RSA_CERTIFICATE\\0" + "MISSING_TMP_DH_KEY\\0" + "MISSING_TMP_ECDH_KEY\\0" + "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\\0" + "MTU_TOO_SMALL\\0" + "NEGOTIATED_BOTH_NPN_AND_ALPN\\0" + "NESTED_GROUP\\0" + "NO_CERTIFICATES_RETURNED\\0" + "NO_CERTIFICATE_ASSIGNED\\0" + "NO_CERTIFICATE_SET\\0" + "NO_CIPHERS_AVAILABLE\\0" + "NO_CIPHERS_PASSED\\0" + "NO_CIPHERS_SPECIFIED\\0" + "NO_CIPHER_MATCH\\0" + "NO_COMMON_SIGNATURE_ALGORITHMS\\0" + "NO_COMPRESSION_SPECIFIED\\0" + "NO_GROUPS_SPECIFIED\\0" + "NO_METHOD_SPECIFIED\\0" + "NO_P256_SUPPORT\\0" + "NO_PRIVATE_KEY_ASSIGNED\\0" + "NO_RENEGOTIATION\\0" + "NO_REQUIRED_DIGEST\\0" + "NO_SHARED_CIPHER\\0" + "NO_SHARED_GROUP\\0" + "NO_SUPPORTED_VERSIONS_ENABLED\\0" + "NULL_SSL_CTX\\0" + "NULL_SSL_METHOD_PASSED\\0" + "OLD_SESSION_CIPHER_NOT_RETURNED\\0" + "OLD_SESSION_PRF_HASH_MISMATCH\\0" + "OLD_SESSION_VERSION_NOT_RETURNED\\0" + "PARSE_TLSEXT\\0" + "PATH_TOO_LONG\\0" + "PEER_DID_NOT_RETURN_A_CERTIFICATE\\0" + "PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\\0" + "PRE_SHARED_KEY_MUST_BE_LAST\\0" + "PROTOCOL_IS_SHUTDOWN\\0" + "PSK_IDENTITY_BINDER_COUNT_MISMATCH\\0" + "PSK_IDENTITY_NOT_FOUND\\0" + "PSK_NO_CLIENT_CB\\0" + "PSK_NO_SERVER_CB\\0" + "READ_TIMEOUT_EXPIRED\\0" + "RECORD_LENGTH_MISMATCH\\0" + "RECORD_TOO_LARGE\\0" + "RENEGOTIATION_EMS_MISMATCH\\0" + "RENEGOTIATION_ENCODING_ERR\\0" + "RENEGOTIATION_MISMATCH\\0" + "REQUIRED_CIPHER_MISSING\\0" + "RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION\\0" + "RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION\\0" + "SCSV_RECEIVED_WHEN_RENEGOTIATING\\0" + "SERVERHELLO_TLSEXT\\0" + "SERVER_CERT_CHANGED\\0" + "SESSION_ID_CONTEXT_UNINITIALIZED\\0" + "SESSION_MAY_NOT_BE_CREATED\\0" + "SHUTDOWN_WHILE_IN_INIT\\0" + "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\\0" + "SRTP_COULD_NOT_ALLOCATE_PROFILES\\0" + "SRTP_UNKNOWN_PROTECTION_PROFILE\\0" + "SSL3_EXT_INVALID_SERVERNAME\\0" + "SSLV3_ALERT_BAD_CERTIFICATE\\0" + "SSLV3_ALERT_BAD_RECORD_MAC\\0" + "SSLV3_ALERT_CERTIFICATE_EXPIRED\\0" + "SSLV3_ALERT_CERTIFICATE_REVOKED\\0" + "SSLV3_ALERT_CERTIFICATE_UNKNOWN\\0" + "SSLV3_ALERT_CLOSE_NOTIFY\\0" + "SSLV3_ALERT_DECOMPRESSION_FAILURE\\0" + "SSLV3_ALERT_HANDSHAKE_FAILURE\\0" + "SSLV3_ALERT_ILLEGAL_PARAMETER\\0" + "SSLV3_ALERT_NO_CERTIFICATE\\0" + "SSLV3_ALERT_UNEXPECTED_MESSAGE\\0" + "SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\\0" + "SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\\0" + "SSL_HANDSHAKE_FAILURE\\0" + "SSL_SESSION_ID_CONTEXT_TOO_LONG\\0" + "TICKET_ENCRYPTION_FAILED\\0" + "TLSV1_ALERT_ACCESS_DENIED\\0" + "TLSV1_ALERT_DECODE_ERROR\\0" + "TLSV1_ALERT_DECRYPTION_FAILED\\0" + "TLSV1_ALERT_DECRYPT_ERROR\\0" + "TLSV1_ALERT_EXPORT_RESTRICTION\\0" + "TLSV1_ALERT_INAPPROPRIATE_FALLBACK\\0" + "TLSV1_ALERT_INSUFFICIENT_SECURITY\\0" + "TLSV1_ALERT_INTERNAL_ERROR\\0" + "TLSV1_ALERT_NO_RENEGOTIATION\\0" + "TLSV1_ALERT_PROTOCOL_VERSION\\0" + "TLSV1_ALERT_RECORD_OVERFLOW\\0" + "TLSV1_ALERT_UNKNOWN_CA\\0" + "TLSV1_ALERT_USER_CANCELLED\\0" + "TLSV1_BAD_CERTIFICATE_HASH_VALUE\\0" + "TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\\0" + "TLSV1_CERTIFICATE_REQUIRED\\0" + "TLSV1_CERTIFICATE_UNOBTAINABLE\\0" + "TLSV1_UNKNOWN_PSK_IDENTITY\\0" + "TLSV1_UNRECOGNIZED_NAME\\0" + "TLSV1_UNSUPPORTED_EXTENSION\\0" + "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\\0" + "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\\0" + "TOO_MANY_EMPTY_FRAGMENTS\\0" + "TOO_MANY_KEY_UPDATES\\0" + "TOO_MANY_WARNING_ALERTS\\0" + "TOO_MUCH_READ_EARLY_DATA\\0" + "TOO_MUCH_SKIPPED_EARLY_DATA\\0" + "UNABLE_TO_FIND_ECDH_PARAMETERS\\0" + "UNEXPECTED_EXTENSION\\0" + "UNEXPECTED_EXTENSION_ON_EARLY_DATA\\0" + "UNEXPECTED_MESSAGE\\0" + "UNEXPECTED_OPERATOR_IN_GROUP\\0" + "UNEXPECTED_RECORD\\0" + "UNKNOWN_ALERT_TYPE\\0" + "UNKNOWN_CERTIFICATE_TYPE\\0" + "UNKNOWN_CIPHER_RETURNED\\0" + "UNKNOWN_CIPHER_TYPE\\0" + "UNKNOWN_KEY_EXCHANGE_TYPE\\0" + "UNKNOWN_PROTOCOL\\0" + "UNKNOWN_SSL_VERSION\\0" + "UNKNOWN_STATE\\0" + "UNSAFE_LEGACY_RENEGOTIATION_DISABLED\\0" + "UNSUPPORTED_COMPRESSION_ALGORITHM\\0" + "UNSUPPORTED_ELLIPTIC_CURVE\\0" + "UNSUPPORTED_PROTOCOL\\0" + "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\\0" + "WRONG_CERTIFICATE_TYPE\\0" + "WRONG_CIPHER_RETURNED\\0" + "WRONG_CURVE\\0" + "WRONG_MESSAGE_TYPE\\0" + "WRONG_SIGNATURE_TYPE\\0" + "WRONG_SSL_VERSION\\0" + "WRONG_VERSION_NUMBER\\0" + "WRONG_VERSION_ON_EARLY_DATA\\0" + "X509_LIB\\0" + "X509_VERIFICATION_SETUP_PROBLEMS\\0" + "AKID_MISMATCH\\0" + "BAD_X509_FILETYPE\\0" + "BASE64_DECODE_ERROR\\0" + "CANT_CHECK_DH_KEY\\0" + "CERT_ALREADY_IN_HASH_TABLE\\0" + "CRL_ALREADY_DELTA\\0" + "CRL_VERIFY_FAILURE\\0" + "IDP_MISMATCH\\0" + "INVALID_DIRECTORY\\0" + "INVALID_FIELD_NAME\\0" + "INVALID_PARAMETER\\0" + "INVALID_PSS_PARAMETERS\\0" + "INVALID_TRUST\\0" + "ISSUER_MISMATCH\\0" + "KEY_TYPE_MISMATCH\\0" + "KEY_VALUES_MISMATCH\\0" + "LOADING_CERT_DIR\\0" + "LOADING_DEFAULTS\\0" + "NAME_TOO_LONG\\0" + "NEWER_CRL_NOT_NEWER\\0" + "NO_CERT_SET_FOR_US_TO_VERIFY\\0" + "NO_CRL_NUMBER\\0" + "PUBLIC_KEY_DECODE_ERROR\\0" + "PUBLIC_KEY_ENCODE_ERROR\\0" + "SHOULD_RETRY\\0" + "UNKNOWN_KEY_TYPE\\0" + "UNKNOWN_PURPOSE_ID\\0" + "UNKNOWN_TRUST_ID\\0" + "WRONG_LOOKUP_TYPE\\0" + "BAD_IP_ADDRESS\\0" + "BAD_OBJECT\\0" + "BN_DEC2BN_ERROR\\0" + "BN_TO_ASN1_INTEGER_ERROR\\0" + "CANNOT_FIND_FREE_FUNCTION\\0" + "DIRNAME_ERROR\\0" + "DISTPOINT_ALREADY_SET\\0" + "DUPLICATE_ZONE_ID\\0" + "ERROR_CONVERTING_ZONE\\0" + "ERROR_CREATING_EXTENSION\\0" + "ERROR_IN_EXTENSION\\0" + "EXPECTED_A_SECTION_NAME\\0" + "EXTENSION_EXISTS\\0" + "EXTENSION_NAME_ERROR\\0" + "EXTENSION_NOT_FOUND\\0" + "EXTENSION_SETTING_NOT_SUPPORTED\\0" + "EXTENSION_VALUE_ERROR\\0" + "ILLEGAL_EMPTY_EXTENSION\\0" + "ILLEGAL_HEX_DIGIT\\0" + "INCORRECT_POLICY_SYNTAX_TAG\\0" + "INVALID_BOOLEAN_STRING\\0" + "INVALID_EXTENSION_STRING\\0" + "INVALID_MULTIPLE_RDNS\\0" + "INVALID_NAME\\0" + "INVALID_NULL_ARGUMENT\\0" + "INVALID_NULL_NAME\\0" + "INVALID_NULL_VALUE\\0" + "INVALID_NUMBERS\\0" + "INVALID_OBJECT_IDENTIFIER\\0" + "INVALID_OPTION\\0" + "INVALID_POLICY_IDENTIFIER\\0" + "INVALID_PROXY_POLICY_SETTING\\0" + "INVALID_PURPOSE\\0" + "INVALID_SECTION\\0" + "INVALID_SYNTAX\\0" + "ISSUER_DECODE_ERROR\\0" + "NEED_ORGANIZATION_AND_NUMBERS\\0" + "NO_CONFIG_DATABASE\\0" + "NO_ISSUER_CERTIFICATE\\0" + "NO_ISSUER_DETAILS\\0" + "NO_POLICY_IDENTIFIER\\0" + "NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED\\0" + "NO_PUBLIC_KEY\\0" + "NO_SUBJECT_DETAILS\\0" + "ODD_NUMBER_OF_DIGITS\\0" + "OPERATION_NOT_DEFINED\\0" + "OTHERNAME_ERROR\\0" + "POLICY_LANGUAGE_ALREADY_DEFINED\\0" + "POLICY_PATH_LENGTH\\0" + "POLICY_PATH_LENGTH_ALREADY_DEFINED\\0" + "POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY\\0" + "SECTION_NOT_FOUND\\0" + "UNABLE_TO_GET_ISSUER_DETAILS\\0" + "UNABLE_TO_GET_ISSUER_KEYID\\0" + "UNKNOWN_BIT_STRING_ARGUMENT\\0" + "UNKNOWN_EXTENSION\\0" + "UNKNOWN_EXTENSION_NAME\\0" + "UNKNOWN_OPTION\\0" + "UNSUPPORTED_OPTION\\0" + "USER_TOO_LONG\\0" + ""; + EOF + + sed -i'.back' '/^#define \\([A-Za-z0-9_]*\\) \\1/d' include/openssl/ssl.h + sed -i'.back' 'N;/^#define \\([A-Za-z0-9_]*\\) *\\\\\\n *\\1/d' include/openssl/ssl.h + sed -i'.back' 's/#ifndef md5_block_data_order/#ifndef GRPC_SHADOW_md5_block_data_order/g' crypto/fipsmodule/md5/md5.c + END_OF_COMMAND + + # Redefine symbols to avoid conflict when the same app also depends on OpenSSL. The list of + # symbols are src/objective-c/grpc_shadow_boringssl_symbol_list. + # This is the last part of this file. + s.prefix_header_contents = + ${expand_symbol_list(settings.grpc_shadow_boringssl_symbols)} + end diff --git a/test/core/iomgr/ios/CFStreamTests/Podfile b/test/core/iomgr/ios/CFStreamTests/Podfile index 630168a363b..e6ec66d5495 100644 --- a/test/core/iomgr/ios/CFStreamTests/Podfile +++ b/test/core/iomgr/ios/CFStreamTests/Podfile @@ -9,6 +9,7 @@ GRPC_LOCAL_SRC = '../../../../..' # Install the dependencies in the main target plus all test targets. target 'CFStreamTests' do pod 'gRPC-Core/CFStream-Implementation', :path => GRPC_LOCAL_SRC + pod 'BoringSSL-GRPC', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true end pre_install do |installer| diff --git a/tools/buildgen/plugins/grpc_shadow_boringssl.py b/tools/buildgen/plugins/grpc_shadow_boringssl.py new file mode 100644 index 00000000000..da4d8c12af2 --- /dev/null +++ b/tools/buildgen/plugins/grpc_shadow_boringssl.py @@ -0,0 +1,32 @@ +# 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. +"""Buldigen generate grpc_shadow_boringssl headers +This script takes the list of symbols from +src/objective-c/grpc_shadow_boringssl_symbols and populate them in +settings.grpc_shadow_boringssl_symbols +""" + + +def mako_plugin(dictionary): + with open('src/objective-c/grpc_shadow_boringssl_symbol_list') as f: + symbols = f.readlines() + # Remove trailing '\n' + symbols = [s.strip() for s in symbols] + # Remove comments + symbols = [s for s in symbols if s[0] != '#'] + # Remove the commit number + del symbols[0] + + settings = dictionary['settings'] + settings['grpc_shadow_boringssl_symbols'] = symbols diff --git a/tools/distrib/check_shadow_boringssl_symbol_list.sh b/tools/distrib/check_shadow_boringssl_symbol_list.sh new file mode 100755 index 00000000000..34ba09e07d9 --- /dev/null +++ b/tools/distrib/check_shadow_boringssl_symbol_list.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# 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. + + +# Check if the commit version of BoringSSL podspec, BoringSSL submodule, and +# the shadowed symbol list are all based on the same BoringSSL commit. +set -e + +cd $(dirname $0) + +boringssl_podspec_original="../../src/objective-c/BoringSSL-GRPC.podspec" +symbol_list="../../src/objective-c/grpc_shadow_boringssl_symbol_list" + +# Check BoringSSL version matches +ver1=$(git submodule |grep "boringssl " | awk '{print $1}' | head -n 1) +ver2=$(cat $boringssl_podspec_original | grep ':commit =>' | sed -E 's/.*"(.*)".*/\1/g') +ver3=$(cat $symbol_list | sed -n '2 p') +[ $ver1 == $ver2 ] && [ $ver1 == $ver3 ] || { echo "BoringSSL podspec (src/objective-c/BoringSSL.podspec), BoringSSL submodule (third_party/boringssl), and BoringSSL symbol list (src/objective-c/grpc_shadow_boringssl_symbol_list) commit do not match." ; echo "BoringSSL podspec: $ver1" ; echo "BoringSSL submodule: $ver2" ; echo "BoringSSL symbol list: $ver3" ; exit 1 ; } + +exit 0 diff --git a/tools/distrib/generate_grpc_shadow_boringssl_symbol_list.sh b/tools/distrib/generate_grpc_shadow_boringssl_symbol_list.sh new file mode 100755 index 00000000000..2e5bb445481 --- /dev/null +++ b/tools/distrib/generate_grpc_shadow_boringssl_symbol_list.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# 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. + +# Generate the list of boringssl symbols that need to be shadowed based on the +# current boringssl submodule. Requires local toolchain to build boringssl. +set -e + +cd $(dirname $0) + +symbol_list="../../src/objective-c/grpc_shadow_boringssl_symbol_list" + +ssl_lib='../../third_party/boringssl/build/ssl/libssl.a' +crypto_lib='../../third_party/boringssl/build/crypto/libcrypto.a' + +# Generate boringssl archives +( cd ../../third_party/boringssl ; mkdir -p build ; cd build ; cmake .. ; make ) + +# Generate shadow_boringssl.h +outputs="$(nm -C $ssl_lib)"$'\n'"$(nm -C $crypto_lib)" +symbols=$(echo "$outputs" | + grep '^[0-9a-f]* [A-Z] ' | # Only public symbols + grep -v ' bssl::' | # Filter BoringSSL symbols since they are already namespaced + sed 's/(.*//g' | # Remove parenthesis from C++ symbols + grep '^[0-9a-f]* [A-Z] _' | # Filter symbols that is not prefixed with '_' + sed 's/[0-9a-f]* [A-Z] _\(.*\)/\1/g') # Extract the symbol names + +commit=$(git submodule | grep "boringssl " | awk '{print $1}' | head -n 1) + +echo "# Automatically generated by tools/distrib/generate_grpc_shadow_boringssl_symbol_list.sh" > $symbol_list +echo $commit >> $symbol_list +echo "$symbols" >> $symbol_list + +exit 0 diff --git a/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh b/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh index 3b901ae4bff..0c8ecc21a0c 100755 --- a/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh +++ b/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh @@ -29,7 +29,7 @@ for dir in $DIRS do for glob in $GLOB do - files="$files `find ${CLANG_FORMAT_ROOT}/$dir -name $glob -and -not -name '*.generated.*' -and -not -name '*.pb.h' -and -not -name '*.pb.c' -and -not -name '*.pb.cc' -and -not -name '*.pbobjc.h' -and -not -name '*.pbobjc.m' -and -not -name '*.pbrpc.h' -and -not -name '*.pbrpc.m' -and -not -name end2end_tests.cc -and -not -name end2end_nosec_tests.cc -and -not -name public_headers_must_be_c89.c`" + files="$files `find ${CLANG_FORMAT_ROOT}/$dir -name $glob -and -not -name '*.generated.*' -and -not -name '*.pb.h' -and -not -name '*.pb.c' -and -not -name '*.pb.cc' -and -not -name '*.pbobjc.h' -and -not -name '*.pbobjc.m' -and -not -name '*.pbrpc.h' -and -not -name '*.pbrpc.m' -and -not -name end2end_tests.cc -and -not -name end2end_nosec_tests.cc -and -not -name public_headers_must_be_c89.c -and -not -name grpc_shadow_boringssl.h`" done done diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 18f56984fe2..a2b7e4fce10 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1501,6 +1501,7 @@ src/core/tsi/alts_transport_security.cc \ src/core/tsi/alts_transport_security.h \ src/core/tsi/fake_transport_security.cc \ src/core/tsi/fake_transport_security.h \ +src/core/tsi/grpc_shadow_boringssl.h \ src/core/tsi/local_transport_security.cc \ src/core/tsi/local_transport_security.h \ src/core/tsi/ssl/session_cache/ssl_session.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index a686dae8b4a..2e1acc61f48 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9051,6 +9051,7 @@ "alts_util", "gpr", "grpc_base", + "grpc_shadow_boringssl", "grpc_transport_chttp2_client_insecure", "tsi", "tsi_interface" @@ -10337,6 +10338,7 @@ "alts_tsi", "gpr", "grpc_base", + "grpc_shadow_boringssl", "grpc_transport_chttp2_alpn", "tsi" ], @@ -10446,6 +10448,20 @@ "third_party": false, "type": "filegroup" }, + { + "deps": [], + "headers": [ + "src/core/tsi/grpc_shadow_boringssl.h" + ], + "is_filegroup": true, + "language": "c", + "name": "grpc_shadow_boringssl", + "src": [ + "src/core/tsi/grpc_shadow_boringssl.h" + ], + "third_party": false, + "type": "filegroup" + }, { "deps": [ "cmdline", @@ -10897,6 +10913,7 @@ "deps": [ "gpr", "grpc_base", + "grpc_shadow_boringssl", "grpc_trace", "tsi_interface" ], diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml index ac0d4c70e5d..72bfad90bcc 100644 --- a/tools/run_tests/sanity/sanity_tests.yaml +++ b/tools/run_tests/sanity/sanity_tests.yaml @@ -22,4 +22,5 @@ - script: tools/distrib/pylint_code.sh - script: tools/distrib/yapf_code.sh - script: tools/distrib/python/check_grpcio_tools.py +- script: tools/distrib/check_shadow_boringssl_symbol_list.sh cpu_cost: 1000 From 0cd641b4449f7d379d59940a2fd4714f7e796c5f Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 23 Aug 2018 10:02:33 -0700 Subject: [PATCH 198/546] do not track fds for poll-cv --- src/core/lib/iomgr/ev_poll_posix.cc | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index dd71ccdd0ca..73563e3aa2c 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -62,7 +62,7 @@ typedef struct grpc_fd_watcher { typedef struct grpc_cached_wakeup_fd grpc_cached_wakeup_fd; -/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ +/* Only used by poll when GRPC_ENABLE_FORK_SUPPORT=1 */ struct grpc_fork_fd_list { /* Only one of fd or cached_wakeup_fd will be set. The unused field will be set to nullptr. */ @@ -122,11 +122,15 @@ struct grpc_fd { grpc_iomgr_object iomgr_object; - /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ + /* Only used by poll when GRPC_ENABLE_FORK_SUPPORT=1 */ grpc_fork_fd_list* fork_fd_list; }; -/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ +/* True when GRPC_ENABLE_FORK_SUPPORT=1 and polling strategy is poll. We do not + * support fork with poll-cv */ +static bool track_fds_for_fork = false; + +/* Only used by poll when GRPC_ENABLE_FORK_SUPPORT=1 */ static grpc_fork_fd_list* fork_fd_list_head = nullptr; static gpr_mu fork_fd_list_mu; @@ -177,7 +181,7 @@ typedef struct grpc_cached_wakeup_fd { grpc_wakeup_fd fd; struct grpc_cached_wakeup_fd* next; - /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ + /* Only used by poll when GRPC_ENABLE_FORK_SUPPORT=1 */ grpc_fork_fd_list* fork_fd_list; } grpc_cached_wakeup_fd; @@ -304,11 +308,11 @@ poll_hash_table poll_cache; grpc_cv_fd_table g_cvfds; /******************************************************************************* - * functions to track opened fds. No-ops unless GRPC_ENABLE_FORK_SUPPORT=1. + * functions to track opened fds. No-ops unless track_fds_for_fork is true. */ static void fork_fd_list_remove_node(grpc_fork_fd_list* node) { - if (grpc_core::Fork::Enabled()) { + if (track_fds_for_fork) { gpr_mu_lock(&fork_fd_list_mu); if (fork_fd_list_head == node) { fork_fd_list_head = node->next; @@ -336,7 +340,7 @@ static void fork_fd_list_add_node(grpc_fork_fd_list* node) { } static void fork_fd_list_add_grpc_fd(grpc_fd* fd) { - if (grpc_core::Fork::Enabled()) { + if (track_fds_for_fork) { fd->fork_fd_list = static_cast(gpr_malloc(sizeof(grpc_fork_fd_list))); fd->fork_fd_list->fd = fd; @@ -346,7 +350,7 @@ static void fork_fd_list_add_grpc_fd(grpc_fd* fd) { } static void fork_fd_list_add_wakeup_fd(grpc_cached_wakeup_fd* fd) { - if (grpc_core::Fork::Enabled()) { + if (track_fds_for_fork) { fd->fork_fd_list = static_cast(gpr_malloc(sizeof(grpc_fork_fd_list))); fd->fork_fd_list->cached_wakeup_fd = fd; @@ -1784,7 +1788,7 @@ static void shutdown_engine(void) { if (grpc_cv_wakeup_fds_enabled()) { global_cv_fd_table_shutdown(); } - if (grpc_core::Fork::Enabled()) { + if (track_fds_for_fork) { gpr_mu_destroy(&fork_fd_list_mu); grpc_core::Fork::SetResetChildPollingEngineFunc(nullptr); } @@ -1854,6 +1858,7 @@ const grpc_event_engine_vtable* grpc_init_poll_posix(bool explicit_request) { return nullptr; } if (grpc_core::Fork::Enabled()) { + track_fds_for_fork = true; gpr_mu_init(&fork_fd_list_mu); grpc_core::Fork::SetResetChildPollingEngineFunc( reset_event_manager_on_fork); From 32a8a860459370c540f1150767a0a703c3c433e0 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 22 Aug 2018 23:09:55 -0700 Subject: [PATCH 199/546] Fix build issue --- .../filters/load_reporting/server_load_reporting_filter.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 6529046a5e7..8ac34c629f7 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 @@ -162,9 +162,10 @@ void ServerLoadReportingCallData::GetCensusSafeClientIpString( } else if (addr->sa_family == GRPC_AF_INET6) { grpc_sockaddr_in6* addr6 = reinterpret_cast(addr); *client_ip_string = static_cast(gpr_malloc(32 + 1)); - for (size_t i = 0; i < 16; ++i) { - snprintf(*client_ip_string + i * 2, 2 + 1, "%02x", - addr6->sin6_addr.__in6_u.__u6_addr8[i]); + uint32_t* addr6_next_long = reinterpret_cast(&addr6->sin6_addr); + for (size_t i = 0; i < 4; ++i) { + snprintf(*client_ip_string + 8 * i, 8 + 1, "%08x", + grpc_ntohl(*addr6_next_long++)); } *size = 32; } else { From 497532027dca770da60ac23e44f60ecf619cc2c5 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 23 Aug 2018 14:00:49 -0700 Subject: [PATCH 200/546] Reviewer comments --- src/core/lib/surface/call.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index fb3161aeaab..0b86a743405 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -510,9 +510,8 @@ static void destroy_call(void* call, grpc_error* error) { GRPC_CQ_INTERNAL_UNREF(c->cq, "bind"); } - grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(c->status_error, c->send_deadline, - &c->final_info.final_status, &slice, nullptr, + &c->final_info.final_status, nullptr, nullptr, &(c->final_info.error_string)); GRPC_ERROR_UNREF(c->status_error); c->final_info.stats.latency = @@ -690,8 +689,6 @@ static void set_final_status(grpc_call* call, grpc_error* error) { gpr_log(GPR_DEBUG, "set_final_status %s", call->is_client ? "CLI" : "SVR"); gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); } - grpc_core::channelz::ChannelNode* channelz_channel = - grpc_channel_get_channelz_node(call->channel); if (call->is_client) { grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(error, call->send_deadline, @@ -699,6 +696,8 @@ static void set_final_status(grpc_call* call, grpc_error* error) { call->final_op.client.error_string); *call->final_op.client.status_details = grpc_slice_ref_internal(slice); call->status_error = error; + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(call->channel); if (channelz_channel != nullptr) { if (*call->final_op.client.status != GRPC_STATUS_OK) { channelz_channel->RecordCallFailed(); @@ -709,13 +708,14 @@ static void set_final_status(grpc_call* call, grpc_error* error) { } else { *call->final_op.server.cancelled = error != GRPC_ERROR_NONE || call->status_error != GRPC_ERROR_NONE; - if (channelz_channel != nullptr) { + /* TODO(ncteisen) : Update channelz handling for server + if (channelz_channel != nullptr) { if (*call->final_op.server.cancelled) { channelz_channel->RecordCallFailed(); } else { channelz_channel->RecordCallSucceeded(); } - } + } */ GRPC_ERROR_UNREF(error); } } @@ -992,7 +992,7 @@ static void recv_trailing_filter(void* args, grpc_metadata_batch* b, grpc_error* batch_error) { grpc_call* call = static_cast(args); if (batch_error != GRPC_ERROR_NONE) { - set_final_status(call, GRPC_ERROR_REF(batch_error)); + set_final_status(call, batch_error); } else if (b->idx.named.grpc_status != nullptr) { grpc_status_code status_code = grpc_get_status_code_from_metadata(b->idx.named.grpc_status->md); @@ -1025,7 +1025,6 @@ static void recv_trailing_filter(void* args, grpc_metadata_batch* b, GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNKNOWN)); } publish_app_metadata(call, b, true); - GRPC_ERROR_UNREF(batch_error); } gpr_arena* grpc_call_get_arena(grpc_call* call) { return call->arena; } From 71655cf48a09621a2cfcdd497e0804b6a452df7d Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 21 Aug 2018 06:58:17 +0200 Subject: [PATCH 201/546] Fixing the SSL_REUSE auth context string attribute. "true" and "false" are strings, so use similar code that of the cstring variant. Otherwise, the generated properties will have an embedded zero in there. --- src/core/tsi/ssl_transport_security.cc | 4 ++-- test/core/tsi/ssl_transport_security_test.cc | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index e66fc9ba034..c329f41348e 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -1049,9 +1049,9 @@ static tsi_result ssl_handshaker_result_extract_peer( } const char* session_reused = SSL_session_reused(impl->ssl) ? "true" : "false"; - result = tsi_construct_string_peer_property( + result = tsi_construct_string_peer_property_from_cstring( TSI_SSL_SESSION_REUSED_PEER_PROPERTY, session_reused, - strlen(session_reused) + 1, &peer->properties[peer->property_count]); + &peer->properties[peer->property_count]); if (result != TSI_OK) return result; peer->property_count++; diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index b477904d60d..baffad6ea36 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -208,9 +208,11 @@ static void check_session_reusage(ssl_tsi_test_fixture* ssl_fixture, tsi_peer_get_property_by_name(peer, TSI_SSL_SESSION_REUSED_PEER_PROPERTY); GPR_ASSERT(session_reused != nullptr); if (ssl_fixture->session_reused) { - GPR_ASSERT(strcmp(session_reused->value.data, "true") == 0); + GPR_ASSERT(strncmp(session_reused->value.data, "true", + session_reused->value.length) == 0); } else { - GPR_ASSERT(strcmp(session_reused->value.data, "false") == 0); + GPR_ASSERT(strncmp(session_reused->value.data, "false", + session_reused->value.length) == 0); } } From 927fc8d3a3f65eb66c8127bae0055b2fae3a73c3 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 23 Aug 2018 14:36:04 -0700 Subject: [PATCH 202/546] Reset bytes_counter on setting socket options. Wrap out sendmsg and add comments for bytes_counter --- src/core/lib/iomgr/tcp_posix.cc | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 8a479d2cccb..44829e2ac52 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -120,8 +120,9 @@ struct grpc_tcp { * requirement from the TCP endpoint layer is that this arg should be non-null * if the user wants timestamps for the write. */ void* outgoing_buffer_arg; - /* Current TCP (relative) sequence number which starts out at zero. Used for - * timestamping traced buffers. */ + /* A counter which starts at 0. It is initialized the first time the socket + * options for collecting timestamps are set, and is incremented with each + * byte sent. */ int bytes_counter; bool socket_ts_enabled; /* True if timestamping options are set on the socket */ @@ -574,6 +575,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, } return false; } + tcp->bytes_counter = 0; tcp->socket_ts_enabled = true; } /* Set control message to indicate that you want timestamps. */ @@ -590,12 +592,8 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, msg->msg_control = u.cmsg_buf; msg->msg_controllen = CMSG_SPACE(sizeof(uint32_t)); - ssize_t length; - do { - GRPC_STATS_INC_SYSCALL_WRITE(); - length = sendmsg(tcp->fd, msg, SENDMSG_FLAGS); - } while (length < 0 && errno == EINTR); /* If there was an error on sendmsg the logic in tcp_flush will handle it. */ + ssize_t length = sendmsg_wrapper(tcp->fd, msg); *sent_length = length; /* Only save timestamps if all the bytes were taken by sendmsg. */ if (sending_length == static_cast(length)) { @@ -763,6 +761,19 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { } #endif /* GRPC_LINUX_ERRQUEUE */ +/* A wrapper around sendmsg. It sends \a msg over \a fd and returns the number + * of bytes sent. */ +ssize_t sendmsg_wrapper(int fd, const struct msghdr* msg) { + GPR_TIMER_SCOPE("sendmsg", 1); + ssize_t sent_length; + do { + /* TODO(klempner): Cork if this is a partial write */ + GRPC_STATS_INC_SYSCALL_WRITE(); + sent_length = sendmsg(fd, msg, SENDMSG_FLAGS); + } while (sent_length < 0 && errno == EINTR); + return sent_length; +} + /* returns true if done, false if pending; if returning true, *error is set */ #if defined(IOV_MAX) && IOV_MAX < 1000 #define MAX_WRITE_IOVEC IOV_MAX @@ -819,12 +830,7 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { GRPC_STATS_INC_TCP_WRITE_SIZE(sending_length); GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(iov_size); - GPR_TIMER_SCOPE("sendmsg", 1); - do { - /* TODO(klempner): Cork if this is a partial write */ - GRPC_STATS_INC_SYSCALL_WRITE(); - sent_length = sendmsg(tcp->fd, &msg, SENDMSG_FLAGS); - } while (sent_length < 0 && errno == EINTR); + sent_length = sendmsg_wrapper(tcp->fd, &msg); } if (sent_length < 0) { From b01a2774f4944c18830b83caded74c102a15cc01 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 23 Aug 2018 15:36:29 -0700 Subject: [PATCH 203/546] fix comments --- src/core/lib/iomgr/ev_poll_posix.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index 73563e3aa2c..b5e008ef05c 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -62,7 +62,7 @@ typedef struct grpc_fd_watcher { typedef struct grpc_cached_wakeup_fd grpc_cached_wakeup_fd; -/* Only used by poll when GRPC_ENABLE_FORK_SUPPORT=1 */ +/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ struct grpc_fork_fd_list { /* Only one of fd or cached_wakeup_fd will be set. The unused field will be set to nullptr. */ @@ -122,15 +122,14 @@ struct grpc_fd { grpc_iomgr_object iomgr_object; - /* Only used by poll when GRPC_ENABLE_FORK_SUPPORT=1 */ + /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ grpc_fork_fd_list* fork_fd_list; }; -/* True when GRPC_ENABLE_FORK_SUPPORT=1 and polling strategy is poll. We do not - * support fork with poll-cv */ +/* True when GRPC_ENABLE_FORK_SUPPORT=1. We do not support fork with poll-cv */ static bool track_fds_for_fork = false; -/* Only used by poll when GRPC_ENABLE_FORK_SUPPORT=1 */ +/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ static grpc_fork_fd_list* fork_fd_list_head = nullptr; static gpr_mu fork_fd_list_mu; @@ -181,7 +180,7 @@ typedef struct grpc_cached_wakeup_fd { grpc_wakeup_fd fd; struct grpc_cached_wakeup_fd* next; - /* Only used by poll when GRPC_ENABLE_FORK_SUPPORT=1 */ + /* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */ grpc_fork_fd_list* fork_fd_list; } grpc_cached_wakeup_fd; From 676f99a8ebd397eb38f59b5b2f91d3e6c4f654d2 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 23 Aug 2018 15:44:26 -0700 Subject: [PATCH 204/546] Fix a parameter name mismatch --- src/core/lib/gprpp/fork.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/lib/gprpp/fork.cc b/src/core/lib/gprpp/fork.cc index 0288c396808..3b9c16510a7 100644 --- a/src/core/lib/gprpp/fork.cc +++ b/src/core/lib/gprpp/fork.cc @@ -222,8 +222,9 @@ void Fork::DecExecCtxCount() { } } -void Fork::SetResetChildPollingEngineFunc(Fork::child_postfork_func func) { - reset_child_polling_engine_ = func; +void Fork::SetResetChildPollingEngineFunc( + Fork::child_postfork_func reset_child_polling_engine) { + reset_child_polling_engine_ = reset_child_polling_engine; } Fork::child_postfork_func Fork::GetResetChildPollingEngineFunc() { return reset_child_polling_engine_; From edac3c6f9b07533aa56ea50e838ff72fd1608019 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 23 Aug 2018 16:05:18 -0700 Subject: [PATCH 205/546] sanity --- src/core/lib/iomgr/ev_poll_posix.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc index b5e008ef05c..16562538a63 100644 --- a/src/core/lib/iomgr/ev_poll_posix.cc +++ b/src/core/lib/iomgr/ev_poll_posix.cc @@ -358,9 +358,9 @@ static void fork_fd_list_add_wakeup_fd(grpc_cached_wakeup_fd* fd) { } } -/******************************************************************************* - * fd_posix.c - */ + /******************************************************************************* + * fd_posix.c + */ #ifndef NDEBUG #define REF_BY(fd, n, reason) ref_by(fd, n, reason, __FILE__, __LINE__) From 571109e40030548a17ea10ff208a1dec6b79f8a3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 23 Aug 2018 16:44:02 -0700 Subject: [PATCH 206/546] Update README to document the change --- src/objective-c/README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/objective-c/README.md b/src/objective-c/README.md index 40aba0317b3..32e3956a1ef 100644 --- a/src/objective-c/README.md +++ b/src/objective-c/README.md @@ -220,3 +220,25 @@ Objective-C Protobuf runtime library. [gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install [example Podfile]:https://github.com/grpc/grpc/blob/master/examples/objective-c/helloworld/Podfile [example apps]: https://github.com/grpc/grpc/tree/master/examples/objective-c + +## Use gRPC with OpenSSL +gRPC uses BoringSSL as its dependency, which is a fork of OpenSSL and export a number of symbols +that are the same as OpenSSL. gRPC avoids conflicts of these symbols by renaming BoringSSL symbols. + +If you need gRPC to use OpenSSL instead of BoringSSL (e.g. for the benefit of reducing the binary +size of your product), you need to make a local `gRPC-Core` podspec and tweak it accordingly: +- Copy the version of `/gRPC-Core.podspec` you wish to use from Github into the repository of your + app; +- In your `Podfile`, add the following line: +``` +pod `gRPC-Core`, :podspec => "." # assuming gRPC-Core.podspec is in the same directory as your Podfile +``` +- Remove [the + macro](https://github.com/grpc/grpc/blob/b24b212ee585d376c618235905757b2445ac6461/gRPC-Core.podspec#L186) + `GRPC_SHADOW_BORINGSSL_SYMBOLS` to disable symbol renaming; +- Substitude the `BoringSSL-GRPC` + [dependency](https://github.com/grpc/grpc/blob/b24b212ee585d376c618235905757b2445ac6461/gRPC-Core.podspec#L184) + to whatever pod of OpenSSL your other libraries use. + +These steps should allow gRPC to use OpenSSL and drop BoringSSL dependency. If you see any issue, +file an issue to us. From 373cb20ea81f24948385954ecd06df199c4267c0 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 23 Aug 2018 17:40:28 -0700 Subject: [PATCH 207/546] expect_tags before callbacks could get executed to avoid a data race --- test/core/end2end/inproc_callback_test.cc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/test/core/end2end/inproc_callback_test.cc b/test/core/end2end/inproc_callback_test.cc index 59d8ed987f5..653e8a4c8ea 100644 --- a/test/core/end2end/inproc_callback_test.cc +++ b/test/core/end2end/inproc_callback_test.cc @@ -104,10 +104,9 @@ bool tags_valid[kAvailableTags]; bool tags_expected[kAvailableTags]; bool tags_needed[kAvailableTags]; -// Mark that a tag is expected; this function must be -// executed in the main thread only while there are no -// other threads altering the expectation set (e.g., -// running callbacks). +// Mark that a tag is expected; this function must be executed in the +// main thread only while there are no other threads altering the +// expectation set (e.g., running callbacks). static void expect_tag(intptr_t tag, bool ok) { size_t idx = static_cast(tag); GPR_ASSERT(idx < kAvailableTags); @@ -340,13 +339,14 @@ static void simple_request_body(grpc_end2end_test_config config, GPR_ASSERT(GRPC_CALL_OK == error); // Register a call at the server-side to match the incoming client call + // First mark that we are expecting its tag to complete in this round + expect_tag(2, true); error = grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(2)); GPR_ASSERT(GRPC_CALL_OK == error); // We expect that the server call creation callback (and no others) will // execute now since no other batch should be complete. - expect_tag(2, true); verify_tags(deadline); peer = grpc_call_get_peer(s); @@ -358,6 +358,11 @@ static void simple_request_body(grpc_end2end_test_config config, gpr_log(GPR_DEBUG, "client_peer=%s", peer); gpr_free(peer); + // Both the client request and server response batches should get complete + // in this round and we should see that their callbacks get executed + expect_tag(3, true); + expect_tag(1, true); + // Create the server response batch (no payload) memset(ops, 0, sizeof(ops)); op = ops; @@ -383,10 +388,7 @@ static void simple_request_body(grpc_end2end_test_config config, nullptr); GPR_ASSERT(GRPC_CALL_OK == error); - // Both the client request and server response batches should get complete - // now and we should see that their callbacks have been executed - expect_tag(3, true); - expect_tag(1, true); + // Make sure that the tags get executed by the deadline verify_tags(deadline); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); From 4f98f82c36d47ff6b3c85b61854c093f93c15eb3 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 23 Aug 2018 17:45:27 -0700 Subject: [PATCH 208/546] Add asserts on bad verify results --- test/core/end2end/inproc_callback_test.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/core/end2end/inproc_callback_test.cc b/test/core/end2end/inproc_callback_test.cc index 653e8a4c8ea..a07b4df29a1 100644 --- a/test/core/end2end/inproc_callback_test.cc +++ b/test/core/end2end/inproc_callback_test.cc @@ -131,11 +131,13 @@ static void verify_tags(gpr_timespec deadline) { if (tags[i] != tags_expected[i]) { gpr_log(GPR_ERROR, "Got wrong result (%d instead of %d) for tag %d", tags[i], tags_expected[i], static_cast(i)); + GPR_ASSERT(false); } tags_valid[i] = false; tags_needed[i] = false; } else if (done) { gpr_log(GPR_ERROR, "Didn't get tag %d", static_cast(i)); + GPR_ASSERT(false); } } } @@ -151,6 +153,7 @@ static void verify_tags(gpr_timespec deadline) { if (tags_valid[i]) { gpr_log(GPR_ERROR, "Got unexpected tag %d and result %d", static_cast(i), tags[i]); + GPR_ASSERT(false); } tags_valid[i] = false; } From 679cbb83a4178e3073d08e293a020fb39244bfe0 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 24 Aug 2018 09:04:28 -0700 Subject: [PATCH 209/546] Improve comments and revert much of 373cb20 --- test/core/end2end/inproc_callback_test.cc | 27 ++++++++++++----------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/test/core/end2end/inproc_callback_test.cc b/test/core/end2end/inproc_callback_test.cc index a07b4df29a1..0d6c7c75a8b 100644 --- a/test/core/end2end/inproc_callback_test.cc +++ b/test/core/end2end/inproc_callback_test.cc @@ -106,7 +106,7 @@ bool tags_needed[kAvailableTags]; // Mark that a tag is expected; this function must be executed in the // main thread only while there are no other threads altering the -// expectation set (e.g., running callbacks). +// expectation set (e.g., by calling expect_tag or verify_tags) static void expect_tag(intptr_t tag, bool ok) { size_t idx = static_cast(tag); GPR_ASSERT(idx < kAvailableTags); @@ -114,10 +114,14 @@ static void expect_tag(intptr_t tag, bool ok) { tags_expected[idx] = ok; } -// The tag verifier doesn't have to drive the CQ at all (unlike the -// next-based end2end tests) because the tags will get set when the -// callbacks are executed, which happens when a particular batch -// related to a callback is complete +// Check that the expected tags have reached, within a certain +// deadline. This must also be executed only on the main thread while +// there are no other threads altering the expectation set (e.g., by +// calling expect_tag or verify_tags). The tag verifier doesn't have +// to drive the CQ at all (unlike the next-based end2end tests) +// because the tags will get set when the callbacks are executed, +// which happens when a particular batch related to a callback is +// complete. static void verify_tags(gpr_timespec deadline) { bool done = false; @@ -342,14 +346,13 @@ static void simple_request_body(grpc_end2end_test_config config, GPR_ASSERT(GRPC_CALL_OK == error); // Register a call at the server-side to match the incoming client call - // First mark that we are expecting its tag to complete in this round - expect_tag(2, true); error = grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(2)); GPR_ASSERT(GRPC_CALL_OK == error); // We expect that the server call creation callback (and no others) will // execute now since no other batch should be complete. + expect_tag(2, true); verify_tags(deadline); peer = grpc_call_get_peer(s); @@ -361,11 +364,6 @@ static void simple_request_body(grpc_end2end_test_config config, gpr_log(GPR_DEBUG, "client_peer=%s", peer); gpr_free(peer); - // Both the client request and server response batches should get complete - // in this round and we should see that their callbacks get executed - expect_tag(3, true); - expect_tag(1, true); - // Create the server response batch (no payload) memset(ops, 0, sizeof(ops)); op = ops; @@ -391,7 +389,10 @@ static void simple_request_body(grpc_end2end_test_config config, nullptr); GPR_ASSERT(GRPC_CALL_OK == error); - // Make sure that the tags get executed by the deadline + // Both the client request and server response batches should get complete + // now and we should see that their callbacks have been executed + expect_tag(3, true); + expect_tag(1, true); verify_tags(deadline); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); From 5be7304b06cfa197c0d63ab0972026745a2c0919 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 24 Aug 2018 09:46:39 -0700 Subject: [PATCH 210/546] used standalone JSON files for scenarios --- test/cpp/qps/BUILD | 32 +++++++++++++++---- .../cpp/qps/json_run_localhost_scenarios.json | 1 + test/cpp/qps/qps_json_driver_scenarios.json | 1 + 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 test/cpp/qps/json_run_localhost_scenarios.json create mode 100644 test/cpp/qps/qps_json_driver_scenarios.json diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index 988385bba5c..848a4ad87ed 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -135,13 +135,24 @@ grpc_cc_library( deps = ["//:grpc++"], ) +filegroup( + name = "json_run_localhost_scenarios", + srcs = [ + ":json_run_localhost_scenarios.json", + ], +) + grpc_cc_test( name = "json_run_localhost", srcs = ["json_run_localhost.cc"], args = [ - "--scenarios_json", - """'{"scenarios": [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_75Kqps_600channel_60Krpcs_300Breq_50Bresp", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 16, "threads_per_cq": 1, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"poisson": {"offered_load": 37500}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 50, "req_size": 300}}, "client_channels": 300, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_75Kqps_600channel_60Krpcs_300Breq_50Bresp", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 16, "threads_per_cq": 1, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"poisson": {"offered_load": 37500}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 50, "req_size": 300}}, "client_channels": 300, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}' -""", + "--scenarios_file", + "$(location //test/cpp/qps:json_run_localhost_scenarios)", + ], + data = [ + "//test/cpp/qps:json_run_localhost_scenarios", + "//test/cpp/qps:qps_json_driver", + "//test/cpp/qps:qps_worker", ], deps = [ "//:gpr", @@ -162,14 +173,23 @@ grpc_cc_test( ], ) +filegroup( + name = "qps_json_driver_scenarios", + srcs = [ + ":qps_json_driver_scenarios.json", + ], +) + grpc_cc_test( name = "qps_json_driver", srcs = ["qps_json_driver.cc"], args = [ "--run_inproc", - "--scenarios_json", - """'{"scenarios": [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}' -""", + "--scenarios_file", + "$(location //test/cpp/qps:qps_json_driver_scenarios)", + ], + data = [ + "//test/cpp/qps:qps_json_driver_scenarios", ], external_deps = [ "gflags", diff --git a/test/cpp/qps/json_run_localhost_scenarios.json b/test/cpp/qps/json_run_localhost_scenarios.json new file mode 100644 index 00000000000..e32fc8f610e --- /dev/null +++ b/test/cpp/qps/json_run_localhost_scenarios.json @@ -0,0 +1 @@ +{"scenarios": [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_75Kqps_600channel_60Krpcs_300Breq_50Bresp", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 16, "threads_per_cq": 1, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"poisson": {"offered_load": 37500}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 50, "req_size": 300}}, "client_channels": 300, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_75Kqps_600channel_60Krpcs_300Breq_50Bresp", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 16, "threads_per_cq": 1, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"poisson": {"offered_load": 37500}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 50, "req_size": 300}}, "client_channels": 300, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]} \ No newline at end of file diff --git a/test/cpp/qps/qps_json_driver_scenarios.json b/test/cpp/qps/qps_json_driver_scenarios.json new file mode 100644 index 00000000000..d8b3413f91f --- /dev/null +++ b/test/cpp/qps/qps_json_driver_scenarios.json @@ -0,0 +1 @@ +{"scenarios": [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]} \ No newline at end of file From 841f186041240612cca1b0010b21c5841a55fc98 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 23 Aug 2018 15:04:46 -0700 Subject: [PATCH 211/546] %s/sendmsg_wrapper/tcp_send --- src/core/lib/iomgr/tcp_posix.cc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 44829e2ac52..1db2790265e 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -546,6 +546,19 @@ static void tcp_read(grpc_endpoint* ep, grpc_slice_buffer* incoming_buffer, } } +/* A wrapper around sendmsg. It sends \a msg over \a fd and returns the number + * of bytes sent. */ +ssize_t tcp_send(int fd, const struct msghdr* msg) { + GPR_TIMER_SCOPE("sendmsg", 1); + ssize_t sent_length; + do { + /* TODO(klempner): Cork if this is a partial write */ + GRPC_STATS_INC_SYSCALL_WRITE(); + sent_length = sendmsg(fd, msg, SENDMSG_FLAGS); + } while (sent_length < 0 && errno == EINTR); + return sent_length; +} + /** This is to be called if outgoing_buffer_arg is not null. On linux platforms, * this will call sendmsg with socket options set to collect timestamps inside * the kernel. On return, sent_length is set to the return value of the sendmsg @@ -575,7 +588,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, } return false; } - tcp->bytes_counter = 0; + tcp->bytes_counter = -1; tcp->socket_ts_enabled = true; } /* Set control message to indicate that you want timestamps. */ @@ -593,7 +606,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, msg->msg_controllen = CMSG_SPACE(sizeof(uint32_t)); /* If there was an error on sendmsg the logic in tcp_flush will handle it. */ - ssize_t length = sendmsg_wrapper(tcp->fd, msg); + ssize_t length = tcp_send(tcp->fd, msg); *sent_length = length; /* Only save timestamps if all the bytes were taken by sendmsg. */ if (sending_length == static_cast(length)) { @@ -761,19 +774,6 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { } #endif /* GRPC_LINUX_ERRQUEUE */ -/* A wrapper around sendmsg. It sends \a msg over \a fd and returns the number - * of bytes sent. */ -ssize_t sendmsg_wrapper(int fd, const struct msghdr* msg) { - GPR_TIMER_SCOPE("sendmsg", 1); - ssize_t sent_length; - do { - /* TODO(klempner): Cork if this is a partial write */ - GRPC_STATS_INC_SYSCALL_WRITE(); - sent_length = sendmsg(fd, msg, SENDMSG_FLAGS); - } while (sent_length < 0 && errno == EINTR); - return sent_length; -} - /* returns true if done, false if pending; if returning true, *error is set */ #if defined(IOV_MAX) && IOV_MAX < 1000 #define MAX_WRITE_IOVEC IOV_MAX @@ -830,7 +830,7 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { GRPC_STATS_INC_TCP_WRITE_SIZE(sending_length); GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(iov_size); - sent_length = sendmsg_wrapper(tcp->fd, &msg); + sent_length = tcp_send(tcp->fd, &msg); } if (sent_length < 0) { From d60a4b0f6b0d0d92944385bc9b629bb12aea24af Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 24 Aug 2018 09:44:37 -0700 Subject: [PATCH 212/546] Reviewer comments --- src/core/lib/surface/call.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 0b86a743405..e568ff3db45 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -690,11 +690,12 @@ static void set_final_status(grpc_call* call, grpc_error* error) { gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); } if (call->is_client) { - grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(error, call->send_deadline, - call->final_op.client.status, &slice, nullptr, + call->final_op.client.status, + call->final_op.client.status_details, nullptr, call->final_op.client.error_string); - *call->final_op.client.status_details = grpc_slice_ref_internal(slice); + // explicitly take a ref + grpc_slice_ref_internal(*call->final_op.client.status_details); call->status_error = error; grpc_core::channelz::ChannelNode* channelz_channel = grpc_channel_get_channelz_node(call->channel); From 5f84445781ef29e50435c2eea661ca435a19b6bc Mon Sep 17 00:00:00 2001 From: Adele Zhou Date: Fri, 24 Aug 2018 14:17:12 -0700 Subject: [PATCH 213/546] Upgrade bazel to 0.16.1 --- bazel/grpc_deps.bzl | 8 ++++---- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 8 ++++---- tools/internal_ci/linux/grpc_msan_on_foundry.sh | 10 +++++----- tools/internal_ci/linux/grpc_ubsan_on_foundry.sh | 8 ++++---- .../linux/pull_request/grpc_ubsan_on_foundry.sh | 8 ++++---- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index d7519b14532..4096720569a 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -169,12 +169,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-4653c01284d8a4a536f8f9bb47b7d10f94c549e7", + strip_prefix = "bazel-toolchains-cdea5b8675914d0a354d89f108de5d28e54e0edc", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/4653c01284d8a4a536f8f9bb47b7d10f94c549e7.tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/4653c01284d8a4a536f8f9bb47b7d10f94c549e7.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/cdea5b8675914d0a354d89f108de5d28e54e0edc.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/cdea5b8675914d0a354d89f108de5d28e54e0edc.tar.gz", ], - sha256 = "1c4a532b396c698e6467a1548554571cb85fa091e472b05e398ebc836c315d77", + sha256 = "cefb6ccf86ca592baaa029bcef04148593c0efe8f734542f10293ea58f170715", ) if "io_opencensus_cpp" not in native.existing_rules(): diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 8f9658f78a6..6419030bbb2 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -22,8 +22,8 @@ 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-rc-0.14.0rc5" ${temp_dir}/bazel -chmod 755 "${KOKORO_GFILE_DIR}/bazel-rc-0.14.0rc5" +ln -f "${KOKORO_GFILE_DIR}/bazel-latest-release" ${temp_dir}/bazel +chmod 755 "${KOKORO_GFILE_DIR}/bazel-latest-release" export PATH="${temp_dir}:${PATH}" # This should show ${temp_dir}/bazel which bazel @@ -49,10 +49,10 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --strategy=Closure=remote \ --genrule_strategy=remote \ --experimental_strict_action_env=true \ - --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.13.0/default:toolchain \ + --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain \ --define GRPC_PORT_ISOLATED_RUNTIME=1 \ --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \ - --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.13.0/cpp:cc-toolchain-clang-x86_64-default \ + --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default \ --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ diff --git a/tools/internal_ci/linux/grpc_msan_on_foundry.sh b/tools/internal_ci/linux/grpc_msan_on_foundry.sh index aa1e613d787..7d11719ea4a 100644 --- a/tools/internal_ci/linux/grpc_msan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_msan_on_foundry.sh @@ -23,8 +23,8 @@ 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-rc-0.14.0rc5" ${temp_dir}/bazel -chmod 755 "${KOKORO_GFILE_DIR}/bazel-rc-0.14.0rc5" +ln -f "${KOKORO_GFILE_DIR}/bazel-latest-release" ${temp_dir}/bazel +chmod 755 "${KOKORO_GFILE_DIR}/bazel-latest-release" export PATH="${temp_dir}:${PATH}" # This should show ${temp_dir}/bazel which bazel @@ -58,10 +58,10 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --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/ubuntu16_04_clang/1.0/bazel_0.13.0/default:toolchain \ - --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.13.0/msan:toolchain \ + --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain \ + --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/msan:toolchain \ --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \ - --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.13.0/cpp:cc-toolchain-clang-x86_64-default \ + --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default \ --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ diff --git a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh index 338b1b6a0d0..1eda166620c 100644 --- a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh @@ -23,8 +23,8 @@ 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-rc-0.14.0rc5" ${temp_dir}/bazel -chmod 755 "${KOKORO_GFILE_DIR}/bazel-rc-0.14.0rc5" +ln -f "${KOKORO_GFILE_DIR}/bazel-latest-release" ${temp_dir}/bazel +chmod 755 "${KOKORO_GFILE_DIR}/bazel-latest-release" export PATH="${temp_dir}:${PATH}" # This should show ${temp_dir}/bazel which bazel @@ -55,9 +55,9 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --strip=never \ --copt=-fsanitize=undefined \ --linkopt=-fsanitize=undefined \ - --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.13.0/ubsan:toolchain \ + --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.15.0/ubsan:toolchain \ --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \ - --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.13.0/cpp:cc-toolchain-clang-x86_64-default \ + --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default \ --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ diff --git a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh index c7ab5b104a9..ffe644a48b4 100644 --- a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh @@ -23,8 +23,8 @@ 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-rc-0.14.0rc5" ${temp_dir}/bazel -chmod 755 "${KOKORO_GFILE_DIR}/bazel-rc-0.14.0rc5" +ln -f "${KOKORO_GFILE_DIR}/bazel-latest-release" ${temp_dir}/bazel +chmod 755 "${KOKORO_GFILE_DIR}/bazel-latest-release" export PATH="${temp_dir}:${PATH}" # This should show ${temp_dir}/bazel which bazel @@ -55,9 +55,9 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --strip=never \ --copt=-fsanitize=undefined \ --linkopt=-fsanitize=undefined \ - --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.13.0/ubsan:toolchain \ + --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.15.0/ubsan:toolchain \ --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \ - --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.13.0/cpp:cc-toolchain-clang-x86_64-default \ + --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default \ --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ From ffdcad5e0699f36b5b1a45aa5a8a8e2733d592f1 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 24 Aug 2018 16:07:49 -0700 Subject: [PATCH 214/546] Redefine constants from errqueue.h. Some header files lag behind the kernel version --- src/core/lib/iomgr/internal_errqueue.h | 21 +++++++++++++++++++++ src/core/lib/iomgr/tcp_posix.cc | 3 ++- test/core/iomgr/buffer_list_test.cc | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h index fc11be9a6dd..9d122808f9b 100644 --- a/src/core/lib/iomgr/internal_errqueue.h +++ b/src/core/lib/iomgr/internal_errqueue.h @@ -43,6 +43,27 @@ namespace grpc_core { #ifdef GRPC_LINUX_ERRQUEUE + +/* Redefining scm_timestamping in the same way that defines + * it, so that code compiles on systems that don't have it. */ +struct scm_timestamping { + struct timespec ts[3]; +}; +/* Also redefine timestamp types */ +/* The timestamp type for when the driver passed skb to NIC, or HW. */ +constexpr int SCM_TSTAMP_SND = 0; +/* The timestamp type for when data entered the packet scheduler. */ +constexpr int SCM_TSTAMP_SCHED = 1; +/* The timestamp type for when data acknowledged by peer. */ +constexpr int SCM_TSTAMP_ACK = 2; +/* Redefine required constants from */ +constexpr uint32_t SOF_TIMESTAMPING_TX_SOFTWARE = 1u << 1; +constexpr uint32_t SOF_TIMESTAMPING_SOFTWARE = 1u << 4; +constexpr uint32_t SOF_TIMESTAMPING_OPT_ID = 1u << 7; +constexpr uint32_t SOF_TIMESTAMPING_TX_SCHED = 1u << 8; +constexpr uint32_t SOF_TIMESTAMPING_TX_ACK = 1u << 9; +constexpr uint32_t SOF_TIMESTAMPING_OPT_TSONLY = 1u << 11; + constexpr uint32_t kTimestampingSocketOptions = SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_OPT_ID | SOF_TIMESTAMPING_OPT_TSONLY; diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 1db2790265e..ac1e919acb1 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -646,7 +646,8 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, return cmsg; } - auto tss = reinterpret_cast(CMSG_DATA(cmsg)); + auto tss = + reinterpret_cast(CMSG_DATA(cmsg)); auto serr = reinterpret_cast(CMSG_DATA(next_cmsg)); if (serr->ee_errno != ENOMSG || serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) { diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index f1773580bd2..9cdeee7a1af 100644 --- a/test/core/iomgr/buffer_list_test.cc +++ b/test/core/iomgr/buffer_list_test.cc @@ -76,7 +76,7 @@ static void TestVerifierCalledOnAck() { struct sock_extended_err serr; serr.ee_data = 213; serr.ee_info = SCM_TSTAMP_ACK; - struct scm_timestamping tss; + struct grpc_core::scm_timestamping tss; tss.ts[0].tv_sec = 123; tss.ts[0].tv_nsec = 456; grpc_core::grpc_tcp_set_write_timestamps_callback( From 8f0f66b3b33a826c4ba154eaea5b0c14a25513c7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 24 Aug 2018 17:07:16 -0700 Subject: [PATCH 215/546] %s/SCM_TSTAMP_ACK/grpc_core::SCM_TSTAMP_ACK --- test/core/iomgr/buffer_list_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc index 9cdeee7a1af..c7f30fa092c 100644 --- a/test/core/iomgr/buffer_list_test.cc +++ b/test/core/iomgr/buffer_list_test.cc @@ -75,7 +75,7 @@ static void TestVerifierCalledOnAckVerifier(void* arg, static void TestVerifierCalledOnAck() { struct sock_extended_err serr; serr.ee_data = 213; - serr.ee_info = SCM_TSTAMP_ACK; + serr.ee_info = grpc_core::SCM_TSTAMP_ACK; struct grpc_core::scm_timestamping tss; tss.ts[0].tv_sec = 123; tss.ts[0].tv_nsec = 456; From 99e09fe82184ff368c39efb3884e03c2ca442884 Mon Sep 17 00:00:00 2001 From: Arian Arfaian Date: Sat, 25 Aug 2018 09:50:58 -0700 Subject: [PATCH 216/546] Fix compilation error due to missing absl qualification. --- src/cpp/ext/filters/census/server_filter.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/ext/filters/census/server_filter.cc b/src/cpp/ext/filters/census/server_filter.cc index c7c62eefe51..b5f3d5a13a7 100644 --- a/src/cpp/ext/filters/census/server_filter.cc +++ b/src/cpp/ext/filters/census/server_filter.cc @@ -93,7 +93,7 @@ void CensusServerCallData::OnDoneRecvInitialMetadataCb(void* user_data, FilterInitialMetadata(initial_metadata, &sml); calld->path_ = grpc_slice_ref_internal(sml.path); calld->method_ = GetMethod(&calld->path_); - calld->qualified_method_ = StrCat("Recv.", calld->method_); + calld->qualified_method_ = absl::StrCat("Recv.", calld->method_); const char* tracing_str = GRPC_SLICE_IS_EMPTY(sml.tracing_slice) ? "" From 839a0520a2d53a220103aed68bbbe95dfd3aba05 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 23 Aug 2018 15:14:51 -0700 Subject: [PATCH 217/546] Add an option to collect medians every epoch. Useful for gathering per second median latencies --- src/proto/grpc/testing/control.proto | 4 ++ test/cpp/qps/client.h | 46 ++++++++++++++++++- test/cpp/qps/driver.cc | 6 ++- test/cpp/qps/driver.h | 3 +- test/cpp/qps/histogram.h | 5 ++ .../qps/inproc_sync_unary_ping_pong_test.cc | 2 +- test/cpp/qps/qps_json_driver.cc | 22 +++++---- test/cpp/qps/qps_openloop_test.cc | 2 +- .../qps/secure_sync_unary_ping_pong_test.cc | 2 +- 9 files changed, 78 insertions(+), 14 deletions(-) diff --git a/src/proto/grpc/testing/control.proto b/src/proto/grpc/testing/control.proto index 57592662c44..a4a9c8fe571 100644 --- a/src/proto/grpc/testing/control.proto +++ b/src/proto/grpc/testing/control.proto @@ -111,6 +111,10 @@ message ClientConfig { // Use coalescing API when possible. bool use_coalesce_api = 19; + + // If 0, disabled. Else, specifies the period between gathering latency + // medians in milliseconds. + int32 median_latency_collection_interval_millis = 20; } message ClientStatus { ClientStats stats = 1; } diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 9d7469c9b57..a0961dc7701 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -180,6 +180,19 @@ class Client { timer_result = timer_->Mark(); } + // Print the median latency per interval for one thread. + // If the number of warmup seconds is x, then the first x + 1 numbers in the + // vector are from the warmup period and should be discarded. + if (median_latency_collection_interval_seconds_ > 0) { + std::vector medians_per_interval = + threads_[0]->GetMedianPerIntervalList(); + gpr_log(GPR_INFO, "Num threads: %ld", threads_.size()); + gpr_log(GPR_INFO, "Number of medians: %ld", medians_per_interval.size()); + for (size_t j = 0; j < medians_per_interval.size(); j++) { + gpr_log(GPR_INFO, "%f", medians_per_interval[j]); + } + } + grpc_stats_data core_stats; grpc_stats_collect(&core_stats); @@ -210,6 +223,12 @@ class Client { } } + // Returns the interval (in seconds) between collecting latency medians. If 0, + // no periodic median latencies will be collected. + double GetLatencyCollectionIntervalInSeconds() { + return median_latency_collection_interval_seconds_; + } + virtual int GetPollCount() { // For sync client. return 0; @@ -218,6 +237,7 @@ class Client { protected: bool closed_loop_; gpr_atm thread_pool_done_; + double median_latency_collection_interval_seconds_; // In seconds void StartThreads(size_t num_threads) { gpr_atm_rel_store(&thread_pool_done_, static_cast(false)); @@ -299,10 +319,28 @@ class Client { MergeStatusHistogram(statuses_, s); } + std::vector GetMedianPerIntervalList() { + return medians_each_interval_list_; + } + + void UpdateHistogram(HistogramEntry* entry) { std::lock_guard g(mu_); if (entry->value_used()) { histogram_.Add(entry->value()); + if (client_->GetLatencyCollectionIntervalInSeconds() > 0) { + histogram_per_interval_.Add(entry->value()); + double now = UsageTimer::Now(); + if ((now - interval_start_time_) >= + client_->GetLatencyCollectionIntervalInSeconds()) { + // Record the median latency of requests from the last interval. + // Divide by 1e3 to get microseconds. + medians_each_interval_list_.push_back( + histogram_per_interval_.Percentile(50) / 1e3); + histogram_per_interval_.Reset(); + interval_start_time_ = now; + } + } } if (entry->status_used()) { statuses_[entry->status()]++; @@ -334,6 +372,11 @@ class Client { Client* client_; const size_t idx_; std::thread impl_; + // The following are used only if + // median_latency_collection_interval_seconds_ is greater than 0 + Histogram histogram_per_interval_; + std::vector medians_each_interval_list_; + double interval_start_time_; }; bool ThreadCompleted() { @@ -392,7 +435,8 @@ class ClientImpl : public Client { for (auto& t : connecting_threads) { t->join(); } - + median_latency_collection_interval_seconds_ = + config.median_latency_collection_interval_millis() / 1e3; ClientRequestCreator create_req(&request_, config.payload_config()); } diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index cabbd518437..11cfb4aa05a 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -198,7 +198,8 @@ std::unique_ptr RunScenario( const ServerConfig& initial_server_config, size_t num_servers, int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count, const grpc::string& qps_server_target_override, - const grpc::string& credential_type, bool run_inproc) { + const grpc::string& credential_type, bool run_inproc, + int32_t median_latency_collection_interval_millis) { if (run_inproc) { g_inproc_servers = new std::vector; } @@ -317,6 +318,9 @@ std::unique_ptr RunScenario( } } + client_config.set_median_latency_collection_interval_millis( + median_latency_collection_interval_millis); + // Targets are all set by now result_client_config = client_config; // Start clients diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h index fede4d80457..cda89f7ddfd 100644 --- a/test/cpp/qps/driver.h +++ b/test/cpp/qps/driver.h @@ -32,7 +32,8 @@ std::unique_ptr RunScenario( const grpc::testing::ServerConfig& server_config, size_t num_servers, int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count, const grpc::string& qps_server_target_override, - const grpc::string& credential_type, bool run_inproc); + const grpc::string& credential_type, bool run_inproc, + int32_t median_latency_collection_interval_millis); bool RunQuit(const grpc::string& credential_type); } // namespace testing diff --git a/test/cpp/qps/histogram.h b/test/cpp/qps/histogram.h index ba72b5b3320..6275128f340 100644 --- a/test/cpp/qps/histogram.h +++ b/test/cpp/qps/histogram.h @@ -34,6 +34,11 @@ class Histogram { ~Histogram() { if (impl_) grpc_histogram_destroy(impl_); } + void Reset() { + if (impl_) grpc_histogram_destroy(impl_); + impl_ = grpc_histogram_create(default_resolution(), default_max_possible()); + } + Histogram(Histogram&& other) : impl_(other.impl_) { other.impl_ = nullptr; } void Merge(const Histogram& h) { grpc_histogram_merge(impl_, h.impl_); } diff --git a/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc b/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc index f2e977d48b6..56d1730252f 100644 --- a/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc +++ b/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc @@ -48,7 +48,7 @@ static void RunSynchronousUnaryPingPong() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "", - kInsecureCredentialsType, true); + kInsecureCredentialsType, true, 0); GetReporter()->ReportQPS(*result); GetReporter()->ReportLatency(*result); diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc index 0ff692255c1..c95e0df251a 100644 --- a/test/cpp/qps/qps_json_driver.cc +++ b/test/cpp/qps/qps_json_driver.cc @@ -66,6 +66,11 @@ DEFINE_string(json_file_out, "", "File to write the JSON output to."); DEFINE_string(credential_type, grpc::testing::kInsecureCredentialsType, "Credential type for communication with workers"); DEFINE_bool(run_inproc, false, "Perform an in-process transport test"); +DEFINE_int32( + median_latency_collection_interval_millis, 0, + "Specifies the period between gathering latency medians in " + "milliseconds. The medians will be logged out on the client at the " + "end of the benchmark run. If 0, this periodic collection is disabled."); namespace grpc { namespace testing { @@ -73,13 +78,13 @@ namespace testing { static std::unique_ptr RunAndReport(const Scenario& scenario, bool* success) { std::cerr << "RUNNING SCENARIO: " << scenario.name() << "\n"; - auto result = - RunScenario(scenario.client_config(), scenario.num_clients(), - scenario.server_config(), scenario.num_servers(), - scenario.warmup_seconds(), scenario.benchmark_seconds(), - !FLAGS_run_inproc ? scenario.spawn_local_worker_count() : -2, - FLAGS_qps_server_target_override, FLAGS_credential_type, - FLAGS_run_inproc); + auto result = RunScenario( + scenario.client_config(), scenario.num_clients(), + scenario.server_config(), scenario.num_servers(), + scenario.warmup_seconds(), scenario.benchmark_seconds(), + !FLAGS_run_inproc ? scenario.spawn_local_worker_count() : -2, + FLAGS_qps_server_target_override, FLAGS_credential_type, FLAGS_run_inproc, + FLAGS_median_latency_collection_interval_millis); // Amend the result with scenario config. Eventually we should adjust // RunScenario contract so we don't need to touch the result here. @@ -145,7 +150,8 @@ static double SearchOfferedLoad(double initial_offered_load, bool* success) { std::cerr << "RUNNING SCENARIO: " << scenario->name() << "\n"; double current_offered_load = initial_offered_load; - double current_cpu_load = GetCpuLoad(scenario, current_offered_load, success); + double current_cpu_load = + GetCpuLoad(scenario, current_offered_load, success); if (current_cpu_load > targeted_cpu_load) { gpr_log(GPR_ERROR, "Initial offered load too high"); return -1; diff --git a/test/cpp/qps/qps_openloop_test.cc b/test/cpp/qps/qps_openloop_test.cc index df929b98111..6044f4265a3 100644 --- a/test/cpp/qps/qps_openloop_test.cc +++ b/test/cpp/qps/qps_openloop_test.cc @@ -52,7 +52,7 @@ static void RunQPS() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "", - kInsecureCredentialsType, false); + kInsecureCredentialsType, false, 0); GetReporter()->ReportQPSPerCore(*result); GetReporter()->ReportLatency(*result); diff --git a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc index bb415e9d63c..a559c82cc81 100644 --- a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc +++ b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc @@ -55,7 +55,7 @@ static void RunSynchronousUnaryPingPong() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "", - kInsecureCredentialsType, false); + kInsecureCredentialsType, false, 0); GetReporter()->ReportQPS(*result); GetReporter()->ReportLatency(*result); From e360d822166d3e3a2d42571da0c4f4636dbc2c96 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Sat, 25 Aug 2018 19:31:00 -0700 Subject: [PATCH 218/546] Clang tidy --- test/cpp/qps/client.h | 1 - test/cpp/qps/qps_json_driver.cc | 15 +++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index a0961dc7701..0b4b2ff0a95 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -323,7 +323,6 @@ class Client { return medians_each_interval_list_; } - void UpdateHistogram(HistogramEntry* entry) { std::lock_guard g(mu_); if (entry->value_used()) { diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc index c95e0df251a..eaa0dd992c5 100644 --- a/test/cpp/qps/qps_json_driver.cc +++ b/test/cpp/qps/qps_json_driver.cc @@ -79,12 +79,12 @@ static std::unique_ptr RunAndReport(const Scenario& scenario, bool* success) { std::cerr << "RUNNING SCENARIO: " << scenario.name() << "\n"; auto result = RunScenario( - scenario.client_config(), scenario.num_clients(), - scenario.server_config(), scenario.num_servers(), - scenario.warmup_seconds(), scenario.benchmark_seconds(), - !FLAGS_run_inproc ? scenario.spawn_local_worker_count() : -2, - FLAGS_qps_server_target_override, FLAGS_credential_type, FLAGS_run_inproc, - FLAGS_median_latency_collection_interval_millis); + scenario.client_config(), scenario.num_clients(), + scenario.server_config(), scenario.num_servers(), + scenario.warmup_seconds(), scenario.benchmark_seconds(), + !FLAGS_run_inproc ? scenario.spawn_local_worker_count() : -2, + FLAGS_qps_server_target_override, FLAGS_credential_type, FLAGS_run_inproc, + FLAGS_median_latency_collection_interval_millis); // Amend the result with scenario config. Eventually we should adjust // RunScenario contract so we don't need to touch the result here. @@ -150,8 +150,7 @@ static double SearchOfferedLoad(double initial_offered_load, bool* success) { std::cerr << "RUNNING SCENARIO: " << scenario->name() << "\n"; double current_offered_load = initial_offered_load; - double current_cpu_load = - GetCpuLoad(scenario, current_offered_load, success); + double current_cpu_load = GetCpuLoad(scenario, current_offered_load, success); if (current_cpu_load > targeted_cpu_load) { gpr_log(GPR_ERROR, "Initial offered load too high"); return -1; From cc3780eb506d34b884bb4f71a1e1ad39c4050331 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sun, 26 Aug 2018 20:30:28 +0200 Subject: [PATCH 219/546] refactor upload_to_bq functions --- .../interop_matrix/run_interop_matrix_tests.py | 2 +- .../python_utils/upload_test_results.py | 17 +++++------------ tools/run_tests/run_interop_tests.py | 2 +- tools/run_tests/run_tests.py | 9 +++++++-- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index 9d442346a70..6cd6f431671 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -235,7 +235,7 @@ def run_tests_for_lang(lang, runtime, images): maxjobs=args.jobs) if args.bq_result_table and resultset: upload_test_results.upload_interop_results_to_bq( - resultset, args.bq_result_table, args) + resultset, args.bq_result_table) if num_failures: jobset.message('FAILED', 'Some tests failed', do_newline=True) total_num_failures += num_failures diff --git a/tools/run_tests/python_utils/upload_test_results.py b/tools/run_tests/python_utils/upload_test_results.py index 9d997037259..f04ef37e087 100644 --- a/tools/run_tests/python_utils/upload_test_results.py +++ b/tools/run_tests/python_utils/upload_test_results.py @@ -104,14 +104,13 @@ def _insert_rows_with_retries(bq, bq_table, bq_rows): sys.exit(1) -def upload_results_to_bq(resultset, bq_table, args, platform): +def upload_results_to_bq(resultset, bq_table, extra_fields): """Upload test results to a BQ table. Args: resultset: dictionary generated by jobset.run bq_table: string name of table to create/upload results to in BQ - args: args in run_tests.py, generated by argparse - platform: string name of platform tests were run on + extra_fields: dict with extra values that will be uploaded along with the results """ bq = big_query_utils.create_big_query() big_query_utils.create_partitioned_table( @@ -129,32 +128,26 @@ def upload_results_to_bq(resultset, bq_table, args, platform): for result in results: test_results = {} _get_build_metadata(test_results) - test_results['compiler'] = args.compiler - test_results['config'] = args.config test_results['cpu_estimated'] = result.cpu_estimated test_results['cpu_measured'] = result.cpu_measured test_results['elapsed_time'] = '%.2f' % result.elapsed_time - test_results['iomgr_platform'] = args.iomgr_platform - # args.language is a list, but will always have one element in the contexts - # this function is used. - test_results['language'] = args.language[0] - test_results['platform'] = platform test_results['result'] = result.state test_results['return_code'] = result.returncode test_results['test_name'] = shortname test_results['timestamp'] = time.strftime('%Y-%m-%d %H:%M:%S') + for field_name, field_value in extra_fields: + test_results[field_name] = field_value row = big_query_utils.make_row(str(uuid.uuid4()), test_results) bq_rows.append(row) _insert_rows_with_retries(bq, bq_table, bq_rows) -def upload_interop_results_to_bq(resultset, bq_table, args): +def upload_interop_results_to_bq(resultset, bq_table): """Upload interop test results to a BQ table. Args: resultset: dictionary generated by jobset.run bq_table: string name of table to create/upload results to in BQ - args: args in run_interop_tests.py, generated by argparse """ bq = big_query_utils.create_big_query() big_query_utils.create_partitioned_table( diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 22055d58e8b..2936bdfa802 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -1494,7 +1494,7 @@ try: maxjobs=args.jobs, skip_jobs=args.manual_run) if args.bq_result_table and resultset: - upload_interop_results_to_bq(resultset, args.bq_result_table, args) + upload_interop_results_to_bq(resultset, args.bq_result_table) if num_failures: jobset.message('FAILED', 'Some tests failed', do_newline=True) else: diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index e04b13b24ca..c4954df12b5 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1821,8 +1821,13 @@ def _build_and_run(check_cancelled, for antagonist in antagonists: antagonist.kill() if args.bq_result_table and resultset: - upload_results_to_bq(resultset, args.bq_result_table, args, - platform_string()) + upload_extra_fields={ + 'compiler': args.compiler, + 'config': args.config, + 'iomgr_plaform': args.iomgr_platform, + 'language': args.language[0], # args.language is a list but will always have one element when uploading to BQ is enabled. + 'plaform': platform_string()} + upload_results_to_bq(resultset, args.bq_result_table, upload_extra_fields) if xml_report and resultset: report_utils.render_junit_xml_report( resultset, xml_report, suite_name=args.report_suite_name) From 2529cfe30a54503246b94a3f0e4d7c3971edf8c3 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Sun, 26 Aug 2018 19:04:01 -0700 Subject: [PATCH 220/546] Light refactoring of some transport code --- .../chttp2/transport/chttp2_transport.cc | 465 +++++++++--------- .../ext/transport/chttp2/transport/internal.h | 2 + 2 files changed, 244 insertions(+), 223 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 027a57d606d..f269c252c63 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -230,35 +230,165 @@ void grpc_chttp2_ref_transport(grpc_chttp2_transport* t) { gpr_ref(&t->refs); } static const grpc_transport_vtable* get_vtable(void); -static void init_transport(grpc_chttp2_transport* t, - const grpc_channel_args* channel_args, - grpc_endpoint* ep, bool is_client) { +/* Returns whether bdp is enabled */ +static bool read_channel_args(grpc_chttp2_transport* t, + const grpc_channel_args* channel_args, + bool is_client) { + bool enable_bdp = true; size_t i; int j; - GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) == - GRPC_CHTTP2_CLIENT_CONNECT_STRLEN); - - t->base.vtable = get_vtable(); - t->ep = ep; - /* one ref is for destroy */ - gpr_ref_init(&t->refs, 1); - t->combiner = grpc_combiner_create(); - t->peer_string = grpc_endpoint_get_peer(ep); - t->endpoint_reading = 1; - t->next_stream_id = is_client ? 1 : 2; - t->is_client = is_client; - t->deframe_state = is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0; - t->is_first_frame = true; - grpc_connectivity_state_init( - &t->channel_callback.state_tracker, GRPC_CHANNEL_READY, - is_client ? "client_transport" : "server_transport"); - - grpc_slice_buffer_init(&t->qbuf); - - grpc_slice_buffer_init(&t->outbuf); - grpc_chttp2_hpack_compressor_init(&t->hpack_compressor); + for (i = 0; i < channel_args->num_args; i++) { + if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER)) { + const grpc_integer_options options = {-1, 0, INT_MAX}; + const int value = + grpc_channel_arg_get_integer(&channel_args->args[i], options); + if (value >= 0) { + if ((t->next_stream_id & 1) != (value & 1)) { + gpr_log(GPR_ERROR, "%s: low bit must be %d on %s", + GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER, t->next_stream_id & 1, + is_client ? "client" : "server"); + } else { + t->next_stream_id = static_cast(value); + } + } + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER)) { + const grpc_integer_options options = {-1, 0, INT_MAX}; + const int value = + grpc_channel_arg_get_integer(&channel_args->args[i], options); + if (value >= 0) { + grpc_chttp2_hpack_compressor_set_max_usable_size( + &t->hpack_compressor, static_cast(value)); + } + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA)) { + t->ping_policy.max_pings_without_data = grpc_channel_arg_get_integer( + &channel_args->args[i], + {g_default_max_pings_without_data, 0, INT_MAX}); + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_MAX_PING_STRIKES)) { + t->ping_policy.max_ping_strikes = grpc_channel_arg_get_integer( + &channel_args->args[i], {g_default_max_ping_strikes, 0, INT_MAX}); + } else if (0 == + strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS)) { + t->ping_policy.min_sent_ping_interval_without_data = + grpc_channel_arg_get_integer( + &channel_args->args[i], + grpc_integer_options{ + g_default_min_sent_ping_interval_without_data_ms, 0, + INT_MAX}); + } else if (0 == + strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS)) { + t->ping_policy.min_recv_ping_interval_without_data = + grpc_channel_arg_get_integer( + &channel_args->args[i], + grpc_integer_options{ + g_default_min_recv_ping_interval_without_data_ms, 0, + INT_MAX}); + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE)) { + t->write_buffer_size = static_cast(grpc_channel_arg_get_integer( + &channel_args->args[i], {0, 0, MAX_WRITE_BUFFER_SIZE})); + } else if (0 == + strcmp(channel_args->args[i].key, GRPC_ARG_HTTP2_BDP_PROBE)) { + enable_bdp = grpc_channel_arg_get_bool(&channel_args->args[i], true); + } else if (0 == + strcmp(channel_args->args[i].key, GRPC_ARG_KEEPALIVE_TIME_MS)) { + const int value = grpc_channel_arg_get_integer( + &channel_args->args[i], + grpc_integer_options{t->is_client + ? g_default_client_keepalive_time_ms + : g_default_server_keepalive_time_ms, + 1, INT_MAX}); + t->keepalive_time = value == INT_MAX ? GRPC_MILLIS_INF_FUTURE : value; + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_KEEPALIVE_TIMEOUT_MS)) { + const int value = grpc_channel_arg_get_integer( + &channel_args->args[i], + grpc_integer_options{t->is_client + ? g_default_client_keepalive_timeout_ms + : g_default_server_keepalive_timeout_ms, + 0, INT_MAX}); + t->keepalive_timeout = value == INT_MAX ? GRPC_MILLIS_INF_FUTURE : value; + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS)) { + t->keepalive_permit_without_calls = static_cast( + grpc_channel_arg_get_integer(&channel_args->args[i], {0, 0, 1})); + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_OPTIMIZATION_TARGET)) { + if (channel_args->args[i].type != GRPC_ARG_STRING) { + gpr_log(GPR_ERROR, "%s should be a string", + GRPC_ARG_OPTIMIZATION_TARGET); + } else if (0 == strcmp(channel_args->args[i].value.string, "blend")) { + t->opt_target = GRPC_CHTTP2_OPTIMIZE_FOR_LATENCY; + } else if (0 == strcmp(channel_args->args[i].value.string, "latency")) { + t->opt_target = GRPC_CHTTP2_OPTIMIZE_FOR_LATENCY; + } else if (0 == + strcmp(channel_args->args[i].value.string, "throughput")) { + t->opt_target = GRPC_CHTTP2_OPTIMIZE_FOR_THROUGHPUT; + } else { + gpr_log(GPR_ERROR, "%s value '%s' unknown, assuming 'blend'", + GRPC_ARG_OPTIMIZATION_TARGET, + channel_args->args[i].value.string); + } + } else { + static const struct { + const char* channel_arg_name; + grpc_chttp2_setting_id setting_id; + grpc_integer_options integer_options; + bool availability[2] /* server, client */; + } settings_map[] = {{GRPC_ARG_MAX_CONCURRENT_STREAMS, + GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, + {-1, 0, INT32_MAX}, + {true, false}}, + {GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER, + GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE, + {-1, 0, INT32_MAX}, + {true, true}}, + {GRPC_ARG_MAX_METADATA_SIZE, + GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, + {-1, 0, INT32_MAX}, + {true, true}}, + {GRPC_ARG_HTTP2_MAX_FRAME_SIZE, + GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE, + {-1, 16384, 16777215}, + {true, true}}, + {GRPC_ARG_HTTP2_ENABLE_TRUE_BINARY, + GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA, + {1, 0, 1}, + {true, true}}, + {GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES, + GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, + {-1, 5, INT32_MAX}, + {true, true}}}; + for (j = 0; j < static_cast GPR_ARRAY_SIZE(settings_map); j++) { + if (0 == strcmp(channel_args->args[i].key, + settings_map[j].channel_arg_name)) { + if (!settings_map[j].availability[is_client]) { + gpr_log(GPR_DEBUG, "%s is not available on %s", + settings_map[j].channel_arg_name, + is_client ? "clients" : "servers"); + } else { + int value = grpc_channel_arg_get_integer( + &channel_args->args[i], settings_map[j].integer_options); + if (value >= 0) { + queue_setting_update(t, settings_map[j].setting_id, + static_cast(value)); + } + } + break; + } + } + } + } + return enable_bdp; +} +static void init_transport_closures(grpc_chttp2_transport* t) { GRPC_CLOSURE_INIT(&t->read_action_locked, read_action_locked, t, grpc_combiner_scheduler(t->combiner)); GRPC_CLOSURE_INIT(&t->benign_reclaimer_locked, benign_reclaimer_locked, t, @@ -286,6 +416,79 @@ static void init_transport(grpc_chttp2_transport* t, GRPC_CLOSURE_INIT(&t->keepalive_watchdog_fired_locked, keepalive_watchdog_fired_locked, t, grpc_combiner_scheduler(t->combiner)); +} + +static void init_transport_keepalive_settings(grpc_chttp2_transport* t) { + if (t->is_client) { + t->keepalive_time = g_default_client_keepalive_time_ms == INT_MAX + ? GRPC_MILLIS_INF_FUTURE + : g_default_client_keepalive_time_ms; + t->keepalive_timeout = g_default_client_keepalive_timeout_ms == INT_MAX + ? GRPC_MILLIS_INF_FUTURE + : g_default_client_keepalive_timeout_ms; + t->keepalive_permit_without_calls = + g_default_client_keepalive_permit_without_calls; + } else { + t->keepalive_time = g_default_server_keepalive_time_ms == INT_MAX + ? GRPC_MILLIS_INF_FUTURE + : g_default_server_keepalive_time_ms; + t->keepalive_timeout = g_default_server_keepalive_timeout_ms == INT_MAX + ? GRPC_MILLIS_INF_FUTURE + : g_default_server_keepalive_timeout_ms; + t->keepalive_permit_without_calls = + g_default_server_keepalive_permit_without_calls; + } +} + +static void configure_transport_ping_policy(grpc_chttp2_transport* t) { + t->ping_policy.max_pings_without_data = g_default_max_pings_without_data; + t->ping_policy.min_sent_ping_interval_without_data = + g_default_min_sent_ping_interval_without_data_ms; + t->ping_policy.max_ping_strikes = g_default_max_ping_strikes; + t->ping_policy.min_recv_ping_interval_without_data = + g_default_min_recv_ping_interval_without_data_ms; +} + +static void init_keepalive_pings_if_enabled(grpc_chttp2_transport* t) { + if (t->keepalive_time != GRPC_MILLIS_INF_FUTURE) { + t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_WAITING; + GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping"); + grpc_timer_init(&t->keepalive_ping_timer, + grpc_core::ExecCtx::Get()->Now() + t->keepalive_time, + &t->init_keepalive_ping_locked); + } else { + /* Use GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED to indicate there are no + inflight keeaplive timers */ + t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED; + } +} + +static void init_transport(grpc_chttp2_transport* t, + const grpc_channel_args* channel_args, + grpc_endpoint* ep, bool is_client) { + GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) == + GRPC_CHTTP2_CLIENT_CONNECT_STRLEN); + + t->base.vtable = get_vtable(); + t->ep = ep; + /* one ref is for destroy */ + gpr_ref_init(&t->refs, 1); + t->combiner = grpc_combiner_create(); + t->peer_string = grpc_endpoint_get_peer(ep); + t->endpoint_reading = 1; + t->next_stream_id = is_client ? 1 : 2; + t->is_client = is_client; + t->deframe_state = is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0; + t->is_first_frame = true; + grpc_connectivity_state_init( + &t->channel_callback.state_tracker, GRPC_CHANNEL_READY, + is_client ? "client_transport" : "server_transport"); + + grpc_slice_buffer_init(&t->qbuf); + grpc_slice_buffer_init(&t->outbuf); + grpc_chttp2_hpack_compressor_init(&t->hpack_compressor); + + init_transport_closures(t); t->goaway_error = GRPC_ERROR_NONE; grpc_chttp2_goaway_parser_init(&t->goaway_parser); @@ -301,6 +504,8 @@ static void init_transport(grpc_chttp2_transport* t, grpc_chttp2_stream_map_init(&t->stream_map, 8); /* copy in initial settings to all setting sets */ + size_t i; + int j; for (i = 0; i < GRPC_CHTTP2_NUM_SETTINGS; i++) { for (j = 0; j < GRPC_NUM_SETTING_SETS; j++) { t->settings[j][i] = grpc_chttp2_settings_parameters[i].default_value; @@ -328,191 +533,14 @@ static void init_transport(grpc_chttp2_transport* t, queue_setting_update(t, GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA, 1); - t->ping_policy.max_pings_without_data = g_default_max_pings_without_data; - t->ping_policy.min_sent_ping_interval_without_data = - g_default_min_sent_ping_interval_without_data_ms; - t->ping_policy.max_ping_strikes = g_default_max_ping_strikes; - t->ping_policy.min_recv_ping_interval_without_data = - g_default_min_recv_ping_interval_without_data_ms; - - /* Keepalive setting */ - if (t->is_client) { - t->keepalive_time = g_default_client_keepalive_time_ms == INT_MAX - ? GRPC_MILLIS_INF_FUTURE - : g_default_client_keepalive_time_ms; - t->keepalive_timeout = g_default_client_keepalive_timeout_ms == INT_MAX - ? GRPC_MILLIS_INF_FUTURE - : g_default_client_keepalive_timeout_ms; - t->keepalive_permit_without_calls = - g_default_client_keepalive_permit_without_calls; - } else { - t->keepalive_time = g_default_server_keepalive_time_ms == INT_MAX - ? GRPC_MILLIS_INF_FUTURE - : g_default_server_keepalive_time_ms; - t->keepalive_timeout = g_default_server_keepalive_timeout_ms == INT_MAX - ? GRPC_MILLIS_INF_FUTURE - : g_default_server_keepalive_timeout_ms; - t->keepalive_permit_without_calls = - g_default_server_keepalive_permit_without_calls; - } + configure_transport_ping_policy(t); + init_transport_keepalive_settings(t); t->opt_target = GRPC_CHTTP2_OPTIMIZE_FOR_LATENCY; bool enable_bdp = true; - if (channel_args) { - for (i = 0; i < channel_args->num_args; i++) { - if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER)) { - const grpc_integer_options options = {-1, 0, INT_MAX}; - const int value = - grpc_channel_arg_get_integer(&channel_args->args[i], options); - if (value >= 0) { - if ((t->next_stream_id & 1) != (value & 1)) { - gpr_log(GPR_ERROR, "%s: low bit must be %d on %s", - GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER, - t->next_stream_id & 1, is_client ? "client" : "server"); - } else { - t->next_stream_id = static_cast(value); - } - } - } else if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER)) { - const grpc_integer_options options = {-1, 0, INT_MAX}; - const int value = - grpc_channel_arg_get_integer(&channel_args->args[i], options); - if (value >= 0) { - grpc_chttp2_hpack_compressor_set_max_usable_size( - &t->hpack_compressor, static_cast(value)); - } - } else if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA)) { - t->ping_policy.max_pings_without_data = grpc_channel_arg_get_integer( - &channel_args->args[i], - {g_default_max_pings_without_data, 0, INT_MAX}); - } else if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_HTTP2_MAX_PING_STRIKES)) { - t->ping_policy.max_ping_strikes = grpc_channel_arg_get_integer( - &channel_args->args[i], {g_default_max_ping_strikes, 0, INT_MAX}); - } else if (0 == - strcmp( - channel_args->args[i].key, - GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS)) { - t->ping_policy.min_sent_ping_interval_without_data = - grpc_channel_arg_get_integer( - &channel_args->args[i], - grpc_integer_options{ - g_default_min_sent_ping_interval_without_data_ms, 0, - INT_MAX}); - } else if (0 == - strcmp( - channel_args->args[i].key, - GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS)) { - t->ping_policy.min_recv_ping_interval_without_data = - grpc_channel_arg_get_integer( - &channel_args->args[i], - grpc_integer_options{ - g_default_min_recv_ping_interval_without_data_ms, 0, - INT_MAX}); - } else if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_HTTP2_WRITE_BUFFER_SIZE)) { - t->write_buffer_size = - static_cast(grpc_channel_arg_get_integer( - &channel_args->args[i], {0, 0, MAX_WRITE_BUFFER_SIZE})); - } else if (0 == - strcmp(channel_args->args[i].key, GRPC_ARG_HTTP2_BDP_PROBE)) { - enable_bdp = grpc_channel_arg_get_bool(&channel_args->args[i], true); - } else if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_KEEPALIVE_TIME_MS)) { - const int value = grpc_channel_arg_get_integer( - &channel_args->args[i], - grpc_integer_options{t->is_client - ? g_default_client_keepalive_time_ms - : g_default_server_keepalive_time_ms, - 1, INT_MAX}); - t->keepalive_time = value == INT_MAX ? GRPC_MILLIS_INF_FUTURE : value; - } else if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_KEEPALIVE_TIMEOUT_MS)) { - const int value = grpc_channel_arg_get_integer( - &channel_args->args[i], - grpc_integer_options{t->is_client - ? g_default_client_keepalive_timeout_ms - : g_default_server_keepalive_timeout_ms, - 0, INT_MAX}); - t->keepalive_timeout = - value == INT_MAX ? GRPC_MILLIS_INF_FUTURE : value; - } else if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS)) { - t->keepalive_permit_without_calls = static_cast( - grpc_channel_arg_get_integer(&channel_args->args[i], {0, 0, 1})); - } else if (0 == strcmp(channel_args->args[i].key, - GRPC_ARG_OPTIMIZATION_TARGET)) { - if (channel_args->args[i].type != GRPC_ARG_STRING) { - gpr_log(GPR_ERROR, "%s should be a string", - GRPC_ARG_OPTIMIZATION_TARGET); - } else if (0 == strcmp(channel_args->args[i].value.string, "blend")) { - t->opt_target = GRPC_CHTTP2_OPTIMIZE_FOR_LATENCY; - } else if (0 == strcmp(channel_args->args[i].value.string, "latency")) { - t->opt_target = GRPC_CHTTP2_OPTIMIZE_FOR_LATENCY; - } else if (0 == - strcmp(channel_args->args[i].value.string, "throughput")) { - t->opt_target = GRPC_CHTTP2_OPTIMIZE_FOR_THROUGHPUT; - } else { - gpr_log(GPR_ERROR, "%s value '%s' unknown, assuming 'blend'", - GRPC_ARG_OPTIMIZATION_TARGET, - channel_args->args[i].value.string); - } - } else { - static const struct { - const char* channel_arg_name; - grpc_chttp2_setting_id setting_id; - grpc_integer_options integer_options; - bool availability[2] /* server, client */; - } settings_map[] = { - {GRPC_ARG_MAX_CONCURRENT_STREAMS, - GRPC_CHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, - {-1, 0, INT32_MAX}, - {true, false}}, - {GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER, - GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE, - {-1, 0, INT32_MAX}, - {true, true}}, - {GRPC_ARG_MAX_METADATA_SIZE, - GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, - {-1, 0, INT32_MAX}, - {true, true}}, - {GRPC_ARG_HTTP2_MAX_FRAME_SIZE, - GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE, - {-1, 16384, 16777215}, - {true, true}}, - {GRPC_ARG_HTTP2_ENABLE_TRUE_BINARY, - GRPC_CHTTP2_SETTINGS_GRPC_ALLOW_TRUE_BINARY_METADATA, - {1, 0, 1}, - {true, true}}, - {GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES, - GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, - {-1, 5, INT32_MAX}, - {true, true}}}; - for (j = 0; j < static_cast GPR_ARRAY_SIZE(settings_map); j++) { - if (0 == strcmp(channel_args->args[i].key, - settings_map[j].channel_arg_name)) { - if (!settings_map[j].availability[is_client]) { - gpr_log(GPR_DEBUG, "%s is not available on %s", - settings_map[j].channel_arg_name, - is_client ? "clients" : "servers"); - } else { - int value = grpc_channel_arg_get_integer( - &channel_args->args[i], settings_map[j].integer_options); - if (value >= 0) { - queue_setting_update(t, settings_map[j].setting_id, - static_cast(value)); - } - } - break; - } - } - } - } + enable_bdp = read_channel_args(t, channel_args, is_client); } if (g_flow_control_enabled) { @@ -531,23 +559,11 @@ static void init_transport(grpc_chttp2_transport* t, t->ping_recv_state.last_ping_recv_time = GRPC_MILLIS_INF_PAST; t->ping_recv_state.ping_strikes = 0; - /* Start keepalive pings */ - if (t->keepalive_time != GRPC_MILLIS_INF_FUTURE) { - t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_WAITING; - GRPC_CHTTP2_REF_TRANSPORT(t, "init keepalive ping"); - grpc_timer_init(&t->keepalive_ping_timer, - grpc_core::ExecCtx::Get()->Now() + t->keepalive_time, - &t->init_keepalive_ping_locked); - } else { - /* Use GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED to indicate there are no - inflight keeaplive timers */ - t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED; - } + init_keepalive_pings_if_enabled(t); if (enable_bdp) { GRPC_CHTTP2_REF_TRANSPORT(t, "bdp_ping"); schedule_bdp_ping_locked(t); - grpc_chttp2_act_on_flowctl_action(t->flow_control->PeriodicUpdate(), t, nullptr); } @@ -2887,17 +2903,20 @@ bool Chttp2IncomingByteStream::Next(size_t max_size_hint, } } +void Chttp2IncomingByteStream::EnsureStreamDecompressionCtxExists() { + if (!stream_->stream_decompression_ctx) { + stream_->stream_decompression_ctx = grpc_stream_compression_context_create( + stream_->stream_decompression_method); + } +} + grpc_error* Chttp2IncomingByteStream::Pull(grpc_slice* slice) { GPR_TIMER_SCOPE("incoming_byte_stream_pull", 0); grpc_error* error; if (stream_->unprocessed_incoming_frames_buffer.length > 0) { if (!stream_->unprocessed_incoming_frames_decompressed) { bool end_of_context; - if (!stream_->stream_decompression_ctx) { - stream_->stream_decompression_ctx = - grpc_stream_compression_context_create( - stream_->stream_decompression_method); - } + EnsureStreamDecompressionCtxExists(); if (!grpc_stream_decompress(stream_->stream_decompression_ctx, &stream_->unprocessed_incoming_frames_buffer, &stream_->decompressed_data_buffer, nullptr, diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index ca6e7159787..0f66faec31f 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -246,6 +246,8 @@ class Chttp2IncomingByteStream : public ByteStream { static void NextLocked(void* arg, grpc_error* error_ignored); static void OrphanLocked(void* arg, grpc_error* error_ignored); + void EnsureStreamDecompressionCtxExists(); + grpc_chttp2_transport* transport_; // Immutable. grpc_chttp2_stream* stream_; // Immutable. From 97ba943f179cf6eda6f1a85abee01d459f507673 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 27 Aug 2018 12:43:20 +0200 Subject: [PATCH 221/546] Revert "Fathom tcp changes" --- BUILD | 4 - CMakeLists.txt | 46 --- Makefile | 48 --- build.yaml | 18 - config.m4 | 2 - config.w32 | 2 - gRPC-C++.podspec | 4 - gRPC-Core.podspec | 6 - grpc.gemspec | 4 - grpc.gyp | 8 - package.xml | 4 - .../client_channel/http_connect_handshaker.cc | 2 +- .../client/insecure/channel_create_posix.cc | 2 +- .../server/insecure/server_chttp2_posix.cc | 2 +- .../chttp2/transport/chttp2_transport.cc | 3 +- src/core/lib/http/httpcli.cc | 2 +- src/core/lib/iomgr/buffer_list.cc | 134 -------- src/core/lib/iomgr/buffer_list.h | 96 ------ src/core/lib/iomgr/endpoint.cc | 4 +- src/core/lib/iomgr/endpoint.h | 8 +- src/core/lib/iomgr/endpoint_cfstream.cc | 2 +- src/core/lib/iomgr/endpoint_pair_posix.cc | 4 +- src/core/lib/iomgr/ev_posix.cc | 9 +- src/core/lib/iomgr/internal_errqueue.cc | 40 --- src/core/lib/iomgr/internal_errqueue.h | 62 ---- src/core/lib/iomgr/port.h | 6 - src/core/lib/iomgr/tcp_client_posix.cc | 2 +- src/core/lib/iomgr/tcp_custom.cc | 2 +- src/core/lib/iomgr/tcp_posix.cc | 311 +----------------- src/core/lib/iomgr/tcp_posix.h | 3 - src/core/lib/iomgr/tcp_server_posix.cc | 4 +- .../iomgr/tcp_server_utils_posix_common.cc | 2 +- src/core/lib/iomgr/tcp_windows.cc | 2 +- src/core/lib/iomgr/udp_server.cc | 2 +- .../lib/security/transport/secure_endpoint.cc | 4 +- .../security/transport/security_handshaker.cc | 2 +- src/python/grpcio/grpc_core_dependencies.py | 2 - test/core/bad_client/bad_client.cc | 2 +- test/core/end2end/bad_server_response_test.cc | 2 +- .../end2end/fixtures/http_proxy_fixture.cc | 10 +- test/core/iomgr/BUILD | 13 - test/core/iomgr/buffer_list_test.cc | 111 ------- test/core/iomgr/endpoint_tests.cc | 7 +- test/core/iomgr/tcp_posix_test.cc | 109 +----- test/core/util/mock_endpoint.cc | 2 +- test/core/util/passthru_endpoint.cc | 2 +- test/core/util/trickle_endpoint.cc | 5 +- .../microbenchmarks/bm_chttp2_transport.cc | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 - tools/doxygen/Doxyfile.core.internal | 4 - .../generated/sources_and_headers.json | 23 -- tools/run_tests/generated/tests.json | 20 -- 52 files changed, 68 insertions(+), 1104 deletions(-) delete mode 100644 src/core/lib/iomgr/buffer_list.cc delete mode 100644 src/core/lib/iomgr/buffer_list.h delete mode 100644 src/core/lib/iomgr/internal_errqueue.cc delete mode 100644 src/core/lib/iomgr/internal_errqueue.h delete mode 100644 test/core/iomgr/buffer_list_test.cc diff --git a/BUILD b/BUILD index c01b971281d..e1b00a5cf0a 100644 --- a/BUILD +++ b/BUILD @@ -696,7 +696,6 @@ grpc_cc_library( "src/core/lib/http/format_request.cc", "src/core/lib/http/httpcli.cc", "src/core/lib/http/parser.cc", - "src/core/lib/iomgr/buffer_list.cc", "src/core/lib/iomgr/call_combiner.cc", "src/core/lib/iomgr/combiner.cc", "src/core/lib/iomgr/endpoint.cc", @@ -717,7 +716,6 @@ grpc_cc_library( "src/core/lib/iomgr/gethostname_fallback.cc", "src/core/lib/iomgr/gethostname_host_name_max.cc", "src/core/lib/iomgr/gethostname_sysconf.cc", - "src/core/lib/iomgr/internal_errqueue.cc", "src/core/lib/iomgr/iocp_windows.cc", "src/core/lib/iomgr/iomgr.cc", "src/core/lib/iomgr/iomgr_custom.cc", @@ -847,7 +845,6 @@ grpc_cc_library( "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", - "src/core/lib/iomgr/buffer_list.h", "src/core/lib/iomgr/block_annotate.h", "src/core/lib/iomgr/call_combiner.h", "src/core/lib/iomgr/closure.h", @@ -865,7 +862,6 @@ grpc_cc_library( "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/gevent_util.h", - "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", "src/core/lib/iomgr/iomgr_custom.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 3895d4c0f17..a330fefc272 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,9 +230,6 @@ add_dependencies(buildtests_c avl_test) add_dependencies(buildtests_c bad_server_response_test) add_dependencies(buildtests_c bin_decoder_test) add_dependencies(buildtests_c bin_encoder_test) -if(_gRPC_PLATFORM_LINUX) -add_dependencies(buildtests_c buffer_list_test) -endif() add_dependencies(buildtests_c channel_create_test) add_dependencies(buildtests_c chttp2_hpack_encoder_test) add_dependencies(buildtests_c chttp2_stream_map_test) @@ -962,7 +959,6 @@ add_library(grpc src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc - src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -983,7 +979,6 @@ add_library(grpc src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc - src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -1370,7 +1365,6 @@ add_library(grpc_cronet src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc - src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -1391,7 +1385,6 @@ add_library(grpc_cronet src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc - src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -1764,7 +1757,6 @@ add_library(grpc_test_util src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc - src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -1785,7 +1777,6 @@ add_library(grpc_test_util src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc - src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -2074,7 +2065,6 @@ add_library(grpc_test_util_unsecure src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc - src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -2095,7 +2085,6 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc - src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -2363,7 +2352,6 @@ add_library(grpc_unsecure src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc - src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -2384,7 +2372,6 @@ add_library(grpc_unsecure src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc - src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -3205,7 +3192,6 @@ add_library(grpc++_cronet src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc - src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -3226,7 +3212,6 @@ add_library(grpc++_cronet src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc - src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -5850,37 +5835,6 @@ target_link_libraries(bin_encoder_test grpc ) -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) -if(_gRPC_PLATFORM_LINUX) - -add_executable(buffer_list_test - test/core/iomgr/buffer_list_test.cc -) - - -target_include_directories(buffer_list_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 ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} -) - -target_link_libraries(buffer_list_test - ${_gRPC_ALLTARGETS_LIBRARIES} - grpc_test_util - grpc - gpr_test_util - gpr -) - -endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 7caf585ee9e..e9a9486a3cc 100644 --- a/Makefile +++ b/Makefile @@ -978,7 +978,6 @@ avl_test: $(BINDIR)/$(CONFIG)/avl_test bad_server_response_test: $(BINDIR)/$(CONFIG)/bad_server_response_test bin_decoder_test: $(BINDIR)/$(CONFIG)/bin_decoder_test bin_encoder_test: $(BINDIR)/$(CONFIG)/bin_encoder_test -buffer_list_test: $(BINDIR)/$(CONFIG)/buffer_list_test channel_create_test: $(BINDIR)/$(CONFIG)/channel_create_test check_epollexclusive: $(BINDIR)/$(CONFIG)/check_epollexclusive chttp2_hpack_encoder_test: $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test @@ -1435,7 +1434,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/bad_server_response_test \ $(BINDIR)/$(CONFIG)/bin_decoder_test \ $(BINDIR)/$(CONFIG)/bin_encoder_test \ - $(BINDIR)/$(CONFIG)/buffer_list_test \ $(BINDIR)/$(CONFIG)/channel_create_test \ $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test \ $(BINDIR)/$(CONFIG)/chttp2_stream_map_test \ @@ -1952,8 +1950,6 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/bin_decoder_test || ( echo test bin_decoder_test failed ; exit 1 ) $(E) "[RUN] Testing bin_encoder_test" $(Q) $(BINDIR)/$(CONFIG)/bin_encoder_test || ( echo test bin_encoder_test failed ; exit 1 ) - $(E) "[RUN] Testing buffer_list_test" - $(Q) $(BINDIR)/$(CONFIG)/buffer_list_test || ( echo test buffer_list_test failed ; exit 1 ) $(E) "[RUN] Testing channel_create_test" $(Q) $(BINDIR)/$(CONFIG)/channel_create_test || ( echo test channel_create_test failed ; exit 1 ) $(E) "[RUN] Testing chttp2_hpack_encoder_test" @@ -3464,7 +3460,6 @@ LIBGRPC_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ - src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -3485,7 +3480,6 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ - src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -3871,7 +3865,6 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ - src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -3892,7 +3885,6 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ - src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -4263,7 +4255,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ - src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -4284,7 +4275,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ - src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -4564,7 +4554,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ - src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -4585,7 +4574,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ - src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -4831,7 +4819,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ - src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -4852,7 +4839,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ - src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -5661,7 +5647,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ - src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -5682,7 +5667,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ - src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -10717,38 +10701,6 @@ endif endif -BUFFER_LIST_TEST_SRC = \ - test/core/iomgr/buffer_list_test.cc \ - -BUFFER_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BUFFER_LIST_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/buffer_list_test: openssl_dep_error - -else - - - -$(BINDIR)/$(CONFIG)/buffer_list_test: $(BUFFER_LIST_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) $(BUFFER_LIST_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)/buffer_list_test - -endif - -$(OBJDIR)/$(CONFIG)/test/core/iomgr/buffer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_buffer_list_test: $(BUFFER_LIST_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(BUFFER_LIST_TEST_OBJS:.o=.dep) -endif -endif - - CHANNEL_CREATE_TEST_SRC = \ test/core/surface/channel_create_test.cc \ diff --git a/build.yaml b/build.yaml index a7ebee7572e..ce21068c312 100644 --- a/build.yaml +++ b/build.yaml @@ -256,7 +256,6 @@ filegroups: - src/core/lib/http/format_request.cc - src/core/lib/http/httpcli.cc - src/core/lib/http/parser.cc - - src/core/lib/iomgr/buffer_list.cc - src/core/lib/iomgr/call_combiner.cc - src/core/lib/iomgr/combiner.cc - src/core/lib/iomgr/endpoint.cc @@ -277,7 +276,6 @@ filegroups: - src/core/lib/iomgr/gethostname_fallback.cc - src/core/lib/iomgr/gethostname_host_name_max.cc - src/core/lib/iomgr/gethostname_sysconf.cc - - src/core/lib/iomgr/internal_errqueue.cc - src/core/lib/iomgr/iocp_windows.cc - src/core/lib/iomgr/iomgr.cc - src/core/lib/iomgr/iomgr_custom.cc @@ -436,7 +434,6 @@ filegroups: - src/core/lib/http/httpcli.h - src/core/lib/http/parser.h - src/core/lib/iomgr/block_annotate.h - - src/core/lib/iomgr/buffer_list.h - src/core/lib/iomgr/call_combiner.h - src/core/lib/iomgr/closure.h - src/core/lib/iomgr/combiner.h @@ -452,7 +449,6 @@ filegroups: - src/core/lib/iomgr/exec_ctx.h - src/core/lib/iomgr/executor.h - src/core/lib/iomgr/gethostname.h - - src/core/lib/iomgr/internal_errqueue.h - src/core/lib/iomgr/iocp_windows.h - src/core/lib/iomgr/iomgr.h - src/core/lib/iomgr/iomgr_custom.h @@ -2143,20 +2139,6 @@ targets: - grpc_test_util - grpc uses_polling: false -- name: buffer_list_test - build: test - language: c - src: - - test/core/iomgr/buffer_list_test.cc - deps: - - grpc_test_util - - grpc - - gpr_test_util - - gpr - exclude_iomgrs: - - uv - platforms: - - linux - name: channel_create_test build: test language: c diff --git a/config.m4 b/config.m4 index af3624cdd1b..7825274eea9 100644 --- a/config.m4 +++ b/config.m4 @@ -108,7 +108,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ - src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -129,7 +128,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ - src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ diff --git a/config.w32 b/config.w32 index ad91ee40bd7..a9d1e6c9d01 100644 --- a/config.w32 +++ b/config.w32 @@ -83,7 +83,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\http\\format_request.cc " + "src\\core\\lib\\http\\httpcli.cc " + "src\\core\\lib\\http\\parser.cc " + - "src\\core\\lib\\iomgr\\buffer_list.cc " + "src\\core\\lib\\iomgr\\call_combiner.cc " + "src\\core\\lib\\iomgr\\combiner.cc " + "src\\core\\lib\\iomgr\\endpoint.cc " + @@ -104,7 +103,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\gethostname_fallback.cc " + "src\\core\\lib\\iomgr\\gethostname_host_name_max.cc " + "src\\core\\lib\\iomgr\\gethostname_sysconf.cc " + - "src\\core\\lib\\iomgr\\internal_errqueue.cc " + "src\\core\\lib\\iomgr\\iocp_windows.cc " + "src\\core\\lib\\iomgr\\iomgr.cc " + "src\\core\\lib\\iomgr\\iomgr_custom.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index a387794f579..207d7baa8f9 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -382,7 +382,6 @@ Pod::Spec.new do |s| 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', 'src/core/lib/iomgr/block_annotate.h', - 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', @@ -398,7 +397,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', - 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', 'src/core/lib/iomgr/iomgr_custom.h', @@ -572,7 +570,6 @@ Pod::Spec.new do |s| 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', 'src/core/lib/iomgr/block_annotate.h', - 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', @@ -588,7 +585,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', - 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', 'src/core/lib/iomgr/iomgr_custom.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 9832283e5c9..f1a9bce7f2e 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -394,7 +394,6 @@ Pod::Spec.new do |s| 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', 'src/core/lib/iomgr/block_annotate.h', - 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', @@ -410,7 +409,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', - 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', 'src/core/lib/iomgr/iomgr_custom.h', @@ -540,7 +538,6 @@ Pod::Spec.new do |s| 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', - 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -561,7 +558,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', - 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', @@ -997,7 +993,6 @@ Pod::Spec.new do |s| 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', 'src/core/lib/iomgr/block_annotate.h', - 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', @@ -1013,7 +1008,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', - 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', 'src/core/lib/iomgr/iomgr_custom.h', diff --git a/grpc.gemspec b/grpc.gemspec index c8e58faec9e..5c38071d15b 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -330,7 +330,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/http/httpcli.h ) s.files += %w( src/core/lib/http/parser.h ) s.files += %w( src/core/lib/iomgr/block_annotate.h ) - s.files += %w( src/core/lib/iomgr/buffer_list.h ) s.files += %w( src/core/lib/iomgr/call_combiner.h ) s.files += %w( src/core/lib/iomgr/closure.h ) s.files += %w( src/core/lib/iomgr/combiner.h ) @@ -346,7 +345,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/exec_ctx.h ) s.files += %w( src/core/lib/iomgr/executor.h ) s.files += %w( src/core/lib/iomgr/gethostname.h ) - s.files += %w( src/core/lib/iomgr/internal_errqueue.h ) s.files += %w( src/core/lib/iomgr/iocp_windows.h ) s.files += %w( src/core/lib/iomgr/iomgr.h ) s.files += %w( src/core/lib/iomgr/iomgr_custom.h ) @@ -476,7 +474,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/http/format_request.cc ) s.files += %w( src/core/lib/http/httpcli.cc ) s.files += %w( src/core/lib/http/parser.cc ) - s.files += %w( src/core/lib/iomgr/buffer_list.cc ) s.files += %w( src/core/lib/iomgr/call_combiner.cc ) s.files += %w( src/core/lib/iomgr/combiner.cc ) s.files += %w( src/core/lib/iomgr/endpoint.cc ) @@ -497,7 +494,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/gethostname_fallback.cc ) s.files += %w( src/core/lib/iomgr/gethostname_host_name_max.cc ) s.files += %w( src/core/lib/iomgr/gethostname_sysconf.cc ) - s.files += %w( src/core/lib/iomgr/internal_errqueue.cc ) s.files += %w( src/core/lib/iomgr/iocp_windows.cc ) s.files += %w( src/core/lib/iomgr/iomgr.cc ) s.files += %w( src/core/lib/iomgr/iomgr_custom.cc ) diff --git a/grpc.gyp b/grpc.gyp index 654a5310923..a36998bcb3b 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -300,7 +300,6 @@ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', - 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -321,7 +320,6 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', - 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', @@ -662,7 +660,6 @@ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', - 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -683,7 +680,6 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', - 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', @@ -897,7 +893,6 @@ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', - 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -918,7 +913,6 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', - 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', @@ -1110,7 +1104,6 @@ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', - 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -1131,7 +1124,6 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', - 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', diff --git a/package.xml b/package.xml index 537c5404e7e..1bdf127c36a 100644 --- a/package.xml +++ b/package.xml @@ -335,7 +335,6 @@ - @@ -351,7 +350,6 @@ - @@ -481,7 +479,6 @@ - @@ -502,7 +499,6 @@ - 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 7ce8da8c00e..4e8b8b71dbd 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -320,7 +320,7 @@ static void http_connect_handshaker_do_handshake( // Take a new ref to be held by the write callback. gpr_ref(&handshaker->refcount); grpc_endpoint_write(args->endpoint, &handshaker->write_buffer, - &handshaker->request_done_closure, nullptr); + &handshaker->request_done_closure); gpr_mu_unlock(&handshaker->mu); } 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 5bdcb387c9b..dfed824cd5b 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 @@ -50,7 +50,7 @@ grpc_channel* grpc_insecure_channel_create_from_fd( GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0); grpc_endpoint* client = grpc_tcp_client_create_from_fd( - grpc_fd_create(fd, "client", true), args, "fd-client"); + grpc_fd_create(fd, "client", false), args, "fd-client"); grpc_transport* transport = grpc_create_chttp2_transport(final_args, client, true); 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 e4bd91d07ba..a0228785eeb 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 @@ -44,7 +44,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server, gpr_asprintf(&name, "fd:%d", fd); grpc_endpoint* server_endpoint = - grpc_tcp_create(grpc_fd_create(fd, name, true), + grpc_tcp_create(grpc_fd_create(fd, name, false), grpc_server_get_channel_args(server), name); gpr_free(name); diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 027a57d606d..36511fa6088 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1029,8 +1029,7 @@ static void write_action(void* gt, grpc_error* error) { grpc_endpoint_write( t->ep, &t->outbuf, GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t, - grpc_combiner_scheduler(t->combiner)), - nullptr); + grpc_combiner_scheduler(t->combiner))); } /* Callback from the grpc_endpoint after bytes have been written by calling diff --git a/src/core/lib/http/httpcli.cc b/src/core/lib/http/httpcli.cc index 3bd7a2ce590..12060074c53 100644 --- a/src/core/lib/http/httpcli.cc +++ b/src/core/lib/http/httpcli.cc @@ -163,7 +163,7 @@ static void done_write(void* arg, grpc_error* error) { static void start_write(internal_request* req) { grpc_slice_ref_internal(req->request_text); grpc_slice_buffer_add(&req->outgoing, req->request_text); - grpc_endpoint_write(req->ep, &req->outgoing, &req->done_write, nullptr); + grpc_endpoint_write(req->ep, &req->outgoing, &req->done_write); } static void on_handshake_done(void* arg, grpc_endpoint* ep) { diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc deleted file mode 100644 index 6ada23db1c2..00000000000 --- a/src/core/lib/iomgr/buffer_list.cc +++ /dev/null @@ -1,134 +0,0 @@ -/* - * - * 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 - -#include "src/core/lib/iomgr/buffer_list.h" -#include "src/core/lib/iomgr/port.h" - -#include - -#ifdef GRPC_LINUX_ERRQUEUE -#include - -#include "src/core/lib/gprpp/memory.h" - -namespace grpc_core { -void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, - void* arg) { - GPR_DEBUG_ASSERT(head != nullptr); - TracedBuffer* new_elem = New(seq_no, arg); - /* Store the current time as the sendmsg time. */ - new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME); - if (*head == nullptr) { - *head = new_elem; - return; - } - /* Append at the end. */ - TracedBuffer* ptr = *head; - while (ptr->next_ != nullptr) { - ptr = ptr->next_; - } - ptr->next_ = new_elem; -} - -namespace { -/** Fills gpr_timespec gts based on values from timespec ts */ -void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) { - gts->tv_sec = ts->tv_sec; - gts->tv_nsec = static_cast(ts->tv_nsec); - gts->clock_type = GPR_CLOCK_REALTIME; -} - -/** The saved callback function that will be invoked when we get all the - * timestamps that we are going to get for a TracedBuffer. */ -void (*timestamps_callback)(void*, grpc_core::Timestamps*, - grpc_error* shutdown_err); -} /* namespace */ - -void TracedBuffer::ProcessTimestamp(TracedBuffer** head, - struct sock_extended_err* serr, - struct scm_timestamping* tss) { - GPR_DEBUG_ASSERT(head != nullptr); - TracedBuffer* elem = *head; - TracedBuffer* next = nullptr; - while (elem != nullptr) { - /* The byte number refers to the sequence number of the last byte which this - * timestamp relates to. */ - if (serr->ee_data >= elem->seq_no_) { - switch (serr->ee_info) { - case SCM_TSTAMP_SCHED: - fill_gpr_from_timestamp(&(elem->ts_.scheduled_time), &(tss->ts[0])); - elem = elem->next_; - break; - case SCM_TSTAMP_SND: - fill_gpr_from_timestamp(&(elem->ts_.sent_time), &(tss->ts[0])); - elem = elem->next_; - break; - case SCM_TSTAMP_ACK: - fill_gpr_from_timestamp(&(elem->ts_.acked_time), &(tss->ts[0])); - /* Got all timestamps. Do the callback and free this TracedBuffer. - * The thing below can be passed by value if we don't want the - * restriction on the lifetime. */ - timestamps_callback(elem->arg_, &(elem->ts_), GRPC_ERROR_NONE); - next = elem->next_; - Delete(elem); - *head = elem = next; - break; - default: - abort(); - } - } else { - break; - } - } -} - -void TracedBuffer::Shutdown(TracedBuffer** head, grpc_error* shutdown_err) { - GPR_DEBUG_ASSERT(head != nullptr); - TracedBuffer* elem = *head; - while (elem != nullptr) { - if (timestamps_callback) { - timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err); - } - auto* next = elem->next_; - Delete(elem); - elem = next; - } - *head = nullptr; - GRPC_ERROR_UNREF(shutdown_err); -} - -void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, - grpc_core::Timestamps*, - grpc_error* error)) { - timestamps_callback = fn; -} -} /* namespace grpc_core */ - -#else /* GRPC_LINUX_ERRQUEUE */ - -namespace grpc_core { -void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, - grpc_core::Timestamps*, - grpc_error* error)) { - gpr_log(GPR_DEBUG, "Timestamps callback is not enabled for this platform"); -} -} /* namespace grpc_core */ - -#endif /* GRPC_LINUX_ERRQUEUE */ diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h deleted file mode 100644 index cbbf50a6575..00000000000 --- a/src/core/lib/iomgr/buffer_list.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H -#define GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H - -#include - -#include "src/core/lib/iomgr/port.h" - -#include - -#include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/iomgr/error.h" -#include "src/core/lib/iomgr/internal_errqueue.h" - -namespace grpc_core { -struct Timestamps { - /* TODO(yashykt): This would also need to store OPTSTAT once support is added - */ - gpr_timespec sendmsg_time; - gpr_timespec scheduled_time; - gpr_timespec sent_time; - gpr_timespec acked_time; -}; - -/** TracedBuffer is a class to keep track of timestamps for a specific buffer in - * the TCP layer. We are only tracking timestamps for Linux kernels and hence - * this class would only be used by Linux platforms. For all other platforms, - * TracedBuffer would be an empty class. - * - * The timestamps collected are according to grpc_core::Timestamps declared - * above. - * - * A TracedBuffer list is kept track of using the head element of the list. If - * the head element of the list is nullptr, then the list is empty. - */ -#ifdef GRPC_LINUX_ERRQUEUE -class TracedBuffer { - public: - /** Add a new entry in the TracedBuffer list pointed to by head. Also saves - * sendmsg_time with the current timestamp. */ - static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no, - void* arg); - - /** Processes a received timestamp based on sock_extended_err and - * scm_timestamping structures. It will invoke the timestamps callback if the - * timestamp type is SCM_TSTAMP_ACK. */ - static void ProcessTimestamp(grpc_core::TracedBuffer** head, - struct sock_extended_err* serr, - struct scm_timestamping* tss); - - /** Cleans the list by calling the callback for each traced buffer in the list - * with timestamps that it has. */ - static void Shutdown(grpc_core::TracedBuffer** head, - grpc_error* shutdown_err); - - private: - GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW - - TracedBuffer(int seq_no, void* arg) - : seq_no_(seq_no), arg_(arg), next_(nullptr) {} - - uint32_t seq_no_; /* The sequence number for the last byte in the buffer */ - void* arg_; /* The arg to pass to timestamps_callback */ - grpc_core::Timestamps ts_; /* The timestamps corresponding to this buffer */ - grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */ -}; -#else /* GRPC_LINUX_ERRQUEUE */ -class TracedBuffer {}; -#endif /* GRPC_LINUX_ERRQUEUE */ - -/** Sets the callback function to call when timestamps for a write are - * collected. The callback does not own a reference to error. */ -void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, - grpc_core::Timestamps*, - grpc_error* error)); - -}; /* namespace grpc_core */ - -#endif /* GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H */ diff --git a/src/core/lib/iomgr/endpoint.cc b/src/core/lib/iomgr/endpoint.cc index 44fb47e19d9..92e79301114 100644 --- a/src/core/lib/iomgr/endpoint.cc +++ b/src/core/lib/iomgr/endpoint.cc @@ -28,8 +28,8 @@ void grpc_endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* slices, } void grpc_endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* arg) { - ep->vtable->write(ep, slices, cb, arg); + grpc_closure* cb) { + ep->vtable->write(ep, slices, cb); } void grpc_endpoint_add_to_pollset(grpc_endpoint* ep, grpc_pollset* pollset) { diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h index 1f590a80cae..15db1649fa9 100644 --- a/src/core/lib/iomgr/endpoint.h +++ b/src/core/lib/iomgr/endpoint.h @@ -33,12 +33,10 @@ typedef struct grpc_endpoint grpc_endpoint; typedef struct grpc_endpoint_vtable grpc_endpoint_vtable; -class Timestamps; struct grpc_endpoint_vtable { void (*read)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb); - void (*write)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb, - void* arg); + void (*write)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb); void (*add_to_pollset)(grpc_endpoint* ep, grpc_pollset* pollset); void (*add_to_pollset_set)(grpc_endpoint* ep, grpc_pollset_set* pollset); void (*delete_from_pollset_set)(grpc_endpoint* ep, grpc_pollset_set* pollset); @@ -72,11 +70,9 @@ int grpc_endpoint_get_fd(grpc_endpoint* ep); \a slices may be mutated at will by the endpoint until cb is called. No guarantee is made to the content of slices after a write EXCEPT that it is a valid slice buffer. - \a arg is platform specific. It is currently only used by TCP on linux - platforms as an argument that would be forwarded to the timestamps callback. */ void grpc_endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* arg); + grpc_closure* cb); /* Causes any pending and future read/write callbacks to run immediately with success==0 */ diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc index df2cf508c8f..c3bc0cc8fd9 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.cc +++ b/src/core/lib/iomgr/endpoint_cfstream.cc @@ -268,7 +268,7 @@ static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices, } static void CFStreamWrite(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* arg) { + grpc_closure* cb) { CFStreamEndpoint* ep_impl = reinterpret_cast(ep); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_DEBUG, "CFStream endpoint:%p write (%p, %p) length:%zu", diff --git a/src/core/lib/iomgr/endpoint_pair_posix.cc b/src/core/lib/iomgr/endpoint_pair_posix.cc index 3afbfd72543..5c5c246f998 100644 --- a/src/core/lib/iomgr/endpoint_pair_posix.cc +++ b/src/core/lib/iomgr/endpoint_pair_posix.cc @@ -59,11 +59,11 @@ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char* name, grpc_core::ExecCtx exec_ctx; gpr_asprintf(&final_name, "%s:client", name); - p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, true), args, + p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, false), args, "socketpair-server"); gpr_free(final_name); gpr_asprintf(&final_name, "%s:server", name); - p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, true), args, + p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, false), args, "socketpair-client"); gpr_free(final_name); diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index d4377e2d504..0205363d5c4 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -237,19 +237,14 @@ void grpc_event_engine_shutdown(void) { } bool grpc_event_engine_can_track_errors(void) { -/* Only track errors if platform supports errqueue. */ -#ifdef GRPC_LINUX_ERRQUEUE return g_event_engine->can_track_err; -#else - return false; -#endif /* GRPC_LINUX_ERRQUEUE */ } grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) { GRPC_POLLING_API_TRACE("fd_create(%d, %s, %d)", fd, name, track_err); GRPC_FD_TRACE("fd_create(%d, %s, %d)", fd, name, track_err); - return g_event_engine->fd_create(fd, name, - track_err && g_event_engine->can_track_err); + GPR_DEBUG_ASSERT(!track_err || g_event_engine->can_track_err); + return g_event_engine->fd_create(fd, name, track_err); } int grpc_fd_wrapped_fd(grpc_fd* fd) { diff --git a/src/core/lib/iomgr/internal_errqueue.cc b/src/core/lib/iomgr/internal_errqueue.cc deleted file mode 100644 index 8823737e494..00000000000 --- a/src/core/lib/iomgr/internal_errqueue.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * 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 - -#include "src/core/lib/iomgr/port.h" - -#include "src/core/lib/iomgr/internal_errqueue.h" - -#ifdef GRPC_POSIX_SOCKET_TCP - -#ifdef GPR_LINUX -#include -#endif /* GPR_LINUX */ - -bool kernel_supports_errqueue() { -#ifdef LINUX_VERSION_CODE -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) - return true; -#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) */ -#endif /* LINUX_VERSION_CODE */ - return false; -} - -#endif /* GRPC_POSIX_SOCKET_TCP */ diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h deleted file mode 100644 index fc11be9a6dd..00000000000 --- a/src/core/lib/iomgr/internal_errqueue.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * 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. - * - */ - -/* This file contains constants defined in and - * so as to allow collecting network timestamps in the - * kernel. This file allows tcp_posix.cc to compile on platforms that do not - * have and . - */ - -#ifndef GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H -#define GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H - -#include - -#include "src/core/lib/iomgr/port.h" - -#ifdef GRPC_POSIX_SOCKET_TCP - -#include -#include - -#ifdef GRPC_LINUX_ERRQUEUE -#include -#include -#include -#endif /* GRPC_LINUX_ERRQUEUE */ - -namespace grpc_core { - -#ifdef GRPC_LINUX_ERRQUEUE -constexpr uint32_t kTimestampingSocketOptions = SOF_TIMESTAMPING_SOFTWARE | - SOF_TIMESTAMPING_OPT_ID | - SOF_TIMESTAMPING_OPT_TSONLY; -constexpr uint32_t kTimestampingRecordingOptions = - SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE | - SOF_TIMESTAMPING_TX_ACK; -#endif /* GRPC_LINUX_ERRQUEUE */ - -/* Returns true if kernel is capable of supporting errqueue and timestamping. - * Currently allowing only linux kernels above 4.0.0 - */ -bool kernel_supports_errqueue(); -} // namespace grpc_core - -#endif /* GRPC_POSIX_SOCKET_TCP */ - -#endif /* GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H */ diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index a4688fd0efb..066417b93cc 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -60,12 +60,6 @@ #define GRPC_HAVE_IP_PKTINFO 1 #define GRPC_HAVE_MSG_NOSIGNAL 1 #define GRPC_HAVE_UNIX_SOCKET 1 -#include -#ifdef LINUX_VERSION_CODE -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) -#define GRPC_LINUX_ERRQUEUE 1 -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */ -#endif /* LINUX_VERSION_CODE */ #define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1 #define GRPC_POSIX_FORK 1 #define GRPC_POSIX_HOST_NAME_MAX 1 diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc index 9c989b7dfee..296ee74311a 100644 --- a/src/core/lib/iomgr/tcp_client_posix.cc +++ b/src/core/lib/iomgr/tcp_client_posix.cc @@ -279,7 +279,7 @@ grpc_error* grpc_tcp_client_prepare_fd(const grpc_channel_args* channel_args, } addr_str = grpc_sockaddr_to_uri(mapped_addr); gpr_asprintf(&name, "tcp-client:%s", addr_str); - *fdobj = grpc_fd_create(fd, name, true); + *fdobj = grpc_fd_create(fd, name, false); gpr_free(name); gpr_free(addr_str); return GRPC_ERROR_NONE; diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc index e02a1898f25..990e8d632b9 100644 --- a/src/core/lib/iomgr/tcp_custom.cc +++ b/src/core/lib/iomgr/tcp_custom.cc @@ -221,7 +221,7 @@ static void custom_write_callback(grpc_custom_socket* socket, } static void endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* write_slices, - grpc_closure* cb, void* arg) { + grpc_closure* cb) { custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 1db2790265e..b53ffbf01cf 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -27,9 +27,7 @@ #include #include -#include #include -#include #include #include #include @@ -48,7 +46,6 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/iomgr/buffer_list.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/profiling/timers.h" @@ -100,42 +97,17 @@ struct grpc_tcp { grpc_closure read_done_closure; grpc_closure write_done_closure; - grpc_closure error_closure; char* peer_string; grpc_resource_user* resource_user; grpc_resource_user_slice_allocator slice_allocator; - - grpc_core::TracedBuffer* tb_head; /* List of traced buffers */ - gpr_mu tb_mu; /* Lock for access to list of traced buffers */ - - /* grpc_endpoint_write takes an argument which if non-null means that the - * transport layer wants the TCP layer to collect timestamps for this write. - * This arg is forwarded to the timestamps callback function when the ACK - * timestamp is received from the kernel. This arg is a (void *) which allows - * users of this API to pass in a pointer to any kind of structure. This - * structure could actually be a tag or any book-keeping object that the user - * can use to distinguish between different traced writes. The only - * requirement from the TCP endpoint layer is that this arg should be non-null - * if the user wants timestamps for the write. */ - void* outgoing_buffer_arg; - /* A counter which starts at 0. It is initialized the first time the socket - * options for collecting timestamps are set, and is incremented with each - * byte sent. */ - int bytes_counter; - bool socket_ts_enabled; /* True if timestamping options are set on the socket - */ - gpr_atm - stop_error_notification; /* Set to 1 if we do not want to be notified on - errors anymore */ }; struct backup_poller { gpr_mu* pollset_mu; grpc_closure run_poller; }; - } // namespace #define BACKUP_POLLER_POLLSET(b) ((grpc_pollset*)((b) + 1)) @@ -330,7 +302,6 @@ static void tcp_free(grpc_tcp* tcp) { grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); gpr_free(tcp->peer_string); - gpr_mu_destroy(&tcp->tb_mu); gpr_free(tcp); } @@ -376,10 +347,6 @@ static void tcp_destroy(grpc_endpoint* ep) { grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = reinterpret_cast(ep); grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); - if (grpc_event_engine_can_track_errors()) { - gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); - grpc_fd_set_error(tcp->em_fd); - } TCP_UNREF(tcp, "destroy"); } @@ -546,234 +513,6 @@ static void tcp_read(grpc_endpoint* ep, grpc_slice_buffer* incoming_buffer, } } -/* A wrapper around sendmsg. It sends \a msg over \a fd and returns the number - * of bytes sent. */ -ssize_t tcp_send(int fd, const struct msghdr* msg) { - GPR_TIMER_SCOPE("sendmsg", 1); - ssize_t sent_length; - do { - /* TODO(klempner): Cork if this is a partial write */ - GRPC_STATS_INC_SYSCALL_WRITE(); - sent_length = sendmsg(fd, msg, SENDMSG_FLAGS); - } while (sent_length < 0 && errno == EINTR); - return sent_length; -} - -/** This is to be called if outgoing_buffer_arg is not null. On linux platforms, - * this will call sendmsg with socket options set to collect timestamps inside - * the kernel. On return, sent_length is set to the return value of the sendmsg - * call. Returns false if setting the socket options failed. This is not - * implemented for non-linux platforms currently, and crashes out. - */ -static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, - size_t sending_length, - ssize_t* sent_length, grpc_error** error); - -/** The callback function to be invoked when we get an error on the socket. */ -static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error); - -#ifdef GRPC_LINUX_ERRQUEUE -static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, - size_t sending_length, - ssize_t* sent_length, - grpc_error** error) { - if (!tcp->socket_ts_enabled) { - uint32_t opt = grpc_core::kTimestampingSocketOptions; - if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, - static_cast(&opt), sizeof(opt)) != 0) { - *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "setsockopt"), tcp); - grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_ERROR, "Failed to set timestamping options on the socket."); - } - return false; - } - tcp->bytes_counter = -1; - tcp->socket_ts_enabled = true; - } - /* Set control message to indicate that you want timestamps. */ - union { - char cmsg_buf[CMSG_SPACE(sizeof(uint32_t))]; - struct cmsghdr align; - } u; - cmsghdr* cmsg = reinterpret_cast(u.cmsg_buf); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SO_TIMESTAMPING; - cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t)); - *reinterpret_cast(CMSG_DATA(cmsg)) = - grpc_core::kTimestampingRecordingOptions; - msg->msg_control = u.cmsg_buf; - msg->msg_controllen = CMSG_SPACE(sizeof(uint32_t)); - - /* If there was an error on sendmsg the logic in tcp_flush will handle it. */ - ssize_t length = tcp_send(tcp->fd, msg); - *sent_length = length; - /* Only save timestamps if all the bytes were taken by sendmsg. */ - if (sending_length == static_cast(length)) { - gpr_mu_lock(&tcp->tb_mu); - grpc_core::TracedBuffer::AddNewEntry( - &tcp->tb_head, static_cast(tcp->bytes_counter + length), - tcp->outgoing_buffer_arg); - gpr_mu_unlock(&tcp->tb_mu); - tcp->outgoing_buffer_arg = nullptr; - } - return true; -} - -/** Reads \a cmsg to derive timestamps from the control messages. If a valid - * timestamp is found, the traced buffer list is updated with this timestamp. - * The caller of this function should be looping on the control messages found - * in \a msg. \a cmsg should point to the control message that the caller wants - * processed. - * On return, a pointer to a control message is returned. On the next iteration, - * CMSG_NXTHDR(msg, ret_val) should be passed as \a cmsg. */ -struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, - struct cmsghdr* cmsg) { - auto next_cmsg = CMSG_NXTHDR(msg, cmsg); - if (next_cmsg == nullptr) { - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_ERROR, "Received timestamp without extended error"); - } - return cmsg; - } - - if (!(next_cmsg->cmsg_level == SOL_IP || next_cmsg->cmsg_level == SOL_IPV6) || - !(next_cmsg->cmsg_type == IP_RECVERR || - next_cmsg->cmsg_type == IPV6_RECVERR)) { - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_ERROR, "Unexpected control message"); - } - return cmsg; - } - - auto tss = reinterpret_cast(CMSG_DATA(cmsg)); - auto serr = reinterpret_cast(CMSG_DATA(next_cmsg)); - if (serr->ee_errno != ENOMSG || - serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) { - gpr_log(GPR_ERROR, "Unexpected control message"); - return cmsg; - } - /* The error handling can potentially be done on another thread so we need - * to protect the traced buffer list. A lock free list might be better. Using - * a simple mutex for now. */ - gpr_mu_lock(&tcp->tb_mu); - grpc_core::TracedBuffer::ProcessTimestamp(&tcp->tb_head, serr, tss); - gpr_mu_unlock(&tcp->tb_mu); - return next_cmsg; -} - -/** For linux platforms, reads the socket's error queue and processes error - * messages from the queue. Returns true if all the errors processed were - * timestamps. Returns false if any of the errors were not timestamps. For - * non-linux platforms, error processing is not used/enabled currently. - */ -static bool process_errors(grpc_tcp* tcp) { - while (true) { - struct iovec iov; - iov.iov_base = nullptr; - iov.iov_len = 0; - struct msghdr msg; - msg.msg_name = nullptr; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 0; - msg.msg_flags = 0; - - union { - char rbuf[1024 /*CMSG_SPACE(sizeof(scm_timestamping)) + - CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in))*/]; - struct cmsghdr align; - } aligned_buf; - memset(&aligned_buf, 0, sizeof(aligned_buf)); - - msg.msg_control = aligned_buf.rbuf; - msg.msg_controllen = sizeof(aligned_buf.rbuf); - - int r, saved_errno; - do { - r = recvmsg(tcp->fd, &msg, MSG_ERRQUEUE); - saved_errno = errno; - } while (r < 0 && saved_errno == EINTR); - - if (r == -1 && saved_errno == EAGAIN) { - return true; /* No more errors to process */ - } - if (r == -1) { - return false; - } - if (grpc_tcp_trace.enabled()) { - if ((msg.msg_flags & MSG_CTRUNC) == 1) { - gpr_log(GPR_INFO, "Error message was truncated."); - } - } - - if (msg.msg_controllen == 0) { - /* There was no control message found. It was probably spurious. */ - return true; - } - for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg && cmsg->cmsg_len; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level != SOL_SOCKET || - cmsg->cmsg_type != SCM_TIMESTAMPING) { - /* Got a control message that is not a timestamp. Don't know how to - * handle this. */ - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_INFO, - "unknown control message cmsg_level:%d cmsg_type:%d", - cmsg->cmsg_level, cmsg->cmsg_type); - } - return false; - } - process_timestamp(tcp, &msg, cmsg); - } - } -} - -static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { - grpc_tcp* tcp = static_cast(arg); - if (grpc_tcp_trace.enabled()) { - gpr_log(GPR_INFO, "TCP:%p got_error: %s", tcp, grpc_error_string(error)); - } - - if (error != GRPC_ERROR_NONE || - static_cast(gpr_atm_acq_load(&tcp->stop_error_notification))) { - /* We aren't going to register to hear on error anymore, so it is safe to - * unref. */ - grpc_core::TracedBuffer::Shutdown(&tcp->tb_head, GRPC_ERROR_REF(error)); - TCP_UNREF(tcp, "error-tracking"); - return; - } - - /* We are still interested in collecting timestamps, so let's try reading - * them. */ - if (!process_errors(tcp)) { - /* This was not a timestamps error. This was an actual error. Set the - * read and write closures to be ready. - */ - grpc_fd_set_readable(tcp->em_fd); - grpc_fd_set_writable(tcp->em_fd); - } - GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, - grpc_schedule_on_exec_ctx); - grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); -} - -#else /* GRPC_LINUX_ERRQUEUE */ -static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, - size_t sending_length, - ssize_t* sent_length, - grpc_error** error) { - gpr_log(GPR_ERROR, "Write with timestamps not supported for this platform"); - GPR_ASSERT(0); - return false; -} - -static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { - gpr_log(GPR_ERROR, "Error handling is not supported for this platform"); - GPR_ASSERT(0); -} -#endif /* GRPC_LINUX_ERRQUEUE */ - /* returns true if done, false if pending; if returning true, *error is set */ #if defined(IOV_MAX) && IOV_MAX < 1000 #define MAX_WRITE_IOVEC IOV_MAX @@ -818,20 +557,19 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = iov_size; + msg.msg_control = nullptr; + msg.msg_controllen = 0; msg.msg_flags = 0; - if (tcp->outgoing_buffer_arg != nullptr) { - if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length, - error)) - return true; /* something went wrong with timestamps */ - } else { - msg.msg_control = nullptr; - msg.msg_controllen = 0; - GRPC_STATS_INC_TCP_WRITE_SIZE(sending_length); - GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(iov_size); + GRPC_STATS_INC_TCP_WRITE_SIZE(sending_length); + GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(iov_size); - sent_length = tcp_send(tcp->fd, &msg); - } + GPR_TIMER_SCOPE("sendmsg", 1); + do { + /* TODO(klempner): Cork if this is a partial write */ + GRPC_STATS_INC_SYSCALL_WRITE(); + sent_length = sendmsg(tcp->fd, &msg, SENDMSG_FLAGS); + } while (sent_length < 0 && errno == EINTR); if (sent_length < 0) { if (errno == EAGAIN) { @@ -855,7 +593,6 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { } GPR_ASSERT(tcp->outgoing_byte_idx == 0); - tcp->bytes_counter += sent_length; trailing = sending_length - static_cast(sent_length); while (trailing > 0) { size_t slice_length; @@ -870,6 +607,7 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { trailing -= slice_length; } } + if (outgoing_slice_idx == tcp->outgoing_buffer->count) { *error = GRPC_ERROR_NONE; grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); @@ -902,13 +640,14 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "write: %s", str); } + GRPC_CLOSURE_SCHED(cb, error); TCP_UNREF(tcp, "write"); } } static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, - grpc_closure* cb, void* arg) { + grpc_closure* cb) { GPR_TIMER_SCOPE("tcp_write", 0); grpc_tcp* tcp = reinterpret_cast(ep); grpc_error* error = GRPC_ERROR_NONE; @@ -936,10 +675,6 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, } tcp->outgoing_buffer = buf; tcp->outgoing_byte_idx = 0; - tcp->outgoing_buffer_arg = arg; - if (arg) { - GPR_ASSERT(grpc_event_engine_can_track_errors()); - } if (!tcp_flush(tcp, &error)) { TCP_REF(tcp, "write"); @@ -1057,8 +792,6 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->bytes_read_this_round = 0; /* Will be set to false by the very first endpoint read function */ tcp->is_first_read = true; - tcp->bytes_counter = -1; - tcp->socket_ts_enabled = false; /* paired with unref in grpc_tcp_destroy */ gpr_ref_init(&tcp->refcount, 1); gpr_atm_no_barrier_store(&tcp->shutdown_count, 0); @@ -1070,19 +803,6 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, /* Tell network status tracker about new endpoint */ grpc_network_status_register_endpoint(&tcp->base); grpc_resource_quota_unref_internal(resource_quota); - gpr_mu_init(&tcp->tb_mu); - tcp->tb_head = nullptr; - /* Start being notified on errors if event engine can track errors. */ - if (grpc_event_engine_can_track_errors()) { - /* Grab a ref to tcp so that we can safely access the tcp struct when - * processing errors. We unref when we no longer want to track errors - * separately. */ - TCP_REF(tcp, "error-tracking"); - gpr_atm_rel_store(&tcp->stop_error_notification, 0); - GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, - grpc_schedule_on_exec_ctx); - grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); - } return &tcp->base; } @@ -1101,11 +821,6 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, tcp->release_fd = fd; tcp->release_fd_cb = done; grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); - if (grpc_event_engine_can_track_errors()) { - /* Stop errors notification. */ - gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); - grpc_fd_set_error(tcp->em_fd); - } TCP_UNREF(tcp, "destroy"); } diff --git a/src/core/lib/iomgr/tcp_posix.h b/src/core/lib/iomgr/tcp_posix.h index eff825cb925..af89bd24db1 100644 --- a/src/core/lib/iomgr/tcp_posix.h +++ b/src/core/lib/iomgr/tcp_posix.h @@ -31,10 +31,7 @@ #include -#include "src/core/lib/iomgr/port.h" - #include "src/core/lib/debug/trace.h" -#include "src/core/lib/iomgr/buffer_list.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_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc index 824db07fbfd..8ddf684feac 100644 --- a/src/core/lib/iomgr/tcp_server_posix.cc +++ b/src/core/lib/iomgr/tcp_server_posix.cc @@ -226,7 +226,7 @@ static void on_read(void* arg, grpc_error* err) { gpr_log(GPR_INFO, "SERVER_CONNECT: incoming connection: %s", addr_str); } - grpc_fd* fdobj = grpc_fd_create(fd, name, true); + grpc_fd* fdobj = grpc_fd_create(fd, name, false); read_notifier_pollset = sp->server->pollsets[static_cast(gpr_atm_no_barrier_fetch_add( @@ -362,7 +362,7 @@ static grpc_error* clone_port(grpc_tcp_listener* listener, unsigned count) { listener->sibling = sp; sp->server = listener->server; sp->fd = fd; - sp->emfd = grpc_fd_create(fd, name, true); + sp->emfd = grpc_fd_create(fd, name, false); memcpy(&sp->addr, &listener->addr, sizeof(grpc_resolved_address)); sp->port = port; sp->port_index = listener->port_index; 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 9595c028ce0..b9f81455729 100644 --- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc @@ -105,7 +105,7 @@ static grpc_error* add_socket_to_server(grpc_tcp_server* s, int fd, s->tail = sp; sp->server = s; sp->fd = fd; - sp->emfd = grpc_fd_create(fd, name, true); + sp->emfd = grpc_fd_create(fd, name, false); memcpy(&sp->addr, addr, sizeof(grpc_resolved_address)); sp->port = port; sp->port_index = port_index; diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index 64c4a56ae95..b3cb442f18f 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -296,7 +296,7 @@ static void on_write(void* tcpp, grpc_error* error) { /* Initiates a write. */ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* arg) { + grpc_closure* cb) { grpc_tcp* tcp = (grpc_tcp*)ep; grpc_winsocket* socket = tcp->socket; grpc_winsocket_callback_info* info = &socket->write_info; diff --git a/src/core/lib/iomgr/udp_server.cc b/src/core/lib/iomgr/udp_server.cc index 3dd7cab855c..bdb2d0e7644 100644 --- a/src/core/lib/iomgr/udp_server.cc +++ b/src/core/lib/iomgr/udp_server.cc @@ -152,7 +152,7 @@ GrpcUdpListener::GrpcUdpListener(grpc_udp_server* server, int fd, grpc_sockaddr_to_string(&addr_str, addr, 1); gpr_asprintf(&name, "udp-server-listener:%s", addr_str); gpr_free(addr_str); - emfd_ = grpc_fd_create(fd, name, true); + emfd_ = grpc_fd_create(fd, name, false); memcpy(&addr_, addr, sizeof(grpc_resolved_address)); GPR_ASSERT(emfd_); gpr_free(name); diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc index f40f969bb7f..840b2e73bcf 100644 --- a/src/core/lib/security/transport/secure_endpoint.cc +++ b/src/core/lib/security/transport/secure_endpoint.cc @@ -254,7 +254,7 @@ static void flush_write_staging_buffer(secure_endpoint* ep, uint8_t** cur, } static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* arg) { + grpc_closure* cb) { GPR_TIMER_SCOPE("secure_endpoint.endpoint_write", 0); unsigned i; @@ -342,7 +342,7 @@ static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, return; } - grpc_endpoint_write(ep->wrapped_ep, &ep->output_buffer, cb, arg); + grpc_endpoint_write(ep->wrapped_ep, &ep->output_buffer, cb); } static void endpoint_shutdown(grpc_endpoint* secure_ep, grpc_error* why) { diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index d76d5826388..aff723ed044 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -259,7 +259,7 @@ static grpc_error* on_handshake_next_done_locked( grpc_slice_buffer_reset_and_unref_internal(&h->outgoing); grpc_slice_buffer_add(&h->outgoing, to_send); grpc_endpoint_write(h->args->endpoint, &h->outgoing, - &h->on_handshake_data_sent_to_peer, nullptr); + &h->on_handshake_data_sent_to_peer); } else if (handshaker_result == nullptr) { // There is nothing to send, but need to read from peer. grpc_endpoint_read(h->args->endpoint, h->args->read_buffer, diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 0f68e823d79..6e6d756eec7 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -82,7 +82,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', - 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -103,7 +102,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', - 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc index ade23133c55..c03ebcf4096 100644 --- a/test/core/bad_client/bad_client.cc +++ b/test/core/bad_client/bad_client.cc @@ -115,7 +115,7 @@ void grpc_run_client_side_validator(grpc_bad_client_arg* arg, uint32_t flags, grpc_schedule_on_exec_ctx); /* Write data */ - grpc_endpoint_write(sfd->client, &outgoing, &done_write_closure, nullptr); + grpc_endpoint_write(sfd->client, &outgoing, &done_write_closure); grpc_core::ExecCtx::Get()->Flush(); /* Await completion, unless the request is large and write may not finish diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index f7396a16845..3d133cfc186 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -104,7 +104,7 @@ static void handle_write() { grpc_slice_buffer_reset_and_unref(&state.outgoing_buffer); grpc_slice_buffer_add(&state.outgoing_buffer, slice); - grpc_endpoint_write(state.tcp, &state.outgoing_buffer, &on_write, nullptr); + grpc_endpoint_write(state.tcp, &state.outgoing_buffer, &on_write); } static void handle_read(void* arg, grpc_error* error) { diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index ea9c000efb9..f02fa9d9983 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -201,7 +201,7 @@ static void on_client_write_done(void* arg, grpc_error* error) { &conn->client_write_buffer); conn->client_is_writing = true; grpc_endpoint_write(conn->client_endpoint, &conn->client_write_buffer, - &conn->on_client_write_done, nullptr); + &conn->on_client_write_done); } else { // No more writes. Unref the connection. proxy_connection_unref(conn, "write_done"); @@ -226,7 +226,7 @@ static void on_server_write_done(void* arg, grpc_error* error) { &conn->server_write_buffer); conn->server_is_writing = true; grpc_endpoint_write(conn->server_endpoint, &conn->server_write_buffer, - &conn->on_server_write_done, nullptr); + &conn->on_server_write_done); } else { // No more writes. Unref the connection. proxy_connection_unref(conn, "server_write"); @@ -257,7 +257,7 @@ static void on_client_read_done(void* arg, grpc_error* error) { proxy_connection_ref(conn, "client_read"); conn->server_is_writing = true; grpc_endpoint_write(conn->server_endpoint, &conn->server_write_buffer, - &conn->on_server_write_done, nullptr); + &conn->on_server_write_done); } // Read more data. grpc_endpoint_read(conn->client_endpoint, &conn->client_read_buffer, @@ -288,7 +288,7 @@ static void on_server_read_done(void* arg, grpc_error* error) { proxy_connection_ref(conn, "server_read"); conn->client_is_writing = true; grpc_endpoint_write(conn->client_endpoint, &conn->client_write_buffer, - &conn->on_client_write_done, nullptr); + &conn->on_client_write_done); } // Read more data. grpc_endpoint_read(conn->server_endpoint, &conn->server_read_buffer, @@ -340,7 +340,7 @@ static void on_server_connect_done(void* arg, grpc_error* error) { grpc_slice_buffer_add(&conn->client_write_buffer, slice); conn->client_is_writing = true; grpc_endpoint_write(conn->client_endpoint, &conn->client_write_buffer, - &conn->on_write_response_done, nullptr); + &conn->on_write_response_done); } /** diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 675d9e6278c..002671a5fae 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -246,19 +246,6 @@ grpc_cc_test( ], ) -grpc_cc_test( - name = "buffer_list_test", - srcs = ["buffer_list_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//:grpc", - "//test/core/util:gpr_test_util", - "//test/core/util:grpc_test_util", - ], -) - - grpc_cc_test( name = "tcp_server_posix_test", srcs = ["tcp_server_posix_test.cc"], diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc deleted file mode 100644 index f1773580bd2..00000000000 --- a/test/core/iomgr/buffer_list_test.cc +++ /dev/null @@ -1,111 +0,0 @@ -/* - * - * 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 "src/core/lib/iomgr/port.h" - -#include "src/core/lib/iomgr/buffer_list.h" - -#include - -#include "test/core/util/test_config.h" - -#ifdef GRPC_LINUX_ERRQUEUE - -static void TestShutdownFlushesListVerifier(void* arg, - grpc_core::Timestamps* ts, - grpc_error* error) { - GPR_ASSERT(error == GRPC_ERROR_NONE); - GPR_ASSERT(arg != nullptr); - gpr_atm* done = reinterpret_cast(arg); - gpr_atm_rel_store(done, static_cast(1)); -} - -/** Tests that all TracedBuffer elements in the list are flushed out on - * shutdown. - * Also tests that arg is passed correctly. - */ -static void TestShutdownFlushesList() { - grpc_core::grpc_tcp_set_write_timestamps_callback( - TestShutdownFlushesListVerifier); - grpc_core::TracedBuffer* list = nullptr; -#define NUM_ELEM 5 - gpr_atm verifier_called[NUM_ELEM]; - for (auto i = 0; i < NUM_ELEM; i++) { - gpr_atm_rel_store(&verifier_called[i], static_cast(0)); - grpc_core::TracedBuffer::AddNewEntry( - &list, i, static_cast(&verifier_called[i])); - } - grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE); - GPR_ASSERT(list == nullptr); - for (auto i = 0; i < NUM_ELEM; i++) { - GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) == - static_cast(1)); - } -} - -static void TestVerifierCalledOnAckVerifier(void* arg, - grpc_core::Timestamps* ts, - grpc_error* error) { - GPR_ASSERT(error == GRPC_ERROR_NONE); - GPR_ASSERT(arg != nullptr); - GPR_ASSERT(ts->acked_time.clock_type == GPR_CLOCK_REALTIME); - GPR_ASSERT(ts->acked_time.tv_sec == 123); - GPR_ASSERT(ts->acked_time.tv_nsec == 456); - gpr_atm* done = reinterpret_cast(arg); - gpr_atm_rel_store(done, static_cast(1)); -} - -/** Tests that the timestamp verifier is called on an ACK timestamp. - */ -static void TestVerifierCalledOnAck() { - struct sock_extended_err serr; - serr.ee_data = 213; - serr.ee_info = SCM_TSTAMP_ACK; - struct scm_timestamping tss; - tss.ts[0].tv_sec = 123; - tss.ts[0].tv_nsec = 456; - grpc_core::grpc_tcp_set_write_timestamps_callback( - TestVerifierCalledOnAckVerifier); - grpc_core::TracedBuffer* list = nullptr; - gpr_atm verifier_called; - gpr_atm_rel_store(&verifier_called, static_cast(0)); - grpc_core::TracedBuffer::AddNewEntry(&list, 213, &verifier_called); - grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, &tss); - GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast(1)); - GPR_ASSERT(list == nullptr); - grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE); -} - -static void TestTcpBufferList() { - TestVerifierCalledOnAck(); - TestShutdownFlushesList(); -} - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - grpc_init(); - TestTcpBufferList(); - grpc_shutdown(); - return 0; -} - -#else /* GRPC_LINUX_ERRQUEUE */ - -int main(int argc, char** argv) { return 0; } - -#endif /* GRPC_LINUX_ERRQUEUE */ diff --git a/test/core/iomgr/endpoint_tests.cc b/test/core/iomgr/endpoint_tests.cc index a9e8ba86c5d..8db8ac5ed6f 100644 --- a/test/core/iomgr/endpoint_tests.cc +++ b/test/core/iomgr/endpoint_tests.cc @@ -150,8 +150,8 @@ static void read_and_write_test_write_handler(void* data, grpc_error* error) { &state->current_write_data); grpc_slice_buffer_reset_and_unref(&state->outgoing); grpc_slice_buffer_addn(&state->outgoing, slices, nslices); - grpc_endpoint_write(state->write_ep, &state->outgoing, &state->done_write, - nullptr); + grpc_endpoint_write(state->write_ep, &state->outgoing, + &state->done_write); gpr_free(slices); return; } @@ -294,8 +294,7 @@ static void multiple_shutdown_test(grpc_endpoint_test_config config) { grpc_slice_buffer_add(&slice_buffer, grpc_slice_from_copied_string("a")); grpc_endpoint_write(f.client_ep, &slice_buffer, GRPC_CLOSURE_CREATE(inc_on_failure, &fail_count, - grpc_schedule_on_exec_ctx), - nullptr); + grpc_schedule_on_exec_ctx)); wait_for_fail_count(&fail_count, 3); grpc_endpoint_shutdown(f.client_ep, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown")); diff --git a/test/core/iomgr/tcp_posix_test.cc b/test/core/iomgr/tcp_posix_test.cc index 6447cc234db..3e87831e440 100644 --- a/test/core/iomgr/tcp_posix_test.cc +++ b/test/core/iomgr/tcp_posix_test.cc @@ -36,9 +36,6 @@ #include #include "src/core/lib/gpr/useful.h" -#include "src/core/lib/iomgr/buffer_list.h" -#include "src/core/lib/iomgr/ev_posix.h" -#include "src/core/lib/iomgr/sockaddr_posix.h" #include "src/core/lib/slice/slice_internal.h" #include "test/core/iomgr/endpoint_tests.h" #include "test/core/util/test_config.h" @@ -71,43 +68,6 @@ static void create_sockets(int sv[2]) { GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0); } -static void create_inet_sockets(int sv[2]) { - /* Prepare listening socket */ - struct sockaddr_in addr; - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - int sock = socket(AF_INET, SOCK_STREAM, 0); - GPR_ASSERT(sock); - GPR_ASSERT(bind(sock, (sockaddr*)&addr, sizeof(sockaddr_in)) == 0); - listen(sock, 1); - - /* Prepare client socket and connect to server */ - socklen_t len = sizeof(sockaddr_in); - GPR_ASSERT(getsockname(sock, (sockaddr*)&addr, &len) == 0); - - int client = socket(AF_INET, SOCK_STREAM, 0); - GPR_ASSERT(client); - int ret; - do { - ret = connect(client, (sockaddr*)&addr, sizeof(sockaddr_in)); - } while (ret == -1 && errno == EINTR); - - /* Accept client connection */ - len = sizeof(socklen_t); - int server; - do { - server = accept(sock, (sockaddr*)&addr, (socklen_t*)&len); - } while (server == -1 && errno == EINTR); - GPR_ASSERT(server != -1); - - sv[0] = server; - sv[1] = client; - int flags = fcntl(sv[0], F_GETFL, 0); - GPR_ASSERT(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK) == 0); - flags = fcntl(sv[1], F_GETFL, 0); - GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0); -} - static ssize_t fill_socket(int fd) { ssize_t write_bytes; ssize_t total_bytes = 0; @@ -329,10 +289,11 @@ static grpc_slice* allocate_blocks(size_t num_bytes, size_t slice_size, static void write_done(void* user_data /* write_socket_state */, grpc_error* error) { - GPR_ASSERT(error == GRPC_ERROR_NONE); struct write_socket_state* state = static_cast(user_data); + gpr_log(GPR_INFO, "Write done callback called"); gpr_mu_lock(g_mu); + gpr_log(GPR_INFO, "Signalling write done"); state->write_done = 1; GPR_ASSERT( GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr))); @@ -379,24 +340,10 @@ void drain_socket_blocking(int fd, size_t num_bytes, size_t read_size) { gpr_free(buf); } -/* Verifier for timestamps callback for write_test */ -void timestamps_verifier(void* arg, grpc_core::Timestamps* ts, - grpc_error* error) { - GPR_ASSERT(error == GRPC_ERROR_NONE); - GPR_ASSERT(arg != nullptr); - GPR_ASSERT(ts->sendmsg_time.clock_type == GPR_CLOCK_REALTIME); - GPR_ASSERT(ts->scheduled_time.clock_type == GPR_CLOCK_REALTIME); - GPR_ASSERT(ts->acked_time.clock_type == GPR_CLOCK_REALTIME); - gpr_atm* done_timestamps = (gpr_atm*)arg; - gpr_atm_rel_store(done_timestamps, static_cast(1)); -} - /* Write to a socket using the grpc_tcp API, then drain it directly. Note that if the write does not complete immediately we need to drain the - socket in parallel with the read. If collect_timestamps is true, it will - try to get timestamps for the write. */ -static void write_test(size_t num_bytes, size_t slice_size, - bool collect_timestamps) { + socket in parallel with the read. */ +static void write_test(size_t num_bytes, size_t slice_size) { int sv[2]; grpc_endpoint* ep; struct write_socket_state state; @@ -409,27 +356,19 @@ static void write_test(size_t num_bytes, size_t slice_size, grpc_timespec_to_millis_round_up(grpc_timeout_seconds_to_deadline(20)); grpc_core::ExecCtx exec_ctx; - if (collect_timestamps && !grpc_event_engine_can_track_errors()) { - return; - } - gpr_log(GPR_INFO, "Start write test with %" PRIuPTR " bytes, slice size %" PRIuPTR, num_bytes, slice_size); - if (collect_timestamps) { - create_inet_sockets(sv); - } else { - create_sockets(sv); - } + create_sockets(sv); grpc_arg a[1]; a[0].key = const_cast(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER, a[0].value.integer = static_cast(slice_size); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; - ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test", collect_timestamps), - &args, "test"); + ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test", false), &args, + "test"); grpc_endpoint_add_to_pollset(ep, g_pollset); state.ep = ep; @@ -442,26 +381,18 @@ static void write_test(size_t num_bytes, size_t slice_size, GRPC_CLOSURE_INIT(&write_done_closure, write_done, &state, grpc_schedule_on_exec_ctx); - gpr_atm done_timestamps; - gpr_atm_rel_store(&done_timestamps, static_cast(0)); - grpc_endpoint_write(ep, &outgoing, &write_done_closure, - grpc_event_engine_can_track_errors() && collect_timestamps - ? (void*)&done_timestamps - : nullptr); + grpc_endpoint_write(ep, &outgoing, &write_done_closure); drain_socket_blocking(sv[0], num_bytes, num_bytes); - exec_ctx.Flush(); gpr_mu_lock(g_mu); for (;;) { grpc_pollset_worker* worker = nullptr; - if (state.write_done && - (!(grpc_event_engine_can_track_errors() && collect_timestamps) || - gpr_atm_acq_load(&done_timestamps) == static_cast(1))) { + if (state.write_done) { break; } GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(g_pollset, &worker, deadline))); gpr_mu_unlock(g_mu); - exec_ctx.Flush(); + gpr_mu_lock(g_mu); } gpr_mu_unlock(g_mu); @@ -566,21 +497,14 @@ void run_tests(void) { large_read_test(8192); large_read_test(1); - write_test(100, 8192, false); - write_test(100, 1, false); - write_test(100000, 8192, false); - write_test(100000, 1, false); - write_test(100000, 137, false); - - write_test(100, 8192, true); - write_test(100, 1, true); - write_test(100000, 8192, true); - write_test(100000, 1, true); - write_test(100, 137, true); + write_test(100, 8192); + write_test(100, 1); + write_test(100000, 8192); + write_test(100000, 1); + write_test(100000, 137); for (i = 1; i < 1000; i = GPR_MAX(i + 1, i * 5 / 4)) { - write_test(40320, i, false); - write_test(40320, i, true); + write_test(40320, i); } release_fd_test(100, 8192); @@ -625,7 +549,6 @@ int main(int argc, char** argv) { grpc_closure destroyed; grpc_test_init(argc, argv); grpc_init(); - grpc_core::grpc_tcp_set_write_timestamps_callback(timestamps_verifier); { grpc_core::ExecCtx exec_ctx; g_pollset = static_cast(gpr_zalloc(grpc_pollset_size())); diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc index ef6fd62b516..1156cd5fc5c 100644 --- a/test/core/util/mock_endpoint.cc +++ b/test/core/util/mock_endpoint.cc @@ -55,7 +55,7 @@ static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, } static void me_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* arg) { + grpc_closure* cb) { mock_endpoint* m = reinterpret_cast(ep); for (size_t i = 0; i < slices->count; i++) { m->on_write(slices->slices[i]); diff --git a/test/core/util/passthru_endpoint.cc b/test/core/util/passthru_endpoint.cc index 3cc8ad6fe14..59582167478 100644 --- a/test/core/util/passthru_endpoint.cc +++ b/test/core/util/passthru_endpoint.cc @@ -76,7 +76,7 @@ static half* other_half(half* h) { } static void me_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* arg) { + grpc_closure* cb) { half* m = other_half(reinterpret_cast(ep)); gpr_mu_lock(&m->parent->mu); grpc_error* error = GRPC_ERROR_NONE; diff --git a/test/core/util/trickle_endpoint.cc b/test/core/util/trickle_endpoint.cc index 62ed72a6295..f2efb049b49 100644 --- a/test/core/util/trickle_endpoint.cc +++ b/test/core/util/trickle_endpoint.cc @@ -62,7 +62,7 @@ static void maybe_call_write_cb_locked(trickle_endpoint* te) { } static void te_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* arg) { + grpc_closure* cb) { trickle_endpoint* te = reinterpret_cast(ep); gpr_mu_lock(&te->mu); GPR_ASSERT(te->write_cb == nullptr); @@ -186,8 +186,7 @@ size_t grpc_trickle_endpoint_trickle(grpc_endpoint* ep) { te->last_write = now; grpc_endpoint_write( te->wrapped, &te->writing_buffer, - GRPC_CLOSURE_CREATE(te_finish_write, te, grpc_schedule_on_exec_ctx), - nullptr); + GRPC_CLOSURE_CREATE(te_finish_write, te, grpc_schedule_on_exec_ctx)); maybe_call_write_cb_locked(te); } } diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index 189923a841e..1e9bd273aaf 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -96,7 +96,7 @@ class DummyEndpoint : public grpc_endpoint { } static void write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb, void* arg) { + grpc_closure* cb) { GRPC_CLOSURE_SCHED(cb, GRPC_ERROR_NONE); } diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index e6d4b1d98fb..43ebf8cad95 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1067,7 +1067,6 @@ src/core/lib/http/format_request.h \ src/core/lib/http/httpcli.h \ src/core/lib/http/parser.h \ src/core/lib/iomgr/block_annotate.h \ -src/core/lib/iomgr/buffer_list.h \ src/core/lib/iomgr/call_combiner.h \ src/core/lib/iomgr/closure.h \ src/core/lib/iomgr/combiner.h \ @@ -1083,7 +1082,6 @@ src/core/lib/iomgr/ev_posix.h \ src/core/lib/iomgr/exec_ctx.h \ src/core/lib/iomgr/executor.h \ src/core/lib/iomgr/gethostname.h \ -src/core/lib/iomgr/internal_errqueue.h \ src/core/lib/iomgr/iocp_windows.h \ src/core/lib/iomgr/iomgr.h \ src/core/lib/iomgr/iomgr_custom.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 7cd1dc7bf37..c1706fd070b 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1159,8 +1159,6 @@ src/core/lib/http/parser.cc \ src/core/lib/http/parser.h \ src/core/lib/iomgr/README.md \ src/core/lib/iomgr/block_annotate.h \ -src/core/lib/iomgr/buffer_list.cc \ -src/core/lib/iomgr/buffer_list.h \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/call_combiner.h \ src/core/lib/iomgr/closure.h \ @@ -1196,8 +1194,6 @@ src/core/lib/iomgr/gethostname.h \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ -src/core/lib/iomgr/internal_errqueue.cc \ -src/core/lib/iomgr/internal_errqueue.h \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iocp_windows.h \ src/core/lib/iomgr/iomgr.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8ea5126fdef..5014aea9cd0 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -163,23 +163,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "gpr", - "gpr_test_util", - "grpc", - "grpc_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "buffer_list_test", - "src": [ - "test/core/iomgr/buffer_list_test.cc" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "gpr", @@ -9505,7 +9488,6 @@ "src/core/lib/http/format_request.cc", "src/core/lib/http/httpcli.cc", "src/core/lib/http/parser.cc", - "src/core/lib/iomgr/buffer_list.cc", "src/core/lib/iomgr/call_combiner.cc", "src/core/lib/iomgr/combiner.cc", "src/core/lib/iomgr/endpoint.cc", @@ -9526,7 +9508,6 @@ "src/core/lib/iomgr/gethostname_fallback.cc", "src/core/lib/iomgr/gethostname_host_name_max.cc", "src/core/lib/iomgr/gethostname_sysconf.cc", - "src/core/lib/iomgr/internal_errqueue.cc", "src/core/lib/iomgr/iocp_windows.cc", "src/core/lib/iomgr/iomgr.cc", "src/core/lib/iomgr/iomgr_custom.cc", @@ -9686,7 +9667,6 @@ "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", "src/core/lib/iomgr/block_annotate.h", - "src/core/lib/iomgr/buffer_list.h", "src/core/lib/iomgr/call_combiner.h", "src/core/lib/iomgr/closure.h", "src/core/lib/iomgr/combiner.h", @@ -9702,7 +9682,6 @@ "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", - "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", "src/core/lib/iomgr/iomgr_custom.h", @@ -9838,7 +9817,6 @@ "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", "src/core/lib/iomgr/block_annotate.h", - "src/core/lib/iomgr/buffer_list.h", "src/core/lib/iomgr/call_combiner.h", "src/core/lib/iomgr/closure.h", "src/core/lib/iomgr/combiner.h", @@ -9854,7 +9832,6 @@ "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", - "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", "src/core/lib/iomgr/iomgr_custom.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index fba76d69d1e..51c7b57d8ae 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -195,26 +195,6 @@ ], "uses_polling": false }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "gtest": false, - "language": "c", - "name": "buffer_list_test", - "platforms": [ - "linux" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, From 2fa4d430a6f0937ac829b28bb28671c4811cc833 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 27 Aug 2018 10:03:03 -0700 Subject: [PATCH 222/546] attempt on fixing the bazel location bug --- bazel/grpc_build_system.bzl | 329 +++++++++++++++++++----------------- 1 file changed, 177 insertions(+), 152 deletions(-) diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index 73147bf3ac9..b3f97650e8c 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -24,178 +24,203 @@ # # The set of pollers to test against if a test exercises polling -POLLERS = ['epollex', 'epollsig', 'epoll1', 'poll', 'poll-cv'] +POLLERS = ["epollex", "epollsig", "epoll1", "poll", "poll-cv"] def if_not_windows(a): - return select({ - "//:windows": [], - "//:windows_msvc": [], - "//conditions:default": a, - }) + return select({ + "//:windows": [], + "//:windows_msvc": [], + "//conditions:default": a, + }) def _get_external_deps(external_deps): - ret = [] - for dep in external_deps: - if dep == "address_sorting": - ret += ["//third_party/address_sorting"] - elif dep == "cares": - ret += select({"//:grpc_no_ares": [], - "//conditions:default": ["//external:cares"],}) - else: - ret += ["//external:" + dep] - return ret + ret = [] + for dep in external_deps: + if dep == "address_sorting": + ret += ["//third_party/address_sorting"] + elif dep == "cares": + ret += select({ + "//:grpc_no_ares": [], + "//conditions:default": ["//external:cares"], + }) + else: + ret += ["//external:" + dep] + return ret def _maybe_update_cc_library_hdrs(hdrs): - ret = [] - hdrs_to_update = { - "third_party/objective_c/Cronet/bidirectional_stream_c.h": "//third_party:objective_c/Cronet/bidirectional_stream_c.h", - } - for h in hdrs: - if h in hdrs_to_update.keys(): - ret.append(hdrs_to_update[h]) - else: - ret.append(h) - return ret - -def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [], - external_deps = [], deps = [], standalone = False, - language = "C++", testonly = False, visibility = None, - alwayslink = 0, data = []): - copts = [] - if language.upper() == "C": - copts = if_not_windows(["-std=c99"]) - native.cc_library( - name = name, - srcs = srcs, - defines = select({"//:grpc_no_ares": ["GRPC_ARES=0"], - "//conditions:default": [],}) + - select({"//:remote_execution": ["GRPC_PORT_ISOLATED_RUNTIME=1"], - "//conditions:default": [],}) + - select({"//:grpc_allow_exceptions": ["GRPC_ALLOW_EXCEPTIONS=1"], - "//:grpc_disallow_exceptions": - ["GRPC_ALLOW_EXCEPTIONS=0"], - "//conditions:default": [],}), - hdrs = _maybe_update_cc_library_hdrs(hdrs + public_hdrs), - deps = deps + _get_external_deps(external_deps), - copts = copts, - visibility = visibility, - testonly = testonly, - linkopts = if_not_windows(["-pthread"]), - includes = [ - "include" - ], - alwayslink = alwayslink, - data = data, - ) + ret = [] + hdrs_to_update = { + "third_party/objective_c/Cronet/bidirectional_stream_c.h": "//third_party:objective_c/Cronet/bidirectional_stream_c.h", + } + for h in hdrs: + if h in hdrs_to_update.keys(): + ret.append(hdrs_to_update[h]) + else: + ret.append(h) + return ret + +def grpc_cc_library( + name, + srcs = [], + public_hdrs = [], + hdrs = [], + external_deps = [], + deps = [], + standalone = False, + language = "C++", + testonly = False, + visibility = None, + alwayslink = 0, + data = []): + copts = [] + if language.upper() == "C": + copts = if_not_windows(["-std=c99"]) + native.cc_library( + name = name, + srcs = srcs, + defines = select({ + "//:grpc_no_ares": ["GRPC_ARES=0"], + "//conditions:default": [], + }) + + select({ + "//:remote_execution": ["GRPC_PORT_ISOLATED_RUNTIME=1"], + "//conditions:default": [], + }) + + select({ + "//:grpc_allow_exceptions": ["GRPC_ALLOW_EXCEPTIONS=1"], + "//:grpc_disallow_exceptions": ["GRPC_ALLOW_EXCEPTIONS=0"], + "//conditions:default": [], + }), + hdrs = _maybe_update_cc_library_hdrs(hdrs + public_hdrs), + deps = deps + _get_external_deps(external_deps), + copts = copts, + visibility = visibility, + testonly = testonly, + linkopts = if_not_windows(["-pthread"]), + includes = [ + "include", + ], + alwayslink = alwayslink, + data = data, + ) def grpc_proto_plugin(name, srcs = [], deps = []): - native.cc_binary( - name = name, - srcs = srcs, - deps = deps, - ) + native.cc_binary( + name = name, + srcs = srcs, + deps = deps, + ) load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library") -def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = False, - has_services = True, use_external = False, generate_mocks = False): - cc_grpc_library( - name = name, - srcs = srcs, - deps = deps, - well_known_protos = well_known_protos, - proto_only = not has_services, - use_external = use_external, - generate_mocks = generate_mocks, - ) +def grpc_proto_library( + name, + srcs = [], + deps = [], + well_known_protos = False, + has_services = True, + use_external = False, + generate_mocks = False): + cc_grpc_library( + name = name, + srcs = srcs, + deps = deps, + well_known_protos = well_known_protos, + proto_only = not has_services, + use_external = use_external, + generate_mocks = generate_mocks, + ) def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = "moderate", tags = []): - copts = [] - if language.upper() == "C": - copts = if_not_windows(["-std=c99"]) - args = { - 'name': name, - 'srcs': srcs, - 'args': args, - 'data': data, - 'deps': deps + _get_external_deps(external_deps), - 'copts': copts, - 'linkopts': if_not_windows(["-pthread"]), - 'size': size, - 'timeout': timeout, - } - if uses_polling: - native.cc_test(testonly=True, tags=['manual'], **args) - for poller in POLLERS: - native.sh_test( - name = name + '@poller=' + poller, - data = [name], - srcs = [ - '//test/core/util:run_with_poller_sh', - ], - size = size, - timeout = timeout, - args = [ - poller, - '$(location %s)' % name, - ] + args['args'], - tags = tags, - ) - else: - native.cc_test(**args) + copts = [] + if language.upper() == "C": + copts = if_not_windows(["-std=c99"]) + args = { + "name": name, + "srcs": srcs, + "args": args, + "data": data, + "deps": deps + _get_external_deps(external_deps), + "copts": copts, + "linkopts": if_not_windows(["-pthread"]), + "size": size, + "timeout": timeout, + } + if uses_polling: + native.cc_test(testonly = True, tags = ["manual"], **args) + for poller in POLLERS: + native.sh_test( + name = name + "@poller=" + poller, + data = [name] + data, + srcs = [ + "//test/core/util:run_with_poller_sh", + ], + size = size, + timeout = timeout, + args = [ + poller, + "$(location %s)" % name, + ] + args["args"], + tags = tags, + ) + else: + native.cc_test(**args) def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = []): - copts = [] - if language.upper() == "C": - copts = ["-std=c99"] - native.cc_binary( - name = name, - srcs = srcs, - args = args, - data = data, - testonly = testonly, - linkshared = linkshared, - deps = deps + _get_external_deps(external_deps), - copts = copts, - linkopts = if_not_windows(["-pthread"]) + linkopts, - ) - -def grpc_generate_one_off_targets(): pass + copts = [] + if language.upper() == "C": + copts = ["-std=c99"] + native.cc_binary( + name = name, + srcs = srcs, + args = args, + data = data, + testonly = testonly, + linkshared = linkshared, + deps = deps + _get_external_deps(external_deps), + copts = copts, + linkopts = if_not_windows(["-pthread"]) + linkopts, + ) + +def grpc_generate_one_off_targets(): + pass def grpc_sh_test(name, srcs, args = [], data = []): - native.sh_test( - name = name, - srcs = srcs, - args = args, - data = data) + native.sh_test( + name = name, + srcs = srcs, + args = args, + data = data, + ) def grpc_sh_binary(name, srcs, data = []): - native.sh_binary( - name = name, - srcs = srcs, - data = data) + native.sh_binary( + name = name, + srcs = srcs, + data = data, + ) def grpc_py_binary(name, srcs, data = [], deps = [], external_deps = [], testonly = False): - native.py_binary( - name = name, - srcs = srcs, - testonly = testonly, - data = data, - deps = deps + _get_external_deps(external_deps) - ) + native.py_binary( + name = name, + srcs = srcs, + testonly = testonly, + data = data, + deps = deps + _get_external_deps(external_deps), + ) def grpc_package(name, visibility = "private", features = []): - if visibility == "tests": - visibility = ["//test:__subpackages__"] - elif visibility == "public": - visibility = ["//visibility:public"] - elif visibility == "private": - visibility = [] - else: - fail("Unknown visibility " + visibility) - - if len(visibility) != 0: - native.package( - default_visibility = visibility, - features = features - ) + if visibility == "tests": + visibility = ["//test:__subpackages__"] + elif visibility == "public": + visibility = ["//visibility:public"] + elif visibility == "private": + visibility = [] + else: + fail("Unknown visibility " + visibility) + + if len(visibility) != 0: + native.package( + default_visibility = visibility, + features = features, + ) From 654a1ea0f6806a3ff310559b44dfac8f93112e3f Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 27 Aug 2018 10:52:17 -0700 Subject: [PATCH 223/546] made timeout longer --- test/cpp/qps/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index 848a4ad87ed..bf0f6186e42 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -144,6 +144,7 @@ filegroup( grpc_cc_test( name = "json_run_localhost", + timeout = "eternal", srcs = ["json_run_localhost.cc"], args = [ "--scenarios_file", From fb704ee949047ebc1d78f00b4b7d6938f8e89a6a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 27 Aug 2018 20:39:26 +0200 Subject: [PATCH 224/546] deserialization context always has non-null payload --- src/csharp/Grpc.Core/DeserializationContext.cs | 11 +++-------- src/csharp/Grpc.Core/Marshaller.cs | 4 ++-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/csharp/Grpc.Core/DeserializationContext.cs b/src/csharp/Grpc.Core/DeserializationContext.cs index 17f0ba2805c..96de08f76d7 100644 --- a/src/csharp/Grpc.Core/DeserializationContext.cs +++ b/src/csharp/Grpc.Core/DeserializationContext.cs @@ -24,14 +24,9 @@ namespace Grpc.Core public abstract class DeserializationContext { /// - /// Returns true if there is a payload to deserialize (= payload is not null), false otherwise. + /// Get the total length of the payload in bytes. /// - public virtual bool HasPayload => PayloadLength.HasValue; - - /// - /// Get the total length of the payload in bytes or null if the payload is null. - /// - public abstract int? PayloadLength { get; } + public abstract int PayloadLength { get; } /// /// Gets the entire payload as a newly allocated byte array. @@ -43,7 +38,7 @@ namespace Grpc.Core /// the payload is more than 86700 bytes large (which means the newly allocated buffer will be placed in LOH, /// and LOH object can only be garbage collected via a full ("stop the world") GC run). /// - /// byte array containing the entire payload or null if there is no payload. + /// byte array containing the entire payload. public abstract byte[] PayloadAsNewBuffer(); } } diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core/Marshaller.cs index df59cbd8d3a..ad01b9383cd 100644 --- a/src/csharp/Grpc.Core/Marshaller.cs +++ b/src/csharp/Grpc.Core/Marshaller.cs @@ -137,10 +137,10 @@ namespace Grpc.Core public EmulatedDeserializationContext(byte[] payload) { - this.payload = payload; + this.payload = GrpcPreconditions.CheckNotNull(payload); } - public override int? PayloadLength => payload?.Length; + public override int PayloadLength => payload.Length; public override byte[] PayloadAsNewBuffer() { From 6ba637f7ecdd45bf43c1a7959115190ca5a2f5c8 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 27 Aug 2018 20:42:06 +0200 Subject: [PATCH 225/546] add Marshallers.Create factory method --- src/csharp/Grpc.Core/Marshaller.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core/Marshaller.cs index ad01b9383cd..7f010dc4192 100644 --- a/src/csharp/Grpc.Core/Marshaller.cs +++ b/src/csharp/Grpc.Core/Marshaller.cs @@ -162,6 +162,15 @@ namespace Grpc.Core return new Marshaller(serializer, deserializer); } + /// + /// Creates a marshaller from specified contextual serializer and deserializer. + /// Note: This method is part of an experimental API that can change or be removed without any prior notice. + /// + public static Marshaller Create(Action serializer, Func deserializer) + { + return new Marshaller(serializer, deserializer); + } + /// /// Returns a marshaller for string type. This is useful for testing. /// From 63322ac828c52136643159f191b7d24b5999550a Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 27 Aug 2018 14:26:45 -0700 Subject: [PATCH 226/546] Bump version to 1.16.0-dev --- BUILD | 4 ++-- build.yaml | 4 ++-- doc/g_stands_for.md | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/BUILD b/BUILD index e1b00a5cf0a..379c9a1f3ad 100644 --- a/BUILD +++ b/BUILD @@ -64,11 +64,11 @@ config_setting( ) # This should be updated along with build.yaml -g_stands_for = "glider" +g_stands_for = "gao" core_version = "6.0.0-dev" -version = "1.15.0-dev" +version = "1.16.0-dev" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index ce21068c312..edf94b1d938 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: glider - version: 1.15.0-dev + g_stands_for: gao + version: 1.16.0-dev filegroups: - name: alts_proto headers: diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md index b3ed9bd7138..c89a6cb5729 100644 --- a/doc/g_stands_for.md +++ b/doc/g_stands_for.md @@ -14,4 +14,5 @@ - 1.12 'g' stands for ['glorious'](https://github.com/grpc/grpc/tree/v1.12.x) - 1.13 'g' stands for ['gloriosa'](https://github.com/grpc/grpc/tree/v1.13.x) - 1.14 'g' stands for ['gladiolus'](https://github.com/grpc/grpc/tree/v1.14.x) -- 1.15 'g' stands for ['glider'](https://github.com/grpc/grpc/tree/master) +- 1.15 'g' stands for ['glider'](https://github.com/grpc/grpc/tree/v1.15.x) +- 1.16 'g' stands for ['gao'](https://github.com/grpc/grpc/tree/master) From 8ceb27a324b5efaf2ed096a7bbdf241295272bf5 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 27 Aug 2018 14:27:55 -0700 Subject: [PATCH 227/546] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 4 ++-- gRPC-C++.podspec | 4 ++-- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/core/lib/surface/version.cc | 2 +- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 4 ++-- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 30 files changed, 34 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a330fefc272..7672e26c442 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.15.0-dev") +set(PACKAGE_VERSION "1.16.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/") diff --git a/Makefile b/Makefile index e9a9486a3cc..2609441a956 100644 --- a/Makefile +++ b/Makefile @@ -437,8 +437,8 @@ Q = @ endif CORE_VERSION = 6.0.0-dev -CPP_VERSION = 1.15.0-dev -CSHARP_VERSION = 1.15.0-dev +CPP_VERSION = 1.16.0-dev +CSHARP_VERSION = 1.16.0-dev CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 207d7baa8f9..d5f275318b9 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,7 +23,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.15.0-dev' + # version = '1.16.0-dev' version = '0.0.3' s.version = version s.summary = 'gRPC C++ library' @@ -31,7 +31,7 @@ Pod::Spec.new do |s| s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.15.0-dev' + grpc_version = '1.16.0-dev' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f1a9bce7f2e..0b4f79ac8b1 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.15.0-dev' + version = '1.16.0-dev' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 79ec679e3aa..75fd592e756 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.15.0-dev' + version = '1.16.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 7a461e270f9..ecd786e7b30 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.15.0-dev' + version = '1.16.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 bf3f56bd549..9164b2169ab 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.15.0-dev' + version = '1.16.0-dev' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 1bdf127c36a..cb1978e2ab2 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.15.0dev - 1.15.0dev + 1.16.0dev + 1.16.0dev beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index e92fe2c5a15..a44f9acdc30 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -25,4 +25,4 @@ const char* grpc_version_string(void) { return "6.0.0-dev"; } -const char* grpc_g_stands_for(void) { return "glider"; } +const char* grpc_g_stands_for(void) { return "gao"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index b8fca9a6ee3..cc797f15467 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.15.0-dev"; } +grpc::string Version() { return "1.16.0-dev"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 45bd8ebd855..18515ea1e8e 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.15.0-dev + 1.16.0-dev 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 295e0f2577b..55d09dda7ab 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.15.0.0"; + public const string CurrentAssemblyFileVersion = "1.16.0.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.15.0-dev"; + public const string CurrentVersion = "1.16.0-dev"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 8f38f0aa204..24d016104c8 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.15.0-dev +set VERSION=1.16.0-dev @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 9c53114b849..4e7ac4e4145 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.15.0-dev +set VERSION=1.16.0-dev @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 5e9a9a45131..200cee5b7b3 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.15.0-dev' + v = '1.16.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/private/version.h b/src/objective-c/GRPCClient/private/version.h index 52fe0dd0502..38862e102a2 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.15.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.16.0-dev" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index d532eed245d..82833102ad1 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.15.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.16.0-dev" #define GRPC_C_VERSION_STRING @"6.0.0-dev" diff --git a/src/php/composer.json b/src/php/composer.json index 91913d73d29..f31423f8c0a 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.15.0", + "version": "1.16.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 99dd9d68f05..469a48e7823 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.15.0dev" +#define PHP_GRPC_VERSION "1.16.0dev" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index c33911ebc1b..24e1557578d 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.15.0.dev0""" +__version__ = """1.16.0.dev0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 9337800a332..6ffe1eb8270 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.15.0.dev0' +VERSION = '1.16.0.dev0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 3b84f7a4c55..e080bf2cbc5 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.15.0.dev0' +VERSION = '1.16.0.dev0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 7b0e48ea23b..4b3b95fee93 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.15.0.dev0' +VERSION = '1.16.0.dev0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index df9953fa257..c12aa153a41 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.15.0.dev0' +VERSION = '1.16.0.dev0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index b2cf129e4fb..f4b8a34a46d 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.15.0.dev0' +VERSION = '1.16.0.dev0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 5c21a5b1685..0c3e1ef734d 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.15.0.dev' + VERSION = '1.16.0.dev' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 1b5e2c362be..03d977c0643 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.15.0.dev' + VERSION = '1.16.0.dev' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index ccb69a8ebcb..581dab3b4e9 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.15.0.dev0' +VERSION = '1.16.0.dev0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 688c271feac..9a97ee84f2c 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.15.0-dev +PROJECT_NUMBER = 1.16.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 43ebf8cad95..de1f48d3692 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.15.0-dev +PROJECT_NUMBER = 1.16.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 From 82af30de3493a6bd5c95efbfa0e0a9931f8f12ae Mon Sep 17 00:00:00 2001 From: Adele Zhou Date: Mon, 27 Aug 2018 14:27:55 -0700 Subject: [PATCH 228/546] Switch to use the default instance. --- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 1 + tools/internal_ci/linux/grpc_msan_on_foundry.sh | 1 + tools/internal_ci/linux/grpc_ubsan_on_foundry.sh | 1 + tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh | 1 + 4 files changed, 4 insertions(+) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 6419030bbb2..b35e6102fc6 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -56,6 +56,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ + --remote_instance_name=grpc-testing/instances/default_instance \ $1 \ -- //test/... || FAILED="true" diff --git a/tools/internal_ci/linux/grpc_msan_on_foundry.sh b/tools/internal_ci/linux/grpc_msan_on_foundry.sh index 7d11719ea4a..dc766b883de 100644 --- a/tools/internal_ci/linux/grpc_msan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_msan_on_foundry.sh @@ -65,6 +65,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ + --remote_instance_name=grpc-testing/instances/default_instance \ -- //test/... || FAILED="true" # Sleep to let ResultStore finish writing results before querying diff --git a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh index 1eda166620c..ad3e28a3940 100644 --- a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh @@ -62,6 +62,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ --cache_test_results=no \ + --remote_instance_name=grpc-testing/instances/default_instance \ -- //test/... || FAILED="true" # Sleep to let ResultStore finish writing results before querying diff --git a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh index ffe644a48b4..5426ca56f7e 100644 --- a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh @@ -61,6 +61,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ + --remote_instance_name=grpc-testing/instances/default_instance \ -- //test/... || FAILED="true" if [ "$FAILED" != "" ] From abb74eaf02e4e3c300b5bb745828792b3ffeaf45 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 27 Aug 2018 14:43:48 -0700 Subject: [PATCH 229/546] Bump version to v1.15.0-pre1 --- BUILD | 4 ++-- build.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BUILD b/BUILD index e1b00a5cf0a..7d2bf2a78be 100644 --- a/BUILD +++ b/BUILD @@ -66,9 +66,9 @@ config_setting( # This should be updated along with build.yaml g_stands_for = "glider" -core_version = "6.0.0-dev" +core_version = "6.0.0-pre1" -version = "1.15.0-dev" +version = "1.15.0-pre1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index ce21068c312..7176c549a73 100644 --- a/build.yaml +++ b/build.yaml @@ -12,9 +12,9 @@ settings: '#08': Use "-preN" suffixes to identify pre-release versions '#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 + core_version: 6.0.0-pre1 g_stands_for: glider - version: 1.15.0-dev + version: 1.15.0-pre1 filegroups: - name: alts_proto headers: From 89659e29257f788b0a1089bfd50bfb966632508a Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 27 Aug 2018 14:45:50 -0700 Subject: [PATCH 230/546] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 6 +++--- gRPC-C++.podspec | 4 ++-- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/core/lib/surface/version.cc | 2 +- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 2 +- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_unitypackage.bat | 2 +- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 4 ++-- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- tools/doxygen/Doxyfile.core | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- 31 files changed, 36 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a330fefc272..acd17ebdc82 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.15.0-dev") +set(PACKAGE_VERSION "1.15.0-pre1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index e9a9486a3cc..7027b5862c5 100644 --- a/Makefile +++ b/Makefile @@ -436,9 +436,9 @@ E = @echo Q = @ endif -CORE_VERSION = 6.0.0-dev -CPP_VERSION = 1.15.0-dev -CSHARP_VERSION = 1.15.0-dev +CORE_VERSION = 6.0.0-pre1 +CPP_VERSION = 1.15.0-pre1 +CSHARP_VERSION = 1.15.0-pre1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 207d7baa8f9..9f61632ffa8 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -23,7 +23,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-C++' # TODO (mxyan): use version that match gRPC version when pod is stabilized - # version = '1.15.0-dev' + # version = '1.15.0-pre1' version = '0.0.3' s.version = version s.summary = 'gRPC C++ library' @@ -31,7 +31,7 @@ Pod::Spec.new do |s| s.license = 'Apache License, Version 2.0' s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } - grpc_version = '1.15.0-dev' + grpc_version = '1.15.0-pre1' s.source = { :git => 'https://github.com/grpc/grpc.git', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f1a9bce7f2e..509c0ed6a08 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -22,7 +22,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '1.15.0-dev' + version = '1.15.0-pre1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 79ec679e3aa..029e64e4962 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '1.15.0-dev' + version = '1.15.0-pre1' 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 7a461e270f9..e9bf60dd6f9 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -21,7 +21,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '1.15.0-dev' + version = '1.15.0-pre1' 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 bf3f56bd549..5692320c8e5 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.15.0-dev' + version = '1.15.0-pre1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 1bdf127c36a..49aae9dd00f 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-19 - 1.15.0dev - 1.15.0dev + 1.15.0RC1 + 1.15.0RC1 beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index e92fe2c5a15..478865015c0 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -23,6 +23,6 @@ #include -const char* grpc_version_string(void) { return "6.0.0-dev"; } +const char* grpc_version_string(void) { return "6.0.0-pre1"; } const char* grpc_g_stands_for(void) { return "glider"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index b8fca9a6ee3..577b6ffa915 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.15.0-dev"; } +grpc::string Version() { return "1.15.0-pre1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 45bd8ebd855..0e3c47fe807 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.15.0-dev + 1.15.0-pre1 3.6.1 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index 295e0f2577b..af37cfc971a 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.15.0-dev"; + public const string CurrentVersion = "1.15.0-pre1"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 8f38f0aa204..d3c19bec385 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.15.0-dev +set VERSION=1.15.0-pre1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat index 9c53114b849..b2dc6e46e57 100644 --- a/src/csharp/build_unitypackage.bat +++ b/src/csharp/build_unitypackage.bat @@ -13,7 +13,7 @@ @rem limitations under the License. @rem Current package versions -set VERSION=1.15.0-dev +set VERSION=1.15.0-pre1 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 5e9a9a45131..dfadcdc211a 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.15.0-dev' + v = '1.15.0-pre1' 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/private/version.h b/src/objective-c/GRPCClient/private/version.h index 52fe0dd0502..4cdd8653bb9 100644 --- a/src/objective-c/GRPCClient/private/version.h +++ b/src/objective-c/GRPCClient/private/version.h @@ -22,4 +22,4 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.15.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.15.0-pre1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index d532eed245d..8bd1f6c525b 100644 --- a/src/objective-c/tests/version.h +++ b/src/objective-c/tests/version.h @@ -22,5 +22,5 @@ // instead. This file can be regenerated from the template by running // `tools/buildgen/generate_projects.sh`. -#define GRPC_OBJC_VERSION_STRING @"1.15.0-dev" -#define GRPC_C_VERSION_STRING @"6.0.0-dev" +#define GRPC_OBJC_VERSION_STRING @"1.15.0-pre1" +#define GRPC_C_VERSION_STRING @"6.0.0-pre1" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 99dd9d68f05..c519809a365 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.15.0dev" +#define PHP_GRPC_VERSION "1.15.0RC1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index c33911ebc1b..e68a13c8e86 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.15.0.dev0""" +__version__ = """1.15.0rc1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 9337800a332..dd45ba66404 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.15.0.dev0' +VERSION = '1.15.0rc1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 3b84f7a4c55..33a02cf2706 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.15.0.dev0' +VERSION = '1.15.0rc1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 7b0e48ea23b..19b613c7ae9 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.15.0.dev0' +VERSION = '1.15.0rc1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index df9953fa257..5f117c6efa0 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.15.0.dev0' +VERSION = '1.15.0rc1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index b2cf129e4fb..5fd88b3ee18 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.15.0.dev0' +VERSION = '1.15.0rc1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 5c21a5b1685..8f981eeebe4 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.15.0.dev' + VERSION = '1.15.0.pre1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 1b5e2c362be..862d975e5ca 100644 --- a/src/ruby/tools/version.rb +++ b/src/ruby/tools/version.rb @@ -14,6 +14,6 @@ module GRPC module Tools - VERSION = '1.15.0.dev' + VERSION = '1.15.0.pre1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index ccb69a8ebcb..2642fe43931 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.15.0.dev0' +VERSION = '1.15.0rc1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 688c271feac..b13cf937e2d 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.15.0-dev +PROJECT_NUMBER = 1.15.0-pre1 # 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 43ebf8cad95..1578679f40e 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.15.0-dev +PROJECT_NUMBER = 1.15.0-pre1 # 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.core b/tools/doxygen/Doxyfile.core index aa75bc68283..26e7a7ccc18 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 6.0.0-dev +PROJECT_NUMBER = 6.0.0-pre1 # 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.core.internal b/tools/doxygen/Doxyfile.core.internal index c1706fd070b..094df63db75 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 6.0.0-dev +PROJECT_NUMBER = 6.0.0-pre1 # 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 From 8d47cd4992c3c3546bef23568fde5fe132144666 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 27 Aug 2018 14:56:01 -0700 Subject: [PATCH 231/546] Revert "Revert "Fathom tcp changes"" --- BUILD | 4 + CMakeLists.txt | 46 +++ Makefile | 48 +++ build.yaml | 18 + config.m4 | 2 + config.w32 | 2 + gRPC-C++.podspec | 4 + gRPC-Core.podspec | 6 + grpc.gemspec | 4 + grpc.gyp | 8 + package.xml | 4 + .../client_channel/http_connect_handshaker.cc | 2 +- .../client/insecure/channel_create_posix.cc | 2 +- .../server/insecure/server_chttp2_posix.cc | 2 +- .../chttp2/transport/chttp2_transport.cc | 3 +- src/core/lib/http/httpcli.cc | 2 +- src/core/lib/iomgr/buffer_list.cc | 134 ++++++++ src/core/lib/iomgr/buffer_list.h | 96 ++++++ src/core/lib/iomgr/endpoint.cc | 4 +- src/core/lib/iomgr/endpoint.h | 8 +- src/core/lib/iomgr/endpoint_cfstream.cc | 2 +- src/core/lib/iomgr/endpoint_pair_posix.cc | 4 +- src/core/lib/iomgr/ev_posix.cc | 9 +- src/core/lib/iomgr/internal_errqueue.cc | 40 +++ src/core/lib/iomgr/internal_errqueue.h | 62 ++++ src/core/lib/iomgr/port.h | 6 + src/core/lib/iomgr/tcp_client_posix.cc | 2 +- src/core/lib/iomgr/tcp_custom.cc | 2 +- src/core/lib/iomgr/tcp_posix.cc | 311 +++++++++++++++++- src/core/lib/iomgr/tcp_posix.h | 3 + src/core/lib/iomgr/tcp_server_posix.cc | 4 +- .../iomgr/tcp_server_utils_posix_common.cc | 2 +- src/core/lib/iomgr/tcp_windows.cc | 2 +- src/core/lib/iomgr/udp_server.cc | 2 +- .../lib/security/transport/secure_endpoint.cc | 4 +- .../security/transport/security_handshaker.cc | 2 +- src/python/grpcio/grpc_core_dependencies.py | 2 + test/core/bad_client/bad_client.cc | 2 +- test/core/end2end/bad_server_response_test.cc | 2 +- .../end2end/fixtures/http_proxy_fixture.cc | 10 +- test/core/iomgr/BUILD | 13 + test/core/iomgr/buffer_list_test.cc | 111 +++++++ test/core/iomgr/endpoint_tests.cc | 7 +- test/core/iomgr/tcp_posix_test.cc | 109 +++++- test/core/util/mock_endpoint.cc | 2 +- test/core/util/passthru_endpoint.cc | 2 +- test/core/util/trickle_endpoint.cc | 5 +- .../microbenchmarks/bm_chttp2_transport.cc | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 + tools/doxygen/Doxyfile.core.internal | 4 + .../generated/sources_and_headers.json | 23 ++ tools/run_tests/generated/tests.json | 20 ++ 52 files changed, 1104 insertions(+), 68 deletions(-) create mode 100644 src/core/lib/iomgr/buffer_list.cc create mode 100644 src/core/lib/iomgr/buffer_list.h create mode 100644 src/core/lib/iomgr/internal_errqueue.cc create mode 100644 src/core/lib/iomgr/internal_errqueue.h create mode 100644 test/core/iomgr/buffer_list_test.cc diff --git a/BUILD b/BUILD index e1b00a5cf0a..c01b971281d 100644 --- a/BUILD +++ b/BUILD @@ -696,6 +696,7 @@ grpc_cc_library( "src/core/lib/http/format_request.cc", "src/core/lib/http/httpcli.cc", "src/core/lib/http/parser.cc", + "src/core/lib/iomgr/buffer_list.cc", "src/core/lib/iomgr/call_combiner.cc", "src/core/lib/iomgr/combiner.cc", "src/core/lib/iomgr/endpoint.cc", @@ -716,6 +717,7 @@ grpc_cc_library( "src/core/lib/iomgr/gethostname_fallback.cc", "src/core/lib/iomgr/gethostname_host_name_max.cc", "src/core/lib/iomgr/gethostname_sysconf.cc", + "src/core/lib/iomgr/internal_errqueue.cc", "src/core/lib/iomgr/iocp_windows.cc", "src/core/lib/iomgr/iomgr.cc", "src/core/lib/iomgr/iomgr_custom.cc", @@ -845,6 +847,7 @@ grpc_cc_library( "src/core/lib/http/format_request.h", "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", + "src/core/lib/iomgr/buffer_list.h", "src/core/lib/iomgr/block_annotate.h", "src/core/lib/iomgr/call_combiner.h", "src/core/lib/iomgr/closure.h", @@ -862,6 +865,7 @@ grpc_cc_library( "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", "src/core/lib/iomgr/gevent_util.h", + "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", "src/core/lib/iomgr/iomgr_custom.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index a330fefc272..3895d4c0f17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -230,6 +230,9 @@ add_dependencies(buildtests_c avl_test) add_dependencies(buildtests_c bad_server_response_test) add_dependencies(buildtests_c bin_decoder_test) add_dependencies(buildtests_c bin_encoder_test) +if(_gRPC_PLATFORM_LINUX) +add_dependencies(buildtests_c buffer_list_test) +endif() add_dependencies(buildtests_c channel_create_test) add_dependencies(buildtests_c chttp2_hpack_encoder_test) add_dependencies(buildtests_c chttp2_stream_map_test) @@ -959,6 +962,7 @@ add_library(grpc src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -979,6 +983,7 @@ add_library(grpc src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -1365,6 +1370,7 @@ add_library(grpc_cronet src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -1385,6 +1391,7 @@ add_library(grpc_cronet src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -1757,6 +1764,7 @@ add_library(grpc_test_util src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -1777,6 +1785,7 @@ add_library(grpc_test_util src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -2065,6 +2074,7 @@ add_library(grpc_test_util_unsecure src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -2085,6 +2095,7 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -2352,6 +2363,7 @@ add_library(grpc_unsecure src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -2372,6 +2384,7 @@ add_library(grpc_unsecure src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -3192,6 +3205,7 @@ add_library(grpc++_cronet src/core/lib/http/format_request.cc src/core/lib/http/httpcli.cc src/core/lib/http/parser.cc + src/core/lib/iomgr/buffer_list.cc src/core/lib/iomgr/call_combiner.cc src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/endpoint.cc @@ -3212,6 +3226,7 @@ add_library(grpc++_cronet src/core/lib/iomgr/gethostname_fallback.cc src/core/lib/iomgr/gethostname_host_name_max.cc src/core/lib/iomgr/gethostname_sysconf.cc + src/core/lib/iomgr/internal_errqueue.cc src/core/lib/iomgr/iocp_windows.cc src/core/lib/iomgr/iomgr.cc src/core/lib/iomgr/iomgr_custom.cc @@ -5835,6 +5850,37 @@ target_link_libraries(bin_encoder_test grpc ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) +if(_gRPC_PLATFORM_LINUX) + +add_executable(buffer_list_test + test/core/iomgr/buffer_list_test.cc +) + + +target_include_directories(buffer_list_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 ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(buffer_list_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr_test_util + gpr +) + +endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index e9a9486a3cc..7caf585ee9e 100644 --- a/Makefile +++ b/Makefile @@ -978,6 +978,7 @@ avl_test: $(BINDIR)/$(CONFIG)/avl_test bad_server_response_test: $(BINDIR)/$(CONFIG)/bad_server_response_test bin_decoder_test: $(BINDIR)/$(CONFIG)/bin_decoder_test bin_encoder_test: $(BINDIR)/$(CONFIG)/bin_encoder_test +buffer_list_test: $(BINDIR)/$(CONFIG)/buffer_list_test channel_create_test: $(BINDIR)/$(CONFIG)/channel_create_test check_epollexclusive: $(BINDIR)/$(CONFIG)/check_epollexclusive chttp2_hpack_encoder_test: $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test @@ -1434,6 +1435,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/bad_server_response_test \ $(BINDIR)/$(CONFIG)/bin_decoder_test \ $(BINDIR)/$(CONFIG)/bin_encoder_test \ + $(BINDIR)/$(CONFIG)/buffer_list_test \ $(BINDIR)/$(CONFIG)/channel_create_test \ $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test \ $(BINDIR)/$(CONFIG)/chttp2_stream_map_test \ @@ -1950,6 +1952,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/bin_decoder_test || ( echo test bin_decoder_test failed ; exit 1 ) $(E) "[RUN] Testing bin_encoder_test" $(Q) $(BINDIR)/$(CONFIG)/bin_encoder_test || ( echo test bin_encoder_test failed ; exit 1 ) + $(E) "[RUN] Testing buffer_list_test" + $(Q) $(BINDIR)/$(CONFIG)/buffer_list_test || ( echo test buffer_list_test failed ; exit 1 ) $(E) "[RUN] Testing channel_create_test" $(Q) $(BINDIR)/$(CONFIG)/channel_create_test || ( echo test channel_create_test failed ; exit 1 ) $(E) "[RUN] Testing chttp2_hpack_encoder_test" @@ -3460,6 +3464,7 @@ LIBGRPC_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -3480,6 +3485,7 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -3865,6 +3871,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -3885,6 +3892,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -4255,6 +4263,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -4275,6 +4284,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -4554,6 +4564,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -4574,6 +4585,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -4819,6 +4831,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -4839,6 +4852,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -5647,6 +5661,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -5667,6 +5682,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ @@ -10701,6 +10717,38 @@ endif endif +BUFFER_LIST_TEST_SRC = \ + test/core/iomgr/buffer_list_test.cc \ + +BUFFER_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BUFFER_LIST_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/buffer_list_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/buffer_list_test: $(BUFFER_LIST_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) $(BUFFER_LIST_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)/buffer_list_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/buffer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_buffer_list_test: $(BUFFER_LIST_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(BUFFER_LIST_TEST_OBJS:.o=.dep) +endif +endif + + CHANNEL_CREATE_TEST_SRC = \ test/core/surface/channel_create_test.cc \ diff --git a/build.yaml b/build.yaml index ce21068c312..a7ebee7572e 100644 --- a/build.yaml +++ b/build.yaml @@ -256,6 +256,7 @@ filegroups: - src/core/lib/http/format_request.cc - src/core/lib/http/httpcli.cc - src/core/lib/http/parser.cc + - src/core/lib/iomgr/buffer_list.cc - src/core/lib/iomgr/call_combiner.cc - src/core/lib/iomgr/combiner.cc - src/core/lib/iomgr/endpoint.cc @@ -276,6 +277,7 @@ filegroups: - src/core/lib/iomgr/gethostname_fallback.cc - src/core/lib/iomgr/gethostname_host_name_max.cc - src/core/lib/iomgr/gethostname_sysconf.cc + - src/core/lib/iomgr/internal_errqueue.cc - src/core/lib/iomgr/iocp_windows.cc - src/core/lib/iomgr/iomgr.cc - src/core/lib/iomgr/iomgr_custom.cc @@ -434,6 +436,7 @@ filegroups: - src/core/lib/http/httpcli.h - src/core/lib/http/parser.h - src/core/lib/iomgr/block_annotate.h + - src/core/lib/iomgr/buffer_list.h - src/core/lib/iomgr/call_combiner.h - src/core/lib/iomgr/closure.h - src/core/lib/iomgr/combiner.h @@ -449,6 +452,7 @@ filegroups: - src/core/lib/iomgr/exec_ctx.h - src/core/lib/iomgr/executor.h - src/core/lib/iomgr/gethostname.h + - src/core/lib/iomgr/internal_errqueue.h - src/core/lib/iomgr/iocp_windows.h - src/core/lib/iomgr/iomgr.h - src/core/lib/iomgr/iomgr_custom.h @@ -2139,6 +2143,20 @@ targets: - grpc_test_util - grpc uses_polling: false +- name: buffer_list_test + build: test + language: c + src: + - test/core/iomgr/buffer_list_test.cc + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr + exclude_iomgrs: + - uv + platforms: + - linux - name: channel_create_test build: test language: c diff --git a/config.m4 b/config.m4 index 7825274eea9..af3624cdd1b 100644 --- a/config.m4 +++ b/config.m4 @@ -108,6 +108,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/http/format_request.cc \ src/core/lib/http/httpcli.cc \ src/core/lib/http/parser.cc \ + src/core/lib/iomgr/buffer_list.cc \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/combiner.cc \ src/core/lib/iomgr/endpoint.cc \ @@ -128,6 +129,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ + src/core/lib/iomgr/internal_errqueue.cc \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iomgr.cc \ src/core/lib/iomgr/iomgr_custom.cc \ diff --git a/config.w32 b/config.w32 index a9d1e6c9d01..ad91ee40bd7 100644 --- a/config.w32 +++ b/config.w32 @@ -83,6 +83,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\http\\format_request.cc " + "src\\core\\lib\\http\\httpcli.cc " + "src\\core\\lib\\http\\parser.cc " + + "src\\core\\lib\\iomgr\\buffer_list.cc " + "src\\core\\lib\\iomgr\\call_combiner.cc " + "src\\core\\lib\\iomgr\\combiner.cc " + "src\\core\\lib\\iomgr\\endpoint.cc " + @@ -103,6 +104,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\gethostname_fallback.cc " + "src\\core\\lib\\iomgr\\gethostname_host_name_max.cc " + "src\\core\\lib\\iomgr\\gethostname_sysconf.cc " + + "src\\core\\lib\\iomgr\\internal_errqueue.cc " + "src\\core\\lib\\iomgr\\iocp_windows.cc " + "src\\core\\lib\\iomgr\\iomgr.cc " + "src\\core\\lib\\iomgr\\iomgr_custom.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 207d7baa8f9..a387794f579 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -382,6 +382,7 @@ Pod::Spec.new do |s| 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', 'src/core/lib/iomgr/block_annotate.h', + 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', @@ -397,6 +398,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', 'src/core/lib/iomgr/iomgr_custom.h', @@ -570,6 +572,7 @@ Pod::Spec.new do |s| 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', 'src/core/lib/iomgr/block_annotate.h', + 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', @@ -585,6 +588,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', 'src/core/lib/iomgr/iomgr_custom.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f1a9bce7f2e..9832283e5c9 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -394,6 +394,7 @@ Pod::Spec.new do |s| 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', 'src/core/lib/iomgr/block_annotate.h', + 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', @@ -409,6 +410,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', 'src/core/lib/iomgr/iomgr_custom.h', @@ -538,6 +540,7 @@ Pod::Spec.new do |s| 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -558,6 +561,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', @@ -993,6 +997,7 @@ Pod::Spec.new do |s| 'src/core/lib/http/httpcli.h', 'src/core/lib/http/parser.h', 'src/core/lib/iomgr/block_annotate.h', + 'src/core/lib/iomgr/buffer_list.h', 'src/core/lib/iomgr/call_combiner.h', 'src/core/lib/iomgr/closure.h', 'src/core/lib/iomgr/combiner.h', @@ -1008,6 +1013,7 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/exec_ctx.h', 'src/core/lib/iomgr/executor.h', 'src/core/lib/iomgr/gethostname.h', + 'src/core/lib/iomgr/internal_errqueue.h', 'src/core/lib/iomgr/iocp_windows.h', 'src/core/lib/iomgr/iomgr.h', 'src/core/lib/iomgr/iomgr_custom.h', diff --git a/grpc.gemspec b/grpc.gemspec index 5c38071d15b..c8e58faec9e 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -330,6 +330,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/http/httpcli.h ) s.files += %w( src/core/lib/http/parser.h ) s.files += %w( src/core/lib/iomgr/block_annotate.h ) + s.files += %w( src/core/lib/iomgr/buffer_list.h ) s.files += %w( src/core/lib/iomgr/call_combiner.h ) s.files += %w( src/core/lib/iomgr/closure.h ) s.files += %w( src/core/lib/iomgr/combiner.h ) @@ -345,6 +346,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/exec_ctx.h ) s.files += %w( src/core/lib/iomgr/executor.h ) s.files += %w( src/core/lib/iomgr/gethostname.h ) + s.files += %w( src/core/lib/iomgr/internal_errqueue.h ) s.files += %w( src/core/lib/iomgr/iocp_windows.h ) s.files += %w( src/core/lib/iomgr/iomgr.h ) s.files += %w( src/core/lib/iomgr/iomgr_custom.h ) @@ -474,6 +476,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/http/format_request.cc ) s.files += %w( src/core/lib/http/httpcli.cc ) s.files += %w( src/core/lib/http/parser.cc ) + s.files += %w( src/core/lib/iomgr/buffer_list.cc ) s.files += %w( src/core/lib/iomgr/call_combiner.cc ) s.files += %w( src/core/lib/iomgr/combiner.cc ) s.files += %w( src/core/lib/iomgr/endpoint.cc ) @@ -494,6 +497,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/gethostname_fallback.cc ) s.files += %w( src/core/lib/iomgr/gethostname_host_name_max.cc ) s.files += %w( src/core/lib/iomgr/gethostname_sysconf.cc ) + s.files += %w( src/core/lib/iomgr/internal_errqueue.cc ) s.files += %w( src/core/lib/iomgr/iocp_windows.cc ) s.files += %w( src/core/lib/iomgr/iomgr.cc ) s.files += %w( src/core/lib/iomgr/iomgr_custom.cc ) diff --git a/grpc.gyp b/grpc.gyp index a36998bcb3b..654a5310923 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -300,6 +300,7 @@ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -320,6 +321,7 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', @@ -660,6 +662,7 @@ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -680,6 +683,7 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', @@ -893,6 +897,7 @@ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -913,6 +918,7 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', @@ -1104,6 +1110,7 @@ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -1124,6 +1131,7 @@ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', diff --git a/package.xml b/package.xml index 1bdf127c36a..537c5404e7e 100644 --- a/package.xml +++ b/package.xml @@ -335,6 +335,7 @@ + @@ -350,6 +351,7 @@ + @@ -479,6 +481,7 @@ + @@ -499,6 +502,7 @@ + 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 4e8b8b71dbd..7ce8da8c00e 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -320,7 +320,7 @@ static void http_connect_handshaker_do_handshake( // Take a new ref to be held by the write callback. gpr_ref(&handshaker->refcount); grpc_endpoint_write(args->endpoint, &handshaker->write_buffer, - &handshaker->request_done_closure); + &handshaker->request_done_closure, nullptr); gpr_mu_unlock(&handshaker->mu); } 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 dfed824cd5b..5bdcb387c9b 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 @@ -50,7 +50,7 @@ grpc_channel* grpc_insecure_channel_create_from_fd( GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0); grpc_endpoint* client = grpc_tcp_client_create_from_fd( - grpc_fd_create(fd, "client", false), args, "fd-client"); + grpc_fd_create(fd, "client", true), args, "fd-client"); grpc_transport* transport = grpc_create_chttp2_transport(final_args, client, true); 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 a0228785eeb..e4bd91d07ba 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 @@ -44,7 +44,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server, gpr_asprintf(&name, "fd:%d", fd); grpc_endpoint* server_endpoint = - grpc_tcp_create(grpc_fd_create(fd, name, false), + grpc_tcp_create(grpc_fd_create(fd, name, true), grpc_server_get_channel_args(server), name); gpr_free(name); diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 36511fa6088..027a57d606d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1029,7 +1029,8 @@ static void write_action(void* gt, grpc_error* error) { grpc_endpoint_write( t->ep, &t->outbuf, GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t, - grpc_combiner_scheduler(t->combiner))); + grpc_combiner_scheduler(t->combiner)), + nullptr); } /* Callback from the grpc_endpoint after bytes have been written by calling diff --git a/src/core/lib/http/httpcli.cc b/src/core/lib/http/httpcli.cc index 12060074c53..3bd7a2ce590 100644 --- a/src/core/lib/http/httpcli.cc +++ b/src/core/lib/http/httpcli.cc @@ -163,7 +163,7 @@ static void done_write(void* arg, grpc_error* error) { static void start_write(internal_request* req) { grpc_slice_ref_internal(req->request_text); grpc_slice_buffer_add(&req->outgoing, req->request_text); - grpc_endpoint_write(req->ep, &req->outgoing, &req->done_write); + grpc_endpoint_write(req->ep, &req->outgoing, &req->done_write, nullptr); } static void on_handshake_done(void* arg, grpc_endpoint* ep) { diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc new file mode 100644 index 00000000000..6ada23db1c2 --- /dev/null +++ b/src/core/lib/iomgr/buffer_list.cc @@ -0,0 +1,134 @@ +/* + * + * 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 + +#include "src/core/lib/iomgr/buffer_list.h" +#include "src/core/lib/iomgr/port.h" + +#include + +#ifdef GRPC_LINUX_ERRQUEUE +#include + +#include "src/core/lib/gprpp/memory.h" + +namespace grpc_core { +void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no, + void* arg) { + GPR_DEBUG_ASSERT(head != nullptr); + TracedBuffer* new_elem = New(seq_no, arg); + /* Store the current time as the sendmsg time. */ + new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME); + if (*head == nullptr) { + *head = new_elem; + return; + } + /* Append at the end. */ + TracedBuffer* ptr = *head; + while (ptr->next_ != nullptr) { + ptr = ptr->next_; + } + ptr->next_ = new_elem; +} + +namespace { +/** Fills gpr_timespec gts based on values from timespec ts */ +void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) { + gts->tv_sec = ts->tv_sec; + gts->tv_nsec = static_cast(ts->tv_nsec); + gts->clock_type = GPR_CLOCK_REALTIME; +} + +/** The saved callback function that will be invoked when we get all the + * timestamps that we are going to get for a TracedBuffer. */ +void (*timestamps_callback)(void*, grpc_core::Timestamps*, + grpc_error* shutdown_err); +} /* namespace */ + +void TracedBuffer::ProcessTimestamp(TracedBuffer** head, + struct sock_extended_err* serr, + struct scm_timestamping* tss) { + GPR_DEBUG_ASSERT(head != nullptr); + TracedBuffer* elem = *head; + TracedBuffer* next = nullptr; + while (elem != nullptr) { + /* The byte number refers to the sequence number of the last byte which this + * timestamp relates to. */ + if (serr->ee_data >= elem->seq_no_) { + switch (serr->ee_info) { + case SCM_TSTAMP_SCHED: + fill_gpr_from_timestamp(&(elem->ts_.scheduled_time), &(tss->ts[0])); + elem = elem->next_; + break; + case SCM_TSTAMP_SND: + fill_gpr_from_timestamp(&(elem->ts_.sent_time), &(tss->ts[0])); + elem = elem->next_; + break; + case SCM_TSTAMP_ACK: + fill_gpr_from_timestamp(&(elem->ts_.acked_time), &(tss->ts[0])); + /* Got all timestamps. Do the callback and free this TracedBuffer. + * The thing below can be passed by value if we don't want the + * restriction on the lifetime. */ + timestamps_callback(elem->arg_, &(elem->ts_), GRPC_ERROR_NONE); + next = elem->next_; + Delete(elem); + *head = elem = next; + break; + default: + abort(); + } + } else { + break; + } + } +} + +void TracedBuffer::Shutdown(TracedBuffer** head, grpc_error* shutdown_err) { + GPR_DEBUG_ASSERT(head != nullptr); + TracedBuffer* elem = *head; + while (elem != nullptr) { + if (timestamps_callback) { + timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err); + } + auto* next = elem->next_; + Delete(elem); + elem = next; + } + *head = nullptr; + GRPC_ERROR_UNREF(shutdown_err); +} + +void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*, + grpc_error* error)) { + timestamps_callback = fn; +} +} /* namespace grpc_core */ + +#else /* GRPC_LINUX_ERRQUEUE */ + +namespace grpc_core { +void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*, + grpc_error* error)) { + gpr_log(GPR_DEBUG, "Timestamps callback is not enabled for this platform"); +} +} /* namespace grpc_core */ + +#endif /* GRPC_LINUX_ERRQUEUE */ diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h new file mode 100644 index 00000000000..cbbf50a6575 --- /dev/null +++ b/src/core/lib/iomgr/buffer_list.h @@ -0,0 +1,96 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H +#define GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H + +#include + +#include "src/core/lib/iomgr/port.h" + +#include + +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/internal_errqueue.h" + +namespace grpc_core { +struct Timestamps { + /* TODO(yashykt): This would also need to store OPTSTAT once support is added + */ + gpr_timespec sendmsg_time; + gpr_timespec scheduled_time; + gpr_timespec sent_time; + gpr_timespec acked_time; +}; + +/** TracedBuffer is a class to keep track of timestamps for a specific buffer in + * the TCP layer. We are only tracking timestamps for Linux kernels and hence + * this class would only be used by Linux platforms. For all other platforms, + * TracedBuffer would be an empty class. + * + * The timestamps collected are according to grpc_core::Timestamps declared + * above. + * + * A TracedBuffer list is kept track of using the head element of the list. If + * the head element of the list is nullptr, then the list is empty. + */ +#ifdef GRPC_LINUX_ERRQUEUE +class TracedBuffer { + public: + /** Add a new entry in the TracedBuffer list pointed to by head. Also saves + * sendmsg_time with the current timestamp. */ + static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no, + void* arg); + + /** Processes a received timestamp based on sock_extended_err and + * scm_timestamping structures. It will invoke the timestamps callback if the + * timestamp type is SCM_TSTAMP_ACK. */ + static void ProcessTimestamp(grpc_core::TracedBuffer** head, + struct sock_extended_err* serr, + struct scm_timestamping* tss); + + /** Cleans the list by calling the callback for each traced buffer in the list + * with timestamps that it has. */ + static void Shutdown(grpc_core::TracedBuffer** head, + grpc_error* shutdown_err); + + private: + GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW + + TracedBuffer(int seq_no, void* arg) + : seq_no_(seq_no), arg_(arg), next_(nullptr) {} + + uint32_t seq_no_; /* The sequence number for the last byte in the buffer */ + void* arg_; /* The arg to pass to timestamps_callback */ + grpc_core::Timestamps ts_; /* The timestamps corresponding to this buffer */ + grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */ +}; +#else /* GRPC_LINUX_ERRQUEUE */ +class TracedBuffer {}; +#endif /* GRPC_LINUX_ERRQUEUE */ + +/** Sets the callback function to call when timestamps for a write are + * collected. The callback does not own a reference to error. */ +void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*, + grpc_core::Timestamps*, + grpc_error* error)); + +}; /* namespace grpc_core */ + +#endif /* GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H */ diff --git a/src/core/lib/iomgr/endpoint.cc b/src/core/lib/iomgr/endpoint.cc index 92e79301114..44fb47e19d9 100644 --- a/src/core/lib/iomgr/endpoint.cc +++ b/src/core/lib/iomgr/endpoint.cc @@ -28,8 +28,8 @@ void grpc_endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* slices, } void grpc_endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { - ep->vtable->write(ep, slices, cb); + grpc_closure* cb, void* arg) { + ep->vtable->write(ep, slices, cb, arg); } void grpc_endpoint_add_to_pollset(grpc_endpoint* ep, grpc_pollset* pollset) { diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h index 15db1649fa9..1f590a80cae 100644 --- a/src/core/lib/iomgr/endpoint.h +++ b/src/core/lib/iomgr/endpoint.h @@ -33,10 +33,12 @@ typedef struct grpc_endpoint grpc_endpoint; typedef struct grpc_endpoint_vtable grpc_endpoint_vtable; +class Timestamps; struct grpc_endpoint_vtable { void (*read)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb); - void (*write)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb); + void (*write)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb, + void* arg); void (*add_to_pollset)(grpc_endpoint* ep, grpc_pollset* pollset); void (*add_to_pollset_set)(grpc_endpoint* ep, grpc_pollset_set* pollset); void (*delete_from_pollset_set)(grpc_endpoint* ep, grpc_pollset_set* pollset); @@ -70,9 +72,11 @@ int grpc_endpoint_get_fd(grpc_endpoint* ep); \a slices may be mutated at will by the endpoint until cb is called. No guarantee is made to the content of slices after a write EXCEPT that it is a valid slice buffer. + \a arg is platform specific. It is currently only used by TCP on linux + platforms as an argument that would be forwarded to the timestamps callback. */ void grpc_endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb); + grpc_closure* cb, void* arg); /* Causes any pending and future read/write callbacks to run immediately with success==0 */ diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc index c3bc0cc8fd9..df2cf508c8f 100644 --- a/src/core/lib/iomgr/endpoint_cfstream.cc +++ b/src/core/lib/iomgr/endpoint_cfstream.cc @@ -268,7 +268,7 @@ static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices, } static void CFStreamWrite(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { CFStreamEndpoint* ep_impl = reinterpret_cast(ep); if (grpc_tcp_trace.enabled()) { gpr_log(GPR_DEBUG, "CFStream endpoint:%p write (%p, %p) length:%zu", diff --git a/src/core/lib/iomgr/endpoint_pair_posix.cc b/src/core/lib/iomgr/endpoint_pair_posix.cc index 5c5c246f998..3afbfd72543 100644 --- a/src/core/lib/iomgr/endpoint_pair_posix.cc +++ b/src/core/lib/iomgr/endpoint_pair_posix.cc @@ -59,11 +59,11 @@ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char* name, grpc_core::ExecCtx exec_ctx; gpr_asprintf(&final_name, "%s:client", name); - p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, false), args, + p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, true), args, "socketpair-server"); gpr_free(final_name); gpr_asprintf(&final_name, "%s:server", name); - p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, false), args, + p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, true), args, "socketpair-client"); gpr_free(final_name); diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 0205363d5c4..d4377e2d504 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -237,14 +237,19 @@ void grpc_event_engine_shutdown(void) { } bool grpc_event_engine_can_track_errors(void) { +/* Only track errors if platform supports errqueue. */ +#ifdef GRPC_LINUX_ERRQUEUE return g_event_engine->can_track_err; +#else + return false; +#endif /* GRPC_LINUX_ERRQUEUE */ } grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) { GRPC_POLLING_API_TRACE("fd_create(%d, %s, %d)", fd, name, track_err); GRPC_FD_TRACE("fd_create(%d, %s, %d)", fd, name, track_err); - GPR_DEBUG_ASSERT(!track_err || g_event_engine->can_track_err); - return g_event_engine->fd_create(fd, name, track_err); + return g_event_engine->fd_create(fd, name, + track_err && g_event_engine->can_track_err); } int grpc_fd_wrapped_fd(grpc_fd* fd) { diff --git a/src/core/lib/iomgr/internal_errqueue.cc b/src/core/lib/iomgr/internal_errqueue.cc new file mode 100644 index 00000000000..8823737e494 --- /dev/null +++ b/src/core/lib/iomgr/internal_errqueue.cc @@ -0,0 +1,40 @@ +/* + * + * 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 + +#include "src/core/lib/iomgr/port.h" + +#include "src/core/lib/iomgr/internal_errqueue.h" + +#ifdef GRPC_POSIX_SOCKET_TCP + +#ifdef GPR_LINUX +#include +#endif /* GPR_LINUX */ + +bool kernel_supports_errqueue() { +#ifdef LINUX_VERSION_CODE +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) + return true; +#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) */ +#endif /* LINUX_VERSION_CODE */ + return false; +} + +#endif /* GRPC_POSIX_SOCKET_TCP */ diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h new file mode 100644 index 00000000000..fc11be9a6dd --- /dev/null +++ b/src/core/lib/iomgr/internal_errqueue.h @@ -0,0 +1,62 @@ +/* + * + * 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. + * + */ + +/* This file contains constants defined in and + * so as to allow collecting network timestamps in the + * kernel. This file allows tcp_posix.cc to compile on platforms that do not + * have and . + */ + +#ifndef GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H +#define GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H + +#include + +#include "src/core/lib/iomgr/port.h" + +#ifdef GRPC_POSIX_SOCKET_TCP + +#include +#include + +#ifdef GRPC_LINUX_ERRQUEUE +#include +#include +#include +#endif /* GRPC_LINUX_ERRQUEUE */ + +namespace grpc_core { + +#ifdef GRPC_LINUX_ERRQUEUE +constexpr uint32_t kTimestampingSocketOptions = SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_OPT_ID | + SOF_TIMESTAMPING_OPT_TSONLY; +constexpr uint32_t kTimestampingRecordingOptions = + SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_TX_ACK; +#endif /* GRPC_LINUX_ERRQUEUE */ + +/* Returns true if kernel is capable of supporting errqueue and timestamping. + * Currently allowing only linux kernels above 4.0.0 + */ +bool kernel_supports_errqueue(); +} // namespace grpc_core + +#endif /* GRPC_POSIX_SOCKET_TCP */ + +#endif /* GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H */ diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 066417b93cc..a4688fd0efb 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -60,6 +60,12 @@ #define GRPC_HAVE_IP_PKTINFO 1 #define GRPC_HAVE_MSG_NOSIGNAL 1 #define GRPC_HAVE_UNIX_SOCKET 1 +#include +#ifdef LINUX_VERSION_CODE +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) +#define GRPC_LINUX_ERRQUEUE 1 +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */ +#endif /* LINUX_VERSION_CODE */ #define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1 #define GRPC_POSIX_FORK 1 #define GRPC_POSIX_HOST_NAME_MAX 1 diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc index 296ee74311a..9c989b7dfee 100644 --- a/src/core/lib/iomgr/tcp_client_posix.cc +++ b/src/core/lib/iomgr/tcp_client_posix.cc @@ -279,7 +279,7 @@ grpc_error* grpc_tcp_client_prepare_fd(const grpc_channel_args* channel_args, } addr_str = grpc_sockaddr_to_uri(mapped_addr); gpr_asprintf(&name, "tcp-client:%s", addr_str); - *fdobj = grpc_fd_create(fd, name, false); + *fdobj = grpc_fd_create(fd, name, true); gpr_free(name); gpr_free(addr_str); return GRPC_ERROR_NONE; diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc index 990e8d632b9..e02a1898f25 100644 --- a/src/core/lib/iomgr/tcp_custom.cc +++ b/src/core/lib/iomgr/tcp_custom.cc @@ -221,7 +221,7 @@ static void custom_write_callback(grpc_custom_socket* socket, } static void endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* write_slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep; GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD(); diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index b53ffbf01cf..1db2790265e 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -27,7 +27,9 @@ #include #include +#include #include +#include #include #include #include @@ -46,6 +48,7 @@ #include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/buffer_list.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/profiling/timers.h" @@ -97,17 +100,42 @@ struct grpc_tcp { grpc_closure read_done_closure; grpc_closure write_done_closure; + grpc_closure error_closure; char* peer_string; grpc_resource_user* resource_user; grpc_resource_user_slice_allocator slice_allocator; + + grpc_core::TracedBuffer* tb_head; /* List of traced buffers */ + gpr_mu tb_mu; /* Lock for access to list of traced buffers */ + + /* grpc_endpoint_write takes an argument which if non-null means that the + * transport layer wants the TCP layer to collect timestamps for this write. + * This arg is forwarded to the timestamps callback function when the ACK + * timestamp is received from the kernel. This arg is a (void *) which allows + * users of this API to pass in a pointer to any kind of structure. This + * structure could actually be a tag or any book-keeping object that the user + * can use to distinguish between different traced writes. The only + * requirement from the TCP endpoint layer is that this arg should be non-null + * if the user wants timestamps for the write. */ + void* outgoing_buffer_arg; + /* A counter which starts at 0. It is initialized the first time the socket + * options for collecting timestamps are set, and is incremented with each + * byte sent. */ + int bytes_counter; + bool socket_ts_enabled; /* True if timestamping options are set on the socket + */ + gpr_atm + stop_error_notification; /* Set to 1 if we do not want to be notified on + errors anymore */ }; struct backup_poller { gpr_mu* pollset_mu; grpc_closure run_poller; }; + } // namespace #define BACKUP_POLLER_POLLSET(b) ((grpc_pollset*)((b) + 1)) @@ -302,6 +330,7 @@ static void tcp_free(grpc_tcp* tcp) { grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer); grpc_resource_user_unref(tcp->resource_user); gpr_free(tcp->peer_string); + gpr_mu_destroy(&tcp->tb_mu); gpr_free(tcp); } @@ -347,6 +376,10 @@ static void tcp_destroy(grpc_endpoint* ep) { grpc_network_status_unregister_endpoint(ep); grpc_tcp* tcp = reinterpret_cast(ep); grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); + if (grpc_event_engine_can_track_errors()) { + gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); + grpc_fd_set_error(tcp->em_fd); + } TCP_UNREF(tcp, "destroy"); } @@ -513,6 +546,234 @@ static void tcp_read(grpc_endpoint* ep, grpc_slice_buffer* incoming_buffer, } } +/* A wrapper around sendmsg. It sends \a msg over \a fd and returns the number + * of bytes sent. */ +ssize_t tcp_send(int fd, const struct msghdr* msg) { + GPR_TIMER_SCOPE("sendmsg", 1); + ssize_t sent_length; + do { + /* TODO(klempner): Cork if this is a partial write */ + GRPC_STATS_INC_SYSCALL_WRITE(); + sent_length = sendmsg(fd, msg, SENDMSG_FLAGS); + } while (sent_length < 0 && errno == EINTR); + return sent_length; +} + +/** This is to be called if outgoing_buffer_arg is not null. On linux platforms, + * this will call sendmsg with socket options set to collect timestamps inside + * the kernel. On return, sent_length is set to the return value of the sendmsg + * call. Returns false if setting the socket options failed. This is not + * implemented for non-linux platforms currently, and crashes out. + */ +static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, + size_t sending_length, + ssize_t* sent_length, grpc_error** error); + +/** The callback function to be invoked when we get an error on the socket. */ +static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error); + +#ifdef GRPC_LINUX_ERRQUEUE +static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, + size_t sending_length, + ssize_t* sent_length, + grpc_error** error) { + if (!tcp->socket_ts_enabled) { + uint32_t opt = grpc_core::kTimestampingSocketOptions; + if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, + static_cast(&opt), sizeof(opt)) != 0) { + *error = tcp_annotate_error(GRPC_OS_ERROR(errno, "setsockopt"), tcp); + grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_ERROR, "Failed to set timestamping options on the socket."); + } + return false; + } + tcp->bytes_counter = -1; + tcp->socket_ts_enabled = true; + } + /* Set control message to indicate that you want timestamps. */ + union { + char cmsg_buf[CMSG_SPACE(sizeof(uint32_t))]; + struct cmsghdr align; + } u; + cmsghdr* cmsg = reinterpret_cast(u.cmsg_buf); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SO_TIMESTAMPING; + cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t)); + *reinterpret_cast(CMSG_DATA(cmsg)) = + grpc_core::kTimestampingRecordingOptions; + msg->msg_control = u.cmsg_buf; + msg->msg_controllen = CMSG_SPACE(sizeof(uint32_t)); + + /* If there was an error on sendmsg the logic in tcp_flush will handle it. */ + ssize_t length = tcp_send(tcp->fd, msg); + *sent_length = length; + /* Only save timestamps if all the bytes were taken by sendmsg. */ + if (sending_length == static_cast(length)) { + gpr_mu_lock(&tcp->tb_mu); + grpc_core::TracedBuffer::AddNewEntry( + &tcp->tb_head, static_cast(tcp->bytes_counter + length), + tcp->outgoing_buffer_arg); + gpr_mu_unlock(&tcp->tb_mu); + tcp->outgoing_buffer_arg = nullptr; + } + return true; +} + +/** Reads \a cmsg to derive timestamps from the control messages. If a valid + * timestamp is found, the traced buffer list is updated with this timestamp. + * The caller of this function should be looping on the control messages found + * in \a msg. \a cmsg should point to the control message that the caller wants + * processed. + * On return, a pointer to a control message is returned. On the next iteration, + * CMSG_NXTHDR(msg, ret_val) should be passed as \a cmsg. */ +struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, + struct cmsghdr* cmsg) { + auto next_cmsg = CMSG_NXTHDR(msg, cmsg); + if (next_cmsg == nullptr) { + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_ERROR, "Received timestamp without extended error"); + } + return cmsg; + } + + if (!(next_cmsg->cmsg_level == SOL_IP || next_cmsg->cmsg_level == SOL_IPV6) || + !(next_cmsg->cmsg_type == IP_RECVERR || + next_cmsg->cmsg_type == IPV6_RECVERR)) { + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_ERROR, "Unexpected control message"); + } + return cmsg; + } + + auto tss = reinterpret_cast(CMSG_DATA(cmsg)); + auto serr = reinterpret_cast(CMSG_DATA(next_cmsg)); + if (serr->ee_errno != ENOMSG || + serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) { + gpr_log(GPR_ERROR, "Unexpected control message"); + return cmsg; + } + /* The error handling can potentially be done on another thread so we need + * to protect the traced buffer list. A lock free list might be better. Using + * a simple mutex for now. */ + gpr_mu_lock(&tcp->tb_mu); + grpc_core::TracedBuffer::ProcessTimestamp(&tcp->tb_head, serr, tss); + gpr_mu_unlock(&tcp->tb_mu); + return next_cmsg; +} + +/** For linux platforms, reads the socket's error queue and processes error + * messages from the queue. Returns true if all the errors processed were + * timestamps. Returns false if any of the errors were not timestamps. For + * non-linux platforms, error processing is not used/enabled currently. + */ +static bool process_errors(grpc_tcp* tcp) { + while (true) { + struct iovec iov; + iov.iov_base = nullptr; + iov.iov_len = 0; + struct msghdr msg; + msg.msg_name = nullptr; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 0; + msg.msg_flags = 0; + + union { + char rbuf[1024 /*CMSG_SPACE(sizeof(scm_timestamping)) + + CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in))*/]; + struct cmsghdr align; + } aligned_buf; + memset(&aligned_buf, 0, sizeof(aligned_buf)); + + msg.msg_control = aligned_buf.rbuf; + msg.msg_controllen = sizeof(aligned_buf.rbuf); + + int r, saved_errno; + do { + r = recvmsg(tcp->fd, &msg, MSG_ERRQUEUE); + saved_errno = errno; + } while (r < 0 && saved_errno == EINTR); + + if (r == -1 && saved_errno == EAGAIN) { + return true; /* No more errors to process */ + } + if (r == -1) { + return false; + } + if (grpc_tcp_trace.enabled()) { + if ((msg.msg_flags & MSG_CTRUNC) == 1) { + gpr_log(GPR_INFO, "Error message was truncated."); + } + } + + if (msg.msg_controllen == 0) { + /* There was no control message found. It was probably spurious. */ + return true; + } + for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg && cmsg->cmsg_len; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level != SOL_SOCKET || + cmsg->cmsg_type != SCM_TIMESTAMPING) { + /* Got a control message that is not a timestamp. Don't know how to + * handle this. */ + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, + "unknown control message cmsg_level:%d cmsg_type:%d", + cmsg->cmsg_level, cmsg->cmsg_type); + } + return false; + } + process_timestamp(tcp, &msg, cmsg); + } + } +} + +static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { + grpc_tcp* tcp = static_cast(arg); + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "TCP:%p got_error: %s", tcp, grpc_error_string(error)); + } + + if (error != GRPC_ERROR_NONE || + static_cast(gpr_atm_acq_load(&tcp->stop_error_notification))) { + /* We aren't going to register to hear on error anymore, so it is safe to + * unref. */ + grpc_core::TracedBuffer::Shutdown(&tcp->tb_head, GRPC_ERROR_REF(error)); + TCP_UNREF(tcp, "error-tracking"); + return; + } + + /* We are still interested in collecting timestamps, so let's try reading + * them. */ + if (!process_errors(tcp)) { + /* This was not a timestamps error. This was an actual error. Set the + * read and write closures to be ready. + */ + grpc_fd_set_readable(tcp->em_fd); + grpc_fd_set_writable(tcp->em_fd); + } + GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, + grpc_schedule_on_exec_ctx); + grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); +} + +#else /* GRPC_LINUX_ERRQUEUE */ +static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, + size_t sending_length, + ssize_t* sent_length, + grpc_error** error) { + gpr_log(GPR_ERROR, "Write with timestamps not supported for this platform"); + GPR_ASSERT(0); + return false; +} + +static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { + gpr_log(GPR_ERROR, "Error handling is not supported for this platform"); + GPR_ASSERT(0); +} +#endif /* GRPC_LINUX_ERRQUEUE */ + /* returns true if done, false if pending; if returning true, *error is set */ #if defined(IOV_MAX) && IOV_MAX < 1000 #define MAX_WRITE_IOVEC IOV_MAX @@ -557,19 +818,20 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = iov_size; - msg.msg_control = nullptr; - msg.msg_controllen = 0; msg.msg_flags = 0; + if (tcp->outgoing_buffer_arg != nullptr) { + if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length, + error)) + return true; /* something went wrong with timestamps */ + } else { + msg.msg_control = nullptr; + msg.msg_controllen = 0; - GRPC_STATS_INC_TCP_WRITE_SIZE(sending_length); - GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(iov_size); + GRPC_STATS_INC_TCP_WRITE_SIZE(sending_length); + GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(iov_size); - GPR_TIMER_SCOPE("sendmsg", 1); - do { - /* TODO(klempner): Cork if this is a partial write */ - GRPC_STATS_INC_SYSCALL_WRITE(); - sent_length = sendmsg(tcp->fd, &msg, SENDMSG_FLAGS); - } while (sent_length < 0 && errno == EINTR); + sent_length = tcp_send(tcp->fd, &msg); + } if (sent_length < 0) { if (errno == EAGAIN) { @@ -593,6 +855,7 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { } GPR_ASSERT(tcp->outgoing_byte_idx == 0); + tcp->bytes_counter += sent_length; trailing = sending_length - static_cast(sent_length); while (trailing > 0) { size_t slice_length; @@ -607,7 +870,6 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) { trailing -= slice_length; } } - if (outgoing_slice_idx == tcp->outgoing_buffer->count) { *error = GRPC_ERROR_NONE; grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer); @@ -640,14 +902,13 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) { const char* str = grpc_error_string(error); gpr_log(GPR_INFO, "write: %s", str); } - GRPC_CLOSURE_SCHED(cb, error); TCP_UNREF(tcp, "write"); } } static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { GPR_TIMER_SCOPE("tcp_write", 0); grpc_tcp* tcp = reinterpret_cast(ep); grpc_error* error = GRPC_ERROR_NONE; @@ -675,6 +936,10 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, } tcp->outgoing_buffer = buf; tcp->outgoing_byte_idx = 0; + tcp->outgoing_buffer_arg = arg; + if (arg) { + GPR_ASSERT(grpc_event_engine_can_track_errors()); + } if (!tcp_flush(tcp, &error)) { TCP_REF(tcp, "write"); @@ -792,6 +1057,8 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->bytes_read_this_round = 0; /* Will be set to false by the very first endpoint read function */ tcp->is_first_read = true; + tcp->bytes_counter = -1; + tcp->socket_ts_enabled = false; /* paired with unref in grpc_tcp_destroy */ gpr_ref_init(&tcp->refcount, 1); gpr_atm_no_barrier_store(&tcp->shutdown_count, 0); @@ -803,6 +1070,19 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, /* Tell network status tracker about new endpoint */ grpc_network_status_register_endpoint(&tcp->base); grpc_resource_quota_unref_internal(resource_quota); + gpr_mu_init(&tcp->tb_mu); + tcp->tb_head = nullptr; + /* Start being notified on errors if event engine can track errors. */ + if (grpc_event_engine_can_track_errors()) { + /* Grab a ref to tcp so that we can safely access the tcp struct when + * processing errors. We unref when we no longer want to track errors + * separately. */ + TCP_REF(tcp, "error-tracking"); + gpr_atm_rel_store(&tcp->stop_error_notification, 0); + GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, + grpc_schedule_on_exec_ctx); + grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); + } return &tcp->base; } @@ -821,6 +1101,11 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd, tcp->release_fd = fd; tcp->release_fd_cb = done; grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer); + if (grpc_event_engine_can_track_errors()) { + /* Stop errors notification. */ + gpr_atm_no_barrier_store(&tcp->stop_error_notification, true); + grpc_fd_set_error(tcp->em_fd); + } TCP_UNREF(tcp, "destroy"); } diff --git a/src/core/lib/iomgr/tcp_posix.h b/src/core/lib/iomgr/tcp_posix.h index af89bd24db1..eff825cb925 100644 --- a/src/core/lib/iomgr/tcp_posix.h +++ b/src/core/lib/iomgr/tcp_posix.h @@ -31,7 +31,10 @@ #include +#include "src/core/lib/iomgr/port.h" + #include "src/core/lib/debug/trace.h" +#include "src/core/lib/iomgr/buffer_list.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_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc index 8ddf684feac..824db07fbfd 100644 --- a/src/core/lib/iomgr/tcp_server_posix.cc +++ b/src/core/lib/iomgr/tcp_server_posix.cc @@ -226,7 +226,7 @@ static void on_read(void* arg, grpc_error* err) { gpr_log(GPR_INFO, "SERVER_CONNECT: incoming connection: %s", addr_str); } - grpc_fd* fdobj = grpc_fd_create(fd, name, false); + grpc_fd* fdobj = grpc_fd_create(fd, name, true); read_notifier_pollset = sp->server->pollsets[static_cast(gpr_atm_no_barrier_fetch_add( @@ -362,7 +362,7 @@ static grpc_error* clone_port(grpc_tcp_listener* listener, unsigned count) { listener->sibling = sp; sp->server = listener->server; sp->fd = fd; - sp->emfd = grpc_fd_create(fd, name, false); + sp->emfd = grpc_fd_create(fd, name, true); memcpy(&sp->addr, &listener->addr, sizeof(grpc_resolved_address)); sp->port = port; sp->port_index = listener->port_index; 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 b9f81455729..9595c028ce0 100644 --- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc @@ -105,7 +105,7 @@ static grpc_error* add_socket_to_server(grpc_tcp_server* s, int fd, s->tail = sp; sp->server = s; sp->fd = fd; - sp->emfd = grpc_fd_create(fd, name, false); + sp->emfd = grpc_fd_create(fd, name, true); memcpy(&sp->addr, addr, sizeof(grpc_resolved_address)); sp->port = port; sp->port_index = port_index; diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc index b3cb442f18f..64c4a56ae95 100644 --- a/src/core/lib/iomgr/tcp_windows.cc +++ b/src/core/lib/iomgr/tcp_windows.cc @@ -296,7 +296,7 @@ static void on_write(void* tcpp, grpc_error* error) { /* Initiates a write. */ static void win_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { grpc_tcp* tcp = (grpc_tcp*)ep; grpc_winsocket* socket = tcp->socket; grpc_winsocket_callback_info* info = &socket->write_info; diff --git a/src/core/lib/iomgr/udp_server.cc b/src/core/lib/iomgr/udp_server.cc index bdb2d0e7644..3dd7cab855c 100644 --- a/src/core/lib/iomgr/udp_server.cc +++ b/src/core/lib/iomgr/udp_server.cc @@ -152,7 +152,7 @@ GrpcUdpListener::GrpcUdpListener(grpc_udp_server* server, int fd, grpc_sockaddr_to_string(&addr_str, addr, 1); gpr_asprintf(&name, "udp-server-listener:%s", addr_str); gpr_free(addr_str); - emfd_ = grpc_fd_create(fd, name, false); + emfd_ = grpc_fd_create(fd, name, true); memcpy(&addr_, addr, sizeof(grpc_resolved_address)); GPR_ASSERT(emfd_); gpr_free(name); diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc index 840b2e73bcf..f40f969bb7f 100644 --- a/src/core/lib/security/transport/secure_endpoint.cc +++ b/src/core/lib/security/transport/secure_endpoint.cc @@ -254,7 +254,7 @@ static void flush_write_staging_buffer(secure_endpoint* ep, uint8_t** cur, } static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { GPR_TIMER_SCOPE("secure_endpoint.endpoint_write", 0); unsigned i; @@ -342,7 +342,7 @@ static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices, return; } - grpc_endpoint_write(ep->wrapped_ep, &ep->output_buffer, cb); + grpc_endpoint_write(ep->wrapped_ep, &ep->output_buffer, cb, arg); } static void endpoint_shutdown(grpc_endpoint* secure_ep, grpc_error* why) { diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index aff723ed044..d76d5826388 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -259,7 +259,7 @@ static grpc_error* on_handshake_next_done_locked( grpc_slice_buffer_reset_and_unref_internal(&h->outgoing); grpc_slice_buffer_add(&h->outgoing, to_send); grpc_endpoint_write(h->args->endpoint, &h->outgoing, - &h->on_handshake_data_sent_to_peer); + &h->on_handshake_data_sent_to_peer, nullptr); } else if (handshaker_result == nullptr) { // There is nothing to send, but need to read from peer. grpc_endpoint_read(h->args->endpoint, h->args->read_buffer, diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 6e6d756eec7..0f68e823d79 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -82,6 +82,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/http/format_request.cc', 'src/core/lib/http/httpcli.cc', 'src/core/lib/http/parser.cc', + 'src/core/lib/iomgr/buffer_list.cc', 'src/core/lib/iomgr/call_combiner.cc', 'src/core/lib/iomgr/combiner.cc', 'src/core/lib/iomgr/endpoint.cc', @@ -102,6 +103,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/gethostname_fallback.cc', 'src/core/lib/iomgr/gethostname_host_name_max.cc', 'src/core/lib/iomgr/gethostname_sysconf.cc', + 'src/core/lib/iomgr/internal_errqueue.cc', 'src/core/lib/iomgr/iocp_windows.cc', 'src/core/lib/iomgr/iomgr.cc', 'src/core/lib/iomgr/iomgr_custom.cc', diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc index c03ebcf4096..ade23133c55 100644 --- a/test/core/bad_client/bad_client.cc +++ b/test/core/bad_client/bad_client.cc @@ -115,7 +115,7 @@ void grpc_run_client_side_validator(grpc_bad_client_arg* arg, uint32_t flags, grpc_schedule_on_exec_ctx); /* Write data */ - grpc_endpoint_write(sfd->client, &outgoing, &done_write_closure); + grpc_endpoint_write(sfd->client, &outgoing, &done_write_closure, nullptr); grpc_core::ExecCtx::Get()->Flush(); /* Await completion, unless the request is large and write may not finish diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index 3d133cfc186..f7396a16845 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -104,7 +104,7 @@ static void handle_write() { grpc_slice_buffer_reset_and_unref(&state.outgoing_buffer); grpc_slice_buffer_add(&state.outgoing_buffer, slice); - grpc_endpoint_write(state.tcp, &state.outgoing_buffer, &on_write); + grpc_endpoint_write(state.tcp, &state.outgoing_buffer, &on_write, nullptr); } static void handle_read(void* arg, grpc_error* error) { diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index f02fa9d9983..ea9c000efb9 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -201,7 +201,7 @@ static void on_client_write_done(void* arg, grpc_error* error) { &conn->client_write_buffer); conn->client_is_writing = true; grpc_endpoint_write(conn->client_endpoint, &conn->client_write_buffer, - &conn->on_client_write_done); + &conn->on_client_write_done, nullptr); } else { // No more writes. Unref the connection. proxy_connection_unref(conn, "write_done"); @@ -226,7 +226,7 @@ static void on_server_write_done(void* arg, grpc_error* error) { &conn->server_write_buffer); conn->server_is_writing = true; grpc_endpoint_write(conn->server_endpoint, &conn->server_write_buffer, - &conn->on_server_write_done); + &conn->on_server_write_done, nullptr); } else { // No more writes. Unref the connection. proxy_connection_unref(conn, "server_write"); @@ -257,7 +257,7 @@ static void on_client_read_done(void* arg, grpc_error* error) { proxy_connection_ref(conn, "client_read"); conn->server_is_writing = true; grpc_endpoint_write(conn->server_endpoint, &conn->server_write_buffer, - &conn->on_server_write_done); + &conn->on_server_write_done, nullptr); } // Read more data. grpc_endpoint_read(conn->client_endpoint, &conn->client_read_buffer, @@ -288,7 +288,7 @@ static void on_server_read_done(void* arg, grpc_error* error) { proxy_connection_ref(conn, "server_read"); conn->client_is_writing = true; grpc_endpoint_write(conn->client_endpoint, &conn->client_write_buffer, - &conn->on_client_write_done); + &conn->on_client_write_done, nullptr); } // Read more data. grpc_endpoint_read(conn->server_endpoint, &conn->server_read_buffer, @@ -340,7 +340,7 @@ static void on_server_connect_done(void* arg, grpc_error* error) { grpc_slice_buffer_add(&conn->client_write_buffer, slice); conn->client_is_writing = true; grpc_endpoint_write(conn->client_endpoint, &conn->client_write_buffer, - &conn->on_write_response_done); + &conn->on_write_response_done, nullptr); } /** diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 002671a5fae..675d9e6278c 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -246,6 +246,19 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "buffer_list_test", + srcs = ["buffer_list_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + + grpc_cc_test( name = "tcp_server_posix_test", srcs = ["tcp_server_posix_test.cc"], diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc new file mode 100644 index 00000000000..f1773580bd2 --- /dev/null +++ b/test/core/iomgr/buffer_list_test.cc @@ -0,0 +1,111 @@ +/* + * + * 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 "src/core/lib/iomgr/port.h" + +#include "src/core/lib/iomgr/buffer_list.h" + +#include + +#include "test/core/util/test_config.h" + +#ifdef GRPC_LINUX_ERRQUEUE + +static void TestShutdownFlushesListVerifier(void* arg, + grpc_core::Timestamps* ts, + grpc_error* error) { + GPR_ASSERT(error == GRPC_ERROR_NONE); + GPR_ASSERT(arg != nullptr); + gpr_atm* done = reinterpret_cast(arg); + gpr_atm_rel_store(done, static_cast(1)); +} + +/** Tests that all TracedBuffer elements in the list are flushed out on + * shutdown. + * Also tests that arg is passed correctly. + */ +static void TestShutdownFlushesList() { + grpc_core::grpc_tcp_set_write_timestamps_callback( + TestShutdownFlushesListVerifier); + grpc_core::TracedBuffer* list = nullptr; +#define NUM_ELEM 5 + gpr_atm verifier_called[NUM_ELEM]; + for (auto i = 0; i < NUM_ELEM; i++) { + gpr_atm_rel_store(&verifier_called[i], static_cast(0)); + grpc_core::TracedBuffer::AddNewEntry( + &list, i, static_cast(&verifier_called[i])); + } + grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE); + GPR_ASSERT(list == nullptr); + for (auto i = 0; i < NUM_ELEM; i++) { + GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) == + static_cast(1)); + } +} + +static void TestVerifierCalledOnAckVerifier(void* arg, + grpc_core::Timestamps* ts, + grpc_error* error) { + GPR_ASSERT(error == GRPC_ERROR_NONE); + GPR_ASSERT(arg != nullptr); + GPR_ASSERT(ts->acked_time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->acked_time.tv_sec == 123); + GPR_ASSERT(ts->acked_time.tv_nsec == 456); + gpr_atm* done = reinterpret_cast(arg); + gpr_atm_rel_store(done, static_cast(1)); +} + +/** Tests that the timestamp verifier is called on an ACK timestamp. + */ +static void TestVerifierCalledOnAck() { + struct sock_extended_err serr; + serr.ee_data = 213; + serr.ee_info = SCM_TSTAMP_ACK; + struct scm_timestamping tss; + tss.ts[0].tv_sec = 123; + tss.ts[0].tv_nsec = 456; + grpc_core::grpc_tcp_set_write_timestamps_callback( + TestVerifierCalledOnAckVerifier); + grpc_core::TracedBuffer* list = nullptr; + gpr_atm verifier_called; + gpr_atm_rel_store(&verifier_called, static_cast(0)); + grpc_core::TracedBuffer::AddNewEntry(&list, 213, &verifier_called); + grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, &tss); + GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast(1)); + GPR_ASSERT(list == nullptr); + grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE); +} + +static void TestTcpBufferList() { + TestVerifierCalledOnAck(); + TestShutdownFlushesList(); +} + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + TestTcpBufferList(); + grpc_shutdown(); + return 0; +} + +#else /* GRPC_LINUX_ERRQUEUE */ + +int main(int argc, char** argv) { return 0; } + +#endif /* GRPC_LINUX_ERRQUEUE */ diff --git a/test/core/iomgr/endpoint_tests.cc b/test/core/iomgr/endpoint_tests.cc index 8db8ac5ed6f..a9e8ba86c5d 100644 --- a/test/core/iomgr/endpoint_tests.cc +++ b/test/core/iomgr/endpoint_tests.cc @@ -150,8 +150,8 @@ static void read_and_write_test_write_handler(void* data, grpc_error* error) { &state->current_write_data); grpc_slice_buffer_reset_and_unref(&state->outgoing); grpc_slice_buffer_addn(&state->outgoing, slices, nslices); - grpc_endpoint_write(state->write_ep, &state->outgoing, - &state->done_write); + grpc_endpoint_write(state->write_ep, &state->outgoing, &state->done_write, + nullptr); gpr_free(slices); return; } @@ -294,7 +294,8 @@ static void multiple_shutdown_test(grpc_endpoint_test_config config) { grpc_slice_buffer_add(&slice_buffer, grpc_slice_from_copied_string("a")); grpc_endpoint_write(f.client_ep, &slice_buffer, GRPC_CLOSURE_CREATE(inc_on_failure, &fail_count, - grpc_schedule_on_exec_ctx)); + grpc_schedule_on_exec_ctx), + nullptr); wait_for_fail_count(&fail_count, 3); grpc_endpoint_shutdown(f.client_ep, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Test Shutdown")); diff --git a/test/core/iomgr/tcp_posix_test.cc b/test/core/iomgr/tcp_posix_test.cc index 3e87831e440..6447cc234db 100644 --- a/test/core/iomgr/tcp_posix_test.cc +++ b/test/core/iomgr/tcp_posix_test.cc @@ -36,6 +36,9 @@ #include #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/iomgr/buffer_list.h" +#include "src/core/lib/iomgr/ev_posix.h" +#include "src/core/lib/iomgr/sockaddr_posix.h" #include "src/core/lib/slice/slice_internal.h" #include "test/core/iomgr/endpoint_tests.h" #include "test/core/util/test_config.h" @@ -68,6 +71,43 @@ static void create_sockets(int sv[2]) { GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0); } +static void create_inet_sockets(int sv[2]) { + /* Prepare listening socket */ + struct sockaddr_in addr; + memset(&addr, 0, sizeof(struct sockaddr_in)); + addr.sin_family = AF_INET; + int sock = socket(AF_INET, SOCK_STREAM, 0); + GPR_ASSERT(sock); + GPR_ASSERT(bind(sock, (sockaddr*)&addr, sizeof(sockaddr_in)) == 0); + listen(sock, 1); + + /* Prepare client socket and connect to server */ + socklen_t len = sizeof(sockaddr_in); + GPR_ASSERT(getsockname(sock, (sockaddr*)&addr, &len) == 0); + + int client = socket(AF_INET, SOCK_STREAM, 0); + GPR_ASSERT(client); + int ret; + do { + ret = connect(client, (sockaddr*)&addr, sizeof(sockaddr_in)); + } while (ret == -1 && errno == EINTR); + + /* Accept client connection */ + len = sizeof(socklen_t); + int server; + do { + server = accept(sock, (sockaddr*)&addr, (socklen_t*)&len); + } while (server == -1 && errno == EINTR); + GPR_ASSERT(server != -1); + + sv[0] = server; + sv[1] = client; + int flags = fcntl(sv[0], F_GETFL, 0); + GPR_ASSERT(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK) == 0); + flags = fcntl(sv[1], F_GETFL, 0); + GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0); +} + static ssize_t fill_socket(int fd) { ssize_t write_bytes; ssize_t total_bytes = 0; @@ -289,11 +329,10 @@ static grpc_slice* allocate_blocks(size_t num_bytes, size_t slice_size, static void write_done(void* user_data /* write_socket_state */, grpc_error* error) { + GPR_ASSERT(error == GRPC_ERROR_NONE); struct write_socket_state* state = static_cast(user_data); - gpr_log(GPR_INFO, "Write done callback called"); gpr_mu_lock(g_mu); - gpr_log(GPR_INFO, "Signalling write done"); state->write_done = 1; GPR_ASSERT( GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr))); @@ -340,10 +379,24 @@ void drain_socket_blocking(int fd, size_t num_bytes, size_t read_size) { gpr_free(buf); } +/* Verifier for timestamps callback for write_test */ +void timestamps_verifier(void* arg, grpc_core::Timestamps* ts, + grpc_error* error) { + GPR_ASSERT(error == GRPC_ERROR_NONE); + GPR_ASSERT(arg != nullptr); + GPR_ASSERT(ts->sendmsg_time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->scheduled_time.clock_type == GPR_CLOCK_REALTIME); + GPR_ASSERT(ts->acked_time.clock_type == GPR_CLOCK_REALTIME); + gpr_atm* done_timestamps = (gpr_atm*)arg; + gpr_atm_rel_store(done_timestamps, static_cast(1)); +} + /* Write to a socket using the grpc_tcp API, then drain it directly. Note that if the write does not complete immediately we need to drain the - socket in parallel with the read. */ -static void write_test(size_t num_bytes, size_t slice_size) { + socket in parallel with the read. If collect_timestamps is true, it will + try to get timestamps for the write. */ +static void write_test(size_t num_bytes, size_t slice_size, + bool collect_timestamps) { int sv[2]; grpc_endpoint* ep; struct write_socket_state state; @@ -356,19 +409,27 @@ static void write_test(size_t num_bytes, size_t slice_size) { grpc_timespec_to_millis_round_up(grpc_timeout_seconds_to_deadline(20)); grpc_core::ExecCtx exec_ctx; + if (collect_timestamps && !grpc_event_engine_can_track_errors()) { + return; + } + gpr_log(GPR_INFO, "Start write test with %" PRIuPTR " bytes, slice size %" PRIuPTR, num_bytes, slice_size); - create_sockets(sv); + if (collect_timestamps) { + create_inet_sockets(sv); + } else { + create_sockets(sv); + } grpc_arg a[1]; a[0].key = const_cast(GRPC_ARG_TCP_READ_CHUNK_SIZE); a[0].type = GRPC_ARG_INTEGER, a[0].value.integer = static_cast(slice_size); grpc_channel_args args = {GPR_ARRAY_SIZE(a), a}; - ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test", false), &args, - "test"); + ep = grpc_tcp_create(grpc_fd_create(sv[1], "write_test", collect_timestamps), + &args, "test"); grpc_endpoint_add_to_pollset(ep, g_pollset); state.ep = ep; @@ -381,18 +442,26 @@ static void write_test(size_t num_bytes, size_t slice_size) { GRPC_CLOSURE_INIT(&write_done_closure, write_done, &state, grpc_schedule_on_exec_ctx); - grpc_endpoint_write(ep, &outgoing, &write_done_closure); + gpr_atm done_timestamps; + gpr_atm_rel_store(&done_timestamps, static_cast(0)); + grpc_endpoint_write(ep, &outgoing, &write_done_closure, + grpc_event_engine_can_track_errors() && collect_timestamps + ? (void*)&done_timestamps + : nullptr); drain_socket_blocking(sv[0], num_bytes, num_bytes); + exec_ctx.Flush(); gpr_mu_lock(g_mu); for (;;) { grpc_pollset_worker* worker = nullptr; - if (state.write_done) { + if (state.write_done && + (!(grpc_event_engine_can_track_errors() && collect_timestamps) || + gpr_atm_acq_load(&done_timestamps) == static_cast(1))) { break; } GPR_ASSERT(GRPC_LOG_IF_ERROR( "pollset_work", grpc_pollset_work(g_pollset, &worker, deadline))); gpr_mu_unlock(g_mu); - + exec_ctx.Flush(); gpr_mu_lock(g_mu); } gpr_mu_unlock(g_mu); @@ -497,14 +566,21 @@ void run_tests(void) { large_read_test(8192); large_read_test(1); - write_test(100, 8192); - write_test(100, 1); - write_test(100000, 8192); - write_test(100000, 1); - write_test(100000, 137); + write_test(100, 8192, false); + write_test(100, 1, false); + write_test(100000, 8192, false); + write_test(100000, 1, false); + write_test(100000, 137, false); + + write_test(100, 8192, true); + write_test(100, 1, true); + write_test(100000, 8192, true); + write_test(100000, 1, true); + write_test(100, 137, true); for (i = 1; i < 1000; i = GPR_MAX(i + 1, i * 5 / 4)) { - write_test(40320, i); + write_test(40320, i, false); + write_test(40320, i, true); } release_fd_test(100, 8192); @@ -549,6 +625,7 @@ int main(int argc, char** argv) { grpc_closure destroyed; grpc_test_init(argc, argv); grpc_init(); + grpc_core::grpc_tcp_set_write_timestamps_callback(timestamps_verifier); { grpc_core::ExecCtx exec_ctx; g_pollset = static_cast(gpr_zalloc(grpc_pollset_size())); diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc index 1156cd5fc5c..ef6fd62b516 100644 --- a/test/core/util/mock_endpoint.cc +++ b/test/core/util/mock_endpoint.cc @@ -55,7 +55,7 @@ static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices, } static void me_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { mock_endpoint* m = reinterpret_cast(ep); for (size_t i = 0; i < slices->count; i++) { m->on_write(slices->slices[i]); diff --git a/test/core/util/passthru_endpoint.cc b/test/core/util/passthru_endpoint.cc index 59582167478..3cc8ad6fe14 100644 --- a/test/core/util/passthru_endpoint.cc +++ b/test/core/util/passthru_endpoint.cc @@ -76,7 +76,7 @@ static half* other_half(half* h) { } static void me_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { half* m = other_half(reinterpret_cast(ep)); gpr_mu_lock(&m->parent->mu); grpc_error* error = GRPC_ERROR_NONE; diff --git a/test/core/util/trickle_endpoint.cc b/test/core/util/trickle_endpoint.cc index f2efb049b49..62ed72a6295 100644 --- a/test/core/util/trickle_endpoint.cc +++ b/test/core/util/trickle_endpoint.cc @@ -62,7 +62,7 @@ static void maybe_call_write_cb_locked(trickle_endpoint* te) { } static void te_write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { trickle_endpoint* te = reinterpret_cast(ep); gpr_mu_lock(&te->mu); GPR_ASSERT(te->write_cb == nullptr); @@ -186,7 +186,8 @@ size_t grpc_trickle_endpoint_trickle(grpc_endpoint* ep) { te->last_write = now; grpc_endpoint_write( te->wrapped, &te->writing_buffer, - GRPC_CLOSURE_CREATE(te_finish_write, te, grpc_schedule_on_exec_ctx)); + GRPC_CLOSURE_CREATE(te_finish_write, te, grpc_schedule_on_exec_ctx), + nullptr); maybe_call_write_cb_locked(te); } } diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index 1e9bd273aaf..189923a841e 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -96,7 +96,7 @@ class DummyEndpoint : public grpc_endpoint { } static void write(grpc_endpoint* ep, grpc_slice_buffer* slices, - grpc_closure* cb) { + grpc_closure* cb, void* arg) { GRPC_CLOSURE_SCHED(cb, GRPC_ERROR_NONE); } diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 43ebf8cad95..e6d4b1d98fb 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1067,6 +1067,7 @@ src/core/lib/http/format_request.h \ src/core/lib/http/httpcli.h \ src/core/lib/http/parser.h \ src/core/lib/iomgr/block_annotate.h \ +src/core/lib/iomgr/buffer_list.h \ src/core/lib/iomgr/call_combiner.h \ src/core/lib/iomgr/closure.h \ src/core/lib/iomgr/combiner.h \ @@ -1082,6 +1083,7 @@ src/core/lib/iomgr/ev_posix.h \ src/core/lib/iomgr/exec_ctx.h \ src/core/lib/iomgr/executor.h \ src/core/lib/iomgr/gethostname.h \ +src/core/lib/iomgr/internal_errqueue.h \ src/core/lib/iomgr/iocp_windows.h \ src/core/lib/iomgr/iomgr.h \ src/core/lib/iomgr/iomgr_custom.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index c1706fd070b..7cd1dc7bf37 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1159,6 +1159,8 @@ src/core/lib/http/parser.cc \ src/core/lib/http/parser.h \ src/core/lib/iomgr/README.md \ src/core/lib/iomgr/block_annotate.h \ +src/core/lib/iomgr/buffer_list.cc \ +src/core/lib/iomgr/buffer_list.h \ src/core/lib/iomgr/call_combiner.cc \ src/core/lib/iomgr/call_combiner.h \ src/core/lib/iomgr/closure.h \ @@ -1194,6 +1196,8 @@ src/core/lib/iomgr/gethostname.h \ src/core/lib/iomgr/gethostname_fallback.cc \ src/core/lib/iomgr/gethostname_host_name_max.cc \ src/core/lib/iomgr/gethostname_sysconf.cc \ +src/core/lib/iomgr/internal_errqueue.cc \ +src/core/lib/iomgr/internal_errqueue.h \ src/core/lib/iomgr/iocp_windows.cc \ src/core/lib/iomgr/iocp_windows.h \ src/core/lib/iomgr/iomgr.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 5014aea9cd0..8ea5126fdef 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -163,6 +163,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "buffer_list_test", + "src": [ + "test/core/iomgr/buffer_list_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -9488,6 +9505,7 @@ "src/core/lib/http/format_request.cc", "src/core/lib/http/httpcli.cc", "src/core/lib/http/parser.cc", + "src/core/lib/iomgr/buffer_list.cc", "src/core/lib/iomgr/call_combiner.cc", "src/core/lib/iomgr/combiner.cc", "src/core/lib/iomgr/endpoint.cc", @@ -9508,6 +9526,7 @@ "src/core/lib/iomgr/gethostname_fallback.cc", "src/core/lib/iomgr/gethostname_host_name_max.cc", "src/core/lib/iomgr/gethostname_sysconf.cc", + "src/core/lib/iomgr/internal_errqueue.cc", "src/core/lib/iomgr/iocp_windows.cc", "src/core/lib/iomgr/iomgr.cc", "src/core/lib/iomgr/iomgr_custom.cc", @@ -9667,6 +9686,7 @@ "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", "src/core/lib/iomgr/block_annotate.h", + "src/core/lib/iomgr/buffer_list.h", "src/core/lib/iomgr/call_combiner.h", "src/core/lib/iomgr/closure.h", "src/core/lib/iomgr/combiner.h", @@ -9682,6 +9702,7 @@ "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", + "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", "src/core/lib/iomgr/iomgr_custom.h", @@ -9817,6 +9838,7 @@ "src/core/lib/http/httpcli.h", "src/core/lib/http/parser.h", "src/core/lib/iomgr/block_annotate.h", + "src/core/lib/iomgr/buffer_list.h", "src/core/lib/iomgr/call_combiner.h", "src/core/lib/iomgr/closure.h", "src/core/lib/iomgr/combiner.h", @@ -9832,6 +9854,7 @@ "src/core/lib/iomgr/exec_ctx.h", "src/core/lib/iomgr/executor.h", "src/core/lib/iomgr/gethostname.h", + "src/core/lib/iomgr/internal_errqueue.h", "src/core/lib/iomgr/iocp_windows.h", "src/core/lib/iomgr/iomgr.h", "src/core/lib/iomgr/iomgr_custom.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 51c7b57d8ae..fba76d69d1e 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -195,6 +195,26 @@ ], "uses_polling": false }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "gtest": false, + "language": "c", + "name": "buffer_list_test", + "platforms": [ + "linux" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From 0cb982974f12ead39b6a8969949f2fbbe59cf3cf Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 27 Aug 2018 15:10:25 -0700 Subject: [PATCH 232/546] Remove linux/version.h include from port.h --- src/core/lib/iomgr/internal_errqueue.cc | 4 ---- src/core/lib/iomgr/port.h | 1 - 2 files changed, 5 deletions(-) diff --git a/src/core/lib/iomgr/internal_errqueue.cc b/src/core/lib/iomgr/internal_errqueue.cc index 8823737e494..99c22e90555 100644 --- a/src/core/lib/iomgr/internal_errqueue.cc +++ b/src/core/lib/iomgr/internal_errqueue.cc @@ -24,10 +24,6 @@ #ifdef GRPC_POSIX_SOCKET_TCP -#ifdef GPR_LINUX -#include -#endif /* GPR_LINUX */ - bool kernel_supports_errqueue() { #ifdef LINUX_VERSION_CODE #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index a4688fd0efb..abf96662f51 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -60,7 +60,6 @@ #define GRPC_HAVE_IP_PKTINFO 1 #define GRPC_HAVE_MSG_NOSIGNAL 1 #define GRPC_HAVE_UNIX_SOCKET 1 -#include #ifdef LINUX_VERSION_CODE #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) #define GRPC_LINUX_ERRQUEUE 1 From 86530acca735b6ba49dee12bfc7e80d86d49c0cb Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 27 Aug 2018 15:14:58 -0700 Subject: [PATCH 233/546] Include linux/version.h in port_platform.h --- include/grpc/impl/codegen/port_platform.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 8d9bd832855..b2028a63053 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -174,6 +174,7 @@ #ifdef __GLIBC__ #define GPR_POSIX_CRASH_HANDLER 1 #define GPR_LINUX_PTHREAD_NAME 1 +#include #else /* musl libc */ #define GPR_MUSL_LIBC_COMPAT 1 #endif From 21824afb09d67390d1d9b6a5179a0695df9bb439 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 27 Aug 2018 15:30:52 -0700 Subject: [PATCH 234/546] used alternative approach - generated bazel scenarios --- test/cpp/qps/BUILD | 75 +++++------------- .../qps/json_run_localhost_scenario_gen.py | 20 +++-- test/cpp/qps/json_run_localhost_scenarios.bzl | 1 + .../cpp/qps/json_run_localhost_scenarios.json | 1 - test/cpp/qps/qps_benchmark_script.bzl | 76 +++++++++++++++++++ test/cpp/qps/qps_json_driver_scenario_gen.py | 8 +- test/cpp/qps/qps_json_driver_scenarios.bzl | 1 + test/cpp/qps/qps_json_driver_scenarios.json | 1 - 8 files changed, 114 insertions(+), 69 deletions(-) create mode 100644 test/cpp/qps/json_run_localhost_scenarios.bzl delete mode 100644 test/cpp/qps/json_run_localhost_scenarios.json create mode 100644 test/cpp/qps/qps_benchmark_script.bzl create mode 100644 test/cpp/qps/qps_json_driver_scenarios.bzl delete mode 100644 test/cpp/qps/qps_json_driver_scenarios.json diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index bf0f6186e42..483b29b1b36 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -15,6 +15,7 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_library", "grpc_cc_binary", "grpc_package") +load("//test/cpp/qps:qps_benchmark_script.bzl", "qps_json_driver_batch", "json_run_localhost_batch") grpc_package(name = "test/cpp/qps") @@ -117,6 +118,21 @@ grpc_cc_library( deps = ["//test/core/util:grpc_test_util"], ) +grpc_cc_binary( + name = "qps_json_driver", + srcs = ["qps_json_driver.cc"], + external_deps = [ + "gflags", + ], + deps = [ + ":benchmark_config", + ":driver_impl", + "//:grpc++", + "//test/cpp/util:test_config", + "//test/cpp/util:test_util", + ], +) + grpc_cc_test( name = "inproc_sync_unary_ping_pong_test", srcs = ["inproc_sync_unary_ping_pong_test.cc"], @@ -135,34 +151,9 @@ grpc_cc_library( deps = ["//:grpc++"], ) -filegroup( - name = "json_run_localhost_scenarios", - srcs = [ - ":json_run_localhost_scenarios.json", - ], -) +qps_json_driver_batch() -grpc_cc_test( - name = "json_run_localhost", - timeout = "eternal", - srcs = ["json_run_localhost.cc"], - args = [ - "--scenarios_file", - "$(location //test/cpp/qps:json_run_localhost_scenarios)", - ], - data = [ - "//test/cpp/qps:json_run_localhost_scenarios", - "//test/cpp/qps:qps_json_driver", - "//test/cpp/qps:qps_worker", - ], - deps = [ - "//:gpr", - "//test/core/util:gpr_test_util", - "//test/core/util:grpc_test_util", - "//test/cpp/util:test_config", - "//test/cpp/util:test_util", - ], -) +json_run_localhost_batch() grpc_cc_test( name = "qps_interarrival_test", @@ -174,36 +165,6 @@ grpc_cc_test( ], ) -filegroup( - name = "qps_json_driver_scenarios", - srcs = [ - ":qps_json_driver_scenarios.json", - ], -) - -grpc_cc_test( - name = "qps_json_driver", - srcs = ["qps_json_driver.cc"], - args = [ - "--run_inproc", - "--scenarios_file", - "$(location //test/cpp/qps:qps_json_driver_scenarios)", - ], - data = [ - "//test/cpp/qps:qps_json_driver_scenarios", - ], - external_deps = [ - "gflags", - ], - deps = [ - ":benchmark_config", - ":driver_impl", - "//:grpc++", - "//test/cpp/util:test_config", - "//test/cpp/util:test_util", - ], -) - grpc_cc_test( name = "qps_openloop_test", srcs = ["qps_openloop_test.cc"], diff --git a/test/cpp/qps/json_run_localhost_scenario_gen.py b/test/cpp/qps/json_run_localhost_scenario_gen.py index 82b2932f3f1..f0c825a1e1b 100755 --- a/test/cpp/qps/json_run_localhost_scenario_gen.py +++ b/test/cpp/qps/json_run_localhost_scenario_gen.py @@ -20,15 +20,19 @@ import json def generate_args(): all_scenario_set = gen.generate_yaml() all_scenario_set = all_scenario_set['tests'] - qps_json_driver_scenario_set = \ - [item for item in all_scenario_set if item['name'] == 'json_run_localhost'] - qps_json_driver_arg_set = \ - [item['args'][1] for item in qps_json_driver_scenario_set \ - if 'args' in item and len(item['args']) > 1] + json_run_localhost_scenarios = \ + [item for item in all_scenario_set if item['name'] == 'qps_json_driver'] + json_run_localhost_arg_set = \ + [item['args'][2] for item in json_run_localhost_scenarios \ + if 'args' in item and len(item['args']) > 2] deserialized_scenarios = [json.loads(item)['scenarios'][0] \ - for item in qps_json_driver_arg_set] - all_scenarios = {'scenarios': deserialized_scenarios} - print('\'' + json.dumps(all_scenarios) + '\'') + for item in json_run_localhost_arg_set] + all_scenarios = [{'scenarios' : [scenario]} \ + for scenario in deserialized_scenarios] + serialized_scenarios_str = str(['\'' + json.dumps(scenario) + '\'' \ + for scenario in all_scenarios]) + with open('json_run_localhost_scenarios.bzl', 'wb') as f: + f.write('JSON_RUN_LOCALHOST_SCENARIOS = ' + serialized_scenarios_str + '\n') generate_args() diff --git a/test/cpp/qps/json_run_localhost_scenarios.bzl b/test/cpp/qps/json_run_localhost_scenarios.bzl new file mode 100644 index 00000000000..1e170ccb35b --- /dev/null +++ b/test/cpp/qps/json_run_localhost_scenarios.bzl @@ -0,0 +1 @@ +JSON_RUN_LOCALHOST_SCENARIOS = ['\'{"scenarios": [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\''] diff --git a/test/cpp/qps/json_run_localhost_scenarios.json b/test/cpp/qps/json_run_localhost_scenarios.json deleted file mode 100644 index e32fc8f610e..00000000000 --- a/test/cpp/qps/json_run_localhost_scenarios.json +++ /dev/null @@ -1 +0,0 @@ -{"scenarios": [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_75Kqps_600channel_60Krpcs_300Breq_50Bresp", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 16, "threads_per_cq": 1, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"poisson": {"offered_load": 37500}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 50, "req_size": 300}}, "client_channels": 300, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_75Kqps_600channel_60Krpcs_300Breq_50Bresp", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 16, "threads_per_cq": 1, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"poisson": {"offered_load": 37500}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 50, "req_size": 300}}, "client_channels": 300, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_one_server_core_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]} \ No newline at end of file diff --git a/test/cpp/qps/qps_benchmark_script.bzl b/test/cpp/qps/qps_benchmark_script.bzl new file mode 100644 index 00000000000..0b823672add --- /dev/null +++ b/test/cpp/qps/qps_benchmark_script.bzl @@ -0,0 +1,76 @@ +# 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. + +# +# This is for the gRPC build system. This isn't intended to be used outsite of +# the BUILD file for gRPC. It contains the mapping for the template system we +# use to generate other platform's build system files. +# +# Please consider that there should be a high bar for additions and changes to +# this file. +# Each rule listed must be re-written for Google's internal build system, and +# each change must be ported from one to the other. +# + +load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_test") +load("//test/cpp/qps:qps_json_driver_scenarios.bzl", "QPS_JSON_DRIVER_SCENARIOS") +load("//test/cpp/qps:json_run_localhost_scenarios.bzl", "JSON_RUN_LOCALHOST_SCENARIOS") + +def qps_json_driver_batch(): + idx = 0 # number for differentiating names + for scenario in QPS_JSON_DRIVER_SCENARIOS: + grpc_cc_test( + name = "qps_json_driver_test_%s" % str(idx), + srcs = ["qps_json_driver.cc"], + args = [ + "--run_inproc", + "--scenarios_json", + scenario, + ], + external_deps = [ + "gflags", + ], + deps = [ + ":benchmark_config", + ":driver_impl", + "//:grpc++", + "//test/cpp/util:test_config", + "//test/cpp/util:test_util", + ], + ) + idx += 1 + +def json_run_localhost_batch(): + idx = 0 # number for differentiating names + for scenario in JSON_RUN_LOCALHOST_SCENARIOS: + grpc_cc_test( + name = "json_run_localhost_%s" % str(idx), + srcs = ["json_run_localhost.cc"], + args = [ + "--scenarios_json", + scenario, + ], + data = [ + "//test/cpp/qps:qps_json_driver", + "//test/cpp/qps:qps_worker", + ], + deps = [ + "//:gpr", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_config", + "//test/cpp/util:test_util", + ], + ) + idx += 1 diff --git a/test/cpp/qps/qps_json_driver_scenario_gen.py b/test/cpp/qps/qps_json_driver_scenario_gen.py index 99bc3828f84..7afa282073b 100755 --- a/test/cpp/qps/qps_json_driver_scenario_gen.py +++ b/test/cpp/qps/qps_json_driver_scenario_gen.py @@ -27,8 +27,12 @@ def generate_args(): if 'args' in item and len(item['args']) > 2] deserialized_scenarios = [json.loads(item)['scenarios'][0] \ for item in qps_json_driver_arg_set] - all_scenarios = {'scenarios': deserialized_scenarios} - print('\'' + json.dumps(all_scenarios) + '\'') + all_scenarios = [{'scenarios' : [scenario]} \ + for scenario in deserialized_scenarios] + serialized_scenarios_str = str(['\'' + json.dumps(scenario) + '\'' \ + for scenario in all_scenarios]) + with open('qps_json_driver_scenarios.bzl', 'wb') as f: + f.write('QPS_JSON_DRIVER_SCENARIOS = ' + serialized_scenarios_str + '\n') generate_args() diff --git a/test/cpp/qps/qps_json_driver_scenarios.bzl b/test/cpp/qps/qps_json_driver_scenarios.bzl new file mode 100644 index 00000000000..2d401261afd --- /dev/null +++ b/test/cpp/qps/qps_json_driver_scenarios.bzl @@ -0,0 +1 @@ +QPS_JSON_DRIVER_SCENARIOS = ['\'{"scenarios": [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\''] diff --git a/test/cpp/qps/qps_json_driver_scenarios.json b/test/cpp/qps/qps_json_driver_scenarios.json deleted file mode 100644 index d8b3413f91f..00000000000 --- a/test/cpp/qps/qps_json_driver_scenarios.json +++ /dev/null @@ -1 +0,0 @@ -{"scenarios": [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}, {"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}, {"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]} \ No newline at end of file From 0ce7f91d9eb8d17e32e33716079e04e61ea07aac Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Mon, 27 Aug 2018 16:10:25 -0700 Subject: [PATCH 235/546] used names instead of numbers for each scenario --- test/cpp/qps/json_run_localhost_scenario_gen.py | 8 ++++---- test/cpp/qps/json_run_localhost_scenarios.bzl | 2 +- test/cpp/qps/qps_benchmark_script.bzl | 12 ++++-------- test/cpp/qps/qps_json_driver_scenario_gen.py | 10 +++++----- test/cpp/qps/qps_json_driver_scenarios.bzl | 2 +- tools/buildgen/generate_build_additions.sh | 0 6 files changed, 15 insertions(+), 19 deletions(-) mode change 100644 => 100755 tools/buildgen/generate_build_additions.sh diff --git a/test/cpp/qps/json_run_localhost_scenario_gen.py b/test/cpp/qps/json_run_localhost_scenario_gen.py index f0c825a1e1b..3cd2b799fec 100755 --- a/test/cpp/qps/json_run_localhost_scenario_gen.py +++ b/test/cpp/qps/json_run_localhost_scenario_gen.py @@ -27,11 +27,11 @@ def generate_args(): if 'args' in item and len(item['args']) > 2] deserialized_scenarios = [json.loads(item)['scenarios'][0] \ for item in json_run_localhost_arg_set] - all_scenarios = [{'scenarios' : [scenario]} \ - for scenario in deserialized_scenarios] + all_scenarios = {scenario['name'].encode('ascii', 'ignore'): \ + '\'{\'scenarios\' : [' + json.dumps(scenario) + ']}\'' \ + for scenario in deserialized_scenarios} - serialized_scenarios_str = str(['\'' + json.dumps(scenario) + '\'' \ - for scenario in all_scenarios]) + serialized_scenarios_str = str(all_scenarios).encode('ascii', 'ignore') with open('json_run_localhost_scenarios.bzl', 'wb') as f: f.write('JSON_RUN_LOCALHOST_SCENARIOS = ' + serialized_scenarios_str + '\n') diff --git a/test/cpp/qps/json_run_localhost_scenarios.bzl b/test/cpp/qps/json_run_localhost_scenarios.bzl index 1e170ccb35b..589dcac2b54 100644 --- a/test/cpp/qps/json_run_localhost_scenarios.bzl +++ b/test/cpp/qps/json_run_localhost_scenarios.bzl @@ -1 +1 @@ -JSON_RUN_LOCALHOST_SCENARIOS = ['\'{"scenarios": [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\''] +JSON_RUN_LOCALHOST_SCENARIOS = {'cpp_protobuf_sync_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_ping_pong_insecure_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_1channel_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_unary_1channel_100rpcs_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\''} diff --git a/test/cpp/qps/qps_benchmark_script.bzl b/test/cpp/qps/qps_benchmark_script.bzl index 0b823672add..90902c0d41d 100644 --- a/test/cpp/qps/qps_benchmark_script.bzl +++ b/test/cpp/qps/qps_benchmark_script.bzl @@ -28,15 +28,14 @@ load("//test/cpp/qps:qps_json_driver_scenarios.bzl", "QPS_JSON_DRIVER_SCENARIOS" load("//test/cpp/qps:json_run_localhost_scenarios.bzl", "JSON_RUN_LOCALHOST_SCENARIOS") def qps_json_driver_batch(): - idx = 0 # number for differentiating names for scenario in QPS_JSON_DRIVER_SCENARIOS: grpc_cc_test( - name = "qps_json_driver_test_%s" % str(idx), + name = "qps_json_driver_test_%s" % scenario, srcs = ["qps_json_driver.cc"], args = [ "--run_inproc", "--scenarios_json", - scenario, + QPS_JSON_DRIVER_SCENARIOS[scenario], ], external_deps = [ "gflags", @@ -49,17 +48,15 @@ def qps_json_driver_batch(): "//test/cpp/util:test_util", ], ) - idx += 1 def json_run_localhost_batch(): - idx = 0 # number for differentiating names for scenario in JSON_RUN_LOCALHOST_SCENARIOS: grpc_cc_test( - name = "json_run_localhost_%s" % str(idx), + name = "json_run_localhost_%s" % scenario, srcs = ["json_run_localhost.cc"], args = [ "--scenarios_json", - scenario, + JSON_RUN_LOCALHOST_SCENARIOS[scenario], ], data = [ "//test/cpp/qps:qps_json_driver", @@ -73,4 +70,3 @@ def json_run_localhost_batch(): "//test/cpp/util:test_util", ], ) - idx += 1 diff --git a/test/cpp/qps/qps_json_driver_scenario_gen.py b/test/cpp/qps/qps_json_driver_scenario_gen.py index 7afa282073b..28fbb895856 100755 --- a/test/cpp/qps/qps_json_driver_scenario_gen.py +++ b/test/cpp/qps/qps_json_driver_scenario_gen.py @@ -27,12 +27,12 @@ def generate_args(): if 'args' in item and len(item['args']) > 2] deserialized_scenarios = [json.loads(item)['scenarios'][0] \ for item in qps_json_driver_arg_set] - all_scenarios = [{'scenarios' : [scenario]} \ - for scenario in deserialized_scenarios] + all_scenarios = {scenario['name'].encode('ascii', 'ignore'): \ + '\'{\'scenarios\' : [' + json.dumps(scenario) + ']}\'' \ + for scenario in deserialized_scenarios} - serialized_scenarios_str = str(['\'' + json.dumps(scenario) + '\'' \ - for scenario in all_scenarios]) - with open('qps_json_driver_scenarios.bzl', 'wb') as f: + serialized_scenarios_str = str(all_scenarios).encode('ascii', 'ignore') + with open('qps_json_driver_scenarios.bzl', 'w') as f: f.write('QPS_JSON_DRIVER_SCENARIOS = ' + serialized_scenarios_str + '\n') generate_args() diff --git a/test/cpp/qps/qps_json_driver_scenarios.bzl b/test/cpp/qps/qps_json_driver_scenarios.bzl index 2d401261afd..6e2c28a8e73 100644 --- a/test/cpp/qps/qps_json_driver_scenarios.bzl +++ b/test/cpp/qps/qps_json_driver_scenarios.bzl @@ -1 +1 @@ -QPS_JSON_DRIVER_SCENARIOS = ['\'{"scenarios": [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', '\'{"scenarios": [{"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\''] +QPS_JSON_DRIVER_SCENARIOS = {'cpp_protobuf_sync_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_ping_pong_insecure_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_1channel_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_unary_1channel_100rpcs_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\''} diff --git a/tools/buildgen/generate_build_additions.sh b/tools/buildgen/generate_build_additions.sh old mode 100644 new mode 100755 From 005cb34614a9084a0230bfe62daa2e83b735b595 Mon Sep 17 00:00:00 2001 From: ganmacs Date: Tue, 28 Aug 2018 16:21:58 +0900 Subject: [PATCH 236/546] Rescue GRPC::Core::CallError not to kill the worker threads --- src/ruby/lib/grpc/generic/rpc_server.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index 838ac45927b..3b5a0ce27f3 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -136,7 +136,7 @@ module GRPC begin blk, args = worker_queue.pop blk.call(*args) - rescue StandardError => e + rescue StandardError, GRPC::Core::CallError => e GRPC.logger.warn('Error in worker thread') GRPC.logger.warn(e) end From bbfb05f61fce9f179484b6d4cf4d1c3c35b500ea Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 28 Aug 2018 10:33:00 +0200 Subject: [PATCH 237/546] run remote bazel tests with GRPC_VERBOSITY=debug --- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 1 + tools/internal_ci/linux/grpc_msan_on_foundry.sh | 1 + tools/internal_ci/linux/grpc_ubsan_on_foundry.sh | 1 + tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh | 1 + 4 files changed, 4 insertions(+) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index b35e6102fc6..3d4d90317c0 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -57,6 +57,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ --remote_instance_name=grpc-testing/instances/default_instance \ + --test_env=GRPC_VERBOSITY=debug \ $1 \ -- //test/... || FAILED="true" diff --git a/tools/internal_ci/linux/grpc_msan_on_foundry.sh b/tools/internal_ci/linux/grpc_msan_on_foundry.sh index dc766b883de..19cfc1739a2 100644 --- a/tools/internal_ci/linux/grpc_msan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_msan_on_foundry.sh @@ -66,6 +66,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ --remote_instance_name=grpc-testing/instances/default_instance \ + --test_env=GRPC_VERBOSITY=debug \ -- //test/... || FAILED="true" # Sleep to let ResultStore finish writing results before querying diff --git a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh index ad3e28a3940..edb2069fb28 100644 --- a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh @@ -63,6 +63,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --platforms=//third_party/toolchains:rbe_ubuntu1604 \ --cache_test_results=no \ --remote_instance_name=grpc-testing/instances/default_instance \ + --test_env=GRPC_VERBOSITY=debug \ -- //test/... || FAILED="true" # Sleep to let ResultStore finish writing results before querying diff --git a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh index 5426ca56f7e..f8c93142366 100644 --- a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh @@ -62,6 +62,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ --remote_instance_name=grpc-testing/instances/default_instance \ + --test_env=GRPC_VERBOSITY=debug \ -- //test/... || FAILED="true" if [ "$FAILED" != "" ] From 99ce3e19afeb445245a8c2a341196ca3356501a4 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 28 Aug 2018 08:51:52 -0700 Subject: [PATCH 238/546] Implement Watch method in health check service. --- .../grpcpp/impl/codegen/completion_queue.h | 1 + .../health/default_health_check_service.cc | 484 +++++++++++++++--- .../health/default_health_check_service.h | 242 ++++++++- src/cpp/server/health/health.pb.c | 1 - src/cpp/server/health/health.pb.h | 7 +- src/cpp/server/server_cc.cc | 27 +- src/proto/grpc/health/v1/health.proto | 20 + .../end2end/health_service_end2end_test.cc | 76 ++- tools/distrib/check_nanopb_output.sh | 18 + 9 files changed, 771 insertions(+), 105 deletions(-) diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 3f7d4fb765f..6c8428ebde6 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -384,6 +384,7 @@ class ServerCompletionQueue : public CompletionQueue { grpc_cq_polling_type polling_type_; friend class ServerBuilder; + friend class Server; }; } // namespace grpc diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index bfda67d0864..670da63a4a0 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -30,29 +30,162 @@ #include "src/cpp/server/health/health.pb.h" namespace grpc { + +// +// DefaultHealthCheckService +// + +DefaultHealthCheckService::DefaultHealthCheckService() { + services_map_[""].SetServingStatus(SERVING); +} + +void DefaultHealthCheckService::SetServingStatus( + const grpc::string& service_name, bool serving) { + std::unique_lock lock(mu_); + services_map_[service_name].SetServingStatus(serving ? SERVING : NOT_SERVING); +} + +void DefaultHealthCheckService::SetServingStatus(bool serving) { + const ServingStatus status = serving ? SERVING : NOT_SERVING; + std::unique_lock lock(mu_); + for (auto& p : services_map_) { + ServiceData& service_data = p.second; + service_data.SetServingStatus(status); + } +} + +DefaultHealthCheckService::ServingStatus +DefaultHealthCheckService::GetServingStatus( + const grpc::string& service_name) const { + std::lock_guard lock(mu_); + auto it = services_map_.find(service_name); + if (it == services_map_.end()) { + return NOT_FOUND; + } + const ServiceData& service_data = it->second; + return service_data.GetServingStatus(); +} + +void DefaultHealthCheckService::RegisterCallHandler( + const grpc::string& service_name, + std::shared_ptr handler) { + std::unique_lock lock(mu_); + ServiceData& service_data = services_map_[service_name]; + service_data.AddCallHandler(handler /* copies ref */); + handler->SendHealth(std::move(handler), service_data.GetServingStatus()); +} + +void DefaultHealthCheckService::UnregisterCallHandler( + const grpc::string& service_name, + std::shared_ptr handler) { + std::unique_lock lock(mu_); + auto it = services_map_.find(service_name); + if (it == services_map_.end()) return; + ServiceData& service_data = it->second; + service_data.RemoveCallHandler(std::move(handler)); + if (service_data.Unused()) { + services_map_.erase(it); + } +} + +DefaultHealthCheckService::HealthCheckServiceImpl* +DefaultHealthCheckService::GetHealthCheckService( + std::unique_ptr cq) { + GPR_ASSERT(impl_ == nullptr); + impl_.reset(new HealthCheckServiceImpl(this, std::move(cq))); + return impl_.get(); +} + +// +// DefaultHealthCheckService::ServiceData +// + +void DefaultHealthCheckService::ServiceData::SetServingStatus( + ServingStatus status) { + status_ = status; + for (auto& call_handler : call_handlers_) { + call_handler->SendHealth(call_handler /* copies ref */, status); + } +} + +void DefaultHealthCheckService::ServiceData::AddCallHandler( + std::shared_ptr handler) { + call_handlers_.insert(std::move(handler)); +} + +void DefaultHealthCheckService::ServiceData::RemoveCallHandler( + std::shared_ptr handler) { + call_handlers_.erase(std::move(handler)); +} + +// +// DefaultHealthCheckService::HealthCheckServiceImpl +// + namespace { const char kHealthCheckMethodName[] = "/grpc.health.v1.Health/Check"; +const char kHealthWatchMethodName[] = "/grpc.health.v1.Health/Watch"; } // namespace DefaultHealthCheckService::HealthCheckServiceImpl::HealthCheckServiceImpl( - DefaultHealthCheckService* service) - : service_(service), method_(nullptr) { - internal::MethodHandler* handler = - new internal::RpcMethodHandler( - std::mem_fn(&HealthCheckServiceImpl::Check), this); - method_ = new internal::RpcServiceMethod( - kHealthCheckMethodName, internal::RpcMethod::NORMAL_RPC, handler); - AddMethod(method_); -} - -Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( - ServerContext* context, const ByteBuffer* request, ByteBuffer* response) { - // Decode request. - std::vector slices; - if (!request->Dump(&slices).ok()) { - return Status(StatusCode::INVALID_ARGUMENT, ""); + DefaultHealthCheckService* database, + std::unique_ptr cq) + : database_(database), cq_(std::move(cq)) { + // Add Check() method. + check_method_ = new internal::RpcServiceMethod( + kHealthCheckMethodName, internal::RpcMethod::NORMAL_RPC, nullptr); + AddMethod(check_method_); + // Add Watch() method. + watch_method_ = new internal::RpcServiceMethod( + kHealthWatchMethodName, internal::RpcMethod::SERVER_STREAMING, nullptr); + AddMethod(watch_method_); + // Create serving thread. + thread_ = std::unique_ptr<::grpc_core::Thread>( + new ::grpc_core::Thread("grpc_health_check_service", Serve, this)); +} + +DefaultHealthCheckService::HealthCheckServiceImpl::~HealthCheckServiceImpl() { + // We will reach here after the server starts shutting down. + shutdown_ = true; + { + std::unique_lock lock(cq_shutdown_mu_); + cq_->Shutdown(); + } + thread_->Join(); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::StartServingThread() { + thread_->Start(); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::Serve(void* arg) { + HealthCheckServiceImpl* service = + reinterpret_cast(arg); + // TODO(juanlishen): This is a workaround to wait for the cq to be ready. + // Need to figure out why cq is not ready after service starts. + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_seconds(1, GPR_TIMESPAN))); + CheckCallHandler::CreateAndStart(service->cq_.get(), service->database_, + service); + WatchCallHandler::CreateAndStart(service->cq_.get(), service->database_, + service); + void* tag; + bool ok; + while (true) { + if (!service->cq_->Next(&tag, &ok)) { + // The completion queue is shutting down. + GPR_ASSERT(service->shutdown_); + break; + } + auto* next_step = static_cast(tag); + next_step->Run(ok); } +} + +bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest( + const ByteBuffer& request, grpc::string* service_name) { + std::vector slices; + if (!request.Dump(&slices).ok()) return false; uint8_t* request_bytes = nullptr; bool request_bytes_owned = false; size_t request_size = 0; @@ -64,14 +197,13 @@ Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( request_size = slices[0].size(); } else { request_bytes_owned = true; - request_bytes = static_cast(gpr_malloc(request->Length())); + request_bytes = static_cast(gpr_malloc(request.Length())); uint8_t* copy_to = request_bytes; for (size_t i = 0; i < slices.size(); i++) { memcpy(copy_to, slices[i].begin(), slices[i].size()); copy_to += slices[i].size(); } } - if (request_bytes != nullptr) { pb_istream_t istream = pb_istream_from_buffer(request_bytes, request_size); bool decode_status = pb_decode( @@ -79,26 +211,22 @@ Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( if (request_bytes_owned) { gpr_free(request_bytes); } - if (!decode_status) { - return Status(StatusCode::INVALID_ARGUMENT, ""); - } - } - - // Check status from the associated default health checking service. - DefaultHealthCheckService::ServingStatus serving_status = - service_->GetServingStatus( - request_struct.has_service ? request_struct.service : ""); - if (serving_status == DefaultHealthCheckService::NOT_FOUND) { - return Status(StatusCode::NOT_FOUND, ""); + if (!decode_status) return false; } + *service_name = request_struct.has_service ? request_struct.service : ""; + return true; +} - // Encode response +bool DefaultHealthCheckService::HealthCheckServiceImpl::EncodeResponse( + ServingStatus status, ByteBuffer* response) { grpc_health_v1_HealthCheckResponse response_struct; response_struct.has_status = true; response_struct.status = - serving_status == DefaultHealthCheckService::SERVING - ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING - : grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING; + status == NOT_FOUND + ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN + : status == SERVING + ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING + : grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING; pb_ostream_t ostream; memset(&ostream, 0, sizeof(ostream)); pb_encode(&ostream, grpc_health_v1_HealthCheckResponse_fields, @@ -108,48 +236,282 @@ Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( GRPC_SLICE_LENGTH(response_slice)); bool encode_status = pb_encode( &ostream, grpc_health_v1_HealthCheckResponse_fields, &response_struct); - if (!encode_status) { - return Status(StatusCode::INTERNAL, "Failed to encode response."); - } + if (!encode_status) return false; Slice encoded_response(response_slice, Slice::STEAL_REF); ByteBuffer response_buffer(&encoded_response, 1); response->Swap(&response_buffer); - return Status::OK; + return true; } -DefaultHealthCheckService::DefaultHealthCheckService() { - services_map_.emplace("", true); +// +// DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler +// + +void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: + CreateAndStart(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service) { + std::shared_ptr self = + std::make_shared(cq, database, service); + CheckCallHandler* handler = static_cast(self.get()); + { + std::unique_lock lock(service->cq_shutdown_mu_); + if (service->shutdown_) return; + // Request a Check() call. + handler->next_ = + CallableTag(std::bind(&CheckCallHandler::OnCallReceived, handler, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + service->RequestAsyncUnary(0, &handler->ctx_, &handler->request_, + &handler->writer_, cq, cq, &handler->next_); + } } -void DefaultHealthCheckService::SetServingStatus( - const grpc::string& service_name, bool serving) { - std::lock_guard lock(mu_); - services_map_[service_name] = serving; +DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: + CheckCallHandler(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service) + : cq_(cq), database_(database), service_(service), writer_(&ctx_) {} + +void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: + OnCallReceived(std::shared_ptr self, bool ok) { + if (!ok) { + // The value of ok being false means that the server is shutting down. + return; + } + // Spawn a new handler instance to serve the next new client. Every handler + // instance will deallocate itself when it's done. + CreateAndStart(cq_, database_, service_); + // Process request. + gpr_log(GPR_DEBUG, "[HCS %p] Health check started for handler %p", service_, + this); + grpc::string service_name; + grpc::Status status = Status::OK; + ByteBuffer response; + if (!service_->DecodeRequest(request_, &service_name)) { + status = Status(INVALID_ARGUMENT, ""); + } else { + ServingStatus serving_status = database_->GetServingStatus(service_name); + if (serving_status == NOT_FOUND) { + status = Status(StatusCode::NOT_FOUND, "service name unknown"); + } else if (!service_->EncodeResponse(serving_status, &response)) { + status = Status(INTERNAL, ""); + } + } + // Send response. + { + std::unique_lock lock(service_->cq_shutdown_mu_); + if (!service_->shutdown_) { + next_ = + CallableTag(std::bind(&CheckCallHandler::OnFinishDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + if (status.ok()) { + writer_.Finish(response, status, &next_); + } else { + writer_.FinishWithError(status, &next_); + } + } + } } -void DefaultHealthCheckService::SetServingStatus(bool serving) { - std::lock_guard lock(mu_); - for (auto iter = services_map_.begin(); iter != services_map_.end(); ++iter) { - iter->second = serving; +void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: + OnFinishDone(std::shared_ptr self, bool ok) { + if (ok) { + gpr_log(GPR_DEBUG, "[HCS %p] Health check call finished for handler %p", + service_, this); } } -DefaultHealthCheckService::ServingStatus -DefaultHealthCheckService::GetServingStatus( - const grpc::string& service_name) const { - std::lock_guard lock(mu_); - const auto& iter = services_map_.find(service_name); - if (iter == services_map_.end()) { - return NOT_FOUND; +// +// DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler +// + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + CreateAndStart(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service) { + std::shared_ptr self = + std::make_shared(cq, database, service); + WatchCallHandler* handler = static_cast(self.get()); + { + std::unique_lock lock(service->cq_shutdown_mu_); + if (service->shutdown_) return; + // Request AsyncNotifyWhenDone(). + handler->on_done_notified_ = + CallableTag(std::bind(&WatchCallHandler::OnDoneNotified, handler, + std::placeholders::_1, std::placeholders::_2), + self /* copies ref */); + handler->ctx_.AsyncNotifyWhenDone(&handler->on_done_notified_); + // Request a Watch() call. + handler->next_ = + CallableTag(std::bind(&WatchCallHandler::OnCallReceived, handler, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + service->RequestAsyncServerStreaming(1, &handler->ctx_, &handler->request_, + &handler->stream_, cq, cq, + &handler->next_); } - return iter->second ? SERVING : NOT_SERVING; } -DefaultHealthCheckService::HealthCheckServiceImpl* -DefaultHealthCheckService::GetHealthCheckService() { - GPR_ASSERT(impl_ == nullptr); - impl_.reset(new HealthCheckServiceImpl(this)); - return impl_.get(); +DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + WatchCallHandler(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service) + : cq_(cq), + database_(database), + service_(service), + stream_(&ctx_), + call_state_(WAITING_FOR_CALL) {} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + OnCallReceived(std::shared_ptr self, bool ok) { + if (ok) { + call_state_ = CALL_RECEIVED; + } else { + // AsyncNotifyWhenDone() needs to be called before the call starts, but the + // tag will not pop out if the call never starts ( + // https://github.com/grpc/grpc/issues/10136). So we need to manually + // release the ownership of the handler in this case. + GPR_ASSERT(on_done_notified_.ReleaseHandler() != nullptr); + } + if (!ok || shutdown_) { + // The value of ok being false means that the server is shutting down. + Shutdown(std::move(self), "OnCallReceived"); + return; + } + // Spawn a new handler instance to serve the next new client. Every handler + // instance will deallocate itself when it's done. + CreateAndStart(cq_, database_, service_); + // Parse request. + if (!service_->DecodeRequest(request_, &service_name_)) { + on_finish_done_ = + CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + stream_.Finish(Status(INVALID_ARGUMENT, ""), &on_finish_done_); + call_state_ = FINISH_CALLED; + return; + } + // Register the call for updates to the service. + gpr_log(GPR_DEBUG, + "[HCS %p] Health check watch started for service \"%s\" " + "(handler: %p)", + service_, service_name_.c_str(), this); + database_->RegisterCallHandler(service_name_, std::move(self)); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + SendHealth(std::shared_ptr self, ServingStatus status) { + std::unique_lock lock(mu_); + // If there's already a send in flight, cache the new status, and + // we'll start a new send for it when the one in flight completes. + if (send_in_flight_) { + pending_status_ = status; + return; + } + // Start a send. + SendHealthLocked(std::move(self), status); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + SendHealthLocked(std::shared_ptr self, ServingStatus status) { + std::unique_lock cq_lock(service_->cq_shutdown_mu_); + if (service_->shutdown_) { + cq_lock.release()->unlock(); + Shutdown(std::move(self), "SendHealthLocked"); + return; + } + send_in_flight_ = true; + call_state_ = SEND_MESSAGE_PENDING; + // Construct response. + ByteBuffer response; + if (!service_->EncodeResponse(status, &response)) { + on_finish_done_ = + CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + stream_.Finish(Status(INTERNAL, ""), &on_finish_done_); + return; + } + next_ = CallableTag(std::bind(&WatchCallHandler::OnSendHealthDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + stream_.Write(response, &next_); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + OnSendHealthDone(std::shared_ptr self, bool ok) { + if (!ok || shutdown_) { + Shutdown(std::move(self), "OnSendHealthDone"); + return; + } + call_state_ = CALL_RECEIVED; + { + std::unique_lock lock(mu_); + send_in_flight_ = false; + // If we got a new status since we started the last send, start a + // new send for it. + if (pending_status_ != NOT_FOUND) { + auto status = pending_status_; + pending_status_ = NOT_FOUND; + SendHealthLocked(std::move(self), status); + } + } +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + OnDoneNotified(std::shared_ptr self, bool ok) { + GPR_ASSERT(ok); + done_notified_ = true; + if (ctx_.IsCancelled()) { + is_cancelled_ = true; + } + gpr_log(GPR_DEBUG, + "[HCS %p] Healt check call is notified done (handler: %p, " + "is_cancelled: %d).", + service_, this, static_cast(is_cancelled_)); + Shutdown(std::move(self), "OnDoneNotified"); +} + +// TODO(roth): This method currently assumes that there will be only one +// thread polling the cq and invoking the corresponding callbacks. If +// that changes, we will need to add synchronization here. +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + Shutdown(std::shared_ptr self, const char* reason) { + if (!shutdown_) { + gpr_log(GPR_DEBUG, + "[HCS %p] Shutting down the handler (service_name: \"%s\", " + "handler: %p, reason: %s).", + service_, service_name_.c_str(), this, reason); + shutdown_ = true; + } + // OnCallReceived() may be called after OnDoneNotified(), so we need to + // try to Finish() every time we are in Shutdown(). + if (call_state_ >= CALL_RECEIVED && call_state_ < FINISH_CALLED) { + std::unique_lock lock(service_->cq_shutdown_mu_); + if (!service_->shutdown_) { + on_finish_done_ = + CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + // TODO(juanlishen): Maybe add a message proto for the client to + // explicitly cancel the stream so that we can return OK status in such + // cases. + stream_.Finish(Status::CANCELLED, &on_finish_done_); + call_state_ = FINISH_CALLED; + } + } +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + OnFinishDone(std::shared_ptr self, bool ok) { + if (ok) { + gpr_log(GPR_DEBUG, + "[HCS %p] Health check call finished (service_name: \"%s\", " + "handler: %p).", + service_, service_name_.c_str(), this); + } } } // namespace grpc diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index a1ce5aa64ec..edad5949362 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -19,42 +19,268 @@ #ifndef GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H #define GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H +#include #include +#include +#include +#include #include +#include +#include #include #include +#include "src/core/lib/gprpp/thd.h" + namespace grpc { // Default implementation of HealthCheckServiceInterface. Server will create and // own it. class DefaultHealthCheckService final : public HealthCheckServiceInterface { public: + enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; + // The service impl to register with the server. class HealthCheckServiceImpl : public Service { public: - explicit HealthCheckServiceImpl(DefaultHealthCheckService* service); + // Base class for call handlers. + class CallHandler { + public: + virtual ~CallHandler() = default; + virtual void SendHealth(std::shared_ptr self, + ServingStatus status) = 0; + }; - Status Check(ServerContext* context, const ByteBuffer* request, - ByteBuffer* response); + HealthCheckServiceImpl(DefaultHealthCheckService* database, + std::unique_ptr cq); + + ~HealthCheckServiceImpl(); + + void StartServingThread(); private: - const DefaultHealthCheckService* const service_; - internal::RpcServiceMethod* method_; + // A tag that can be called with a bool argument. It's tailored for + // CallHandler's use. Before being used, it should be constructed with a + // method of CallHandler and a shared pointer to the handler. The + // shared pointer will be moved to the invoked function and the function + // can only be invoked once. That makes ref counting of the handler easier, + // because the shared pointer is not bound to the function and can be gone + // once the invoked function returns (if not used any more). + class CallableTag { + public: + using HandlerFunction = + std::function, bool)>; + + CallableTag() {} + + CallableTag(HandlerFunction func, std::shared_ptr handler) + : handler_function_(std::move(func)), handler_(std::move(handler)) { + GPR_ASSERT(handler_function_ != nullptr); + GPR_ASSERT(handler_ != nullptr); + } + + // Runs the tag. This should be called only once. The handler is no + // longer owned by this tag after this method is invoked. + void Run(bool ok) { + GPR_ASSERT(handler_function_ != nullptr); + GPR_ASSERT(handler_ != nullptr); + handler_function_(std::move(handler_), ok); + } + + // Releases and returns the shared pointer to the handler. + std::shared_ptr ReleaseHandler() { + return std::move(handler_); + } + + private: + HandlerFunction handler_function_ = nullptr; + std::shared_ptr handler_; + }; + + // Call handler for Check method. + // Each handler takes care of one call. It contains per-call data and it + // will access the members of the parent class (i.e., + // DefaultHealthCheckService) for per-service health data. + class CheckCallHandler : public CallHandler { + public: + // Instantiates a CheckCallHandler and requests the next health check + // call. The handler object will manage its own lifetime, so no action is + // needed from the caller any more regarding that object. + static void CreateAndStart(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service); + + // This ctor is public because we want to use std::make_shared<> in + // CreateAndStart(). This ctor shouldn't be used elsewhere. + CheckCallHandler(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service); + + // Not used for Check. + void SendHealth(std::shared_ptr self, + ServingStatus status) override {} + + private: + // Called when we receive a call. + // Spawns a new handler so that we can keep servicing future calls. + void OnCallReceived(std::shared_ptr self, bool ok); + + // Called when Finish() is done. + void OnFinishDone(std::shared_ptr self, bool ok); + + // The members passed down from HealthCheckServiceImpl. + ServerCompletionQueue* cq_; + DefaultHealthCheckService* database_; + HealthCheckServiceImpl* service_; + + ByteBuffer request_; + GenericServerAsyncResponseWriter writer_; + ServerContext ctx_; + + CallableTag next_; + }; + + // Call handler for Watch method. + // Each handler takes care of one call. It contains per-call data and it + // will access the members of the parent class (i.e., + // DefaultHealthCheckService) for per-service health data. + class WatchCallHandler : public CallHandler { + public: + // Instantiates a WatchCallHandler and requests the next health check + // call. The handler object will manage its own lifetime, so no action is + // needed from the caller any more regarding that object. + static void CreateAndStart(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service); + + // This ctor is public because we want to use std::make_shared<> in + // CreateAndStart(). This ctor shouldn't be used elsewhere. + WatchCallHandler(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service); + + void SendHealth(std::shared_ptr self, + ServingStatus status) override; + + private: + // Called when we receive a call. + // Spawns a new handler so that we can keep servicing future calls. + void OnCallReceived(std::shared_ptr self, bool ok); + + // Requires holding mu_. + void SendHealthLocked(std::shared_ptr self, + ServingStatus status); + + // When sending a health result finishes. + void OnSendHealthDone(std::shared_ptr self, bool ok); + + // Called when Finish() is done. + void OnFinishDone(std::shared_ptr self, bool ok); + + // Called when AsyncNotifyWhenDone() notifies us. + void OnDoneNotified(std::shared_ptr self, bool ok); + + void Shutdown(std::shared_ptr self, const char* reason); + + // The members passed down from HealthCheckServiceImpl. + ServerCompletionQueue* cq_; + DefaultHealthCheckService* database_; + HealthCheckServiceImpl* service_; + + ByteBuffer request_; + grpc::string service_name_; + GenericServerAsyncWriter stream_; + ServerContext ctx_; + + std::mutex mu_; + bool send_in_flight_ = false; // Guarded by mu_. + ServingStatus pending_status_ = NOT_FOUND; // Guarded by mu_. + + // The state of the RPC progress. + enum CallState { + WAITING_FOR_CALL, + CALL_RECEIVED, + SEND_MESSAGE_PENDING, + FINISH_CALLED + } call_state_; + + bool shutdown_ = false; + bool done_notified_ = false; + bool is_cancelled_ = false; + CallableTag next_; + CallableTag on_done_notified_; + CallableTag on_finish_done_; + }; + + // Handles the incoming requests and drives the completion queue in a loop. + static void Serve(void* arg); + + // Returns true on success. + static bool DecodeRequest(const ByteBuffer& request, + grpc::string* service_name); + static bool EncodeResponse(ServingStatus status, ByteBuffer* response); + + // Needed to appease Windows compilers, which don't seem to allow + // nested classes to access protected members in the parent's + // superclass. + using Service::RequestAsyncServerStreaming; + using Service::RequestAsyncUnary; + + DefaultHealthCheckService* database_; + std::unique_ptr cq_; + internal::RpcServiceMethod* check_method_; + internal::RpcServiceMethod* watch_method_; + + // To synchronize the operations related to shutdown state of cq_, so that + // we don't enqueue new tags into cq_ after it is already shut down. + std::mutex cq_shutdown_mu_; + std::atomic_bool shutdown_{false}; + std::unique_ptr<::grpc_core::Thread> thread_; }; DefaultHealthCheckService(); + void SetServingStatus(const grpc::string& service_name, bool serving) override; void SetServingStatus(bool serving) override; - enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; + ServingStatus GetServingStatus(const grpc::string& service_name) const; - HealthCheckServiceImpl* GetHealthCheckService(); + + HealthCheckServiceImpl* GetHealthCheckService( + std::unique_ptr cq); private: + // Stores the current serving status of a service and any call + // handlers registered for updates when the service's status changes. + class ServiceData { + public: + void SetServingStatus(ServingStatus status); + ServingStatus GetServingStatus() const { return status_; } + void AddCallHandler( + std::shared_ptr handler); + void RemoveCallHandler( + std::shared_ptr handler); + bool Unused() const { + return call_handlers_.empty() && status_ == NOT_FOUND; + } + + private: + ServingStatus status_ = NOT_FOUND; + std::set> + call_handlers_; + }; + + void RegisterCallHandler( + const grpc::string& service_name, + std::shared_ptr handler); + + void UnregisterCallHandler( + const grpc::string& service_name, + std::shared_ptr handler); + mutable std::mutex mu_; - std::map services_map_; + std::map services_map_; // Guarded by mu_. std::unique_ptr impl_; }; diff --git a/src/cpp/server/health/health.pb.c b/src/cpp/server/health/health.pb.c index 09bd98a3d97..5c214c7160f 100644 --- a/src/cpp/server/health/health.pb.c +++ b/src/cpp/server/health/health.pb.c @@ -2,7 +2,6 @@ /* Generated by nanopb-0.3.7-dev */ #include "src/cpp/server/health/health.pb.h" - /* @@protoc_insertion_point(includes) */ #if PB_PROTO_HEADER_VERSION != 30 #error Regenerate this file with the current version of nanopb generator. diff --git a/src/cpp/server/health/health.pb.h b/src/cpp/server/health/health.pb.h index 29e1f3bacb1..9d54ccd6182 100644 --- a/src/cpp/server/health/health.pb.h +++ b/src/cpp/server/health/health.pb.h @@ -17,11 +17,12 @@ extern "C" { typedef enum _grpc_health_v1_HealthCheckResponse_ServingStatus { grpc_health_v1_HealthCheckResponse_ServingStatus_UNKNOWN = 0, grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING = 1, - grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING = 2 + grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING = 2, + grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN = 3 } grpc_health_v1_HealthCheckResponse_ServingStatus; #define _grpc_health_v1_HealthCheckResponse_ServingStatus_MIN grpc_health_v1_HealthCheckResponse_ServingStatus_UNKNOWN -#define _grpc_health_v1_HealthCheckResponse_ServingStatus_MAX grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING -#define _grpc_health_v1_HealthCheckResponse_ServingStatus_ARRAYSIZE ((grpc_health_v1_HealthCheckResponse_ServingStatus)(grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING+1)) +#define _grpc_health_v1_HealthCheckResponse_ServingStatus_MAX grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN +#define _grpc_health_v1_HealthCheckResponse_ServingStatus_ARRAYSIZE ((grpc_health_v1_HealthCheckResponse_ServingStatus)(grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN+1)) /* Struct definitions */ typedef struct _grpc_health_v1_HealthCheckRequest { diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 36c709eb45b..3cadf65c801 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -559,16 +559,20 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { // Only create default health check service when user did not provide an // explicit one. + ServerCompletionQueue* health_check_cq = nullptr; + DefaultHealthCheckService::HealthCheckServiceImpl* + default_health_check_service_impl = nullptr; if (health_check_service_ == nullptr && !health_check_service_disabled_ && DefaultHealthCheckServiceEnabled()) { - if (sync_server_cqs_ == nullptr || sync_server_cqs_->empty()) { - gpr_log(GPR_INFO, - "Default health check service disabled at async-only server."); - } else { - auto* default_hc_service = new DefaultHealthCheckService; - health_check_service_.reset(default_hc_service); - RegisterService(nullptr, default_hc_service->GetHealthCheckService()); - } + auto* default_hc_service = new DefaultHealthCheckService; + health_check_service_.reset(default_hc_service); + health_check_cq = new ServerCompletionQueue(GRPC_CQ_DEFAULT_POLLING); + grpc_server_register_completion_queue(server_, health_check_cq->cq(), + nullptr); + default_health_check_service_impl = + default_hc_service->GetHealthCheckService( + std::unique_ptr(health_check_cq)); + RegisterService(nullptr, default_health_check_service_impl); } grpc_server_start(server_); @@ -583,6 +587,9 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { new UnimplementedAsyncRequest(this, cqs[i]); } } + if (health_check_cq != nullptr) { + new UnimplementedAsyncRequest(this, health_check_cq); + } } // If this server has any support for synchronous methods (has any sync @@ -595,6 +602,10 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { (*it)->Start(); } + + if (default_health_check_service_impl != nullptr) { + default_health_check_service_impl->StartServingThread(); + } } void Server::ShutdownInternal(gpr_timespec deadline) { diff --git a/src/proto/grpc/health/v1/health.proto b/src/proto/grpc/health/v1/health.proto index 4b4677b8a4d..38843ff1e73 100644 --- a/src/proto/grpc/health/v1/health.proto +++ b/src/proto/grpc/health/v1/health.proto @@ -34,10 +34,30 @@ message HealthCheckResponse { UNKNOWN = 0; SERVING = 1; NOT_SERVING = 2; + SERVICE_UNKNOWN = 3; // Used only by the Watch method. } ServingStatus status = 1; } service Health { + // If the requested service is unknown, the call will fail with status + // NOT_FOUND. rpc Check(HealthCheckRequest) returns (HealthCheckResponse); + + // Performs a watch for the serving status of the requested service. + // The server will immediately send back a message indicating the current + // serving status. It will then subsequently send a new message whenever + // the service's serving status changes. + // + // If the requested service is unknown when the call is received, the + // server will send a message setting the serving status to + // SERVICE_UNKNOWN but will *not* terminate the call. If at some + // future point, the serving status of the service becomes known, the + // server will send a new message with the service's serving status. + // + // If the call terminates with status UNIMPLEMENTED, then clients + // should assume this method is not supported and should not retry the + // call. If the call terminates with any other status (including OK), + // clients should retry the call with appropriate exponential backoff. + rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); } diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index 1c48b9d151a..fca65dfc13b 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -64,6 +64,29 @@ class HealthCheckServiceImpl : public ::grpc::health::v1::Health::Service { return Status::OK; } + Status Watch(ServerContext* context, const HealthCheckRequest* request, + ::grpc::ServerWriter* writer) override { + auto last_state = HealthCheckResponse::UNKNOWN; + while (!context->IsCancelled()) { + { + std::lock_guard lock(mu_); + HealthCheckResponse response; + auto iter = status_map_.find(request->service()); + if (iter == status_map_.end()) { + response.set_status(response.SERVICE_UNKNOWN); + } else { + response.set_status(iter->second); + } + if (response.status() != last_state) { + writer->Write(response, ::grpc::WriteOptions()); + } + } + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis(1000, GPR_TIMESPAN))); + } + return Status::OK; + } + void SetStatus(const grpc::string& service_name, HealthCheckResponse::ServingStatus status) { std::lock_guard lock(mu_); @@ -106,14 +129,6 @@ class CustomHealthCheckService : public HealthCheckServiceInterface { HealthCheckServiceImpl* impl_; // not owned }; -void LoopCompletionQueue(ServerCompletionQueue* cq) { - void* tag; - bool ok; - while (cq->Next(&tag, &ok)) { - abort(); // Nothing should come out of the cq. - } -} - class HealthServiceEnd2endTest : public ::testing::Test { protected: HealthServiceEnd2endTest() {} @@ -218,6 +233,33 @@ class HealthServiceEnd2endTest : public ::testing::Test { Status(StatusCode::NOT_FOUND, "")); } + void VerifyHealthCheckServiceStreaming() { + const grpc::string kServiceName("service_name"); + HealthCheckServiceInterface* service = server_->GetHealthCheckService(); + // Start Watch for service. + ClientContext context; + HealthCheckRequest request; + request.set_service(kServiceName); + std::unique_ptr<::grpc::ClientReaderInterface> reader = + hc_stub_->Watch(&context, request); + // Initial response will be SERVICE_UNKNOWN. + HealthCheckResponse response; + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.SERVICE_UNKNOWN, response.status()); + response.Clear(); + // Now set service to NOT_SERVING and make sure we get an update. + service->SetServingStatus(kServiceName, false); + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.NOT_SERVING, response.status()); + response.Clear(); + // Now set service to SERVING and make sure we get another update. + service->SetServingStatus(kServiceName, true); + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.SERVING, response.status()); + // Finish call. + context.TryCancel(); + } + TestServiceImpl echo_test_service_; HealthCheckServiceImpl health_check_service_impl_; std::unique_ptr hc_stub_; @@ -245,6 +287,7 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); SetUpServer(true, false, false, nullptr); VerifyHealthCheckService(); + VerifyHealthCheckServiceStreaming(); // The default service has a size limit of the service name. const grpc::string kTooLongServiceName(201, 'x'); @@ -252,22 +295,6 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { Status(StatusCode::INVALID_ARGUMENT, "")); } -// The server has no sync service. -TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceAsyncOnly) { - EnableDefaultHealthCheckService(true); - EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); - SetUpServer(false, true, false, nullptr); - cq_thread_ = std::thread(LoopCompletionQueue, cq_.get()); - - HealthCheckServiceInterface* default_service = - server_->GetHealthCheckService(); - EXPECT_TRUE(default_service == nullptr); - - ResetStubs(); - - SendHealthCheckRpc("", Status(StatusCode::UNIMPLEMENTED, "")); -} - // Provide an empty service to disable the default service. TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) { EnableDefaultHealthCheckService(true); @@ -296,6 +323,7 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) { ResetStubs(); VerifyHealthCheckService(); + VerifyHealthCheckServiceStreaming(); } } // namespace diff --git a/tools/distrib/check_nanopb_output.sh b/tools/distrib/check_nanopb_output.sh index 6b98619c320..1c2ef9b7686 100755 --- a/tools/distrib/check_nanopb_output.sh +++ b/tools/distrib/check_nanopb_output.sh @@ -16,6 +16,7 @@ set -ex readonly NANOPB_ALTS_TMP_OUTPUT="$(mktemp -d)" +readonly NANOPB_HEALTH_TMP_OUTPUT="$(mktemp -d)" readonly NANOPB_TMP_OUTPUT="$(mktemp -d)" readonly PROTOBUF_INSTALL_PREFIX="$(mktemp -d)" @@ -67,6 +68,23 @@ if ! diff -r "$NANOPB_TMP_OUTPUT" src/core/ext/filters/client_channel/lb_policy/ exit 2 fi +# +# checks for health.proto +# +readonly HEALTH_GRPC_OUTPUT_PATH='src/cpp/server/health' +# nanopb-compile the proto to a temp location +./tools/codegen/core/gen_nano_proto.sh \ + src/proto/grpc/health/v1/health.proto \ + "$NANOPB_HEALTH_TMP_OUTPUT" \ + "$HEALTH_GRPC_OUTPUT_PATH" +# compare outputs to checked compiled code +for NANOPB_OUTPUT_FILE in $NANOPB_HEALTH_TMP_OUTPUT/*.pb.*; do + if ! diff "$NANOPB_OUTPUT_FILE" "src/cpp/server/health/$(basename $NANOPB_OUTPUT_FILE)"; then + echo "Outputs differ: $NANOPB_HEALTH_TMP_OUTPUT vs $HEALTH_GRPC_OUTPUT_PATH" + exit 2 + fi +done + # # Checks for handshaker.proto and transport_security_common.proto # From 69b416a08c266f65e75fa5be70cd95788fbd968d Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 28 Aug 2018 08:53:31 -0700 Subject: [PATCH 239/546] Update naming documentation. --- doc/naming.md | 64 +++++++++++-------- src/core/ext/filters/client_channel/README.md | 18 +----- 2 files changed, 40 insertions(+), 42 deletions(-) diff --git a/doc/naming.md b/doc/naming.md index 676aa9f2980..581c550567f 100644 --- a/doc/naming.md +++ b/doc/naming.md @@ -14,34 +14,48 @@ be plugged in. ### Name Syntax A fully qualified, self contained name used for gRPC channel construction -uses the syntax: - -``` -scheme://authority/endpoint_name -``` - -Here, `scheme` indicates the name-system to be used. Currently, we -support the following schemes: - -- `dns` - -- `ipv4` (IPv4 address) - -- `ipv6` (IPv6 address) - -- `unix` (path to unix domain socket -- unix systems only) +uses URI syntax as defined in [RFC 3986](https://tools.ietf.org/html/rfc3986). + +The URI scheme indicates what resolver plugin to use. If no scheme +prefix is specified or the scheme is unknown, the `dns` scheme is used +by default. + +The URI path indicates the name to be resolved. + +Most gRPC implementations support the following URI schemes: + +- `dns:[//authority/]host[:port]` -- DNS (default) + - `host` is the host to resolve via DNS. + - `port` is the port to return for each address. If not specified, + 443 is used (but some implementations default to 80 for insecure + channels). + - `authority` indicates the DNS server to use, although this is only + supported by some implementations. (In C-core, the default DNS + resolver does not support this, but the c-ares based resolver + supports specifying this in the form "IP:port".) + +- `unix:path` or `unix://absolute_path` -- Unix domain sockets (Unix systems only) + - `path` indicates the location of the desired socket. + - In the first form, the path may be relative or absolute; in the + second form, the path must be absolute (i.e., there will actually be + three slashes, two prior to the path and another to begin the + absolute path). + +The following schemes are supported by the gRPC C-core implementation, +but may not be supported in other languages: + +- `ipv4:address[:port][,address[:port],...]` -- IPv4 addresses + - Can specify multiple comma-delimited addresses of the form `address[:port]`: + - `address` is the IPv4 address to use. + - `port` is the port to use. If not specified, 443 is used. + +- `ipv6:address[:port][,address[:port],...]` -- IPv6 addresses + - Can specify multiple comma-delimited addresses of the form `address[:port]`: + - `address` is the IPv6 address to use. + - `port` is the port to use. If not specified, 443 is used. In the future, additional schemes such as `etcd` could be added. -The `authority` indicates some scheme-specific bootstrap information, e.g., -for DNS, the authority may include the IP[:port] of the DNS server to -use. Often, a DNS name may be used as the authority, since the ability to -resolve DNS names is already built into all gRPC client libraries. - -Finally, the `endpoint_name` indicates a concrete name to be looked up -in a given name-system identified by the scheme and the authority. The -syntax of the endpoint name is dictated by the scheme in use. - ### Resolver Plugins The gRPC client library will use the specified scheme to pick the right diff --git a/src/core/ext/filters/client_channel/README.md b/src/core/ext/filters/client_channel/README.md index 7c209db12e3..9676a4535b2 100644 --- a/src/core/ext/filters/client_channel/README.md +++ b/src/core/ext/filters/client_channel/README.md @@ -46,20 +46,4 @@ construction arguments for concrete grpc_subchannel instances. Naming for GRPC =============== -Names in GRPC are represented by a URI (as defined in -[RFC 3986](https://tools.ietf.org/html/rfc3986)). - -The following schemes are currently supported: - -dns:///host:port - dns schemes are currently supported so long as authority is - empty (authority based dns resolution is expected in a future - release) - -unix:path - the unix scheme is used to create and connect to unix domain - sockets - the authority must be empty, and the path - represents the absolute or relative path to the desired - socket - -ipv4:host:port - a pre-resolved ipv4 dotted decimal address/port combination - -ipv6:[host]:port - a pre-resolved ipv6 address/port combination +See [/doc/naming.md](gRPC name resolution). From 25d570c39c166f3dd6139f45779a15f725db5c4f Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 28 Aug 2018 10:31:43 -0700 Subject: [PATCH 240/546] flipped logic to enable pollers --- test/core/end2end/end2end_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/end2end/end2end_test.sh b/test/core/end2end/end2end_test.sh index 5bfb253090a..6b23d848be6 100755 --- a/test/core/end2end/end2end_test.sh +++ b/test/core/end2end/end2end_test.sh @@ -15,7 +15,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -if [ -z "$3" ] +if [ -n "$3" ] then export GRPC_POLL_STRATEGY=$3 fi From 6e4df4fdfab0e45131bc48d0e8ee204557172c0d Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 28 Aug 2018 11:36:26 -0700 Subject: [PATCH 241/546] added qps scenario change to sanity checks --- .../sanity/check_qps_scenario_changes.py | 33 +++++++++++++++++++ tools/run_tests/sanity/sanity_tests.yaml | 1 + 2 files changed, 34 insertions(+) create mode 100755 tools/run_tests/sanity/check_qps_scenario_changes.py diff --git a/tools/run_tests/sanity/check_qps_scenario_changes.py b/tools/run_tests/sanity/check_qps_scenario_changes.py new file mode 100755 index 00000000000..1c64943cb58 --- /dev/null +++ b/tools/run_tests/sanity/check_qps_scenario_changes.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +# Copyright 2018 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import sys +import subprocess + +os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../../test/cpp/qps')) +subprocess.call(['./json_run_localhost_scenario_gen.py']) +subprocess.call(['./qps_json_driver_scenario_gen.py']) + +output = subprocess.check_output(['git', 'status', '--porcelain']) +qps_json_driver_bzl = 'test/cpp/qps/qps_json_driver_scenarios.bzl' +json_run_localhost_bzl = 'test/cpp/qps/json_run_localhost_scenarios.bzl' + +if qps_json_driver_bzl in output or json_run_localhost_bzl in output: + print('qps benchmark scenarios have been updated, please commit ' + 'test/cpp/qps/qps_json_driver_scenarios.bzl and/or ' + 'test/cpp/qps/json_run_localhost_scenarios.bzl') + sys.exit(1) \ No newline at end of file diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml index fd9b34a1981..1913edd4257 100644 --- a/tools/run_tests/sanity/sanity_tests.yaml +++ b/tools/run_tests/sanity/sanity_tests.yaml @@ -3,6 +3,7 @@ - script: tools/run_tests/sanity/check_bazel_workspace.py - script: tools/run_tests/sanity/check_cache_mk.sh - script: tools/run_tests/sanity/check_owners.sh +- script: tools/run_tests/sanity/check_qps_scenario_changes.py - script: tools/run_tests/sanity/check_shellcheck.sh - script: tools/run_tests/sanity/check_submodules.sh - script: tools/run_tests/sanity/check_test_filtering.py From 507c80e3094d46dea5ffb812dddc0dde4553ea43 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 28 Aug 2018 12:00:47 -0700 Subject: [PATCH 242/546] added a newline to end of file --- tools/run_tests/sanity/check_qps_scenario_changes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/run_tests/sanity/check_qps_scenario_changes.py b/tools/run_tests/sanity/check_qps_scenario_changes.py index 1c64943cb58..2c34251eaac 100755 --- a/tools/run_tests/sanity/check_qps_scenario_changes.py +++ b/tools/run_tests/sanity/check_qps_scenario_changes.py @@ -30,4 +30,4 @@ if qps_json_driver_bzl in output or json_run_localhost_bzl in output: print('qps benchmark scenarios have been updated, please commit ' 'test/cpp/qps/qps_json_driver_scenarios.bzl and/or ' 'test/cpp/qps/json_run_localhost_scenarios.bzl') - sys.exit(1) \ No newline at end of file + sys.exit(1) From 918427237c0bd65f2500c3b0b3ffbd003f100797 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 28 Aug 2018 12:03:38 -0700 Subject: [PATCH 243/546] fixed indentation --- .../qps/json_run_localhost_scenario_gen.py | 30 +++++++++---------- test/cpp/qps/qps_json_driver_scenario_gen.py | 24 +++++++-------- .../sanity/check_qps_scenario_changes.py | 4 +-- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/test/cpp/qps/json_run_localhost_scenario_gen.py b/test/cpp/qps/json_run_localhost_scenario_gen.py index 3cd2b799fec..01f6a699d55 100755 --- a/test/cpp/qps/json_run_localhost_scenario_gen.py +++ b/test/cpp/qps/json_run_localhost_scenario_gen.py @@ -18,21 +18,21 @@ import gen_build_yaml as gen import json def generate_args(): - all_scenario_set = gen.generate_yaml() - all_scenario_set = all_scenario_set['tests'] - json_run_localhost_scenarios = \ - [item for item in all_scenario_set if item['name'] == 'qps_json_driver'] - json_run_localhost_arg_set = \ - [item['args'][2] for item in json_run_localhost_scenarios \ - if 'args' in item and len(item['args']) > 2] - deserialized_scenarios = [json.loads(item)['scenarios'][0] \ - for item in json_run_localhost_arg_set] - all_scenarios = {scenario['name'].encode('ascii', 'ignore'): \ - '\'{\'scenarios\' : [' + json.dumps(scenario) + ']}\'' \ - for scenario in deserialized_scenarios} + all_scenario_set = gen.generate_yaml() + all_scenario_set = all_scenario_set['tests'] + json_run_localhost_scenarios = \ + [item for item in all_scenario_set if item['name'] == 'qps_json_driver'] + json_run_localhost_arg_set = \ + [item['args'][2] for item in json_run_localhost_scenarios \ + if 'args' in item and len(item['args']) > 2] + deserialized_scenarios = [json.loads(item)['scenarios'][0] \ + for item in json_run_localhost_arg_set] + all_scenarios = {scenario['name'].encode('ascii', 'ignore'): \ + '\'{\'scenarios\' : [' + json.dumps(scenario) + ']}\'' \ + for scenario in deserialized_scenarios} - serialized_scenarios_str = str(all_scenarios).encode('ascii', 'ignore') - with open('json_run_localhost_scenarios.bzl', 'wb') as f: - f.write('JSON_RUN_LOCALHOST_SCENARIOS = ' + serialized_scenarios_str + '\n') + serialized_scenarios_str = str(all_scenarios).encode('ascii', 'ignore') + with open('json_run_localhost_scenarios.bzl', 'wb') as f: + f.write('JSON_RUN_LOCALHOST_SCENARIOS = ' + serialized_scenarios_str + '\n') generate_args() diff --git a/test/cpp/qps/qps_json_driver_scenario_gen.py b/test/cpp/qps/qps_json_driver_scenario_gen.py index 28fbb895856..393f968a645 100755 --- a/test/cpp/qps/qps_json_driver_scenario_gen.py +++ b/test/cpp/qps/qps_json_driver_scenario_gen.py @@ -18,21 +18,21 @@ import gen_build_yaml as gen import json def generate_args(): - all_scenario_set = gen.generate_yaml() - all_scenario_set = all_scenario_set['tests'] - qps_json_driver_scenario_set = \ - [item for item in all_scenario_set if item['name'] == 'qps_json_driver'] - qps_json_driver_arg_set = \ - [item['args'][2] for item in qps_json_driver_scenario_set \ - if 'args' in item and len(item['args']) > 2] - deserialized_scenarios = [json.loads(item)['scenarios'][0] \ + all_scenario_set = gen.generate_yaml() + all_scenario_set = all_scenario_set['tests'] + qps_json_driver_scenario_set = \ + [item for item in all_scenario_set if item['name'] == 'qps_json_driver'] + qps_json_driver_arg_set = \ + [item['args'][2] for item in qps_json_driver_scenario_set \ + if 'args' in item and len(item['args']) > 2] + deserialized_scenarios = [json.loads(item)['scenarios'][0] \ for item in qps_json_driver_arg_set] - all_scenarios = {scenario['name'].encode('ascii', 'ignore'): \ + all_scenarios = {scenario['name'].encode('ascii', 'ignore'): \ '\'{\'scenarios\' : [' + json.dumps(scenario) + ']}\'' \ for scenario in deserialized_scenarios} - serialized_scenarios_str = str(all_scenarios).encode('ascii', 'ignore') - with open('qps_json_driver_scenarios.bzl', 'w') as f: - f.write('QPS_JSON_DRIVER_SCENARIOS = ' + serialized_scenarios_str + '\n') + serialized_scenarios_str = str(all_scenarios).encode('ascii', 'ignore') + with open('qps_json_driver_scenarios.bzl', 'w') as f: + f.write('QPS_JSON_DRIVER_SCENARIOS = ' + serialized_scenarios_str + '\n') generate_args() diff --git a/tools/run_tests/sanity/check_qps_scenario_changes.py b/tools/run_tests/sanity/check_qps_scenario_changes.py index 2c34251eaac..35f997a2cb3 100755 --- a/tools/run_tests/sanity/check_qps_scenario_changes.py +++ b/tools/run_tests/sanity/check_qps_scenario_changes.py @@ -27,7 +27,7 @@ qps_json_driver_bzl = 'test/cpp/qps/qps_json_driver_scenarios.bzl' json_run_localhost_bzl = 'test/cpp/qps/json_run_localhost_scenarios.bzl' if qps_json_driver_bzl in output or json_run_localhost_bzl in output: - print('qps benchmark scenarios have been updated, please commit ' + print('qps benchmark scenarios have been updated, please commit ' 'test/cpp/qps/qps_json_driver_scenarios.bzl and/or ' 'test/cpp/qps/json_run_localhost_scenarios.bzl') - sys.exit(1) + sys.exit(1) From 90e646e7d8272b6d746d746b9ae6058b8c016f46 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 28 Aug 2018 12:14:52 -0700 Subject: [PATCH 244/546] yapf fix --- tools/run_tests/sanity/check_qps_scenario_changes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/sanity/check_qps_scenario_changes.py b/tools/run_tests/sanity/check_qps_scenario_changes.py index 35f997a2cb3..635fee6a608 100755 --- a/tools/run_tests/sanity/check_qps_scenario_changes.py +++ b/tools/run_tests/sanity/check_qps_scenario_changes.py @@ -28,6 +28,6 @@ json_run_localhost_bzl = 'test/cpp/qps/json_run_localhost_scenarios.bzl' if qps_json_driver_bzl in output or json_run_localhost_bzl in output: print('qps benchmark scenarios have been updated, please commit ' - 'test/cpp/qps/qps_json_driver_scenarios.bzl and/or ' - 'test/cpp/qps/json_run_localhost_scenarios.bzl') + 'test/cpp/qps/qps_json_driver_scenarios.bzl and/or ' + 'test/cpp/qps/json_run_localhost_scenarios.bzl') sys.exit(1) From e3e1840efb3c491fc823c80dd92f41a53aa39143 Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Tue, 28 Aug 2018 14:36:20 -0700 Subject: [PATCH 245/546] Porting fix from CL- https://critique.corp.google.com/#review/210573936 --- src/core/ext/filters/max_age/max_age_filter.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1fe8288bd0a..07ed417c95b 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -430,7 +430,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, : DEFAULT_MAX_CONNECTION_IDLE_MS; chand->idle_state = MAX_IDLE_STATE_INIT; gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis, - GRPC_MILLIS_INF_PAST); + GPR_ATM_MIN); for (size_t i = 0; i < args->channel_args->num_args; ++i) { if (0 == strcmp(args->channel_args->args[i].key, GRPC_ARG_MAX_CONNECTION_AGE_MS)) { From 12b9e0beb591c2718f950c044405c870828dac75 Mon Sep 17 00:00:00 2001 From: Moiz Haidry Date: Tue, 28 Aug 2018 15:44:39 -0700 Subject: [PATCH 246/546] Fixed formatting --- src/core/ext/filters/max_age/max_age_filter.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 07ed417c95b..431472609eb 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -429,8 +429,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, ? GRPC_MILLIS_INF_FUTURE : DEFAULT_MAX_CONNECTION_IDLE_MS; chand->idle_state = MAX_IDLE_STATE_INIT; - gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis, - GPR_ATM_MIN); + gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis, GPR_ATM_MIN); for (size_t i = 0; i < args->channel_args->num_args; ++i) { if (0 == strcmp(args->channel_args->args[i].key, GRPC_ARG_MAX_CONNECTION_AGE_MS)) { From 743d40d6354c710f91d0fcf918ea2b90aa799ebc Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 20 Aug 2018 20:54:14 -0700 Subject: [PATCH 247/546] Lazily fill metadata map --- include/grpcpp/impl/codegen/call.h | 11 +------- include/grpcpp/impl/codegen/client_context.h | 6 ++-- include/grpcpp/impl/codegen/metadata_map.h | 29 ++++++++++++++++++++ include/grpcpp/impl/codegen/server_context.h | 3 +- src/cpp/server/server_cc.cc | 3 -- src/cpp/server/server_context.cc | 1 - 6 files changed, 36 insertions(+), 17 deletions(-) diff --git a/include/grpcpp/impl/codegen/call.h b/include/grpcpp/impl/codegen/call.h index a5e930aaa5c..e94adada940 100644 --- a/include/grpcpp/impl/codegen/call.h +++ b/include/grpcpp/impl/codegen/call.h @@ -50,8 +50,6 @@ namespace internal { class Call; class CallHook; -const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin"; - // TODO(yangg) if the map is changed before we send, the pointers will be a // mess. Make sure it does not happen. inline grpc_metadata* FillMetadataArray( @@ -531,7 +529,6 @@ class CallOpRecvInitialMetadata { void FinishOp(bool* status) { if (metadata_map_ == nullptr) return; - metadata_map_->FillMap(); metadata_map_ = nullptr; } @@ -566,13 +563,7 @@ class CallOpClientRecvStatus { void FinishOp(bool* status) { if (recv_status_ == nullptr) return; - metadata_map_->FillMap(); - grpc::string binary_error_details; - auto iter = metadata_map_->map()->find(kBinaryErrorDetailsKey); - if (iter != metadata_map_->map()->end()) { - binary_error_details = - grpc::string(iter->second.begin(), iter->second.length()); - } + grpc::string binary_error_details = metadata_map_->GetBinaryErrorDetails(); *recv_status_ = Status(static_cast(status_code_), GRPC_SLICE_IS_EMPTY(error_message_) diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 9dda4c7fac8..cf1d9018885 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -202,6 +202,7 @@ class ClientContext { const std::multimap& GetServerInitialMetadata() const { GPR_CODEGEN_ASSERT(initial_metadata_received_); + recv_initial_metadata_.FillMap(); return *recv_initial_metadata_.map(); } @@ -214,6 +215,7 @@ class ClientContext { const std::multimap& GetServerTrailingMetadata() const { // TODO(yangg) check finished + trailing_metadata_.FillMap(); return *trailing_metadata_.map(); } @@ -425,8 +427,8 @@ class ClientContext { mutable std::shared_ptr auth_context_; struct census_context* census_context_; std::multimap send_initial_metadata_; - internal::MetadataMap recv_initial_metadata_; - internal::MetadataMap trailing_metadata_; + mutable internal::MetadataMap recv_initial_metadata_; + mutable internal::MetadataMap trailing_metadata_; grpc_call* propagate_from_call_; PropagationOptions propagation_options_; diff --git a/include/grpcpp/impl/codegen/metadata_map.h b/include/grpcpp/impl/codegen/metadata_map.h index 0866539d886..6e0c2a96372 100644 --- a/include/grpcpp/impl/codegen/metadata_map.h +++ b/include/grpcpp/impl/codegen/metadata_map.h @@ -19,11 +19,15 @@ #ifndef GRPCPP_IMPL_CODEGEN_METADATA_MAP_H #define GRPCPP_IMPL_CODEGEN_METADATA_MAP_H +#include #include namespace grpc { namespace internal { + +const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin"; + class MetadataMap { public: MetadataMap() { memset(&arr_, 0, sizeof(arr_)); } @@ -32,7 +36,31 @@ class MetadataMap { g_core_codegen_interface->grpc_metadata_array_destroy(&arr_); } + grpc::string GetBinaryErrorDetails() { + // if filled, extract from the multimap for O(log(n)) + if (filled) { + auto iter = map_.find(kBinaryErrorDetailsKey); + if (iter != map_.end()) { + return grpc::string(iter->second.begin(), iter->second.length()); + } + } + // if not yet filled, take the O(n) lookup to avoid allocating the + // multimap until it is requested. + else { + for (size_t i = 0; i < arr_.count; i++) { + if (grpc_slice_str_cmp(arr_.metadata[i].key, kBinaryErrorDetailsKey)) { + return grpc::string(reinterpret_cast( + GRPC_SLICE_START_PTR(arr_.metadata[i].value)), + GRPC_SLICE_LENGTH(arr_.metadata[i].value)); + } + } + } + return grpc::string(); + } + void FillMap() { + if (filled) return; + filled = true; for (size_t i = 0; i < arr_.count; i++) { // TODO(yangg) handle duplicates? map_.insert(std::pair( @@ -48,6 +76,7 @@ class MetadataMap { grpc_metadata_array* arr() { return &arr_; } private: + bool filled = false; grpc_metadata_array arr_; std::multimap map_; }; diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index 6314364db67..506c51a5d96 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -169,6 +169,7 @@ class ServerContext { /// \return A multimap of initial metadata key-value pairs from the server. const std::multimap& client_metadata() const { + client_metadata_.FillMap(); return *client_metadata_.map(); } @@ -294,7 +295,7 @@ class ServerContext { CompletionQueue* cq_; bool sent_initial_metadata_; mutable std::shared_ptr auth_context_; - internal::MetadataMap client_metadata_; + mutable internal::MetadataMap client_metadata_; std::multimap initial_metadata_; std::multimap trailing_metadata_; diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 3cadf65c801..48f0f110a6c 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -697,9 +697,6 @@ ServerInterface::BaseAsyncRequest::~BaseAsyncRequest() { bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag, bool* status) { - if (*status) { - context_->client_metadata_.FillMap(); - } context_->set_call(call_); context_->cq_ = call_cq_; internal::Call call(call_, server_, call_cq_, diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index 6f5bde0d9f4..bf0c027cda0 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -134,7 +134,6 @@ ServerContext::ServerContext(gpr_timespec deadline, grpc_metadata_array* arr) compression_level_set_(false), has_pending_ops_(false) { std::swap(*client_metadata_.arr(), *arr); - client_metadata_.FillMap(); } ServerContext::~ServerContext() { From e165579d3e9e40c5bef77f775fac9e0860a1c527 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 20 Jul 2018 16:18:04 -0700 Subject: [PATCH 248/546] Subchannel support to C++ --- src/cpp/server/channelz/channelz_service.cc | 16 ++++ src/cpp/server/channelz/channelz_service.h | 4 + test/cpp/end2end/channelz_service_test.cc | 81 ++++++++++++++++++--- 3 files changed, 90 insertions(+), 11 deletions(-) diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc index 77c175e5b8f..f6f6e47917b 100644 --- a/src/cpp/server/channelz/channelz_service.cc +++ b/src/cpp/server/channelz/channelz_service.cc @@ -32,6 +32,7 @@ Status ChannelzService::GetTopChannels( ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request, channelz::v1::GetTopChannelsResponse* response) { char* json_str = grpc_channelz_get_top_channels(request->start_channel_id()); + // gpr_log(GPR_ERROR, "%s", json_str); google::protobuf::util::Status s = google::protobuf::util::JsonStringToMessage(json_str, response); gpr_free(json_str); @@ -45,6 +46,21 @@ Status ChannelzService::GetChannel( ServerContext* unused, const channelz::v1::GetChannelRequest* request, channelz::v1::GetChannelResponse* response) { char* json_str = grpc_channelz_get_channel(request->channel_id()); + // gpr_log(GPR_ERROR, "%s", json_str); + google::protobuf::util::Status s = + google::protobuf::util::JsonStringToMessage(json_str, response); + gpr_free(json_str); + if (s != google::protobuf::util::Status::OK) { + return Status(INTERNAL, s.ToString()); + } + return Status::OK; +} + +Status ChannelzService::GetSubchannel( + ServerContext* unused, const channelz::v1::GetSubchannelRequest* request, + channelz::v1::GetSubchannelResponse* response) { + char* json_str = grpc_channelz_get_subchannel(request->subchannel_id()); + // gpr_log(GPR_ERROR, "%s", json_str); google::protobuf::util::Status s = google::protobuf::util::JsonStringToMessage(json_str, response); gpr_free(json_str); diff --git a/src/cpp/server/channelz/channelz_service.h b/src/cpp/server/channelz/channelz_service.h index f619ea49e04..95d6f47cff1 100644 --- a/src/cpp/server/channelz/channelz_service.h +++ b/src/cpp/server/channelz/channelz_service.h @@ -36,6 +36,10 @@ class ChannelzService final : public channelz::v1::Channelz::Service { Status GetChannel(ServerContext* unused, const channelz::v1::GetChannelRequest* request, channelz::v1::GetChannelResponse* response) override; + // implementation of GetSubchannel rpc + Status GetSubchannel(ServerContext* unused, + const channelz::v1::GetSubchannelRequest* request, + channelz::v1::GetSubchannelResponse* response) override; }; } // namespace grpc diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index 933e4a1ff67..504eb8441ee 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -35,10 +35,14 @@ #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" +#include + #include using grpc::channelz::v1::GetChannelRequest; using grpc::channelz::v1::GetChannelResponse; +using grpc::channelz::v1::GetSubchannelRequest; +using grpc::channelz::v1::GetSubchannelResponse; using grpc::channelz::v1::GetTopChannelsRequest; using grpc::channelz::v1::GetTopChannelsResponse; @@ -140,7 +144,7 @@ class ChannelzServerTest : public ::testing::Test { ClientContext context; Status s = echo_stub_->Echo(&context, request, &response); EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); } void SendFailedEcho(int channel_idx) { @@ -190,7 +194,7 @@ TEST_F(ChannelzServerTest, BasicTest) { request.set_start_channel_id(0); ClientContext context; Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel_size(), 1); } @@ -202,7 +206,7 @@ TEST_F(ChannelzServerTest, HighStartId) { request.set_start_channel_id(10000); ClientContext context; Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel_size(), 0); } @@ -215,7 +219,7 @@ TEST_F(ChannelzServerTest, SuccessfulRequestTest) { request.set_channel_id(1); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), 1); EXPECT_EQ(response.channel().data().calls_succeeded(), 1); EXPECT_EQ(response.channel().data().calls_failed(), 0); @@ -230,7 +234,7 @@ TEST_F(ChannelzServerTest, FailedRequestTest) { request.set_channel_id(1); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), 1); EXPECT_EQ(response.channel().data().calls_succeeded(), 0); EXPECT_EQ(response.channel().data().calls_failed(), 1); @@ -253,7 +257,7 @@ TEST_F(ChannelzServerTest, ManyRequestsTest) { request.set_channel_id(1); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess + kNumFailed); EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); @@ -269,7 +273,7 @@ TEST_F(ChannelzServerTest, ManyChannels) { request.set_start_channel_id(0); ClientContext context; Status s = channelz_stub_->GetTopChannels(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel_size(), kNumChannels); } @@ -295,7 +299,7 @@ TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { request.set_channel_id(1); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess); EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); EXPECT_EQ(response.channel().data().calls_failed(), 0); @@ -308,7 +312,7 @@ TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { request.set_channel_id(2); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), kNumFailed); EXPECT_EQ(response.channel().data().calls_succeeded(), 0); EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed); @@ -321,7 +325,7 @@ TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { request.set_channel_id(3); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess + kNumFailed); EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess); @@ -335,13 +339,68 @@ TEST_F(ChannelzServerTest, ManyRequestsManyChannels) { request.set_channel_id(4); ClientContext context; Status s = channelz_stub_->GetChannel(&context, request, &response); - EXPECT_TRUE(s.ok()); + EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(response.channel().data().calls_started(), 0); EXPECT_EQ(response.channel().data().calls_succeeded(), 0); EXPECT_EQ(response.channel().data().calls_failed(), 0); } } +TEST_F(ChannelzServerTest, ManySubchannels) { + ResetStubs(); + const int kNumChannels = 4; + ConfigureProxy(kNumChannels); + const int kNumSuccess = 10; + const int kNumFailed = 11; + for (int i = 0; i < kNumSuccess; ++i) { + SendSuccessfulEcho(0); + SendSuccessfulEcho(2); + } + for (int i = 0; i < kNumFailed; ++i) { + SendFailedEcho(1); + SendFailedEcho(2); + } + + GetTopChannelsRequest gtc_request; + GetTopChannelsResponse gtc_response; + gtc_request.set_start_channel_id(0); + ClientContext context; + Status s = + channelz_stub_->GetTopChannels(&context, gtc_request, >c_response); + EXPECT_TRUE(s.ok()) << s.error_message(); + EXPECT_EQ(gtc_response.channel_size(), kNumChannels); + + // std::string gtc_str; + // google::protobuf::TextFormat::PrintToString(gtc_response, >c_str); + // std::cout << "GetTopChannels:\n" << gtc_str << "\n"; + + for (int i = 0; i < gtc_response.channel_size(); ++i) { + // if the channel sent no RPCs, then expect no subchannels to have been + // created. + if (gtc_response.channel(i).data().calls_started() == 0) { + EXPECT_EQ(gtc_response.channel(i).subchannel_ref_size(), 0); + continue; + } + // Since this is pick first, we know that there was only one subchannel + // used. We request it here. + ASSERT_GT(gtc_response.channel(i).subchannel_ref_size(), 0); + GetSubchannelRequest gsc_request; + GetSubchannelResponse gsc_response; + gsc_request.set_subchannel_id( + gtc_response.channel(i).subchannel_ref(0).subchannel_id()); + ClientContext context; + Status s = + channelz_stub_->GetSubchannel(&context, gsc_request, &gsc_response); + EXPECT_TRUE(s.ok()) << s.error_message(); + EXPECT_EQ(gtc_response.channel(i).data().calls_started(), + gsc_response.subchannel().data().calls_started()); + EXPECT_EQ(gtc_response.channel(i).data().calls_succeeded(), + gsc_response.subchannel().data().calls_succeeded()); + EXPECT_EQ(gtc_response.channel(i).data().calls_failed(), + gsc_response.subchannel().data().calls_failed()); + } +} + } // namespace testing } // namespace grpc From 73d0cd4d2d16e59a5b2ec21614b1511822e2039a Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 28 Aug 2018 20:22:15 -0700 Subject: [PATCH 249/546] Add ability to use static hpack table on the encode path --- .../filters/http/server/http_server_filter.cc | 4 +- .../chttp2/transport/hpack_encoder.cc | 6 +- src/core/lib/transport/metadata.h | 190 ++++++++++++++++++ src/core/lib/transport/metadata_batch.cc | 27 ++- src/core/lib/transport/metadata_batch.h | 30 ++- 5 files changed, 250 insertions(+), 7 deletions(-) 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 3919447f264..8e9db0a5e77 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -322,9 +322,9 @@ static grpc_error* hs_mutate_op(grpc_call_element* elem, grpc_error* error = GRPC_ERROR_NONE; static const char* error_name = "Failed sending initial metadata"; hs_add_error(error_name, &error, - grpc_metadata_batch_add_head( + grpc_metadata_batch_add_head_index( op->payload->send_initial_metadata.send_initial_metadata, - &calld->status, GRPC_MDELEM_STATUS_200)); + &calld->status, GRPC_MDELEM_STATUS_200_INDEX)); hs_add_error(error_name, &error, grpc_metadata_batch_add_tail( op->payload->send_initial_metadata.send_initial_metadata, diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 0eaf63f133b..4ce139eb0d3 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -692,7 +692,11 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, } grpc_metadata_batch_assert_ok(metadata); for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) { - hpack_enc(c, l->md, &st); + if (is_valid_mdelem_index(l->md_index)) { + emit_indexed(c, l->md_index, &st); + } else { + hpack_enc(c, l->md, &st); + } } grpc_millis deadline = metadata->deadline; if (deadline != GRPC_MILLIS_INF_FUTURE) { diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 78df4bc3a31..eeb09aff974 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -162,4 +162,194 @@ void grpc_mdelem_unref(grpc_mdelem md); void grpc_mdctx_global_init(void); void grpc_mdctx_global_shutdown(); +#define MIN_STATIC_HPACK_TABLE_IDX 1 +#define MAX_STATIC_HPACK_TABLE_IDX 61 + +/* Static hpack table metadata indices */ + +/* {:authority, ""} */ +#define GRPC_MDELEM_AUTHORITY_EMPTY_INDEX 1 + +/* {":method", "GET"} */ +#define GRPC_MDELEM_METHOD_GET_INDEX 2 + +/* {":method", "POST"} */ +#define GRPC_MDELEM_METHOD_POST_INDEX 3 + +/* {":path", "/"} */ +#define GRPC_MDELEM_PATH_SLASH_INDEX 4 + +/* {":path", "/index.html"} */ +#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML_INDEX 5 + +/* {":scheme", "http"} */ +#define GRPC_MDELEM_SCHEME_HTTP_INDEX 6 + +/* {":scheme", "https"} */ +#define GRPC_MDELEM_SCHEME_HTTPS_INDEX 7 + +/* {":status", "200"} */ +#define GRPC_MDELEM_STATUS_200_INDEX 8 + +/* {":status", "204"} */ +#define GRPC_MDELEM_STATUS_204_INDEX 9 + +/* {":status", "206"} */ +#define GRPC_MDELEM_STATUS_206_INDEX 10 + +/* {":status", "304"} */ +#define GRPC_MDELEM_STATUS_304_INDEX 11 + +/* {":status", "400"} */ +#define GRPC_MDELEM_STATUS_400_INDEX 12 + +/* {":status", "404"} */ +#define GRPC_MDELEM_STATUS_404_INDEX 13 + +/* {":status", "500"} */ +#define GRPC_MDELEM_STATUS_500_INDEX 14 + +/* {"accept-charset", ""} */ +#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY_INDEX 15 + +/* {"accept-encoding", "gzip, deflate"} */ +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_DEFLATE_INDEX 16 + +/* {"accept-language", ""} */ +#define GRPC_MDELEM_MDELEM_ACCEPT_LANGUAGE_EMPTY_INDEX 17 + +/* {"accept-ranges", ""} */ +#define GRPC_MDELEM_MDELEM_ACCEPT_RANGES_EMPTY_INDEX 18 + +/* {"accept", ""} */ +#define GRPC_MDELEM_ACCEPT_EMPTY_INDEX 19 + +/* {"access-control-allow-origin", ""} */ +#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY_INDEX 20 + +/* {"age", ""} */ +#define GRPC_MDELEM_AGE_EMPTY_INDEX 21 + +/* {"allow", ""} */ +#define GRPC_MDELEM_ALLOW_EMPTY_INDEX 22 + +/* {"authorization", ""} */ +#define GRPC_MDELEM_AUTHORIZATION_EMPTY_INDEX 23 + +/* {"cache-control", ""} */ +#define GRPC_MDELEM_CACHE_CONTROL_EMPTY_INDEX 24 + +/* {"content-disposition", ""} */ +#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY_INDEX 25 + +/* {"content-encoding", ""} */ +#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY_INDEX 26 + +/* {"content-language", ""} */ +#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY_INDEX 27 + +/* {"content-length", ""} */ +#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY_INDEX 28 + +/* {"content-location", ""} */ +#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY_INDEX 29 + +/* {"content-range", ""} */ +#define GRPC_MDELEM_CONTENT_RANGE_EMPTY_INDEX 30 + +/* {"content-type", ""} */ +#define GRPC_MDELEM_CONTENT_TYPE_EMPTY_INDEX 31 + +/* {"cookie", ""} */ +#define GRPC_MDELEM_COOKIE_EMPTY_INDEX 32 + +/* {"date", ""} */ +#define GRPC_MDELEM_DATE_EMPTY_INDEX 33 + +/* {"etag", ""} */ +#define GRPC_MDELEM_ETAG_EMPTY_INDEX 34 + +/* {"expect", ""} */ +#define GRPC_MDELEM_EXPECT_EMPTY_INDEX 35 + +/* {"expires", ""} */ +#define GRPC_MDELEM_EXPIRES_EMPTY_INDEX 36 + +/* {"from", ""} */ +#define GRPC_MDELEM_FROM_EMPTY_INDEX 37 + +/* {"host", ""} */ +#define GRPC_MDELEM_HOST_EMPTY_INDEX 38 + +/* {"if-match", ""} */ +#define GRPC_MDELEM_IF_MATCH_EMPTY_INDEX 39 + +/* {"if-modified-since", ""} */ +#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY_INDEX 40 + +/* {"if-none-match", ""} */ +#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY_INDEX 41 + +/* {"if-range", ""} */ +#define GRPC_MDELEM_IF_RANGE_EMPTY_INDEX 42 + +/* {"if-unmodified-since", ""} */ +#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY_INDEX 43 + +/* {"last-modified", ""} */ +#define GRPC_MDELEM_LAST_MODIFIED_EMPTY_INDEX 44 + +/* {"link", ""} */ +#define GRPC_MDELEM_LINK_EMPTY_INDEX 45 + +/* {"location", ""} */ +#define GRPC_MDELEM_LOCATION_EMPTY_INDEX 46 + +/* {"max-forwards", ""} */ +#define GRPC_MDELEM_MAX_FORWARDS_EMPTY_INDEX 47 + +/* {"proxy-authenticate", ""} */ +#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY_INDEX 48 + +/* {"proxy-authorization", ""} */ +#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY_INDEX 49 + +/* {"range", ""} */ +#define GRPC_MDELEM_RANGE_EMPTY_INDEX 50 + +/* {"referer", ""} */ +#define GRPC_MDELEM_REFERER_EMPTY_INDEX 51 + +/* {"refresh", ""} */ +#define GRPC_MDELEM_REFRESH_EMPTY_INDEX 52 + +/* {"retry-after", ""} */ +#define GRPC_MDELEM_RETRY_AFTER_EMPTY_INDEX 53 + +/* {"server", ""} */ +#define GRPC_MDELEM_SERVER_EMPTY_INDEX 54 + +/* {"set-cookie", ""} */ +#define GRPC_MDELEM_SET_COOKIE_EMPTY_INDEX 55 * / + +/* {"strict-transport-security", ""} */ +#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY_INDEX 56 + +/* {"transfer-encoding", ""} */ +#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY_INDEX 57 + +/* {"user-agent", ""} */ +#define GRPC_MDELEM_USER_AGENT_EMPTY_INDEX 58 + +/* {"vary", ""} */ +#define GRPC_MDELEM_VARY_EMPTY_INDEX 59 + +/* {"via", ""} */ +#define GRPC_MDELEM_VIA_EMPTY_INDEX 60 + +/* {"www-authenticate", ""} */ +#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY_INDEX 61 + +/* Forward declarations */ +typedef struct grpc_mdelem grpc_mdelem; #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */ diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index 49740fcd1e3..6cad7c90284 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -126,6 +126,11 @@ static void maybe_unlink_callout(grpc_metadata_batch* batch, batch->idx.array[idx] = nullptr; } +bool is_valid_mdelem_index(int64_t index) { + return index >= MIN_STATIC_HPACK_TABLE_IDX && + index <= MAX_STATIC_HPACK_TABLE_IDX; +} + grpc_error* grpc_metadata_batch_add_head(grpc_metadata_batch* batch, grpc_linked_mdelem* storage, grpc_mdelem elem_to_add) { @@ -134,9 +139,18 @@ grpc_error* grpc_metadata_batch_add_head(grpc_metadata_batch* batch, return grpc_metadata_batch_link_head(batch, storage); } +grpc_error* grpc_metadata_batch_add_head_index(grpc_metadata_batch* batch, + grpc_linked_mdelem* storage, + int64_t index_to_add) { + GPR_ASSERT(is_valid_mdelem_index(index_to_add)); + storage->md_index = index_to_add; + return grpc_metadata_batch_link_head(batch, storage); +} + static void link_head(grpc_mdelem_list* list, grpc_linked_mdelem* storage) { assert_valid_list(list); - GPR_ASSERT(!GRPC_MDISNULL(storage->md)); + GPR_ASSERT(is_valid_mdelem_index(storage->md_index) || + !GRPC_MDISNULL(storage->md)); storage->prev = nullptr; storage->next = list->head; if (list->head != nullptr) { @@ -170,9 +184,18 @@ grpc_error* grpc_metadata_batch_add_tail(grpc_metadata_batch* batch, return grpc_metadata_batch_link_tail(batch, storage); } +grpc_error* grpc_metadata_batch_add_tail_index(grpc_metadata_batch* batch, + grpc_linked_mdelem* storage, + int64_t index_to_add) { + GPR_ASSERT(is_valid_mdelem_index(index_to_add)); + storage->md_index = index_to_add; + return grpc_metadata_batch_link_tail(batch, storage); +} + static void link_tail(grpc_mdelem_list* list, grpc_linked_mdelem* storage) { assert_valid_list(list); - GPR_ASSERT(!GRPC_MDISNULL(storage->md)); + GPR_ASSERT(is_valid_mdelem_index(storage->md_index) || + !GRPC_MDISNULL(storage->md)); storage->prev = list->tail; storage->next = nullptr; storage->reserved = nullptr; diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index 7068750b6f2..f1c199489fa 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -30,8 +30,16 @@ #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/static_metadata.h" +/** Each grpc_linked_mdelem refers to a particular metadata element by either: + 1) grpc_mdelem md + 2) int64_t md_index + md_index is an optional optimization. It can only be used for metadata in + the hpack static table and is equivalent to the metadata's index in the + table. If a metadata elem is not contained in the hpack static table, then + md must be used instead. */ typedef struct grpc_linked_mdelem { - grpc_mdelem md; + int64_t md_index; // If -1, not used. Else, use this field instead of md. + grpc_mdelem md; // If md_index is 0, use this field instead of md_index. struct grpc_linked_mdelem* next; struct grpc_linked_mdelem* prev; void* reserved; @@ -50,7 +58,7 @@ typedef struct grpc_metadata_batch { grpc_metadata_batch_callouts idx; /** Used to calculate grpc-timeout at the point of sending, or GRPC_MILLIS_INF_FUTURE if this batch does not need to send a - grpc-timeout */ + grpc-timeout. */ grpc_millis deadline; } grpc_metadata_batch; @@ -82,6 +90,7 @@ void grpc_metadata_batch_set_value(grpc_linked_mdelem* storage, grpc_error* grpc_metadata_batch_link_head(grpc_metadata_batch* batch, grpc_linked_mdelem* storage) GRPC_MUST_USE_RESULT; + /** Add \a storage to the end of \a batch. storage->md is assumed to be valid. \a storage is owned by the caller and must survive for the @@ -100,6 +109,14 @@ grpc_error* grpc_metadata_batch_link_tail(grpc_metadata_batch* batch, grpc_error* grpc_metadata_batch_add_head( grpc_metadata_batch* batch, grpc_linked_mdelem* storage, grpc_mdelem elem_to_add) GRPC_MUST_USE_RESULT; + +/** Identical to grpc_metadata_batch_add_head, except takes the index of the + metadata element to add instead of a grpc_mdelem object. The index must + be a valid static hpack table index */ +grpc_error* grpc_metadata_batch_add_head_index( + grpc_metadata_batch* batch, grpc_linked_mdelem* storage, + int64_t index_to_add) GRPC_MUST_USE_RESULT; + /** Add \a elem_to_add as the last element in \a batch, using \a storage as backing storage for the linked list element. \a storage is owned by the caller and must survive for the @@ -110,8 +127,17 @@ grpc_error* grpc_metadata_batch_add_tail( grpc_metadata_batch* batch, grpc_linked_mdelem* storage, grpc_mdelem elem_to_add) GRPC_MUST_USE_RESULT; +/** Identical to grpc_metadata_batch_add_tail, except takes the index of the + metadata element to add instead of a grpc_mdelem object. The index must + be a valid static hpack table index */ +grpc_error* grpc_metadata_batch_add_head_index( + grpc_metadata_batch* batch, grpc_linked_mdelem* storage, + int64_t index_to_add) GRPC_MUST_USE_RESULT; + grpc_error* grpc_attach_md_to_error(grpc_error* src, grpc_mdelem md); +bool is_valid_mdelem_index(int64_t index); + typedef struct { grpc_error* error; grpc_mdelem md; From 9e735f40e5299d0bd0e6b09d1fa0f9fb38bfb7b6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 29 Aug 2018 09:36:22 +0200 Subject: [PATCH 250/546] fix port picker for remote bazel --- .../core/util/port_isolated_runtime_environment.cc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/test/core/util/port_isolated_runtime_environment.cc b/test/core/util/port_isolated_runtime_environment.cc index ff8342ff4a4..773290b7952 100644 --- a/test/core/util/port_isolated_runtime_environment.cc +++ b/test/core/util/port_isolated_runtime_environment.cc @@ -16,8 +16,9 @@ * */ -/* When running tests on remote machines, the framework takes a round-robin pick - * of a port within certain range. There is no need to recycle ports. +/* When individual tests run in an isolated runtime environment (e.g. each test + * runs in a separate container) the framework takes a round-robin pick of a + * port within certain range. There is no need to recycle ports. */ #include #include @@ -28,18 +29,21 @@ #include "test/core/util/port.h" #define MIN_PORT 49152 -#define MAX_PORT 65536 +#define MAX_PORT 65535 int get_random_starting_port() { srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec); - return rand() % (MAX_PORT - MIN_PORT + 1) + MIN_PORT; + double rnd = static_cast(rand()) / + (static_cast(RAND_MAX) + 1.0); // values from [0,1) + return static_cast(rnd * (MAX_PORT - MIN_PORT + 1)) + MIN_PORT; } static int s_allocated_port = get_random_starting_port(); int grpc_pick_unused_port_or_die(void) { + // TODO(jtattermusch): protect by mutex int allocated_port = s_allocated_port++; - if (s_allocated_port == MAX_PORT) { + if (s_allocated_port == MAX_PORT + 1) { s_allocated_port = MIN_PORT; } From ca77fcd7cdb4c220e53c9e8465aa85e198e144ed Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 29 Aug 2018 07:46:48 -0700 Subject: [PATCH 251/546] Reviewer comments --- include/grpcpp/impl/codegen/client_context.h | 2 -- include/grpcpp/impl/codegen/metadata_map.h | 36 +++++++++++--------- include/grpcpp/impl/codegen/server_context.h | 1 - 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index cf1d9018885..c6c95409504 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -202,7 +202,6 @@ class ClientContext { const std::multimap& GetServerInitialMetadata() const { GPR_CODEGEN_ASSERT(initial_metadata_received_); - recv_initial_metadata_.FillMap(); return *recv_initial_metadata_.map(); } @@ -215,7 +214,6 @@ class ClientContext { const std::multimap& GetServerTrailingMetadata() const { // TODO(yangg) check finished - trailing_metadata_.FillMap(); return *trailing_metadata_.map(); } diff --git a/include/grpcpp/impl/codegen/metadata_map.h b/include/grpcpp/impl/codegen/metadata_map.h index 6e0c2a96372..5e480bc7ace 100644 --- a/include/grpcpp/impl/codegen/metadata_map.h +++ b/include/grpcpp/impl/codegen/metadata_map.h @@ -19,6 +19,7 @@ #ifndef GRPCPP_IMPL_CODEGEN_METADATA_MAP_H #define GRPCPP_IMPL_CODEGEN_METADATA_MAP_H +#include #include #include @@ -37,8 +38,8 @@ class MetadataMap { } grpc::string GetBinaryErrorDetails() { - // if filled, extract from the multimap for O(log(n)) - if (filled) { + // if filled_, extract from the multimap for O(log(n)) + if (filled_) { auto iter = map_.find(kBinaryErrorDetailsKey); if (iter != map_.end()) { return grpc::string(iter->second.begin(), iter->second.length()); @@ -46,9 +47,12 @@ class MetadataMap { } // if not yet filled, take the O(n) lookup to avoid allocating the // multimap until it is requested. + // TODO(ncteisen): plumb this through core as a first class object, just + // like code and message. else { for (size_t i = 0; i < arr_.count; i++) { - if (grpc_slice_str_cmp(arr_.metadata[i].key, kBinaryErrorDetailsKey)) { + if (grpc_slice_str_cmp(arr_.metadata[i].key, kBinaryErrorDetailsKey) == + 0) { return grpc::string(reinterpret_cast( GRPC_SLICE_START_PTR(arr_.metadata[i].value)), GRPC_SLICE_LENGTH(arr_.metadata[i].value)); @@ -58,9 +62,20 @@ class MetadataMap { return grpc::string(); } + std::multimap* map() { + FillMap(); + return &map_; + } + grpc_metadata_array* arr() { return &arr_; } + + private: + bool filled_ = false; + grpc_metadata_array arr_; + std::multimap map_; + void FillMap() { - if (filled) return; - filled = true; + if (filled_) return; + filled_ = true; for (size_t i = 0; i < arr_.count; i++) { // TODO(yangg) handle duplicates? map_.insert(std::pair( @@ -68,17 +83,6 @@ class MetadataMap { StringRefFromSlice(&arr_.metadata[i].value))); } } - - std::multimap* map() { return &map_; } - const std::multimap* map() const { - return &map_; - } - grpc_metadata_array* arr() { return &arr_; } - - private: - bool filled = false; - grpc_metadata_array arr_; - std::multimap map_; }; } // namespace internal diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index 506c51a5d96..b58f029de93 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -169,7 +169,6 @@ class ServerContext { /// \return A multimap of initial metadata key-value pairs from the server. const std::multimap& client_metadata() const { - client_metadata_.FillMap(); return *client_metadata_.map(); } From 58e99b6377b7c0a897f57a337803ebfd0a3b759e Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 29 Aug 2018 10:30:31 -0700 Subject: [PATCH 252/546] Use strncmp over grpc_slice_str_cmp --- include/grpcpp/impl/codegen/metadata_map.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/impl/codegen/metadata_map.h b/include/grpcpp/impl/codegen/metadata_map.h index 5e480bc7ace..5e062a50f83 100644 --- a/include/grpcpp/impl/codegen/metadata_map.h +++ b/include/grpcpp/impl/codegen/metadata_map.h @@ -20,7 +20,6 @@ #define GRPCPP_IMPL_CODEGEN_METADATA_MAP_H #include -#include #include namespace grpc { @@ -51,8 +50,10 @@ class MetadataMap { // like code and message. else { for (size_t i = 0; i < arr_.count; i++) { - if (grpc_slice_str_cmp(arr_.metadata[i].key, kBinaryErrorDetailsKey) == - 0) { + if (strncmp(reinterpret_cast( + GRPC_SLICE_START_PTR(arr_.metadata[i].key)), + kBinaryErrorDetailsKey, + GRPC_SLICE_LENGTH(arr_.metadata[i].key)) == 0) { return grpc::string(reinterpret_cast( GRPC_SLICE_START_PTR(arr_.metadata[i].value)), GRPC_SLICE_LENGTH(arr_.metadata[i].value)); From 40ec97dbff8e1248c2d0da9efe642f2ce5770969 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 29 Aug 2018 12:20:27 -0700 Subject: [PATCH 253/546] Enable timer test on windows --- test/core/iomgr/timer_list_test.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/core/iomgr/timer_list_test.cc b/test/core/iomgr/timer_list_test.cc index feedf3f1493..fd65d1abf1f 100644 --- a/test/core/iomgr/timer_list_test.cc +++ b/test/core/iomgr/timer_list_test.cc @@ -248,11 +248,7 @@ int main(int argc, char** argv) { grpc_determine_iomgr_platform(); grpc_iomgr_platform_init(); gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); -#ifndef GPR_WINDOWS - /* Skip this test on Windows until we figure out why it fails */ - /* https://github.com/grpc/grpc/issues/16417 */ long_running_service_cleanup_test(); -#endif // GPR_WINDOWS add_test(); destruction_test(); grpc_iomgr_platform_shutdown(); From f8a4aae1197e586d5c34f1acff450eac4d764c4b Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 1 Aug 2018 08:36:03 -0700 Subject: [PATCH 254/546] Fix all instances of bugprone-undefined-memory-manipulation --- .clang-tidy | 4 ++-- .../filters/client_channel/client_channel.cc | 1 - src/core/lib/surface/channel.cc | 1 - src/core/tsi/alts_transport_security.cc | 4 +++- test/{cpp/util => }/.clang-tidy | 0 .../end2end/fixtures/http_proxy_fixture.cc | 18 ++++++++++++------ test/core/end2end/fixtures/proxy.cc | 17 +++++++++++++---- 7 files changed, 30 insertions(+), 15 deletions(-) rename test/{cpp/util => }/.clang-tidy (100%) diff --git a/.clang-tidy b/.clang-tidy index fbf0b6541e3..d2174417920 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,6 @@ --- -Checks: 'modernize-use-nullptr,google-build-namespaces,google-build-explicit-make-pair,readability-function-size,performance-*' -WarningsAsErrors: 'modernize-use-nullptr,google-build-namespaces,google-build-explicit-make-pair,readability-function-size,performance-*' +Checks: 'modernize-use-nullptr,google-build-namespaces,google-build-explicit-make-pair,readability-function-size,performance-*,bugprone-*' +WarningsAsErrors: 'modernize-use-nullptr,google-build-namespaces,google-build-explicit-make-pair,readability-function-size,performance-*,bugprone-*' CheckOptions: - key: readability-function-size.StatementThreshold value: '450' diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index b06f09d8c7b..b2275441e58 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -457,7 +457,6 @@ get_service_config_from_resolver_result_locked(channel_data* chand) { 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, diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index 82635d3c215..e3dde51d697 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -100,7 +100,6 @@ grpc_channel* grpc_channel_create_with_builder( return channel; } - memset(channel, 0, sizeof(*channel)); channel->target = target; channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type); size_t channel_tracer_max_nodes = 0; // default to off diff --git a/src/core/tsi/alts_transport_security.cc b/src/core/tsi/alts_transport_security.cc index 2fd408103bf..dac23bbf7a4 100644 --- a/src/core/tsi/alts_transport_security.cc +++ b/src/core/tsi/alts_transport_security.cc @@ -45,7 +45,9 @@ void grpc_tsi_alts_signal_for_cq_destroy() { } void grpc_tsi_alts_init() { - memset(&g_alts_resource, 0, sizeof(alts_shared_resource)); + g_alts_resource.channel = nullptr; + g_alts_resource.cq = nullptr; + g_alts_resource.is_cq_drained = false; gpr_mu_init(&g_alts_resource.mu); gpr_cv_init(&g_alts_resource.cv); } diff --git a/test/cpp/util/.clang-tidy b/test/.clang-tidy similarity index 100% rename from test/cpp/util/.clang-tidy rename to test/.clang-tidy diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index f02fa9d9983..6f444bf66a2 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -52,6 +52,16 @@ #include "test/core/util/port.h" struct grpc_end2end_http_proxy { + grpc_end2end_http_proxy() + : proxy_name(nullptr), + server(nullptr), + channel_args(nullptr), + mu(nullptr), + pollset(nullptr), + combiner(nullptr) { + gpr_ref_init(&users, 1); + combiner = grpc_combiner_create(); + } char* proxy_name; grpc_core::Thread thd; grpc_tcp_server* server; @@ -519,11 +529,7 @@ static void thread_main(void* arg) { grpc_end2end_http_proxy* grpc_end2end_http_proxy_create( grpc_channel_args* args) { grpc_core::ExecCtx exec_ctx; - grpc_end2end_http_proxy* proxy = - static_cast(gpr_malloc(sizeof(*proxy))); - memset(proxy, 0, sizeof(*proxy)); - proxy->combiner = grpc_combiner_create(); - gpr_ref_init(&proxy->users, 1); + grpc_end2end_http_proxy* proxy = grpc_core::New(); // Construct proxy address. const int proxy_port = grpc_pick_unused_port_or_die(); gpr_join_host_port(&proxy->proxy_name, "localhost", proxy_port); @@ -573,7 +579,7 @@ void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) { GRPC_CLOSURE_CREATE(destroy_pollset, proxy->pollset, grpc_schedule_on_exec_ctx)); GRPC_COMBINER_UNREF(proxy->combiner, "test"); - gpr_free(proxy); + grpc_core::Delete(proxy); } const char* grpc_end2end_http_proxy_get_proxy_name( diff --git a/test/core/end2end/fixtures/proxy.cc b/test/core/end2end/fixtures/proxy.cc index 042c858b4cb..869b6e846d3 100644 --- a/test/core/end2end/fixtures/proxy.cc +++ b/test/core/end2end/fixtures/proxy.cc @@ -30,6 +30,17 @@ #include "test/core/util/port.h" struct grpc_end2end_proxy { + grpc_end2end_proxy() + : proxy_port(nullptr), + server_port(nullptr), + cq(nullptr), + server(nullptr), + client(nullptr), + shutdown(false), + new_call(nullptr) { + memset(&new_call_details, 0, sizeof(new_call_details)); + memset(&new_call_metadata, 0, sizeof(new_call_metadata)); + } grpc_core::Thread thd; char* proxy_port; char* server_port; @@ -79,9 +90,7 @@ grpc_end2end_proxy* grpc_end2end_proxy_create(const grpc_end2end_proxy_def* def, int proxy_port = grpc_pick_unused_port_or_die(); int server_port = grpc_pick_unused_port_or_die(); - grpc_end2end_proxy* proxy = - static_cast(gpr_malloc(sizeof(*proxy))); - memset(proxy, 0, sizeof(*proxy)); + grpc_end2end_proxy* proxy = grpc_core::New(); gpr_join_host_port(&proxy->proxy_port, "localhost", proxy_port); gpr_join_host_port(&proxy->server_port, "localhost", server_port); @@ -128,7 +137,7 @@ void grpc_end2end_proxy_destroy(grpc_end2end_proxy* proxy) { grpc_channel_destroy(proxy->client); grpc_completion_queue_destroy(proxy->cq); grpc_call_details_destroy(&proxy->new_call_details); - gpr_free(proxy); + grpc_core::Delete(proxy); } static void unrefpc(proxy_call* pc, const char* reason) { From 62e9ddbcbe37b3c36a25e4e3a74a9bddac30ab36 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 29 Aug 2018 16:26:13 -0700 Subject: [PATCH 255/546] Update building with Visual Studio documentation --- BUILDING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index 81edb68e435..615b371db6e 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -132,8 +132,8 @@ you will be able to browse and build the code. > @rem Run from grpc directory after cloning the repo with --recursive or updating submodules. > md .build > cd .build -> cmake .. -G "Visual Studio 14 2015" -DCMAKE_BUILD_TYPE=Release -> cmake --build . +> cmake .. -G "Visual Studio 14 2015" +> cmake --build . --config Release ``` ## cmake: Windows, Using Ninja (faster build, supports boringssl's assembly optimizations). From 14a858123d929d7eaa87bec00357fea938e75656 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 29 Aug 2018 21:36:41 -0700 Subject: [PATCH 256/546] Revert "Implement Watch method in health check service." --- .../grpcpp/impl/codegen/completion_queue.h | 1 - .../health/default_health_check_service.cc | 484 +++--------------- .../health/default_health_check_service.h | 242 +-------- src/cpp/server/health/health.pb.c | 1 + src/cpp/server/health/health.pb.h | 7 +- src/cpp/server/server_cc.cc | 27 +- src/proto/grpc/health/v1/health.proto | 20 - .../end2end/health_service_end2end_test.cc | 76 +-- tools/distrib/check_nanopb_output.sh | 18 - 9 files changed, 105 insertions(+), 771 deletions(-) diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 6c8428ebde6..3f7d4fb765f 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -384,7 +384,6 @@ class ServerCompletionQueue : public CompletionQueue { grpc_cq_polling_type polling_type_; friend class ServerBuilder; - friend class Server; }; } // namespace grpc diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index 670da63a4a0..bfda67d0864 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -30,162 +30,29 @@ #include "src/cpp/server/health/health.pb.h" namespace grpc { - -// -// DefaultHealthCheckService -// - -DefaultHealthCheckService::DefaultHealthCheckService() { - services_map_[""].SetServingStatus(SERVING); -} - -void DefaultHealthCheckService::SetServingStatus( - const grpc::string& service_name, bool serving) { - std::unique_lock lock(mu_); - services_map_[service_name].SetServingStatus(serving ? SERVING : NOT_SERVING); -} - -void DefaultHealthCheckService::SetServingStatus(bool serving) { - const ServingStatus status = serving ? SERVING : NOT_SERVING; - std::unique_lock lock(mu_); - for (auto& p : services_map_) { - ServiceData& service_data = p.second; - service_data.SetServingStatus(status); - } -} - -DefaultHealthCheckService::ServingStatus -DefaultHealthCheckService::GetServingStatus( - const grpc::string& service_name) const { - std::lock_guard lock(mu_); - auto it = services_map_.find(service_name); - if (it == services_map_.end()) { - return NOT_FOUND; - } - const ServiceData& service_data = it->second; - return service_data.GetServingStatus(); -} - -void DefaultHealthCheckService::RegisterCallHandler( - const grpc::string& service_name, - std::shared_ptr handler) { - std::unique_lock lock(mu_); - ServiceData& service_data = services_map_[service_name]; - service_data.AddCallHandler(handler /* copies ref */); - handler->SendHealth(std::move(handler), service_data.GetServingStatus()); -} - -void DefaultHealthCheckService::UnregisterCallHandler( - const grpc::string& service_name, - std::shared_ptr handler) { - std::unique_lock lock(mu_); - auto it = services_map_.find(service_name); - if (it == services_map_.end()) return; - ServiceData& service_data = it->second; - service_data.RemoveCallHandler(std::move(handler)); - if (service_data.Unused()) { - services_map_.erase(it); - } -} - -DefaultHealthCheckService::HealthCheckServiceImpl* -DefaultHealthCheckService::GetHealthCheckService( - std::unique_ptr cq) { - GPR_ASSERT(impl_ == nullptr); - impl_.reset(new HealthCheckServiceImpl(this, std::move(cq))); - return impl_.get(); -} - -// -// DefaultHealthCheckService::ServiceData -// - -void DefaultHealthCheckService::ServiceData::SetServingStatus( - ServingStatus status) { - status_ = status; - for (auto& call_handler : call_handlers_) { - call_handler->SendHealth(call_handler /* copies ref */, status); - } -} - -void DefaultHealthCheckService::ServiceData::AddCallHandler( - std::shared_ptr handler) { - call_handlers_.insert(std::move(handler)); -} - -void DefaultHealthCheckService::ServiceData::RemoveCallHandler( - std::shared_ptr handler) { - call_handlers_.erase(std::move(handler)); -} - -// -// DefaultHealthCheckService::HealthCheckServiceImpl -// - namespace { const char kHealthCheckMethodName[] = "/grpc.health.v1.Health/Check"; -const char kHealthWatchMethodName[] = "/grpc.health.v1.Health/Watch"; } // namespace DefaultHealthCheckService::HealthCheckServiceImpl::HealthCheckServiceImpl( - DefaultHealthCheckService* database, - std::unique_ptr cq) - : database_(database), cq_(std::move(cq)) { - // Add Check() method. - check_method_ = new internal::RpcServiceMethod( - kHealthCheckMethodName, internal::RpcMethod::NORMAL_RPC, nullptr); - AddMethod(check_method_); - // Add Watch() method. - watch_method_ = new internal::RpcServiceMethod( - kHealthWatchMethodName, internal::RpcMethod::SERVER_STREAMING, nullptr); - AddMethod(watch_method_); - // Create serving thread. - thread_ = std::unique_ptr<::grpc_core::Thread>( - new ::grpc_core::Thread("grpc_health_check_service", Serve, this)); -} - -DefaultHealthCheckService::HealthCheckServiceImpl::~HealthCheckServiceImpl() { - // We will reach here after the server starts shutting down. - shutdown_ = true; - { - std::unique_lock lock(cq_shutdown_mu_); - cq_->Shutdown(); - } - thread_->Join(); -} - -void DefaultHealthCheckService::HealthCheckServiceImpl::StartServingThread() { - thread_->Start(); -} - -void DefaultHealthCheckService::HealthCheckServiceImpl::Serve(void* arg) { - HealthCheckServiceImpl* service = - reinterpret_cast(arg); - // TODO(juanlishen): This is a workaround to wait for the cq to be ready. - // Need to figure out why cq is not ready after service starts. - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(1, GPR_TIMESPAN))); - CheckCallHandler::CreateAndStart(service->cq_.get(), service->database_, - service); - WatchCallHandler::CreateAndStart(service->cq_.get(), service->database_, - service); - void* tag; - bool ok; - while (true) { - if (!service->cq_->Next(&tag, &ok)) { - // The completion queue is shutting down. - GPR_ASSERT(service->shutdown_); - break; - } - auto* next_step = static_cast(tag); - next_step->Run(ok); - } -} - -bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest( - const ByteBuffer& request, grpc::string* service_name) { + DefaultHealthCheckService* service) + : service_(service), method_(nullptr) { + internal::MethodHandler* handler = + new internal::RpcMethodHandler( + std::mem_fn(&HealthCheckServiceImpl::Check), this); + method_ = new internal::RpcServiceMethod( + kHealthCheckMethodName, internal::RpcMethod::NORMAL_RPC, handler); + AddMethod(method_); +} + +Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( + ServerContext* context, const ByteBuffer* request, ByteBuffer* response) { + // Decode request. std::vector slices; - if (!request.Dump(&slices).ok()) return false; + if (!request->Dump(&slices).ok()) { + return Status(StatusCode::INVALID_ARGUMENT, ""); + } uint8_t* request_bytes = nullptr; bool request_bytes_owned = false; size_t request_size = 0; @@ -197,13 +64,14 @@ bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest( request_size = slices[0].size(); } else { request_bytes_owned = true; - request_bytes = static_cast(gpr_malloc(request.Length())); + request_bytes = static_cast(gpr_malloc(request->Length())); uint8_t* copy_to = request_bytes; for (size_t i = 0; i < slices.size(); i++) { memcpy(copy_to, slices[i].begin(), slices[i].size()); copy_to += slices[i].size(); } } + if (request_bytes != nullptr) { pb_istream_t istream = pb_istream_from_buffer(request_bytes, request_size); bool decode_status = pb_decode( @@ -211,22 +79,26 @@ bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest( if (request_bytes_owned) { gpr_free(request_bytes); } - if (!decode_status) return false; + if (!decode_status) { + return Status(StatusCode::INVALID_ARGUMENT, ""); + } } - *service_name = request_struct.has_service ? request_struct.service : ""; - return true; -} -bool DefaultHealthCheckService::HealthCheckServiceImpl::EncodeResponse( - ServingStatus status, ByteBuffer* response) { + // Check status from the associated default health checking service. + DefaultHealthCheckService::ServingStatus serving_status = + service_->GetServingStatus( + request_struct.has_service ? request_struct.service : ""); + if (serving_status == DefaultHealthCheckService::NOT_FOUND) { + return Status(StatusCode::NOT_FOUND, ""); + } + + // Encode response grpc_health_v1_HealthCheckResponse response_struct; response_struct.has_status = true; response_struct.status = - status == NOT_FOUND - ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN - : status == SERVING - ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING - : grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING; + serving_status == DefaultHealthCheckService::SERVING + ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING + : grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING; pb_ostream_t ostream; memset(&ostream, 0, sizeof(ostream)); pb_encode(&ostream, grpc_health_v1_HealthCheckResponse_fields, @@ -236,282 +108,48 @@ bool DefaultHealthCheckService::HealthCheckServiceImpl::EncodeResponse( GRPC_SLICE_LENGTH(response_slice)); bool encode_status = pb_encode( &ostream, grpc_health_v1_HealthCheckResponse_fields, &response_struct); - if (!encode_status) return false; + if (!encode_status) { + return Status(StatusCode::INTERNAL, "Failed to encode response."); + } Slice encoded_response(response_slice, Slice::STEAL_REF); ByteBuffer response_buffer(&encoded_response, 1); response->Swap(&response_buffer); - return true; -} - -// -// DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler -// - -void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: - CreateAndStart(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service) { - std::shared_ptr self = - std::make_shared(cq, database, service); - CheckCallHandler* handler = static_cast(self.get()); - { - std::unique_lock lock(service->cq_shutdown_mu_); - if (service->shutdown_) return; - // Request a Check() call. - handler->next_ = - CallableTag(std::bind(&CheckCallHandler::OnCallReceived, handler, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - service->RequestAsyncUnary(0, &handler->ctx_, &handler->request_, - &handler->writer_, cq, cq, &handler->next_); - } -} - -DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: - CheckCallHandler(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service) - : cq_(cq), database_(database), service_(service), writer_(&ctx_) {} - -void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: - OnCallReceived(std::shared_ptr self, bool ok) { - if (!ok) { - // The value of ok being false means that the server is shutting down. - return; - } - // Spawn a new handler instance to serve the next new client. Every handler - // instance will deallocate itself when it's done. - CreateAndStart(cq_, database_, service_); - // Process request. - gpr_log(GPR_DEBUG, "[HCS %p] Health check started for handler %p", service_, - this); - grpc::string service_name; - grpc::Status status = Status::OK; - ByteBuffer response; - if (!service_->DecodeRequest(request_, &service_name)) { - status = Status(INVALID_ARGUMENT, ""); - } else { - ServingStatus serving_status = database_->GetServingStatus(service_name); - if (serving_status == NOT_FOUND) { - status = Status(StatusCode::NOT_FOUND, "service name unknown"); - } else if (!service_->EncodeResponse(serving_status, &response)) { - status = Status(INTERNAL, ""); - } - } - // Send response. - { - std::unique_lock lock(service_->cq_shutdown_mu_); - if (!service_->shutdown_) { - next_ = - CallableTag(std::bind(&CheckCallHandler::OnFinishDone, this, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - if (status.ok()) { - writer_.Finish(response, status, &next_); - } else { - writer_.FinishWithError(status, &next_); - } - } - } -} - -void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: - OnFinishDone(std::shared_ptr self, bool ok) { - if (ok) { - gpr_log(GPR_DEBUG, "[HCS %p] Health check call finished for handler %p", - service_, this); - } -} - -// -// DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler -// - -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - CreateAndStart(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service) { - std::shared_ptr self = - std::make_shared(cq, database, service); - WatchCallHandler* handler = static_cast(self.get()); - { - std::unique_lock lock(service->cq_shutdown_mu_); - if (service->shutdown_) return; - // Request AsyncNotifyWhenDone(). - handler->on_done_notified_ = - CallableTag(std::bind(&WatchCallHandler::OnDoneNotified, handler, - std::placeholders::_1, std::placeholders::_2), - self /* copies ref */); - handler->ctx_.AsyncNotifyWhenDone(&handler->on_done_notified_); - // Request a Watch() call. - handler->next_ = - CallableTag(std::bind(&WatchCallHandler::OnCallReceived, handler, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - service->RequestAsyncServerStreaming(1, &handler->ctx_, &handler->request_, - &handler->stream_, cq, cq, - &handler->next_); - } + return Status::OK; } -DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - WatchCallHandler(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service) - : cq_(cq), - database_(database), - service_(service), - stream_(&ctx_), - call_state_(WAITING_FOR_CALL) {} - -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - OnCallReceived(std::shared_ptr self, bool ok) { - if (ok) { - call_state_ = CALL_RECEIVED; - } else { - // AsyncNotifyWhenDone() needs to be called before the call starts, but the - // tag will not pop out if the call never starts ( - // https://github.com/grpc/grpc/issues/10136). So we need to manually - // release the ownership of the handler in this case. - GPR_ASSERT(on_done_notified_.ReleaseHandler() != nullptr); - } - if (!ok || shutdown_) { - // The value of ok being false means that the server is shutting down. - Shutdown(std::move(self), "OnCallReceived"); - return; - } - // Spawn a new handler instance to serve the next new client. Every handler - // instance will deallocate itself when it's done. - CreateAndStart(cq_, database_, service_); - // Parse request. - if (!service_->DecodeRequest(request_, &service_name_)) { - on_finish_done_ = - CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - stream_.Finish(Status(INVALID_ARGUMENT, ""), &on_finish_done_); - call_state_ = FINISH_CALLED; - return; - } - // Register the call for updates to the service. - gpr_log(GPR_DEBUG, - "[HCS %p] Health check watch started for service \"%s\" " - "(handler: %p)", - service_, service_name_.c_str(), this); - database_->RegisterCallHandler(service_name_, std::move(self)); -} - -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - SendHealth(std::shared_ptr self, ServingStatus status) { - std::unique_lock lock(mu_); - // If there's already a send in flight, cache the new status, and - // we'll start a new send for it when the one in flight completes. - if (send_in_flight_) { - pending_status_ = status; - return; - } - // Start a send. - SendHealthLocked(std::move(self), status); -} - -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - SendHealthLocked(std::shared_ptr self, ServingStatus status) { - std::unique_lock cq_lock(service_->cq_shutdown_mu_); - if (service_->shutdown_) { - cq_lock.release()->unlock(); - Shutdown(std::move(self), "SendHealthLocked"); - return; - } - send_in_flight_ = true; - call_state_ = SEND_MESSAGE_PENDING; - // Construct response. - ByteBuffer response; - if (!service_->EncodeResponse(status, &response)) { - on_finish_done_ = - CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - stream_.Finish(Status(INTERNAL, ""), &on_finish_done_); - return; - } - next_ = CallableTag(std::bind(&WatchCallHandler::OnSendHealthDone, this, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - stream_.Write(response, &next_); +DefaultHealthCheckService::DefaultHealthCheckService() { + services_map_.emplace("", true); } -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - OnSendHealthDone(std::shared_ptr self, bool ok) { - if (!ok || shutdown_) { - Shutdown(std::move(self), "OnSendHealthDone"); - return; - } - call_state_ = CALL_RECEIVED; - { - std::unique_lock lock(mu_); - send_in_flight_ = false; - // If we got a new status since we started the last send, start a - // new send for it. - if (pending_status_ != NOT_FOUND) { - auto status = pending_status_; - pending_status_ = NOT_FOUND; - SendHealthLocked(std::move(self), status); - } - } +void DefaultHealthCheckService::SetServingStatus( + const grpc::string& service_name, bool serving) { + std::lock_guard lock(mu_); + services_map_[service_name] = serving; } -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - OnDoneNotified(std::shared_ptr self, bool ok) { - GPR_ASSERT(ok); - done_notified_ = true; - if (ctx_.IsCancelled()) { - is_cancelled_ = true; +void DefaultHealthCheckService::SetServingStatus(bool serving) { + std::lock_guard lock(mu_); + for (auto iter = services_map_.begin(); iter != services_map_.end(); ++iter) { + iter->second = serving; } - gpr_log(GPR_DEBUG, - "[HCS %p] Healt check call is notified done (handler: %p, " - "is_cancelled: %d).", - service_, this, static_cast(is_cancelled_)); - Shutdown(std::move(self), "OnDoneNotified"); } -// TODO(roth): This method currently assumes that there will be only one -// thread polling the cq and invoking the corresponding callbacks. If -// that changes, we will need to add synchronization here. -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - Shutdown(std::shared_ptr self, const char* reason) { - if (!shutdown_) { - gpr_log(GPR_DEBUG, - "[HCS %p] Shutting down the handler (service_name: \"%s\", " - "handler: %p, reason: %s).", - service_, service_name_.c_str(), this, reason); - shutdown_ = true; - } - // OnCallReceived() may be called after OnDoneNotified(), so we need to - // try to Finish() every time we are in Shutdown(). - if (call_state_ >= CALL_RECEIVED && call_state_ < FINISH_CALLED) { - std::unique_lock lock(service_->cq_shutdown_mu_); - if (!service_->shutdown_) { - on_finish_done_ = - CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - // TODO(juanlishen): Maybe add a message proto for the client to - // explicitly cancel the stream so that we can return OK status in such - // cases. - stream_.Finish(Status::CANCELLED, &on_finish_done_); - call_state_ = FINISH_CALLED; - } +DefaultHealthCheckService::ServingStatus +DefaultHealthCheckService::GetServingStatus( + const grpc::string& service_name) const { + std::lock_guard lock(mu_); + const auto& iter = services_map_.find(service_name); + if (iter == services_map_.end()) { + return NOT_FOUND; } + return iter->second ? SERVING : NOT_SERVING; } -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - OnFinishDone(std::shared_ptr self, bool ok) { - if (ok) { - gpr_log(GPR_DEBUG, - "[HCS %p] Health check call finished (service_name: \"%s\", " - "handler: %p).", - service_, service_name_.c_str(), this); - } +DefaultHealthCheckService::HealthCheckServiceImpl* +DefaultHealthCheckService::GetHealthCheckService() { + GPR_ASSERT(impl_ == nullptr); + impl_.reset(new HealthCheckServiceImpl(this)); + return impl_.get(); } } // namespace grpc diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index edad5949362..a1ce5aa64ec 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -19,268 +19,42 @@ #ifndef GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H #define GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H -#include #include -#include -#include -#include #include -#include -#include #include #include -#include "src/core/lib/gprpp/thd.h" - namespace grpc { // Default implementation of HealthCheckServiceInterface. Server will create and // own it. class DefaultHealthCheckService final : public HealthCheckServiceInterface { public: - enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; - // The service impl to register with the server. class HealthCheckServiceImpl : public Service { public: - // Base class for call handlers. - class CallHandler { - public: - virtual ~CallHandler() = default; - virtual void SendHealth(std::shared_ptr self, - ServingStatus status) = 0; - }; + explicit HealthCheckServiceImpl(DefaultHealthCheckService* service); - HealthCheckServiceImpl(DefaultHealthCheckService* database, - std::unique_ptr cq); - - ~HealthCheckServiceImpl(); - - void StartServingThread(); + Status Check(ServerContext* context, const ByteBuffer* request, + ByteBuffer* response); private: - // A tag that can be called with a bool argument. It's tailored for - // CallHandler's use. Before being used, it should be constructed with a - // method of CallHandler and a shared pointer to the handler. The - // shared pointer will be moved to the invoked function and the function - // can only be invoked once. That makes ref counting of the handler easier, - // because the shared pointer is not bound to the function and can be gone - // once the invoked function returns (if not used any more). - class CallableTag { - public: - using HandlerFunction = - std::function, bool)>; - - CallableTag() {} - - CallableTag(HandlerFunction func, std::shared_ptr handler) - : handler_function_(std::move(func)), handler_(std::move(handler)) { - GPR_ASSERT(handler_function_ != nullptr); - GPR_ASSERT(handler_ != nullptr); - } - - // Runs the tag. This should be called only once. The handler is no - // longer owned by this tag after this method is invoked. - void Run(bool ok) { - GPR_ASSERT(handler_function_ != nullptr); - GPR_ASSERT(handler_ != nullptr); - handler_function_(std::move(handler_), ok); - } - - // Releases and returns the shared pointer to the handler. - std::shared_ptr ReleaseHandler() { - return std::move(handler_); - } - - private: - HandlerFunction handler_function_ = nullptr; - std::shared_ptr handler_; - }; - - // Call handler for Check method. - // Each handler takes care of one call. It contains per-call data and it - // will access the members of the parent class (i.e., - // DefaultHealthCheckService) for per-service health data. - class CheckCallHandler : public CallHandler { - public: - // Instantiates a CheckCallHandler and requests the next health check - // call. The handler object will manage its own lifetime, so no action is - // needed from the caller any more regarding that object. - static void CreateAndStart(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service); - - // This ctor is public because we want to use std::make_shared<> in - // CreateAndStart(). This ctor shouldn't be used elsewhere. - CheckCallHandler(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service); - - // Not used for Check. - void SendHealth(std::shared_ptr self, - ServingStatus status) override {} - - private: - // Called when we receive a call. - // Spawns a new handler so that we can keep servicing future calls. - void OnCallReceived(std::shared_ptr self, bool ok); - - // Called when Finish() is done. - void OnFinishDone(std::shared_ptr self, bool ok); - - // The members passed down from HealthCheckServiceImpl. - ServerCompletionQueue* cq_; - DefaultHealthCheckService* database_; - HealthCheckServiceImpl* service_; - - ByteBuffer request_; - GenericServerAsyncResponseWriter writer_; - ServerContext ctx_; - - CallableTag next_; - }; - - // Call handler for Watch method. - // Each handler takes care of one call. It contains per-call data and it - // will access the members of the parent class (i.e., - // DefaultHealthCheckService) for per-service health data. - class WatchCallHandler : public CallHandler { - public: - // Instantiates a WatchCallHandler and requests the next health check - // call. The handler object will manage its own lifetime, so no action is - // needed from the caller any more regarding that object. - static void CreateAndStart(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service); - - // This ctor is public because we want to use std::make_shared<> in - // CreateAndStart(). This ctor shouldn't be used elsewhere. - WatchCallHandler(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service); - - void SendHealth(std::shared_ptr self, - ServingStatus status) override; - - private: - // Called when we receive a call. - // Spawns a new handler so that we can keep servicing future calls. - void OnCallReceived(std::shared_ptr self, bool ok); - - // Requires holding mu_. - void SendHealthLocked(std::shared_ptr self, - ServingStatus status); - - // When sending a health result finishes. - void OnSendHealthDone(std::shared_ptr self, bool ok); - - // Called when Finish() is done. - void OnFinishDone(std::shared_ptr self, bool ok); - - // Called when AsyncNotifyWhenDone() notifies us. - void OnDoneNotified(std::shared_ptr self, bool ok); - - void Shutdown(std::shared_ptr self, const char* reason); - - // The members passed down from HealthCheckServiceImpl. - ServerCompletionQueue* cq_; - DefaultHealthCheckService* database_; - HealthCheckServiceImpl* service_; - - ByteBuffer request_; - grpc::string service_name_; - GenericServerAsyncWriter stream_; - ServerContext ctx_; - - std::mutex mu_; - bool send_in_flight_ = false; // Guarded by mu_. - ServingStatus pending_status_ = NOT_FOUND; // Guarded by mu_. - - // The state of the RPC progress. - enum CallState { - WAITING_FOR_CALL, - CALL_RECEIVED, - SEND_MESSAGE_PENDING, - FINISH_CALLED - } call_state_; - - bool shutdown_ = false; - bool done_notified_ = false; - bool is_cancelled_ = false; - CallableTag next_; - CallableTag on_done_notified_; - CallableTag on_finish_done_; - }; - - // Handles the incoming requests and drives the completion queue in a loop. - static void Serve(void* arg); - - // Returns true on success. - static bool DecodeRequest(const ByteBuffer& request, - grpc::string* service_name); - static bool EncodeResponse(ServingStatus status, ByteBuffer* response); - - // Needed to appease Windows compilers, which don't seem to allow - // nested classes to access protected members in the parent's - // superclass. - using Service::RequestAsyncServerStreaming; - using Service::RequestAsyncUnary; - - DefaultHealthCheckService* database_; - std::unique_ptr cq_; - internal::RpcServiceMethod* check_method_; - internal::RpcServiceMethod* watch_method_; - - // To synchronize the operations related to shutdown state of cq_, so that - // we don't enqueue new tags into cq_ after it is already shut down. - std::mutex cq_shutdown_mu_; - std::atomic_bool shutdown_{false}; - std::unique_ptr<::grpc_core::Thread> thread_; + const DefaultHealthCheckService* const service_; + internal::RpcServiceMethod* method_; }; DefaultHealthCheckService(); - void SetServingStatus(const grpc::string& service_name, bool serving) override; void SetServingStatus(bool serving) override; - + enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; ServingStatus GetServingStatus(const grpc::string& service_name) const; - - HealthCheckServiceImpl* GetHealthCheckService( - std::unique_ptr cq); + HealthCheckServiceImpl* GetHealthCheckService(); private: - // Stores the current serving status of a service and any call - // handlers registered for updates when the service's status changes. - class ServiceData { - public: - void SetServingStatus(ServingStatus status); - ServingStatus GetServingStatus() const { return status_; } - void AddCallHandler( - std::shared_ptr handler); - void RemoveCallHandler( - std::shared_ptr handler); - bool Unused() const { - return call_handlers_.empty() && status_ == NOT_FOUND; - } - - private: - ServingStatus status_ = NOT_FOUND; - std::set> - call_handlers_; - }; - - void RegisterCallHandler( - const grpc::string& service_name, - std::shared_ptr handler); - - void UnregisterCallHandler( - const grpc::string& service_name, - std::shared_ptr handler); - mutable std::mutex mu_; - std::map services_map_; // Guarded by mu_. + std::map services_map_; std::unique_ptr impl_; }; diff --git a/src/cpp/server/health/health.pb.c b/src/cpp/server/health/health.pb.c index 5c214c7160f..09bd98a3d97 100644 --- a/src/cpp/server/health/health.pb.c +++ b/src/cpp/server/health/health.pb.c @@ -2,6 +2,7 @@ /* Generated by nanopb-0.3.7-dev */ #include "src/cpp/server/health/health.pb.h" + /* @@protoc_insertion_point(includes) */ #if PB_PROTO_HEADER_VERSION != 30 #error Regenerate this file with the current version of nanopb generator. diff --git a/src/cpp/server/health/health.pb.h b/src/cpp/server/health/health.pb.h index 9d54ccd6182..29e1f3bacb1 100644 --- a/src/cpp/server/health/health.pb.h +++ b/src/cpp/server/health/health.pb.h @@ -17,12 +17,11 @@ extern "C" { typedef enum _grpc_health_v1_HealthCheckResponse_ServingStatus { grpc_health_v1_HealthCheckResponse_ServingStatus_UNKNOWN = 0, grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING = 1, - grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING = 2, - grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN = 3 + grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING = 2 } grpc_health_v1_HealthCheckResponse_ServingStatus; #define _grpc_health_v1_HealthCheckResponse_ServingStatus_MIN grpc_health_v1_HealthCheckResponse_ServingStatus_UNKNOWN -#define _grpc_health_v1_HealthCheckResponse_ServingStatus_MAX grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN -#define _grpc_health_v1_HealthCheckResponse_ServingStatus_ARRAYSIZE ((grpc_health_v1_HealthCheckResponse_ServingStatus)(grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN+1)) +#define _grpc_health_v1_HealthCheckResponse_ServingStatus_MAX grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING +#define _grpc_health_v1_HealthCheckResponse_ServingStatus_ARRAYSIZE ((grpc_health_v1_HealthCheckResponse_ServingStatus)(grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING+1)) /* Struct definitions */ typedef struct _grpc_health_v1_HealthCheckRequest { diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 3cadf65c801..36c709eb45b 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -559,20 +559,16 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { // Only create default health check service when user did not provide an // explicit one. - ServerCompletionQueue* health_check_cq = nullptr; - DefaultHealthCheckService::HealthCheckServiceImpl* - default_health_check_service_impl = nullptr; if (health_check_service_ == nullptr && !health_check_service_disabled_ && DefaultHealthCheckServiceEnabled()) { - auto* default_hc_service = new DefaultHealthCheckService; - health_check_service_.reset(default_hc_service); - health_check_cq = new ServerCompletionQueue(GRPC_CQ_DEFAULT_POLLING); - grpc_server_register_completion_queue(server_, health_check_cq->cq(), - nullptr); - default_health_check_service_impl = - default_hc_service->GetHealthCheckService( - std::unique_ptr(health_check_cq)); - RegisterService(nullptr, default_health_check_service_impl); + if (sync_server_cqs_ == nullptr || sync_server_cqs_->empty()) { + gpr_log(GPR_INFO, + "Default health check service disabled at async-only server."); + } else { + auto* default_hc_service = new DefaultHealthCheckService; + health_check_service_.reset(default_hc_service); + RegisterService(nullptr, default_hc_service->GetHealthCheckService()); + } } grpc_server_start(server_); @@ -587,9 +583,6 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { new UnimplementedAsyncRequest(this, cqs[i]); } } - if (health_check_cq != nullptr) { - new UnimplementedAsyncRequest(this, health_check_cq); - } } // If this server has any support for synchronous methods (has any sync @@ -602,10 +595,6 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { (*it)->Start(); } - - if (default_health_check_service_impl != nullptr) { - default_health_check_service_impl->StartServingThread(); - } } void Server::ShutdownInternal(gpr_timespec deadline) { diff --git a/src/proto/grpc/health/v1/health.proto b/src/proto/grpc/health/v1/health.proto index 38843ff1e73..4b4677b8a4d 100644 --- a/src/proto/grpc/health/v1/health.proto +++ b/src/proto/grpc/health/v1/health.proto @@ -34,30 +34,10 @@ message HealthCheckResponse { UNKNOWN = 0; SERVING = 1; NOT_SERVING = 2; - SERVICE_UNKNOWN = 3; // Used only by the Watch method. } ServingStatus status = 1; } service Health { - // If the requested service is unknown, the call will fail with status - // NOT_FOUND. rpc Check(HealthCheckRequest) returns (HealthCheckResponse); - - // Performs a watch for the serving status of the requested service. - // The server will immediately send back a message indicating the current - // serving status. It will then subsequently send a new message whenever - // the service's serving status changes. - // - // If the requested service is unknown when the call is received, the - // server will send a message setting the serving status to - // SERVICE_UNKNOWN but will *not* terminate the call. If at some - // future point, the serving status of the service becomes known, the - // server will send a new message with the service's serving status. - // - // If the call terminates with status UNIMPLEMENTED, then clients - // should assume this method is not supported and should not retry the - // call. If the call terminates with any other status (including OK), - // clients should retry the call with appropriate exponential backoff. - rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); } diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index fca65dfc13b..1c48b9d151a 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -64,29 +64,6 @@ class HealthCheckServiceImpl : public ::grpc::health::v1::Health::Service { return Status::OK; } - Status Watch(ServerContext* context, const HealthCheckRequest* request, - ::grpc::ServerWriter* writer) override { - auto last_state = HealthCheckResponse::UNKNOWN; - while (!context->IsCancelled()) { - { - std::lock_guard lock(mu_); - HealthCheckResponse response; - auto iter = status_map_.find(request->service()); - if (iter == status_map_.end()) { - response.set_status(response.SERVICE_UNKNOWN); - } else { - response.set_status(iter->second); - } - if (response.status() != last_state) { - writer->Write(response, ::grpc::WriteOptions()); - } - } - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis(1000, GPR_TIMESPAN))); - } - return Status::OK; - } - void SetStatus(const grpc::string& service_name, HealthCheckResponse::ServingStatus status) { std::lock_guard lock(mu_); @@ -129,6 +106,14 @@ class CustomHealthCheckService : public HealthCheckServiceInterface { HealthCheckServiceImpl* impl_; // not owned }; +void LoopCompletionQueue(ServerCompletionQueue* cq) { + void* tag; + bool ok; + while (cq->Next(&tag, &ok)) { + abort(); // Nothing should come out of the cq. + } +} + class HealthServiceEnd2endTest : public ::testing::Test { protected: HealthServiceEnd2endTest() {} @@ -233,33 +218,6 @@ class HealthServiceEnd2endTest : public ::testing::Test { Status(StatusCode::NOT_FOUND, "")); } - void VerifyHealthCheckServiceStreaming() { - const grpc::string kServiceName("service_name"); - HealthCheckServiceInterface* service = server_->GetHealthCheckService(); - // Start Watch for service. - ClientContext context; - HealthCheckRequest request; - request.set_service(kServiceName); - std::unique_ptr<::grpc::ClientReaderInterface> reader = - hc_stub_->Watch(&context, request); - // Initial response will be SERVICE_UNKNOWN. - HealthCheckResponse response; - EXPECT_TRUE(reader->Read(&response)); - EXPECT_EQ(response.SERVICE_UNKNOWN, response.status()); - response.Clear(); - // Now set service to NOT_SERVING and make sure we get an update. - service->SetServingStatus(kServiceName, false); - EXPECT_TRUE(reader->Read(&response)); - EXPECT_EQ(response.NOT_SERVING, response.status()); - response.Clear(); - // Now set service to SERVING and make sure we get another update. - service->SetServingStatus(kServiceName, true); - EXPECT_TRUE(reader->Read(&response)); - EXPECT_EQ(response.SERVING, response.status()); - // Finish call. - context.TryCancel(); - } - TestServiceImpl echo_test_service_; HealthCheckServiceImpl health_check_service_impl_; std::unique_ptr hc_stub_; @@ -287,7 +245,6 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); SetUpServer(true, false, false, nullptr); VerifyHealthCheckService(); - VerifyHealthCheckServiceStreaming(); // The default service has a size limit of the service name. const grpc::string kTooLongServiceName(201, 'x'); @@ -295,6 +252,22 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { Status(StatusCode::INVALID_ARGUMENT, "")); } +// The server has no sync service. +TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceAsyncOnly) { + EnableDefaultHealthCheckService(true); + EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); + SetUpServer(false, true, false, nullptr); + cq_thread_ = std::thread(LoopCompletionQueue, cq_.get()); + + HealthCheckServiceInterface* default_service = + server_->GetHealthCheckService(); + EXPECT_TRUE(default_service == nullptr); + + ResetStubs(); + + SendHealthCheckRpc("", Status(StatusCode::UNIMPLEMENTED, "")); +} + // Provide an empty service to disable the default service. TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) { EnableDefaultHealthCheckService(true); @@ -323,7 +296,6 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) { ResetStubs(); VerifyHealthCheckService(); - VerifyHealthCheckServiceStreaming(); } } // namespace diff --git a/tools/distrib/check_nanopb_output.sh b/tools/distrib/check_nanopb_output.sh index 1c2ef9b7686..6b98619c320 100755 --- a/tools/distrib/check_nanopb_output.sh +++ b/tools/distrib/check_nanopb_output.sh @@ -16,7 +16,6 @@ set -ex readonly NANOPB_ALTS_TMP_OUTPUT="$(mktemp -d)" -readonly NANOPB_HEALTH_TMP_OUTPUT="$(mktemp -d)" readonly NANOPB_TMP_OUTPUT="$(mktemp -d)" readonly PROTOBUF_INSTALL_PREFIX="$(mktemp -d)" @@ -68,23 +67,6 @@ if ! diff -r "$NANOPB_TMP_OUTPUT" src/core/ext/filters/client_channel/lb_policy/ exit 2 fi -# -# checks for health.proto -# -readonly HEALTH_GRPC_OUTPUT_PATH='src/cpp/server/health' -# nanopb-compile the proto to a temp location -./tools/codegen/core/gen_nano_proto.sh \ - src/proto/grpc/health/v1/health.proto \ - "$NANOPB_HEALTH_TMP_OUTPUT" \ - "$HEALTH_GRPC_OUTPUT_PATH" -# compare outputs to checked compiled code -for NANOPB_OUTPUT_FILE in $NANOPB_HEALTH_TMP_OUTPUT/*.pb.*; do - if ! diff "$NANOPB_OUTPUT_FILE" "src/cpp/server/health/$(basename $NANOPB_OUTPUT_FILE)"; then - echo "Outputs differ: $NANOPB_HEALTH_TMP_OUTPUT vs $HEALTH_GRPC_OUTPUT_PATH" - exit 2 - fi -done - # # Checks for handshaker.proto and transport_security_common.proto # From 3c78606fb22d4cb9f648165688285ecfa00b7725 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 30 Aug 2018 18:45:38 +0200 Subject: [PATCH 257/546] yapf code --- tools/run_tests/run_tests.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index c4954df12b5..60c35b7220d 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1821,13 +1821,16 @@ def _build_and_run(check_cancelled, for antagonist in antagonists: antagonist.kill() if args.bq_result_table and resultset: - upload_extra_fields={ + upload_extra_fields = { 'compiler': args.compiler, 'config': args.config, 'iomgr_plaform': args.iomgr_platform, - 'language': args.language[0], # args.language is a list but will always have one element when uploading to BQ is enabled. - 'plaform': platform_string()} - upload_results_to_bq(resultset, args.bq_result_table, upload_extra_fields) + 'language': args.language[ + 0], # args.language is a list but will always have one element when uploading to BQ is enabled. + 'plaform': platform_string() + } + upload_results_to_bq(resultset, args.bq_result_table, + upload_extra_fields) if xml_report and resultset: report_utils.render_junit_xml_report( resultset, xml_report, suite_name=args.report_suite_name) From 2bc7b8e0a3975352eeffcb7751d6aef687fd1284 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 30 Aug 2018 19:28:30 +0200 Subject: [PATCH 258/546] address comments --- include/grpc/grpc_security_constants.h | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h index c115cd36592..7f7c89d6672 100644 --- a/include/grpc/grpc_security_constants.h +++ b/include/grpc/grpc_security_constants.h @@ -57,9 +57,10 @@ typedef enum { } grpc_ssl_certificate_config_reload_status; typedef enum { - /** Server does not request client certificate. A client may present a self - signed or signed certificate or not present a certificate at all and any of - those option would be accepted. */ + /** Server does not request client certificate. + The certificate presented by the client is not checked by the server at all. + (A client may present a self signed or signed certificate or not present a certificate at all and any of + those option would be accepted) */ GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, /** Server requests client certificate but does not enforce that the client presents a certificate. @@ -68,17 +69,18 @@ typedef enum { the application (the necessary metadata will be available to the application via authentication context properties, see grpc_auth_context). - The key cert pair should still be valid for the SSL connection to be + The client's key certificate pair must be valid for the SSL connection to be established. */ GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, /** Server requests client certificate but does not enforce that the client presents a certificate. If the client presents a certificate, the client authentication is done by - the gRPC framework (the client needs to either present a signed cert or not - present a certificate at all for a successful connection). + the gRPC framework. (For a successful connection the client needs to either + present a certificate that can be verified against the root certificate configured by the server + or not present a certificate at all) - The key cert pair should still be valid for the SSL connection to be + The client's key certificate pair must be valid for the SSL connection to be established. */ GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, /** Server requests client certificate and enforces that the client presents a @@ -88,16 +90,17 @@ typedef enum { the application (the necessary metadata will be available to the application via authentication context properties, see grpc_auth_context). - The key cert pair should still be valid for the SSL connection to be + The client's key certificate pair must be valid for the SSL connection to be established. */ GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, /** Server requests client certificate and enforces that the client presents a certificate. - The cerificate presented by the client is verified by the gRPC framework - (the client needs to present signed certs for a successful connection). + The cerificate presented by the client is verified by the gRPC framework. + (For a successful connection the client needs to present a certificate that can be verified against + the root certificate configured by the server) - The key cert pair should still be valid for the SSL connection to be + The client's key certificate pair must be valid for the SSL connection to be established. */ GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY } grpc_ssl_client_certificate_request_type; From bc8f515fb8a9053c05d2a62336fe181113262a17 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 30 Aug 2018 19:36:25 +0200 Subject: [PATCH 259/546] clang format --- include/grpc/grpc_security_constants.h | 30 +++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h index 7f7c89d6672..f935557f2d4 100644 --- a/include/grpc/grpc_security_constants.h +++ b/include/grpc/grpc_security_constants.h @@ -58,9 +58,9 @@ typedef enum { typedef enum { /** Server does not request client certificate. - The certificate presented by the client is not checked by the server at all. - (A client may present a self signed or signed certificate or not present a certificate at all and any of - those option would be accepted) */ + The certificate presented by the client is not checked by the server at + all. (A client may present a self signed or signed certificate or not + present a certificate at all and any of those option would be accepted) */ GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, /** Server requests client certificate but does not enforce that the client presents a certificate. @@ -69,19 +69,19 @@ typedef enum { the application (the necessary metadata will be available to the application via authentication context properties, see grpc_auth_context). - The client's key certificate pair must be valid for the SSL connection to be - established. */ + The client's key certificate pair must be valid for the SSL connection to + be established. */ GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, /** Server requests client certificate but does not enforce that the client presents a certificate. If the client presents a certificate, the client authentication is done by the gRPC framework. (For a successful connection the client needs to either - present a certificate that can be verified against the root certificate configured by the server - or not present a certificate at all) + present a certificate that can be verified against the root certificate + configured by the server or not present a certificate at all) - The client's key certificate pair must be valid for the SSL connection to be - established. */ + The client's key certificate pair must be valid for the SSL connection to + be established. */ GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY, /** Server requests client certificate and enforces that the client presents a certificate. @@ -90,18 +90,18 @@ typedef enum { the application (the necessary metadata will be available to the application via authentication context properties, see grpc_auth_context). - The client's key certificate pair must be valid for the SSL connection to be - established. */ + The client's key certificate pair must be valid for the SSL connection to + be established. */ GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY, /** Server requests client certificate and enforces that the client presents a certificate. The cerificate presented by the client is verified by the gRPC framework. - (For a successful connection the client needs to present a certificate that can be verified against - the root certificate configured by the server) + (For a successful connection the client needs to present a certificate that + can be verified against the root certificate configured by the server) - The client's key certificate pair must be valid for the SSL connection to be - established. */ + The client's key certificate pair must be valid for the SSL connection to + be established. */ GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY } grpc_ssl_client_certificate_request_type; From 7269fd47eb12f9383535c657b855286cd4570d9f Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 30 Aug 2018 11:37:34 -0700 Subject: [PATCH 260/546] Fix ipv6 address parsing issue --- src/core/ext/filters/client_channel/parse_address.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc index b3900114ad9..5eeea1b148b 100644 --- a/src/core/ext/filters/client_channel/parse_address.cc +++ b/src/core/ext/filters/client_channel/parse_address.cc @@ -128,6 +128,13 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, char host_without_scope[GRPC_INET6_ADDRSTRLEN]; size_t host_without_scope_len = static_cast(host_end - host); uint32_t sin6_scope_id = 0; + if (host_without_scope_len > GRPC_INET6_ADDRSTRLEN) { + gpr_log(GPR_ERROR, + "invalid ipv6 address length %d. Length cannot be greater than " + "GRPC_INET6_ADDRSTRLEN i.e %d)", + host_without_scope_len, GRPC_INET6_ADDRSTRLEN); + goto done; + } strncpy(host_without_scope, host, host_without_scope_len); host_without_scope[host_without_scope_len] = '\0'; if (grpc_inet_pton(GRPC_AF_INET6, host_without_scope, &in6->sin6_addr) == From 8018b462b025bb02e04d1624e59e0dcd5ee1f323 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 30 Aug 2018 20:39:52 +0200 Subject: [PATCH 261/546] update C# examples to netcoreapp2.1 --- examples/csharp/Helloworld/Greeter/Greeter.csproj | 2 +- .../csharp/Helloworld/GreeterClient/GreeterClient.csproj | 2 +- .../csharp/Helloworld/GreeterServer/GreeterServer.csproj | 2 +- examples/csharp/Helloworld/README.md | 8 +++----- examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj | 2 +- .../RouteGuide/RouteGuideClient/RouteGuideClient.csproj | 2 +- .../RouteGuide/RouteGuideServer/RouteGuideServer.csproj | 2 +- 7 files changed, 9 insertions(+), 11 deletions(-) diff --git a/examples/csharp/Helloworld/Greeter/Greeter.csproj b/examples/csharp/Helloworld/Greeter/Greeter.csproj index 1ca821320cd..eba262565d7 100644 --- a/examples/csharp/Helloworld/Greeter/Greeter.csproj +++ b/examples/csharp/Helloworld/Greeter/Greeter.csproj @@ -2,7 +2,7 @@ Greeter - netcoreapp1.0 + netcoreapp2.1 portable Greeter Greeter diff --git a/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj b/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj index d1ed0404118..24a89d58c55 100644 --- a/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj +++ b/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj @@ -2,7 +2,7 @@ GreeterClient - netcoreapp1.0 + netcoreapp2.1 portable GreeterClient Exe diff --git a/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj b/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj index 159fbd8a23d..9ea1fa3817c 100644 --- a/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj +++ b/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj @@ -2,7 +2,7 @@ GreeterServer - netcoreapp1.0 + netcoreapp2.1 portable GreeterServer Exe diff --git a/examples/csharp/Helloworld/README.md b/examples/csharp/Helloworld/README.md index e6031794388..48711324262 100644 --- a/examples/csharp/Helloworld/README.md +++ b/examples/csharp/Helloworld/README.md @@ -12,7 +12,7 @@ which have been already added to the project for you. PREREQUISITES ------------- -- The [.NET Core SDK](https://www.microsoft.com/net/core) (version 2+ is recommended) +- The [.NET Core SDK 2.1+](https://www.microsoft.com/net/core) You can also build the example directly using Visual Studio 2017, but it's not a requirement. @@ -23,8 +23,6 @@ From the `examples/csharp/Helloworld` directory: - `dotnet build Greeter.sln` -(if you're using dotnet SDK 1.x you need to run `dotnet restore Greeter.sln` first) - Try it! ------- @@ -32,14 +30,14 @@ Try it! ``` > cd GreeterServer - > dotnet run -f netcoreapp1.0 + > dotnet run -f netcoreapp2.1 ``` - Run the client ``` > cd GreeterClient - > dotnet run -f netcoreapp1.0 + > dotnet run -f netcoreapp2.1 ``` Tutorial diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj index e1c44ecf3c4..86346d1e149 100644 --- a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj +++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj @@ -2,7 +2,7 @@ RouteGuide - netcoreapp1.0 + netcoreapp2.1 portable RouteGuide RouteGuide diff --git a/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj b/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj index 96cc204ba37..c6dadf082b8 100644 --- a/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj +++ b/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj @@ -2,7 +2,7 @@ RouteGuideClient - netcoreapp1.0 + netcoreapp2.1 portable RouteGuideClient Exe diff --git a/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj index aa6315bf818..005c87ca0c2 100644 --- a/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj +++ b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj @@ -2,7 +2,7 @@ RouteGuideServer - netcoreapp1.0 + netcoreapp2.1 portable RouteGuideServer Exe From 0a7363ffcbbb578a7dc94f2bcffbe7b8ba78e1d2 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 30 Aug 2018 13:13:48 -0700 Subject: [PATCH 262/546] Add a test to parse invalid addresses --- .../ext/filters/client_channel/parse_address.cc | 2 +- test/core/client_channel/parse_address_test.cc | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc index 5eeea1b148b..c1dc0bc2cea 100644 --- a/src/core/ext/filters/client_channel/parse_address.cc +++ b/src/core/ext/filters/client_channel/parse_address.cc @@ -125,7 +125,7 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, char* host_end = static_cast(gpr_memrchr(host, '%', strlen(host))); if (host_end != nullptr) { GPR_ASSERT(host_end >= host); - char host_without_scope[GRPC_INET6_ADDRSTRLEN]; + char host_without_scope[GRPC_INET6_ADDRSTRLEN + 1]; size_t host_without_scope_len = static_cast(host_end - host); uint32_t sin6_scope_id = 0; if (host_without_scope_len > GRPC_INET6_ADDRSTRLEN) { diff --git a/test/core/client_channel/parse_address_test.cc b/test/core/client_channel/parse_address_test.cc index ae157fbb8b8..798600293ba 100644 --- a/test/core/client_channel/parse_address_test.cc +++ b/test/core/client_channel/parse_address_test.cc @@ -91,6 +91,14 @@ static void test_grpc_parse_ipv6(const char* uri_text, const char* host, grpc_uri_destroy(uri); } +/* Test parsing invalid ipv6 addresses (valid uri_text but invalid ipv6 addr) */ +static void test_grpc_parse_ipv6_invalid(const char* uri_text) { + grpc_core::ExecCtx exec_ctx; + grpc_uri* uri = grpc_uri_parse(uri_text, 0); + grpc_resolved_address addr; + GPR_ASSERT(!grpc_parse_ipv6(uri, &addr)); +} + int main(int argc, char** argv) { grpc_test_init(argc, argv); grpc_init(); @@ -100,5 +108,10 @@ int main(int argc, char** argv) { test_grpc_parse_ipv6("ipv6:[2001:db8::1]:12345", "2001:db8::1", 12345, 0); test_grpc_parse_ipv6("ipv6:[2001:db8::1%252]:12345", "2001:db8::1", 12345, 2); - grpc_shutdown(); + /* Address length greater than GRPC_INET6_ADDRSTRLEN */ + test_grpc_parse_ipv6_invalid( + "ipv6:WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW45%" + "v6:45%x$1*"); + + test_grpc_parse grpc_shutdown(); } From 50419a04ae9c1012a4eb6e159fdb225175e99bf6 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 30 Aug 2018 13:23:27 -0700 Subject: [PATCH 263/546] fix format specifier for size_t and and a typo in test --- src/core/ext/filters/client_channel/parse_address.cc | 2 +- test/core/client_channel/parse_address_test.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc index c1dc0bc2cea..7e726dd5624 100644 --- a/src/core/ext/filters/client_channel/parse_address.cc +++ b/src/core/ext/filters/client_channel/parse_address.cc @@ -130,7 +130,7 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, uint32_t sin6_scope_id = 0; if (host_without_scope_len > GRPC_INET6_ADDRSTRLEN) { gpr_log(GPR_ERROR, - "invalid ipv6 address length %d. Length cannot be greater than " + "invalid ipv6 address length %zu. Length cannot be greater than " "GRPC_INET6_ADDRSTRLEN i.e %d)", host_without_scope_len, GRPC_INET6_ADDRSTRLEN); goto done; diff --git a/test/core/client_channel/parse_address_test.cc b/test/core/client_channel/parse_address_test.cc index 798600293ba..d51c6178f88 100644 --- a/test/core/client_channel/parse_address_test.cc +++ b/test/core/client_channel/parse_address_test.cc @@ -113,5 +113,5 @@ int main(int argc, char** argv) { "ipv6:WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW45%" "v6:45%x$1*"); - test_grpc_parse grpc_shutdown(); + grpc_shutdown(); } From af1966aa037bf3515f553aee87c886ac829efc02 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 30 Aug 2018 22:26:56 +0200 Subject: [PATCH 264/546] fixes to run_tests.py bq uploading --- tools/run_tests/python_utils/upload_test_results.py | 2 +- tools/run_tests/run_tests.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/run_tests/python_utils/upload_test_results.py b/tools/run_tests/python_utils/upload_test_results.py index f04ef37e087..0ca23f56cf1 100644 --- a/tools/run_tests/python_utils/upload_test_results.py +++ b/tools/run_tests/python_utils/upload_test_results.py @@ -135,7 +135,7 @@ def upload_results_to_bq(resultset, bq_table, extra_fields): test_results['return_code'] = result.returncode test_results['test_name'] = shortname test_results['timestamp'] = time.strftime('%Y-%m-%d %H:%M:%S') - for field_name, field_value in extra_fields: + for field_name, field_value in six.iteritems(extra_fields): test_results[field_name] = field_value row = big_query_utils.make_row(str(uuid.uuid4()), test_results) bq_rows.append(row) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 60c35b7220d..ecb5e1d899e 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1824,10 +1824,10 @@ def _build_and_run(check_cancelled, upload_extra_fields = { 'compiler': args.compiler, 'config': args.config, - 'iomgr_plaform': args.iomgr_platform, + 'iomgr_platform': args.iomgr_platform, 'language': args.language[ 0], # args.language is a list but will always have one element when uploading to BQ is enabled. - 'plaform': platform_string() + 'platform': platform_string() } upload_results_to_bq(resultset, args.bq_result_table, upload_extra_fields) From 9d143dd3b967d57ba9a0d6a7cf98b2507d8050d8 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 29 Aug 2018 15:42:10 -0700 Subject: [PATCH 265/546] Fix internal format issue --- test/cpp/qps/json_run_localhost_scenario_gen.py | 1 + test/cpp/qps/json_run_localhost_scenarios.bzl | 2 ++ test/cpp/qps/qps_benchmark_script.bzl | 4 +++- test/cpp/qps/qps_json_driver_scenario_gen.py | 1 + test/cpp/qps/qps_json_driver_scenarios.bzl | 2 ++ 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/test/cpp/qps/json_run_localhost_scenario_gen.py b/test/cpp/qps/json_run_localhost_scenario_gen.py index 01f6a699d55..7fe12234d48 100755 --- a/test/cpp/qps/json_run_localhost_scenario_gen.py +++ b/test/cpp/qps/json_run_localhost_scenario_gen.py @@ -33,6 +33,7 @@ def generate_args(): serialized_scenarios_str = str(all_scenarios).encode('ascii', 'ignore') with open('json_run_localhost_scenarios.bzl', 'wb') as f: + f.write('"""Scenarios run on localhost."""\n\n') f.write('JSON_RUN_LOCALHOST_SCENARIOS = ' + serialized_scenarios_str + '\n') generate_args() diff --git a/test/cpp/qps/json_run_localhost_scenarios.bzl b/test/cpp/qps/json_run_localhost_scenarios.bzl index 589dcac2b54..33e49e92140 100644 --- a/test/cpp/qps/json_run_localhost_scenarios.bzl +++ b/test/cpp/qps/json_run_localhost_scenarios.bzl @@ -1 +1,3 @@ +"""Scenarios run on localhost.""" + JSON_RUN_LOCALHOST_SCENARIOS = {'cpp_protobuf_sync_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_ping_pong_insecure_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_1channel_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_unary_1channel_100rpcs_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\''} diff --git a/test/cpp/qps/qps_benchmark_script.bzl b/test/cpp/qps/qps_benchmark_script.bzl index 90902c0d41d..0904ceb0364 100644 --- a/test/cpp/qps/qps_benchmark_script.bzl +++ b/test/cpp/qps/qps_benchmark_script.bzl @@ -23,7 +23,9 @@ # each change must be ported from one to the other. # -load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_test") +"""Script to run qps benchmark.""" + +load("//bazel:grpc_build_system.bzl", "grpc_cc_test") load("//test/cpp/qps:qps_json_driver_scenarios.bzl", "QPS_JSON_DRIVER_SCENARIOS") load("//test/cpp/qps:json_run_localhost_scenarios.bzl", "JSON_RUN_LOCALHOST_SCENARIOS") diff --git a/test/cpp/qps/qps_json_driver_scenario_gen.py b/test/cpp/qps/qps_json_driver_scenario_gen.py index 393f968a645..2b66c69d8ad 100755 --- a/test/cpp/qps/qps_json_driver_scenario_gen.py +++ b/test/cpp/qps/qps_json_driver_scenario_gen.py @@ -33,6 +33,7 @@ def generate_args(): serialized_scenarios_str = str(all_scenarios).encode('ascii', 'ignore') with open('qps_json_driver_scenarios.bzl', 'w') as f: + f.write('"""Scenarios of qps driver."""\n\n') f.write('QPS_JSON_DRIVER_SCENARIOS = ' + serialized_scenarios_str + '\n') generate_args() diff --git a/test/cpp/qps/qps_json_driver_scenarios.bzl b/test/cpp/qps/qps_json_driver_scenarios.bzl index 6e2c28a8e73..95b49113257 100644 --- a/test/cpp/qps/qps_json_driver_scenarios.bzl +++ b/test/cpp/qps/qps_json_driver_scenarios.bzl @@ -1 +1,3 @@ +"""Scenarios of qps driver.""" + QPS_JSON_DRIVER_SCENARIOS = {'cpp_protobuf_sync_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_ping_pong_insecure_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_1channel_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_unary_1channel_100rpcs_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\''} From cf12e451ff67f01878537db732f0550d978ee55a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 30 Aug 2018 22:44:09 +0200 Subject: [PATCH 266/546] run_interop_tests.py: make sure to fail on exception --- tools/run_tests/run_interop_tests.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 22055d58e8b..e3356cda911 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -1519,9 +1519,6 @@ try: sys.exit(1) else: sys.exit(0) -except Exception as e: - print('exception occurred:') - traceback.print_exc(file=sys.stdout) finally: # Check if servers are still running. for server, job in server_jobs.items(): From 38d3298d534ed90a952ab2e571a34bacff798faa Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 30 Aug 2018 22:29:13 +0200 Subject: [PATCH 267/546] fix run_interop_tests.py --- tools/run_tests/run_interop_tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index e3356cda911..741e3c2b32d 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -776,9 +776,9 @@ def cloud_to_prod_jobspec(language, '--test_case=%s' % test_case ] if transport_security == 'tls': - transport_security_options += ['--use_tls=true'] + transport_security_options = ['--use_tls=true'] elif transport_security == 'google_default_credentials' and language == 'c++': - transport_security_options += [ + transport_security_options = [ '--custom_credentials_type=google_default_credentials' ] else: From c4a53233628dacc563fc53ab1582b659f3f0a5de Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 30 Aug 2018 15:22:08 -0700 Subject: [PATCH 268/546] fixed a bug in json_run_localhost scenario generation --- test/cpp/qps/json_run_localhost_scenario_gen.py | 6 +++--- test/cpp/qps/json_run_localhost_scenarios.bzl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/cpp/qps/json_run_localhost_scenario_gen.py b/test/cpp/qps/json_run_localhost_scenario_gen.py index 7fe12234d48..ab14f0e4a51 100755 --- a/test/cpp/qps/json_run_localhost_scenario_gen.py +++ b/test/cpp/qps/json_run_localhost_scenario_gen.py @@ -21,10 +21,10 @@ def generate_args(): all_scenario_set = gen.generate_yaml() all_scenario_set = all_scenario_set['tests'] json_run_localhost_scenarios = \ - [item for item in all_scenario_set if item['name'] == 'qps_json_driver'] + [item for item in all_scenario_set if item['name'] == 'json_run_localhost'] json_run_localhost_arg_set = \ - [item['args'][2] for item in json_run_localhost_scenarios \ - if 'args' in item and len(item['args']) > 2] + [item['args'][1] for item in json_run_localhost_scenarios \ + if 'args' in item and len(item['args']) > 1] deserialized_scenarios = [json.loads(item)['scenarios'][0] \ for item in json_run_localhost_arg_set] all_scenarios = {scenario['name'].encode('ascii', 'ignore'): \ diff --git a/test/cpp/qps/json_run_localhost_scenarios.bzl b/test/cpp/qps/json_run_localhost_scenarios.bzl index 33e49e92140..5bfb0bca766 100644 --- a/test/cpp/qps/json_run_localhost_scenarios.bzl +++ b/test/cpp/qps/json_run_localhost_scenarios.bzl @@ -1,3 +1,3 @@ """Scenarios run on localhost.""" -JSON_RUN_LOCALHOST_SCENARIOS = {'cpp_protobuf_sync_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_ping_pong_insecure_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_1channel_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_unary_1channel_100rpcs_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 16, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\''} +JSON_RUN_LOCALHOST_SCENARIOS = {'cpp_protobuf_async_unary_75Kqps_600channel_60Krpcs_300Breq_50Bresp': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_75Kqps_600channel_60Krpcs_300Breq_50Bresp", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 16, "threads_per_cq": 1, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"poisson": {"offered_load": 37500}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 50, "req_size": 300}}, "client_channels": 300, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_from_client_qps_unconstrained_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_ping_pong_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_generic_async_streaming_qps_1channel_1MBmsg_secure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_server_ping_pong_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1mps_secure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1cq_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_10mps_secure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_ping_pong_insecure_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_ping_pong_insecure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_generic_async_streaming_qps_one_server_core_secure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_one_server_core_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_secure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_ping_pong_secure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_from_server_qps_unconstrained_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_unary_qps_unconstrained_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_from_client_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_from_client_ping_pong_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_client_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_64KBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 65536, "req_size": 65536}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_server_qps_unconstrained_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_server_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_streaming_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_streaming_from_client_1channel_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_1channel_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_unary_1channel_100rpcs_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_1channel_100rpcs_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_secure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_1channel_1MBmsg_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_ping_pong_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_server_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_unary_1channel_64wide_128Breq_8MBresp_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 8388608, "req_size": 128}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_generic_async_streaming_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_sync_streaming_from_server_ping_pong_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_1cq_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_unary_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_unary_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_one_server_core_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_one_server_core_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 1, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_server_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 2}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_ping_pong_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 2, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 2}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_unary_ping_pong_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_unary_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_from_server_ping_pong_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_from_server_ping_pong_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "SYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING_FROM_SERVER", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_client_sync_server_unary_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 10, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_qps_unconstrained_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_qps_unconstrained_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_1cq_secure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_1cq_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 1000000}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_generic_async_streaming_qps_unconstrained_10mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_generic_async_streaming_qps_unconstrained_10mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"async_server_threads": 0, "security_params": null, "server_type": "ASYNC_GENERIC_SERVER", "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "threads_per_cq": 0}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"bytebuf_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_10mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 10, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_ping_pong_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_ping_pong_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 1, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\'', 'cpp_protobuf_async_streaming_from_client_qps_unconstrained_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_from_client_qps_unconstrained_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 3, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING_FROM_CLIENT", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 3}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1cq_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 1000000, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 13, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 1000000}, "num_clients": 0}]}\'', 'cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_sync_streaming_qps_unconstrained_1mps_secure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "SYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 1, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "SYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_streaming_qps_unconstrained_1mps_insecure", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": null, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}]}, "client_config": {"security_params": null, "channel_args": [{"str_value": "throughput", "name": "grpc.optimization_target"}, {"int_value": 1, "name": "grpc.minimal_stack"}], "async_client_threads": 0, "outstanding_rpcs_per_channel": 100, "rpc_type": "STREAMING", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "messages_per_stream": 1, "payload_config": {"simple_params": {"resp_size": 0, "req_size": 0}}, "client_channels": 64, "threads_per_cq": 0}, "num_clients": 0}]}\'', 'cpp_protobuf_async_unary_ping_pong_secure_1MB': '\'{\'scenarios\' : [{"name": "cpp_protobuf_async_unary_ping_pong_secure_1MB", "warmup_seconds": 0, "benchmark_seconds": 1, "num_servers": 1, "server_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "server_type": "ASYNC_SERVER", "async_server_threads": 0, "threads_per_cq": 0, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}]}, "client_config": {"security_params": {"use_test_ca": true, "server_host_override": "foo.test.google.fr"}, "channel_args": [{"str_value": "latency", "name": "grpc.optimization_target"}], "async_client_threads": 1, "outstanding_rpcs_per_channel": 1, "rpc_type": "UNARY", "load_params": {"closed_loop": {}}, "histogram_params": {"resolution": 0.01, "max_possible": 60000000000.0}, "client_type": "ASYNC_CLIENT", "payload_config": {"simple_params": {"resp_size": 1048576, "req_size": 1048576}}, "client_channels": 1, "threads_per_cq": 0}, "num_clients": 1}]}\''} From 8bf52535d1008a3f38e70d1387846f0e942761b5 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 21 Aug 2018 14:32:13 -0700 Subject: [PATCH 269/546] Provide a generic client-side unary callback API --- BUILD | 4 + CMakeLists.txt | 57 ++++++++ Makefile | 64 +++++++++ build.yaml | 18 +++ gRPC-C++.podspec | 4 + grpc.gyp | 2 + include/grpcpp/channel.h | 5 + include/grpcpp/generic/generic_stub.h | 23 ++++ include/grpcpp/impl/codegen/call.h | 10 +- include/grpcpp/impl/codegen/callback_common.h | 79 +++++++++++ .../grpcpp/impl/codegen/channel_interface.h | 14 ++ include/grpcpp/impl/codegen/client_callback.h | 92 +++++++++++++ include/grpcpp/impl/codegen/client_context.h | 4 + .../grpcpp/impl/codegen/completion_queue.h | 3 + include/grpcpp/support/client_callback.h | 24 ++++ src/core/lib/surface/completion_queue.cc | 4 +- src/cpp/client/channel_cc.cc | 41 +++++- src/cpp/client/generic_stub.cc | 14 +- src/cpp/common/callback_common.cc | 109 +++++++++++++++ src/cpp/server/server_cc.cc | 3 +- src/cpp/server/server_context.cc | 3 + test/cpp/end2end/BUILD | 19 +++ .../end2end/client_callback_end2end_test.cc | 126 ++++++++++++++++++ tools/doxygen/Doxyfile.c++ | 3 + tools/doxygen/Doxyfile.c++.internal | 4 + .../generated/sources_and_headers.json | 26 ++++ tools/run_tests/generated/tests.json | 24 ++++ 27 files changed, 772 insertions(+), 7 deletions(-) create mode 100644 include/grpcpp/impl/codegen/callback_common.h create mode 100644 include/grpcpp/impl/codegen/client_callback.h create mode 100644 include/grpcpp/support/client_callback.h create mode 100644 src/cpp/common/callback_common.cc create mode 100644 test/cpp/end2end/client_callback_end2end_test.cc diff --git a/BUILD b/BUILD index 925e277cf77..271e57e36cf 100644 --- a/BUILD +++ b/BUILD @@ -119,6 +119,7 @@ GRPCXX_SRCS = [ "src/cpp/client/credentials_cc.cc", "src/cpp/client/generic_stub.cc", "src/cpp/common/alarm.cc", + "src/cpp/common/callback_common.cc", "src/cpp/common/channel_arguments.cc", "src/cpp/common/channel_filter.cc", "src/cpp/common/completion_queue_cc.cc", @@ -243,6 +244,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/client_callback.h", "include/grpcpp/support/config.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", @@ -1979,7 +1981,9 @@ grpc_cc_library( "include/grpcpp/impl/codegen/byte_buffer.h", "include/grpcpp/impl/codegen/call.h", "include/grpcpp/impl/codegen/call_hook.h", + "include/grpcpp/impl/codegen/callback_common.h", "include/grpcpp/impl/codegen/channel_interface.h", + "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index a21bb8b5fae..8679c5b4e27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -564,6 +564,7 @@ add_dependencies(buildtests_cxx check_gcp_environment_linux_test) add_dependencies(buildtests_cxx check_gcp_environment_windows_test) add_dependencies(buildtests_cxx chttp2_settings_timeout_test) add_dependencies(buildtests_cxx cli_call_test) +add_dependencies(buildtests_cxx client_callback_end2end_test) add_dependencies(buildtests_cxx client_channel_stress_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx client_crash_test) @@ -2771,6 +2772,7 @@ add_library(grpc++ src/cpp/client/credentials_cc.cc src/cpp/client/generic_stub.cc src/cpp/common/alarm.cc + src/cpp/common/callback_common.cc src/cpp/common/channel_arguments.cc src/cpp/common/channel_filter.cc src/cpp/common/completion_queue_cc.cc @@ -2917,6 +2919,7 @@ foreach(_hdr include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h + include/grpcpp/support/client_callback.h include/grpcpp/support/config.h include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h @@ -3014,7 +3017,9 @@ foreach(_hdr include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h + include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h + include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h @@ -3129,6 +3134,7 @@ add_library(grpc++_cronet src/cpp/client/credentials_cc.cc src/cpp/client/generic_stub.cc src/cpp/common/alarm.cc + src/cpp/common/callback_common.cc src/cpp/common/channel_arguments.cc src/cpp/common/channel_filter.cc src/cpp/common/completion_queue_cc.cc @@ -3486,6 +3492,7 @@ foreach(_hdr include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h + include/grpcpp/support/client_callback.h include/grpcpp/support/config.h include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h @@ -3583,7 +3590,9 @@ foreach(_hdr include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h + include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h + include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h @@ -3993,7 +4002,9 @@ foreach(_hdr include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h + include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h + include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h @@ -4171,7 +4182,9 @@ foreach(_hdr include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h + include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h + include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h @@ -4247,6 +4260,7 @@ add_library(grpc++_unsecure src/cpp/client/credentials_cc.cc src/cpp/client/generic_stub.cc src/cpp/common/alarm.cc + src/cpp/common/callback_common.cc src/cpp/common/channel_arguments.cc src/cpp/common/channel_filter.cc src/cpp/common/completion_queue_cc.cc @@ -4392,6 +4406,7 @@ foreach(_hdr include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h + include/grpcpp/support/client_callback.h include/grpcpp/support/config.h include/grpcpp/support/proto_buffer_reader.h include/grpcpp/support/proto_buffer_writer.h @@ -4489,7 +4504,9 @@ foreach(_hdr include/grpcpp/impl/codegen/byte_buffer.h include/grpcpp/impl/codegen/call.h include/grpcpp/impl/codegen/call_hook.h + include/grpcpp/impl/codegen/callback_common.h include/grpcpp/impl/codegen/channel_interface.h + include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h @@ -11297,6 +11314,46 @@ target_link_libraries(cli_call_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(client_callback_end2end_test + test/cpp/end2end/client_callback_end2end_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(client_callback_end2end_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 ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_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(client_callback_end2end_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc++_test_util + grpc_test_util + grpc++ + grpc + gpr_test_util + gpr + ${_gRPC_GFLAGS_LIBRARIES} +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(client_channel_stress_test ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc diff --git a/Makefile b/Makefile index 96ea890bcb8..33ec3d93e71 100644 --- a/Makefile +++ b/Makefile @@ -1160,6 +1160,7 @@ check_gcp_environment_linux_test: $(BINDIR)/$(CONFIG)/check_gcp_environment_linu check_gcp_environment_windows_test: $(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test chttp2_settings_timeout_test: $(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test cli_call_test: $(BINDIR)/$(CONFIG)/cli_call_test +client_callback_end2end_test: $(BINDIR)/$(CONFIG)/client_callback_end2end_test client_channel_stress_test: $(BINDIR)/$(CONFIG)/client_channel_stress_test client_crash_test: $(BINDIR)/$(CONFIG)/client_crash_test client_crash_test_server: $(BINDIR)/$(CONFIG)/client_crash_test_server @@ -1665,6 +1666,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test \ $(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test \ $(BINDIR)/$(CONFIG)/cli_call_test \ + $(BINDIR)/$(CONFIG)/client_callback_end2end_test \ $(BINDIR)/$(CONFIG)/client_channel_stress_test \ $(BINDIR)/$(CONFIG)/client_crash_test \ $(BINDIR)/$(CONFIG)/client_crash_test_server \ @@ -1845,6 +1847,7 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test \ $(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test \ $(BINDIR)/$(CONFIG)/cli_call_test \ + $(BINDIR)/$(CONFIG)/client_callback_end2end_test \ $(BINDIR)/$(CONFIG)/client_channel_stress_test \ $(BINDIR)/$(CONFIG)/client_crash_test \ $(BINDIR)/$(CONFIG)/client_crash_test_server \ @@ -2302,6 +2305,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/chttp2_settings_timeout_test || ( echo test chttp2_settings_timeout_test failed ; exit 1 ) $(E) "[RUN] Testing cli_call_test" $(Q) $(BINDIR)/$(CONFIG)/cli_call_test || ( echo test cli_call_test failed ; exit 1 ) + $(E) "[RUN] Testing client_callback_end2end_test" + $(Q) $(BINDIR)/$(CONFIG)/client_callback_end2end_test || ( echo test client_callback_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing client_channel_stress_test" $(Q) $(BINDIR)/$(CONFIG)/client_channel_stress_test || ( echo test client_channel_stress_test failed ; exit 1 ) $(E) "[RUN] Testing client_crash_test" @@ -5219,6 +5224,7 @@ LIBGRPC++_SRC = \ src/cpp/client/credentials_cc.cc \ src/cpp/client/generic_stub.cc \ src/cpp/common/alarm.cc \ + src/cpp/common/callback_common.cc \ src/cpp/common/channel_arguments.cc \ src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue_cc.cc \ @@ -5329,6 +5335,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ + include/grpcpp/support/client_callback.h \ include/grpcpp/support/config.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ @@ -5426,7 +5433,9 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ + include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ + include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ @@ -5585,6 +5594,7 @@ LIBGRPC++_CRONET_SRC = \ src/cpp/client/credentials_cc.cc \ src/cpp/client/generic_stub.cc \ src/cpp/common/alarm.cc \ + src/cpp/common/callback_common.cc \ src/cpp/common/channel_arguments.cc \ src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue_cc.cc \ @@ -5905,6 +5915,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ + include/grpcpp/support/client_callback.h \ include/grpcpp/support/config.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ @@ -6002,7 +6013,9 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ + include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ + include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ @@ -6392,7 +6405,9 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ + include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ + include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ @@ -6546,7 +6561,9 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ + include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ + include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ @@ -6661,6 +6678,7 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/client/credentials_cc.cc \ src/cpp/client/generic_stub.cc \ src/cpp/common/alarm.cc \ + src/cpp/common/callback_common.cc \ src/cpp/common/channel_arguments.cc \ src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue_cc.cc \ @@ -6771,6 +6789,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ + include/grpcpp/support/client_callback.h \ include/grpcpp/support/config.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ @@ -6868,7 +6887,9 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ + include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ + include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ @@ -17076,6 +17097,49 @@ endif endif +CLIENT_CALLBACK_END2END_TEST_SRC = \ + test/cpp/end2end/client_callback_end2end_test.cc \ + +CLIENT_CALLBACK_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CLIENT_CALLBACK_END2END_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/client_callback_end2end_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.5.0+. + +$(BINDIR)/$(CONFIG)/client_callback_end2end_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/client_callback_end2end_test: $(PROTOBUF_DEP) $(CLIENT_CALLBACK_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_CALLBACK_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/client_callback_end2end_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/client_callback_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_client_callback_end2end_test: $(CLIENT_CALLBACK_END2END_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(CLIENT_CALLBACK_END2END_TEST_OBJS:.o=.dep) +endif +endif + + CLIENT_CHANNEL_STRESS_TEST_SRC = \ $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \ test/cpp/client/client_channel_stress_test.cc \ diff --git a/build.yaml b/build.yaml index a50a0a4ab65..b775773e42c 100644 --- a/build.yaml +++ b/build.yaml @@ -1169,7 +1169,9 @@ filegroups: - include/grpcpp/impl/codegen/byte_buffer.h - include/grpcpp/impl/codegen/call.h - include/grpcpp/impl/codegen/call_hook.h + - include/grpcpp/impl/codegen/callback_common.h - include/grpcpp/impl/codegen/channel_interface.h + - include/grpcpp/impl/codegen/client_callback.h - include/grpcpp/impl/codegen/client_context.h - include/grpcpp/impl/codegen/client_unary_call.h - include/grpcpp/impl/codegen/completion_queue.h @@ -1297,6 +1299,7 @@ filegroups: - include/grpcpp/support/async_unary_call.h - include/grpcpp/support/byte_buffer.h - include/grpcpp/support/channel_arguments.h + - include/grpcpp/support/client_callback.h - include/grpcpp/support/config.h - include/grpcpp/support/proto_buffer_reader.h - include/grpcpp/support/proto_buffer_writer.h @@ -1324,6 +1327,7 @@ filegroups: - src/cpp/client/credentials_cc.cc - src/cpp/client/generic_stub.cc - src/cpp/common/alarm.cc + - src/cpp/common/callback_common.cc - src/cpp/common/channel_arguments.cc - src/cpp/common/channel_filter.cc - src/cpp/common/completion_queue_cc.cc @@ -4465,6 +4469,20 @@ targets: - grpc - gpr_test_util - gpr +- name: client_callback_end2end_test + gtest: true + cpu_cost: 0.5 + build: test + language: c++ + src: + - test/cpp/end2end/client_callback_end2end_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr - name: client_channel_stress_test gtest: false build: test diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 581b9246bc5..03ec223279e 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -111,6 +111,7 @@ Pod::Spec.new do |s| 'include/grpcpp/support/async_unary_call.h', 'include/grpcpp/support/byte_buffer.h', 'include/grpcpp/support/channel_arguments.h', + 'include/grpcpp/support/client_callback.h', 'include/grpcpp/support/config.h', 'include/grpcpp/support/proto_buffer_reader.h', 'include/grpcpp/support/proto_buffer_writer.h', @@ -127,7 +128,9 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/byte_buffer.h', 'include/grpcpp/impl/codegen/call.h', 'include/grpcpp/impl/codegen/call_hook.h', + 'include/grpcpp/impl/codegen/callback_common.h', 'include/grpcpp/impl/codegen/channel_interface.h', + 'include/grpcpp/impl/codegen/client_callback.h', 'include/grpcpp/impl/codegen/client_context.h', 'include/grpcpp/impl/codegen/client_unary_call.h', 'include/grpcpp/impl/codegen/completion_queue.h', @@ -187,6 +190,7 @@ Pod::Spec.new do |s| 'src/cpp/client/credentials_cc.cc', 'src/cpp/client/generic_stub.cc', 'src/cpp/common/alarm.cc', + 'src/cpp/common/callback_common.cc', 'src/cpp/common/channel_arguments.cc', 'src/cpp/common/channel_filter.cc', 'src/cpp/common/completion_queue_cc.cc', diff --git a/grpc.gyp b/grpc.gyp index 654a5310923..b8aae44de30 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1381,6 +1381,7 @@ 'src/cpp/client/credentials_cc.cc', 'src/cpp/client/generic_stub.cc', 'src/cpp/common/alarm.cc', + 'src/cpp/common/callback_common.cc', 'src/cpp/common/channel_arguments.cc', 'src/cpp/common/channel_filter.cc', 'src/cpp/common/completion_queue_cc.cc', @@ -1528,6 +1529,7 @@ 'src/cpp/client/credentials_cc.cc', 'src/cpp/client/generic_stub.cc', 'src/cpp/common/alarm.cc', + 'src/cpp/common/callback_common.cc', 'src/cpp/common/channel_arguments.cc', 'src/cpp/common/channel_filter.cc', 'src/cpp/common/completion_queue_cc.cc', diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h index fed02bf7bc7..58a6f516648 100644 --- a/include/grpcpp/channel.h +++ b/include/grpcpp/channel.h @@ -78,8 +78,13 @@ class Channel final : public ChannelInterface, bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) override; + CompletionQueue* CallbackCQ() override; + const grpc::string host_; grpc_channel* const c_channel_; // owned + + CompletionQueue* callback_cq_ = nullptr; + std::mutex mu_; }; } // namespace grpc diff --git a/include/grpcpp/generic/generic_stub.h b/include/grpcpp/generic/generic_stub.h index 92405a43fae..d509d9a5206 100644 --- a/include/grpcpp/generic/generic_stub.h +++ b/include/grpcpp/generic/generic_stub.h @@ -19,9 +19,12 @@ #ifndef GRPCPP_GENERIC_GENERIC_STUB_H #define GRPCPP_GENERIC_GENERIC_STUB_H +#include + #include #include #include +#include namespace grpc { @@ -62,6 +65,26 @@ class GenericStub final { ClientContext* context, const grpc::string& method, CompletionQueue* cq, void* tag); + /// NOTE: class experimental_type is not part of the public API of this class + /// TODO(vjpai): Move these contents to the public API of GenericStub when + /// they are no longer experimental + class experimental_type { + public: + explicit experimental_type(GenericStub* stub) : stub_(stub) {} + + void UnaryCall(ClientContext* context, const grpc::string& method, + const ByteBuffer* request, ByteBuffer* response, + std::function on_completion); + + private: + GenericStub* stub_; + }; + + /// NOTE: The function experimental() is not stable public API. It is a view + /// to the experimental components of this class. It may be changed or removed + /// at any time. + experimental_type experimental() { return experimental_type(this); } + private: std::shared_ptr channel_; }; diff --git a/include/grpcpp/impl/codegen/call.h b/include/grpcpp/impl/codegen/call.h index a5e930aaa5c..7bd03b6b1bd 100644 --- a/include/grpcpp/impl/codegen/call.h +++ b/include/grpcpp/impl/codegen/call.h @@ -608,6 +608,9 @@ class CallOpSetInterface : public CompletionQueueTag { /// Fills in grpc_op, starting from ops[*nops] and moving /// upwards. virtual void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) = 0; + + /// Get the tag to be used at the CQ + virtual void* cq_tag() = 0; }; /// Primary implementation of CallOpSetInterface. @@ -627,7 +630,7 @@ class CallOpSet : public CallOpSetInterface, public Op5, public Op6 { public: - CallOpSet() : return_tag_(this), call_(nullptr) {} + CallOpSet() : cq_tag_(this), return_tag_(this), call_(nullptr) {} void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) override { this->Op1::AddOp(ops, nops); this->Op2::AddOp(ops, nops); @@ -654,7 +657,12 @@ class CallOpSet : public CallOpSetInterface, void set_output_tag(void* return_tag) { return_tag_ = return_tag; } + void* cq_tag() override { return cq_tag_; } + + void set_cq_tag(void* cq_tag) { cq_tag_ = cq_tag; } + private: + void* cq_tag_; void* return_tag_; grpc_call* call_; }; diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h new file mode 100644 index 00000000000..5e1530a310a --- /dev/null +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -0,0 +1,79 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_IMPL_CODEGEN_CALLBACK_COMMON_H +#define GRPCPP_IMPL_CODEGEN_CALLBACK_COMMON_H + +#include + +#include +#include +#include +#include +#include + +// Forward declarations +namespace grpc_core { +class CQCallbackInterface; +}; + +namespace grpc { +namespace internal { + +class CallbackWithStatusTag { + public: + // TODO(vjpai): make impl and ops part of this structure to avoid allocation, + // ownership transfer, and delete + CallbackWithStatusTag(std::function f, bool self_delete, + CompletionQueueTag* ops); + ~CallbackWithStatusTag() { delete ops_; } + void* tag() { return static_cast(impl_); } + Status* status_ptr() { return status_; } + CompletionQueueTag* ops() { return ops_; } + + // force_run can only be performed on a tag before it can ever be active + void force_run(Status s); + + private: + grpc_core::CQCallbackInterface* impl_; + Status* status_; + CompletionQueueTag* ops_; +}; + +class CallbackWithSuccessTag { + public: + // TODO(vjpai): make impl and ops part of this structure to avoid allocation, + // ownership transfer, and delete + CallbackWithSuccessTag(std::function f, bool self_delete, + CompletionQueueTag* ops); + ~CallbackWithSuccessTag() { delete ops_; } + void* tag() { return static_cast(impl_); } + CompletionQueueTag* ops() { return ops_; } + + // force_run can only be performed on a tag before it can ever be active + void force_run(bool ok); + + private: + grpc_core::CQCallbackInterface* impl_; + CompletionQueueTag* ops_; +}; + +} // namespace internal +} // namespace grpc + +#endif // GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h index ec1c6c25d87..b257acc1abd 100644 --- a/include/grpcpp/impl/codegen/channel_interface.h +++ b/include/grpcpp/impl/codegen/channel_interface.h @@ -41,6 +41,8 @@ class CallOpSetInterface; class RpcMethod; template class BlockingUnaryCallImpl; +template +class CallbackUnaryCallImpl; template class ClientAsyncReaderFactory; template @@ -103,6 +105,8 @@ class ChannelInterface { friend class ::grpc::internal::ClientAsyncResponseReaderFactory; template friend class ::grpc::internal::BlockingUnaryCallImpl; + template + friend class ::grpc::internal::CallbackUnaryCallImpl; friend class ::grpc::internal::RpcMethod; virtual internal::Call CreateCall(const internal::RpcMethod& method, ClientContext* context, @@ -115,6 +119,16 @@ class ChannelInterface { CompletionQueue* cq, void* tag) = 0; virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, gpr_timespec deadline) = 0; + + // EXPERIMENTAL + // A method to get the callbackable completion queue associated with this + // channel. If the return value is nullptr, this channel doesn't support + // callback operations. + // TODO(vjpai): Consider a better default like using a global CQ + // Returns nullptr (rather than being pure) since this is a new method + // and adding a new pure method to an interface would be a breaking change + // (even though this is private and non-API) + virtual CompletionQueue* CallbackCQ() { return nullptr; } }; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h new file mode 100644 index 00000000000..419933f85cc --- /dev/null +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -0,0 +1,92 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H +#define GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H + +#include + +#include +#include +#include +#include +#include +#include + +namespace grpc { + +class Channel; +class ClientContext; +class CompletionQueue; + +namespace internal { +class RpcMethod; + +/// Perform a callback-based unary call +/// TODO(vjpai): Combine as much as possible with the blocking unary call code +template +void CallbackUnaryCall(ChannelInterface* channel, const RpcMethod& method, + ClientContext* context, const InputMessage* request, + OutputMessage* result, + std::function on_completion) { + CallbackUnaryCallImpl x( + channel, method, context, request, result, on_completion); +} + +template +class CallbackUnaryCallImpl { + public: + CallbackUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method, + ClientContext* context, const InputMessage* request, + OutputMessage* result, + std::function on_completion) { + CompletionQueue* cq = channel->CallbackCQ(); + GPR_CODEGEN_ASSERT(cq != nullptr); + + // TODO(vjpai): Allocate this as part of the tag's arena + auto* ops = new CallOpSet, + CallOpClientSendClose, CallOpClientRecvStatus>; + + // TODO(vjpai): Move to using pre-allocated tags rather than new/self-delete + auto* tag = new CallbackWithStatusTag(on_completion, true, ops); + + // TODO(vjpai): Unify code with sync API as much as possible + Call call(channel->CreateCall(method, context, cq)); + Status s = ops->SendMessage(*request); + if (!s.ok()) { + tag->force_run(s); + return; + } + ops->SendInitialMetadata(context->send_initial_metadata_, + context->initial_metadata_flags()); + ops->RecvInitialMetadata(context); + ops->RecvMessage(result); + ops->AllowNoMessage(); + ops->ClientSendClose(); + ops->ClientRecvStatus(context, tag->status_ptr()); + ops->set_cq_tag(tag->tag()); + call.PerformOps(ops); + } +}; + +} // namespace internal +} // namespace grpc + +#endif // GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 9dda4c7fac8..7db31fcbcf7 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -68,6 +68,8 @@ class CallOpClientRecvStatus; class CallOpRecvInitialMetadata; template class BlockingUnaryCallImpl; +template +class CallbackUnaryCallImpl; } // namespace internal template @@ -389,6 +391,8 @@ class ClientContext { friend class ::grpc::ClientAsyncResponseReader; template friend class ::grpc::internal::BlockingUnaryCallImpl; + template + friend class ::grpc::internal::CallbackUnaryCallImpl; // Used by friend class CallOpClientRecvStatus void set_debug_error_string(const grpc::string& debug_error_string) { diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 3f7d4fb765f..f52f9a53bea 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -274,6 +274,9 @@ class CompletionQueue : private GrpcLibraryCodegen { template friend class ::grpc::internal::BlockingUnaryCallImpl; + // Friends that need access to constructor for callback CQ + friend class ::grpc::Channel; + /// EXPERIMENTAL /// Creates a Thread Local cache to store the first event /// On this completion queue queued from this thread. Once diff --git a/include/grpcpp/support/client_callback.h b/include/grpcpp/support/client_callback.h new file mode 100644 index 00000000000..03a7e1400c9 --- /dev/null +++ b/include/grpcpp/support/client_callback.h @@ -0,0 +1,24 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_CLIENT_CALLBACK_H +#define GRPCPP_SUPPORT_CLIENT_CALLBACK_H + +#include + +#endif // GRPCPP_SUPPORT_CLIENT_CALLBACK_H diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 0769d9e4f63..c2cf450e949 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -1364,9 +1364,11 @@ static void cq_shutdown_callback(grpc_completion_queue* cq) { } cqd->shutdown_called = true; if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) { + gpr_mu_unlock(cq->mu); cq_finish_shutdown_callback(cq); + } else { + gpr_mu_unlock(cq->mu); } - gpr_mu_unlock(cq->mu); GRPC_CQ_INTERNAL_UNREF(cq, "shutting_down (callback cq)"); } diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 39b891c2e1f..2a961e6e27d 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -42,8 +42,10 @@ #include #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/memory.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/profiling/timers.h" +#include "src/core/lib/surface/completion_queue.h" namespace grpc { @@ -53,7 +55,12 @@ Channel::Channel(const grpc::string& host, grpc_channel* channel) g_gli_initializer.summon(); } -Channel::~Channel() { grpc_channel_destroy(c_channel_); } +Channel::~Channel() { + grpc_channel_destroy(c_channel_); + if (callback_cq_ != nullptr) { + callback_cq_->Shutdown(); + } +} namespace { @@ -135,8 +142,8 @@ void Channel::PerformOpsOnCall(internal::CallOpSetInterface* ops, size_t nops = 0; grpc_op cops[MAX_OPS]; ops->FillOps(call->call(), cops, &nops); - GPR_ASSERT(GRPC_CALL_OK == - grpc_call_start_batch(call->call(), cops, nops, ops, nullptr)); + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call->call(), cops, nops, + ops->cq_tag(), nullptr)); } void* Channel::RegisterMethod(const char* method) { @@ -185,4 +192,32 @@ bool Channel::WaitForStateChangeImpl(grpc_connectivity_state last_observed, return ok; } +namespace { +class ShutdownCallback : public grpc_core::CQCallbackInterface { + public: + void TakeCQ(CompletionQueue* cq) { cq_ = cq; } + void Run(bool) override { + delete cq_; + grpc_core::Delete(this); + } + + private: + CompletionQueue* cq_ = nullptr; +}; +} // namespace + +CompletionQueue* Channel::CallbackCQ() { + // TODO(vjpai): Consider using a single global CQ for the default CQ + // if there is no explicit per-channel CQ registered + std::lock_guard l(mu_); + if (callback_cq_ == nullptr) { + auto* shutdown_callback = grpc_core::New(); + callback_cq_ = new CompletionQueue(grpc_completion_queue_attributes{ + GRPC_CQ_CURRENT_VERSION, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING, + shutdown_callback}); + shutdown_callback->TakeCQ(callback_cq_); + } + return callback_cq_; +} + } // namespace grpc diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc index 67ef46bebea..07c34c88788 100644 --- a/src/cpp/client/generic_stub.cc +++ b/src/cpp/client/generic_stub.cc @@ -16,9 +16,11 @@ * */ -#include +#include +#include #include +#include namespace grpc { @@ -60,4 +62,14 @@ std::unique_ptr GenericStub::PrepareUnaryCall( context, request, false)); } +void GenericStub::experimental_type::UnaryCall( + ClientContext* context, const grpc::string& method, + const ByteBuffer* request, ByteBuffer* response, + std::function on_completion) { + internal::CallbackUnaryCall( + stub_->channel_.get(), + internal::RpcMethod(method.c_str(), internal::RpcMethod::NORMAL_RPC), + context, request, response, on_completion); +} + } // namespace grpc diff --git a/src/cpp/common/callback_common.cc b/src/cpp/common/callback_common.cc new file mode 100644 index 00000000000..2598d37e274 --- /dev/null +++ b/src/cpp/common/callback_common.cc @@ -0,0 +1,109 @@ +/* + * + * 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 + +#include +#include + +#include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/surface/completion_queue.h" + +namespace grpc { +namespace internal { + +namespace { +class CallbackWithSuccessImpl : public grpc_core::CQCallbackInterface { + public: + CallbackWithSuccessImpl(CallbackWithSuccessTag* parent, + std::function f, bool self_delete) + : parent_(parent), func_(f), self_delete_(self_delete) {} + + void Run(bool ok) override { + void* ignored = parent_->ops(); + bool new_ok = ok; + GPR_ASSERT(parent_->ops()->FinalizeResult(&ignored, &new_ok)); + GPR_ASSERT(ignored == parent_->ops()); + func_(ok); + if (self_delete_) { + delete parent_; + // Must use grpc_core::Delete since base is GRPC_ABSTRACT + grpc_core::Delete(this); + } + } + + private: + CallbackWithSuccessTag* parent_; + std::function func_; + bool self_delete_; +}; + +class CallbackWithStatusImpl : public grpc_core::CQCallbackInterface { + public: + CallbackWithStatusImpl(CallbackWithStatusTag* parent, + std::function f, bool self_delete) + : parent_(parent), func_(f), status_(), self_delete_(self_delete) {} + + void Run(bool ok) override { + void* ignored = parent_->ops(); + + GPR_ASSERT(parent_->ops()->FinalizeResult(&ignored, &ok)); + GPR_ASSERT(ignored == parent_->ops()); + + func_(status_); + if (self_delete_) { + delete parent_; + // Must use grpc_core::Delete since base is GRPC_ABSTRACT + grpc_core::Delete(this); + } + } + Status* status_ptr() { return &status_; } + + private: + CallbackWithStatusTag* parent_; + std::function func_; + Status status_; + bool self_delete_; +}; + +} // namespace + +CallbackWithSuccessTag::CallbackWithSuccessTag(std::function f, + bool self_delete, + CompletionQueueTag* ops) + : impl_(grpc_core::New(this, f, self_delete)), + ops_(ops) {} + +void CallbackWithSuccessTag::force_run(bool ok) { impl_->Run(ok); } + +CallbackWithStatusTag::CallbackWithStatusTag(std::function f, + bool self_delete, + CompletionQueueTag* ops) + : ops_(ops) { + auto* impl = grpc_core::New(this, f, self_delete); + impl_ = impl; + status_ = impl->status_ptr(); +} + +void CallbackWithStatusTag::force_run(Status s) { + *status_ = s; + impl_->Run(true); +} + +} // namespace internal +} // namespace grpc diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 36c709eb45b..f271825cbab 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -657,7 +657,8 @@ void Server::PerformOpsOnCall(internal::CallOpSetInterface* ops, size_t nops = 0; grpc_op cops[MAX_OPS]; ops->FillOps(call->call(), cops, &nops); - auto result = grpc_call_start_batch(call->call(), cops, nops, ops, nullptr); + auto result = + grpc_call_start_batch(call->call(), cops, nops, ops->cq_tag(), nullptr); if (result != GRPC_CALL_OK) { gpr_log(GPR_ERROR, "Fatal: grpc_call_start_batch returned %d", result); grpc_call_log_batch(__FILE__, __LINE__, GPR_LOG_SEVERITY_ERROR, diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index 6f5bde0d9f4..f76f64e3dac 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -61,6 +61,9 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { tag_ = tag; } + /// TODO(vjpai): Allow override of cq_tag if appropriate for callback API + void* cq_tag() override { return this; } + void Unref(); private: diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 75dec56a602..0415efc1ef9 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -98,6 +98,25 @@ grpc_cc_binary( ], ) +grpc_cc_test( + name = "client_callback_end2end_test", + srcs = ["client_callback_end2end_test.cc"], + external_deps = [ + "gtest", + ], + deps = [ + ":test_service_impl", + "//:gpr", + "//:grpc", + "//:grpc++", + "//src/proto/grpc/testing:echo_messages_proto", + "//src/proto/grpc/testing:echo_proto", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_util", + ], +) + grpc_cc_library( name = "end2end_test_lib", testonly = True, diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc new file mode 100644 index 00000000000..be732a0ca6c --- /dev/null +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -0,0 +1,126 @@ +/* + * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" +#include "test/cpp/util/byte_buffer_proto_helper.h" + +#include + +namespace grpc { +namespace testing { +namespace { + +class ClientCallbackEnd2endTest : public ::testing::Test { + protected: + ClientCallbackEnd2endTest() {} + + void SetUp() override { + ServerBuilder builder; + builder.RegisterService(&service_); + + server_ = builder.BuildAndStart(); + is_server_started_ = true; + } + + void ResetStub() { + ChannelArguments args; + channel_ = server_->InProcessChannel(args); + stub_.reset(new GenericStub(channel_)); + } + + void TearDown() override { + if (is_server_started_) { + server_->Shutdown(); + } + } + + void SendRpcs(int num_rpcs) { + const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo"); + grpc::string test_string(""); + for (int i = 0; i < num_rpcs; i++) { + EchoRequest request; + std::unique_ptr send_buf; + ByteBuffer recv_buf; + ClientContext cli_ctx; + + test_string += "Hello world. "; + request.set_message(test_string); + send_buf = SerializeToByteBuffer(&request); + + std::mutex mu; + std::condition_variable cv; + bool done; + stub_->experimental().UnaryCall( + &cli_ctx, kMethodName, send_buf.get(), &recv_buf, + [&request, &recv_buf, &done, &mu, &cv](Status s) { + GPR_ASSERT(s.ok()); + + EchoResponse response; + EXPECT_TRUE(ParseFromByteBuffer(&recv_buf, &response)); + EXPECT_EQ(request.message(), response.message()); + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } + } + } + bool is_server_started_; + std::shared_ptr channel_; + std::unique_ptr stub_; + TestServiceImpl service_; + std::unique_ptr server_; +}; + +TEST_F(ClientCallbackEnd2endTest, SimpleRpc) { + ResetStub(); + SendRpcs(1); +} + +TEST_F(ClientCallbackEnd2endTest, SequentialRpcs) { + ResetStub(); + SendRpcs(10); +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 9a97ee84f2c..3b7fd1fa8e0 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -945,7 +945,9 @@ include/grpcpp/impl/codegen/async_unary_call.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ +include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ +include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ @@ -997,6 +999,7 @@ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ +include/grpcpp/support/client_callback.h \ include/grpcpp/support/config.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 0cd4cfd6474..a72390d9f8f 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -946,7 +946,9 @@ include/grpcpp/impl/codegen/async_unary_call.h \ include/grpcpp/impl/codegen/byte_buffer.h \ include/grpcpp/impl/codegen/call.h \ include/grpcpp/impl/codegen/call_hook.h \ +include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ +include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ @@ -999,6 +1001,7 @@ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ +include/grpcpp/support/client_callback.h \ include/grpcpp/support/config.h \ include/grpcpp/support/proto_buffer_reader.h \ include/grpcpp/support/proto_buffer_writer.h \ @@ -1187,6 +1190,7 @@ src/cpp/client/secure_credentials.h \ src/cpp/codegen/codegen_init.cc \ src/cpp/common/alarm.cc \ src/cpp/common/auth_property_iterator.cc \ +src/cpp/common/callback_common.cc \ src/cpp/common/channel_arguments.cc \ src/cpp/common/channel_filter.cc \ src/cpp/common/channel_filter.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8ea5126fdef..9637fa8787d 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3302,6 +3302,25 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "client_callback_end2end_test", + "src": [ + "test/cpp/end2end/client_callback_end2end_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -11081,7 +11100,9 @@ "include/grpcpp/impl/codegen/byte_buffer.h", "include/grpcpp/impl/codegen/call.h", "include/grpcpp/impl/codegen/call_hook.h", + "include/grpcpp/impl/codegen/callback_common.h", "include/grpcpp/impl/codegen/channel_interface.h", + "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", @@ -11147,7 +11168,9 @@ "include/grpcpp/impl/codegen/byte_buffer.h", "include/grpcpp/impl/codegen/call.h", "include/grpcpp/impl/codegen/call_hook.h", + "include/grpcpp/impl/codegen/callback_common.h", "include/grpcpp/impl/codegen/channel_interface.h", + "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", @@ -11305,6 +11328,7 @@ "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/client_callback.h", "include/grpcpp/support/config.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", @@ -11409,6 +11433,7 @@ "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/client_callback.h", "include/grpcpp/support/config.h", "include/grpcpp/support/proto_buffer_reader.h", "include/grpcpp/support/proto_buffer_writer.h", @@ -11428,6 +11453,7 @@ "src/cpp/client/credentials_cc.cc", "src/cpp/client/generic_stub.cc", "src/cpp/common/alarm.cc", + "src/cpp/common/callback_common.cc", "src/cpp/common/channel_arguments.cc", "src/cpp/common/channel_filter.cc", "src/cpp/common/channel_filter.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index fba76d69d1e..a48b9c60dae 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3945,6 +3945,30 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 0.5, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "client_callback_end2end_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From ccddc1bd177ff2ff6ff7500e1cd66e2be409614c Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 29 Aug 2018 05:51:00 -0700 Subject: [PATCH 270/546] Initialize bool --- test/cpp/end2end/client_callback_end2end_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index be732a0ca6c..75b896b33d8 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -79,7 +79,7 @@ class ClientCallbackEnd2endTest : public ::testing::Test { std::mutex mu; std::condition_variable cv; - bool done; + bool done = false; stub_->experimental().UnaryCall( &cli_ctx, kMethodName, send_buf.get(), &recv_buf, [&request, &recv_buf, &done, &mu, &cv](Status s) { From 6b6bdbbb769776430a2f8aa782f1141b7eea91ad Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 29 Aug 2018 11:20:16 -0700 Subject: [PATCH 271/546] Address reviewer and clang-tidy comments --- include/grpcpp/impl/codegen/callback_common.h | 2 +- include/grpcpp/support/client_callback.h | 2 +- src/cpp/client/channel_cc.cc | 7 +++++++ src/cpp/client/generic_stub.cc | 2 +- src/cpp/common/callback_common.cc | 9 ++++++--- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index 5e1530a310a..b14ed0c24f8 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -76,4 +76,4 @@ class CallbackWithSuccessTag { } // namespace internal } // namespace grpc -#endif // GRPCPP_IMPL_CODEGEN_CLIENT_CALLBACK_H +#endif // GRPCPP_IMPL_CODEGEN_CALLBACK_COMMON_H diff --git a/include/grpcpp/support/client_callback.h b/include/grpcpp/support/client_callback.h index 03a7e1400c9..063fdc4f859 100644 --- a/include/grpcpp/support/client_callback.h +++ b/include/grpcpp/support/client_callback.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 gRPC authors. + * Copyright 2018 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 2a961e6e27d..ad71286e051 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -195,7 +195,12 @@ bool Channel::WaitForStateChangeImpl(grpc_connectivity_state last_observed, namespace { class ShutdownCallback : public grpc_core::CQCallbackInterface { public: + // TakeCQ takes ownership of the cq into the shutdown callback + // so that the shutdown callback will be responsible for destroying it void TakeCQ(CompletionQueue* cq) { cq_ = cq; } + + // The Run function will get invoked by the completion queue library + // when the shutdown is actually complete void Run(bool) override { delete cq_; grpc_core::Delete(this); @@ -215,6 +220,8 @@ CompletionQueue* Channel::CallbackCQ() { callback_cq_ = new CompletionQueue(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING, shutdown_callback}); + + // Transfer ownership of the new cq to its own shutdown callback shutdown_callback->TakeCQ(callback_cq_); } return callback_cq_; diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc index 07c34c88788..87902b26f0e 100644 --- a/src/cpp/client/generic_stub.cc +++ b/src/cpp/client/generic_stub.cc @@ -69,7 +69,7 @@ void GenericStub::experimental_type::UnaryCall( internal::CallbackUnaryCall( stub_->channel_.get(), internal::RpcMethod(method.c_str(), internal::RpcMethod::NORMAL_RPC), - context, request, response, on_completion); + context, request, response, std::move(on_completion)); } } // namespace grpc diff --git a/src/cpp/common/callback_common.cc b/src/cpp/common/callback_common.cc index 2598d37e274..a2c32fe72ba 100644 --- a/src/cpp/common/callback_common.cc +++ b/src/cpp/common/callback_common.cc @@ -32,7 +32,7 @@ class CallbackWithSuccessImpl : public grpc_core::CQCallbackInterface { public: CallbackWithSuccessImpl(CallbackWithSuccessTag* parent, std::function f, bool self_delete) - : parent_(parent), func_(f), self_delete_(self_delete) {} + : parent_(parent), func_(std::move(f)), self_delete_(self_delete) {} void Run(bool ok) override { void* ignored = parent_->ops(); @@ -57,7 +57,10 @@ class CallbackWithStatusImpl : public grpc_core::CQCallbackInterface { public: CallbackWithStatusImpl(CallbackWithStatusTag* parent, std::function f, bool self_delete) - : parent_(parent), func_(f), status_(), self_delete_(self_delete) {} + : parent_(parent), + func_(std::move(f)), + status_(), + self_delete_(self_delete) {} void Run(bool ok) override { void* ignored = parent_->ops(); @@ -101,7 +104,7 @@ CallbackWithStatusTag::CallbackWithStatusTag(std::function f, } void CallbackWithStatusTag::force_run(Status s) { - *status_ = s; + *status_ = std::move(s); impl_->Run(true); } From d4afae9a56ff0f5b9b3cda380c0b9c64be170f87 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 30 Aug 2018 16:25:43 -0700 Subject: [PATCH 272/546] regen projects --- tools/run_tests/generated/sources_and_headers.json | 10 +++++----- tools/run_tests/generated/tests.json | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 9637fa8787d..4ebe6692441 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3309,14 +3309,15 @@ "grpc", "grpc++", "grpc++_test_util", + "grpc_cli_libs", "grpc_test_util" ], "headers": [], "is_filegroup": false, "language": "c++", - "name": "client_callback_end2end_test", + "name": "cli_call_test", "src": [ - "test/cpp/end2end/client_callback_end2end_test.cc" + "test/cpp/util/cli_call_test.cc" ], "third_party": false, "type": "target" @@ -3328,15 +3329,14 @@ "grpc", "grpc++", "grpc++_test_util", - "grpc_cli_libs", "grpc_test_util" ], "headers": [], "is_filegroup": false, "language": "c++", - "name": "cli_call_test", + "name": "client_callback_end2end_test", "src": [ - "test/cpp/util/cli_call_test.cc" + "test/cpp/end2end/client_callback_end2end_test.cc" ], "third_party": false, "type": "target" diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index a48b9c60dae..b5714c274ba 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -3954,13 +3954,13 @@ "posix", "windows" ], - "cpu_cost": 0.5, + "cpu_cost": 1.0, "exclude_configs": [], "exclude_iomgrs": [], "flaky": false, "gtest": true, "language": "c++", - "name": "client_callback_end2end_test", + "name": "cli_call_test", "platforms": [ "linux", "mac", @@ -3978,13 +3978,13 @@ "posix", "windows" ], - "cpu_cost": 1.0, + "cpu_cost": 0.5, "exclude_configs": [], "exclude_iomgrs": [], "flaky": false, "gtest": true, "language": "c++", - "name": "cli_call_test", + "name": "client_callback_end2end_test", "platforms": [ "linux", "mac", From 9d0535fd1f60ab430c5ea9a73f25edaea16596ba Mon Sep 17 00:00:00 2001 From: Adele Zhou Date: Thu, 30 Aug 2018 23:08:51 -0700 Subject: [PATCH 273/546] merge --- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 2 +- tools/internal_ci/linux/grpc_msan_on_foundry.sh | 2 +- tools/internal_ci/linux/grpc_ubsan_on_foundry.sh | 2 +- tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 3d4d90317c0..7b977581ca5 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -56,8 +56,8 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --remote_instance_name=grpc-testing/instances/default_instance \ --test_env=GRPC_VERBOSITY=debug \ + --remote_instance_name=projects/grpc-testing/instances/default_instance \ $1 \ -- //test/... || FAILED="true" diff --git a/tools/internal_ci/linux/grpc_msan_on_foundry.sh b/tools/internal_ci/linux/grpc_msan_on_foundry.sh index 19cfc1739a2..e55db7ff355 100644 --- a/tools/internal_ci/linux/grpc_msan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_msan_on_foundry.sh @@ -65,8 +65,8 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --remote_instance_name=grpc-testing/instances/default_instance \ --test_env=GRPC_VERBOSITY=debug \ + --remote_instance_name=projects/grpc-testing/instances/default_instance \ -- //test/... || FAILED="true" # Sleep to let ResultStore finish writing results before querying diff --git a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh index edb2069fb28..d1974b4e6c3 100644 --- a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh @@ -62,8 +62,8 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ --cache_test_results=no \ - --remote_instance_name=grpc-testing/instances/default_instance \ --test_env=GRPC_VERBOSITY=debug \ + --remote_instance_name=projects/grpc-testing/instances/default_instance \ -- //test/... || FAILED="true" # Sleep to let ResultStore finish writing results before querying diff --git a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh index f8c93142366..0c7d539e8c4 100644 --- a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh @@ -61,8 +61,8 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ --platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --remote_instance_name=grpc-testing/instances/default_instance \ --test_env=GRPC_VERBOSITY=debug \ + --remote_instance_name=projects/grpc-testing/instances/default_instance \ -- //test/... || FAILED="true" if [ "$FAILED" != "" ] From 2c8d34663effc5187e9c6f7be3c2ed7140568b5a Mon Sep 17 00:00:00 2001 From: Adele Zhou Date: Thu, 30 Aug 2018 23:18:04 -0700 Subject: [PATCH 274/546] Set KOKORO_FOUNDRY_PROJECT_ID env var. --- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 2 ++ tools/internal_ci/linux/grpc_msan_on_foundry.sh | 2 ++ tools/internal_ci/linux/grpc_ubsan_on_foundry.sh | 2 ++ tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh | 2 ++ 4 files changed, 8 insertions(+) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 7b977581ca5..8b427793664 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -34,6 +34,8 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc +export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instance" + # TODO(adelez): implement size for test targets and change test_timeout back "${KOKORO_GFILE_DIR}/bazel_wrapper.py" \ --host_jvm_args=-Dbazel.DigestFunction=SHA256 \ diff --git a/tools/internal_ci/linux/grpc_msan_on_foundry.sh b/tools/internal_ci/linux/grpc_msan_on_foundry.sh index e55db7ff355..1ef13ef0d46 100644 --- a/tools/internal_ci/linux/grpc_msan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_msan_on_foundry.sh @@ -35,6 +35,8 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc +export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instance" + "${KOKORO_GFILE_DIR}/bazel_wrapper.py" \ --host_jvm_args=-Dbazel.DigestFunction=SHA256 \ test --jobs="200" \ diff --git a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh index d1974b4e6c3..e0ae9103c40 100644 --- a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh @@ -35,6 +35,8 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc +export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instance" + "${KOKORO_GFILE_DIR}/bazel_wrapper.py" \ --host_jvm_args=-Dbazel.DigestFunction=SHA256 \ test --jobs="200" \ diff --git a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh index 0c7d539e8c4..8547fa4d93d 100644 --- a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh @@ -35,6 +35,8 @@ cd $(dirname $0)/../../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc +export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instance" + "${KOKORO_GFILE_DIR}/bazel_wrapper.py" \ --host_jvm_args=-Dbazel.DigestFunction=SHA256 \ test --jobs="200" \ From 577c2e4090386c75c30bbf9110aa596b766f6037 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 31 Aug 2018 15:28:04 +0200 Subject: [PATCH 275/546] threadsafe port picker for remote bazel --- .../util/port_isolated_runtime_environment.cc | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/test/core/util/port_isolated_runtime_environment.cc b/test/core/util/port_isolated_runtime_environment.cc index 773290b7952..c1ca185a670 100644 --- a/test/core/util/port_isolated_runtime_environment.cc +++ b/test/core/util/port_isolated_runtime_environment.cc @@ -20,6 +20,8 @@ * runs in a separate container) the framework takes a round-robin pick of a * port within certain range. There is no need to recycle ports. */ +#include +#include #include #include #include "src/core/lib/iomgr/port.h" @@ -31,23 +33,22 @@ #define MIN_PORT 49152 #define MAX_PORT 65535 -int get_random_starting_port() { +static int get_random_port_offset() { srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec); double rnd = static_cast(rand()) / (static_cast(RAND_MAX) + 1.0); // values from [0,1) - return static_cast(rnd * (MAX_PORT - MIN_PORT + 1)) + MIN_PORT; + return static_cast(rnd * (MAX_PORT - MIN_PORT + 1)); } -static int s_allocated_port = get_random_starting_port(); +static int s_initial_offset = get_random_port_offset(); +static gpr_atm s_pick_counter = 0; int grpc_pick_unused_port_or_die(void) { - // TODO(jtattermusch): protect by mutex - int allocated_port = s_allocated_port++; - if (s_allocated_port == MAX_PORT + 1) { - s_allocated_port = MIN_PORT; - } - - return allocated_port; + int orig_counter_val = + static_cast(gpr_atm_full_fetch_add(&s_pick_counter, 1)); + GPR_ASSERT(orig_counter_val < (MAX_PORT - MIN_PORT + 1)); + return MIN_PORT + + (s_initial_offset + orig_counter_val) % (MAX_PORT - MIN_PORT + 1); } void grpc_recycle_unused_port(int port) { (void)port; } From 5474e92292a37ea9017db02da1e8e6aea621b156 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 30 Aug 2018 17:21:07 -0700 Subject: [PATCH 276/546] Allocate using call arenas --- include/grpcpp/impl/codegen/callback_common.h | 22 ++++--- include/grpcpp/impl/codegen/client_callback.h | 19 +++--- src/cpp/common/callback_common.cc | 59 ++++++++++--------- 3 files changed, 57 insertions(+), 43 deletions(-) diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index b14ed0c24f8..3481460c767 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -37,11 +37,14 @@ namespace internal { class CallbackWithStatusTag { public: - // TODO(vjpai): make impl and ops part of this structure to avoid allocation, - // ownership transfer, and delete - CallbackWithStatusTag(std::function f, bool self_delete, + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(CallbackWithStatusTag)); + } + + CallbackWithStatusTag(grpc_call* call, std::function f, CompletionQueueTag* ops); - ~CallbackWithStatusTag() { delete ops_; } + ~CallbackWithStatusTag() {} void* tag() { return static_cast(impl_); } Status* status_ptr() { return status_; } CompletionQueueTag* ops() { return ops_; } @@ -57,11 +60,14 @@ class CallbackWithStatusTag { class CallbackWithSuccessTag { public: - // TODO(vjpai): make impl and ops part of this structure to avoid allocation, - // ownership transfer, and delete - CallbackWithSuccessTag(std::function f, bool self_delete, + // always allocated against a call arena, no memory free required + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(CallbackWithSuccessTag)); + } + + CallbackWithSuccessTag(grpc_call* call, std::function f, CompletionQueueTag* ops); - ~CallbackWithSuccessTag() { delete ops_; } + void* tag() { return static_cast(impl_); } CompletionQueueTag* ops() { return ops_; } diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index 419933f85cc..fc81c8aa0ae 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -57,18 +57,21 @@ class CallbackUnaryCallImpl { std::function on_completion) { CompletionQueue* cq = channel->CallbackCQ(); GPR_CODEGEN_ASSERT(cq != nullptr); + Call call(channel->CreateCall(method, context, cq)); + + using FullCallOpSet = + CallOpSet, + CallOpClientSendClose, CallOpClientRecvStatus>; - // TODO(vjpai): Allocate this as part of the tag's arena - auto* ops = new CallOpSet, - CallOpClientSendClose, CallOpClientRecvStatus>; + auto* ops = new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(FullCallOpSet))) FullCallOpSet; - // TODO(vjpai): Move to using pre-allocated tags rather than new/self-delete - auto* tag = new CallbackWithStatusTag(on_completion, true, ops); + auto* tag = new (g_core_codegen_interface->grpc_call_arena_alloc( + call.call(), sizeof(CallbackWithStatusTag))) + CallbackWithStatusTag(call.call(), on_completion, ops); // TODO(vjpai): Unify code with sync API as much as possible - Call call(channel->CreateCall(method, context, cq)); Status s = ops->SendMessage(*request); if (!s.ok()) { tag->force_run(s); diff --git a/src/cpp/common/callback_common.cc b/src/cpp/common/callback_common.cc index a2c32fe72ba..68df1166ba9 100644 --- a/src/cpp/common/callback_common.cc +++ b/src/cpp/common/callback_common.cc @@ -30,9 +30,15 @@ namespace internal { namespace { class CallbackWithSuccessImpl : public grpc_core::CQCallbackInterface { public: - CallbackWithSuccessImpl(CallbackWithSuccessTag* parent, - std::function f, bool self_delete) - : parent_(parent), func_(std::move(f)), self_delete_(self_delete) {} + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(CallbackWithSuccessImpl)); + } + + CallbackWithSuccessImpl(grpc_call* call, CallbackWithSuccessTag* parent, + std::function f) + : call_(call), parent_(parent), func_(std::move(f)) { + grpc_call_ref(call); + } void Run(bool ok) override { void* ignored = parent_->ops(); @@ -40,27 +46,27 @@ class CallbackWithSuccessImpl : public grpc_core::CQCallbackInterface { GPR_ASSERT(parent_->ops()->FinalizeResult(&ignored, &new_ok)); GPR_ASSERT(ignored == parent_->ops()); func_(ok); - if (self_delete_) { - delete parent_; - // Must use grpc_core::Delete since base is GRPC_ABSTRACT - grpc_core::Delete(this); - } + func_ = nullptr; // release the function + grpc_call_unref(call_); } private: + grpc_call* call_; CallbackWithSuccessTag* parent_; std::function func_; - bool self_delete_; }; class CallbackWithStatusImpl : public grpc_core::CQCallbackInterface { public: - CallbackWithStatusImpl(CallbackWithStatusTag* parent, - std::function f, bool self_delete) - : parent_(parent), - func_(std::move(f)), - status_(), - self_delete_(self_delete) {} + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(CallbackWithStatusImpl)); + } + + CallbackWithStatusImpl(grpc_call* call, CallbackWithStatusTag* parent, + std::function f) + : call_(call), parent_(parent), func_(std::move(f)), status_() { + grpc_call_ref(call); + } void Run(bool ok) override { void* ignored = parent_->ops(); @@ -69,36 +75,35 @@ class CallbackWithStatusImpl : public grpc_core::CQCallbackInterface { GPR_ASSERT(ignored == parent_->ops()); func_(status_); - if (self_delete_) { - delete parent_; - // Must use grpc_core::Delete since base is GRPC_ABSTRACT - grpc_core::Delete(this); - } + func_ = nullptr; // release the function + grpc_call_unref(call_); } Status* status_ptr() { return &status_; } private: + grpc_call* call_; CallbackWithStatusTag* parent_; std::function func_; Status status_; - bool self_delete_; }; } // namespace -CallbackWithSuccessTag::CallbackWithSuccessTag(std::function f, - bool self_delete, +CallbackWithSuccessTag::CallbackWithSuccessTag(grpc_call* call, + std::function f, CompletionQueueTag* ops) - : impl_(grpc_core::New(this, f, self_delete)), + : impl_(new (grpc_call_arena_alloc(call, sizeof(CallbackWithSuccessImpl))) + CallbackWithSuccessImpl(call, this, std::move(f))), ops_(ops) {} void CallbackWithSuccessTag::force_run(bool ok) { impl_->Run(ok); } -CallbackWithStatusTag::CallbackWithStatusTag(std::function f, - bool self_delete, +CallbackWithStatusTag::CallbackWithStatusTag(grpc_call* call, + std::function f, CompletionQueueTag* ops) : ops_(ops) { - auto* impl = grpc_core::New(this, f, self_delete); + auto* impl = new (grpc_call_arena_alloc(call, sizeof(CallbackWithStatusImpl))) + CallbackWithStatusImpl(call, this, std::move(f)); impl_ = impl; status_ = impl->status_ptr(); } From 97264ea3365bfa895dbd20983772178feaef0908 Mon Sep 17 00:00:00 2001 From: Eundoo Song Date: Sat, 1 Sep 2018 02:18:52 +0900 Subject: [PATCH 277/546] Remove unused import --- .../default_value/default_value_client_interceptor.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/python/interceptors/default_value/default_value_client_interceptor.py b/examples/python/interceptors/default_value/default_value_client_interceptor.py index c549f2b8613..c935b954918 100644 --- a/examples/python/interceptors/default_value/default_value_client_interceptor.py +++ b/examples/python/interceptors/default_value/default_value_client_interceptor.py @@ -13,8 +13,6 @@ # limitations under the License. """Interceptor that adds headers to outgoing requests.""" -import collections - import grpc From d68e8b4f6267a1aa16bf5c8253f39b1be6f47188 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 31 Aug 2018 12:12:35 -0700 Subject: [PATCH 278/546] %s/state_op_done[OP_FAILED]/state_callback_received[OP_FAILED] --- src/core/ext/transport/cronet/transport/cronet_transport.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 4a252d972d5..81e2634e3a7 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -1287,7 +1287,7 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) { grpc_error* error = GRPC_ERROR_NONE; if (stream_state->state_op_done[OP_CANCEL_ERROR]) { error = GRPC_ERROR_REF(stream_state->cancel_error); - } else if (stream_state->state_op_done[OP_FAILED]) { + } else if (stream_state->state_callback_received[OP_FAILED]) { error = make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable."); } else if (oas->s->state.rs.trailing_metadata_valid) { grpc_chttp2_incoming_metadata_buffer_publish( From 0b59c106d7d225995c2adb59c5c945f7b5319613 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 31 Aug 2018 14:51:39 -0700 Subject: [PATCH 279/546] use grpc_slice_unref_internal inside grpc --- .../tsi/alts/handshaker/alts_handshaker_client.cc | 9 +++++---- .../handshaker/alts_handshaker_service_api_util.cc | 4 +++- src/core/tsi/alts/handshaker/alts_tsi_event.cc | 6 ++++-- src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc | 11 ++++++----- src/core/tsi/alts/handshaker/alts_tsi_utils.cc | 4 +++- .../alts_grpc_privacy_integrity_record_protocol.cc | 4 ++-- src/core/tsi/ssl/session_cache/ssl_session_cache.cc | 3 ++- 7 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc index b5268add0d1..17e80260964 100644 --- a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +++ b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc @@ -24,6 +24,7 @@ #include #include +#include "src/core/lib/slice/slice_internal.h" #include "src/core/tsi/alts/handshaker/alts_handshaker_service_api.h" const int kHandshakerClientOpNum = 4; @@ -109,7 +110,7 @@ static grpc_byte_buffer* get_serialized_start_client(alts_tsi_event* event) { if (ok) { buffer = grpc_raw_byte_buffer_create(&slice, 1 /* number of slices */); } - grpc_slice_unref(slice); + grpc_slice_unref_internal(slice); gpr_free(target_name); grpc_gcp_handshaker_req_destroy(req); return buffer; @@ -157,7 +158,7 @@ static grpc_byte_buffer* get_serialized_start_server( if (ok) { buffer = grpc_raw_byte_buffer_create(&req_slice, 1 /* number of slices */); } - grpc_slice_unref(req_slice); + grpc_slice_unref_internal(req_slice); grpc_gcp_handshaker_req_destroy(req); return buffer; } @@ -195,7 +196,7 @@ static grpc_byte_buffer* get_serialized_next(grpc_slice* bytes_received) { if (ok) { buffer = grpc_raw_byte_buffer_create(&req_slice, 1 /* number of slices */); } - grpc_slice_unref(req_slice); + grpc_slice_unref_internal(req_slice); grpc_gcp_handshaker_req_destroy(req); return buffer; } @@ -258,7 +259,7 @@ alts_handshaker_client* alts_grpc_handshaker_client_create( grpc_slice_from_static_string(ALTS_SERVICE_METHOD), &slice, gpr_inf_future(GPR_CLOCK_REALTIME), nullptr); client->base.vtable = &vtable; - grpc_slice_unref(slice); + grpc_slice_unref_internal(slice); return &client->base; } diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc b/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc index e0e4184686f..d63d3538c56 100644 --- a/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc +++ b/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc @@ -20,6 +20,8 @@ #include "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h" +#include "src/core/lib/slice/slice_internal.h" + void add_repeated_field(repeated_field** head, const void* data) { repeated_field* field = static_cast(gpr_zalloc(sizeof(*field))); @@ -67,7 +69,7 @@ grpc_slice* create_slice(const char* data, size_t size) { void destroy_slice(grpc_slice* slice) { if (slice != nullptr) { - grpc_slice_unref(*slice); + grpc_slice_unref_internal(*slice); gpr_free(slice); } } diff --git a/src/core/tsi/alts/handshaker/alts_tsi_event.cc b/src/core/tsi/alts/handshaker/alts_tsi_event.cc index ec0bf12b95e..cb36d5ebd1a 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_event.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_event.cc @@ -24,6 +24,8 @@ #include #include +#include "src/core/lib/slice/slice_internal.h" + tsi_result alts_tsi_event_create(alts_tsi_handshaker* handshaker, tsi_handshaker_on_next_done_cb cb, void* user_data, @@ -66,8 +68,8 @@ void alts_tsi_event_destroy(alts_tsi_event* event) { grpc_byte_buffer_destroy(event->recv_buffer); grpc_metadata_array_destroy(&event->initial_metadata); grpc_metadata_array_destroy(&event->trailing_metadata); - grpc_slice_unref(event->details); - grpc_slice_unref(event->target_name); + grpc_slice_unref_internal(event->details); + grpc_slice_unref_internal(event->target_name); grpc_alts_credentials_options_destroy(event->options); gpr_free(event); } diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc index 1df1021bb17..34608a3de19 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc @@ -31,6 +31,7 @@ #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gprpp/thd.h" +#include "src/core/lib/slice/slice_internal.h" #include "src/core/tsi/alts/frame_protector/alts_frame_protector.h" #include "src/core/tsi/alts/handshaker/alts_handshaker_client.h" #include "src/core/tsi/alts/handshaker/alts_tsi_utils.h" @@ -182,7 +183,7 @@ static void handshaker_result_destroy(tsi_handshaker_result* self) { gpr_free(result->peer_identity); gpr_free(result->key_data); gpr_free(result->unused_bytes); - grpc_slice_unref(result->rpc_versions); + grpc_slice_unref_internal(result->rpc_versions); gpr_free(result); } @@ -269,12 +270,12 @@ static tsi_result handshaker_next( handshaker->has_sent_start_message = true; } else { if (!GRPC_SLICE_IS_EMPTY(handshaker->recv_bytes)) { - grpc_slice_unref(handshaker->recv_bytes); + grpc_slice_unref_internal(handshaker->recv_bytes); } handshaker->recv_bytes = grpc_slice_ref(slice); ok = alts_handshaker_client_next(handshaker->client, event, &slice); } - grpc_slice_unref(slice); + grpc_slice_unref_internal(slice); if (ok != TSI_OK) { gpr_log(GPR_ERROR, "Failed to schedule ALTS handshaker requests"); return ok; @@ -299,8 +300,8 @@ static void handshaker_destroy(tsi_handshaker* self) { alts_tsi_handshaker* handshaker = reinterpret_cast(self); alts_handshaker_client_destroy(handshaker->client); - grpc_slice_unref(handshaker->recv_bytes); - grpc_slice_unref(handshaker->target_name); + grpc_slice_unref_internal(handshaker->recv_bytes); + grpc_slice_unref_internal(handshaker->target_name); grpc_alts_credentials_options_destroy(handshaker->options); gpr_free(handshaker->buffer); gpr_free(handshaker); diff --git a/src/core/tsi/alts/handshaker/alts_tsi_utils.cc b/src/core/tsi/alts/handshaker/alts_tsi_utils.cc index d9b5e6c9453..1747f1ad04f 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_utils.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_utils.cc @@ -22,6 +22,8 @@ #include +#include "src/core/lib/slice/slice_internal.h" + tsi_result alts_tsi_utils_convert_to_tsi_result(grpc_status_code code) { switch (code) { case GRPC_STATUS_OK: @@ -47,7 +49,7 @@ grpc_gcp_handshaker_resp* alts_tsi_utils_deserialize_response( grpc_slice slice = grpc_byte_buffer_reader_readall(&bbr); grpc_gcp_handshaker_resp* resp = grpc_gcp_handshaker_resp_create(); bool ok = grpc_gcp_handshaker_resp_decode(slice, resp); - grpc_slice_unref(slice); + grpc_slice_unref_internal(slice); grpc_byte_buffer_reader_destroy(&bbr); if (!ok) { grpc_gcp_handshaker_resp_destroy(resp); diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc index d4fd88d1e23..e7890903d57 100644 --- a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc +++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc @@ -61,7 +61,7 @@ static tsi_result alts_grpc_privacy_integrity_protect( if (status != GRPC_STATUS_OK) { gpr_log(GPR_ERROR, "Failed to protect, %s", error_details); gpr_free(error_details); - grpc_slice_unref(protected_slice); + grpc_slice_unref_internal(protected_slice); return TSI_INTERNAL_ERROR; } grpc_slice_buffer_add(protected_slices, protected_slice); @@ -106,7 +106,7 @@ static tsi_result alts_grpc_privacy_integrity_unprotect( if (status != GRPC_STATUS_OK) { gpr_log(GPR_ERROR, "Failed to unprotect, %s", error_details); gpr_free(error_details); - grpc_slice_unref(unprotected_slice); + grpc_slice_unref_internal(unprotected_slice); return TSI_INTERNAL_ERROR; } grpc_slice_buffer_reset_and_unref_internal(&rp->header_sb); diff --git a/src/core/tsi/ssl/session_cache/ssl_session_cache.cc b/src/core/tsi/ssl/session_cache/ssl_session_cache.cc index ce74fde3434..f9184bcc34f 100644 --- a/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +++ b/src/core/tsi/ssl/session_cache/ssl_session_cache.cc @@ -19,6 +19,7 @@ #include #include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/slice/slice_internal.h" #include "src/core/tsi/ssl/session_cache/ssl_session.h" #include "src/core/tsi/ssl/session_cache/ssl_session_cache.h" @@ -53,7 +54,7 @@ class SslSessionLRUCache::Node { SetSession(std::move(session)); } - ~Node() { grpc_slice_unref(key_); } + ~Node() { grpc_slice_unref_internal(key_); } // Not copyable nor movable. Node(const Node&) = delete; From 85721e22b40323c767cdcaf0f1be6c12e1755d9d Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Fri, 31 Aug 2018 12:54:55 -0700 Subject: [PATCH 280/546] Change method name for consistency --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 4 ++-- src/core/ext/transport/chttp2/transport/internal.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index f269c252c63..26cad2cc9a6 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -2903,7 +2903,7 @@ bool Chttp2IncomingByteStream::Next(size_t max_size_hint, } } -void Chttp2IncomingByteStream::EnsureStreamDecompressionCtxExists() { +void Chttp2IncomingByteStream::MaybeCreateStreamDecompressionCtx() { if (!stream_->stream_decompression_ctx) { stream_->stream_decompression_ctx = grpc_stream_compression_context_create( stream_->stream_decompression_method); @@ -2916,7 +2916,7 @@ grpc_error* Chttp2IncomingByteStream::Pull(grpc_slice* slice) { if (stream_->unprocessed_incoming_frames_buffer.length > 0) { if (!stream_->unprocessed_incoming_frames_decompressed) { bool end_of_context; - EnsureStreamDecompressionCtxExists(); + MaybeCreateStreamDecompressionCtx(); if (!grpc_stream_decompress(stream_->stream_decompression_ctx, &stream_->unprocessed_incoming_frames_buffer, &stream_->decompressed_data_buffer, nullptr, diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 0f66faec31f..6b5309bab48 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -246,7 +246,7 @@ class Chttp2IncomingByteStream : public ByteStream { static void NextLocked(void* arg, grpc_error* error_ignored); static void OrphanLocked(void* arg, grpc_error* error_ignored); - void EnsureStreamDecompressionCtxExists(); + void MaybeCreateStreamDecompressionCtx(); grpc_chttp2_transport* transport_; // Immutable. grpc_chttp2_stream* stream_; // Immutable. From 4c0d540fb6545db5a347bf9e45b8bf31ea499986 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 1 Sep 2018 13:18:48 +0200 Subject: [PATCH 281/546] add exception info to Status.Detail if metadata credentials fail --- .../Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs | 6 ++++-- .../Grpc.IntegrationTesting/MetadataCredentialsTest.cs | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs index 4d695e88505..36e8cbbf314 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs @@ -68,7 +68,8 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionStatusMsg); + var detail = GetMetadataExceptionStatusMsg + " " + e.ToString(); + Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, detail); Logger.Error(e, GetMetadataExceptionLogMsg); } } @@ -87,7 +88,8 @@ namespace Grpc.Core.Internal } catch (Exception e) { - Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionStatusMsg); + string detail = GetMetadataExceptionStatusMsg + " " + e.ToString(); + Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, detail); Logger.Error(e, GetMetadataExceptionLogMsg); } } diff --git a/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs index c83ccd26128..40447854f47 100644 --- a/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs @@ -153,9 +153,10 @@ namespace Grpc.IntegrationTesting [Test] public void MetadataCredentials_InterceptorThrows() { + var authInterceptorExceptionMessage = "Auth interceptor throws"; var callCredentials = CallCredentials.FromInterceptor(new AsyncAuthInterceptor((context, metadata) => { - throw new Exception("Auth interceptor throws"); + throw new Exception(authInterceptorExceptionMessage); })); var channelCredentials = ChannelCredentials.Create(TestCredentials.CreateSslCredentials(), callCredentials); channel = new Channel(Host, server.Ports.Single().BoundPort, channelCredentials, options); @@ -163,6 +164,7 @@ namespace Grpc.IntegrationTesting var ex = Assert.Throws(() => client.UnaryCall(new SimpleRequest { })); Assert.AreEqual(StatusCode.Unavailable, ex.Status.StatusCode); + StringAssert.Contains(authInterceptorExceptionMessage, ex.Status.Detail); } private class FakeTestService : TestService.TestServiceBase From db0e21a5cbeb105a6878bb8c0b63bc6a23acee4b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 14 May 2018 14:00:29 -0700 Subject: [PATCH 282/546] Expose certificate request type in SslServerCredentials. --- .../Internal/NativeMethods.Generated.cs | 6 +- .../Internal/ServerCredentialsSafeHandle.cs | 4 +- src/csharp/Grpc.Core/ServerCredentials.cs | 97 ++++++++++-- .../SslCredentialsTest.cs | 143 ++++++++++++++++-- src/csharp/ext/grpc_csharp_ext.c | 6 +- .../NativeMethods.Generated.cs.template | 2 +- 6 files changed, 225 insertions(+), 33 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs index 153a52f9478..a45cbe4107d 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs @@ -505,7 +505,7 @@ namespace Grpc.Core.Internal public delegate void grpcsharp_redirect_log_delegate(GprLogDelegate callback); public delegate CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin_delegate(NativeMetadataInterceptor interceptor); public delegate void grpcsharp_metadata_credentials_notify_from_plugin_delegate(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails); - public delegate ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create_delegate(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, int forceClientAuth); + public delegate ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create_delegate(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, SslClientCertificateRequestType clientCertificateRequest); public delegate void grpcsharp_server_credentials_release_delegate(IntPtr credentials); public delegate ServerSafeHandle grpcsharp_server_create_delegate(ChannelArgsSafeHandle args); public delegate void grpcsharp_server_register_completion_queue_delegate(ServerSafeHandle server, CompletionQueueSafeHandle cq); @@ -752,7 +752,7 @@ namespace Grpc.Core.Internal public static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails); [DllImport(ImportName)] - public static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, int forceClientAuth); + public static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, SslClientCertificateRequestType clientCertificateRequest); [DllImport(ImportName)] public static extern void grpcsharp_server_credentials_release(IntPtr credentials); @@ -1045,7 +1045,7 @@ namespace Grpc.Core.Internal public static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails); [DllImport(ImportName)] - public static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, int forceClientAuth); + public static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, SslClientCertificateRequestType clientCertificateRequest); [DllImport(ImportName)] public static extern void grpcsharp_server_credentials_release(IntPtr credentials); diff --git a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs index 545e581f949..5f8c95c4ea6 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs @@ -32,13 +32,13 @@ namespace Grpc.Core.Internal { } - public static ServerCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, bool forceClientAuth) + public static ServerCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, SslClientCertificateRequestType clientCertificateRequest) { GrpcPreconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length); return Native.grpcsharp_ssl_server_credentials_create(pemRootCerts, keyCertPairCertChainArray, keyCertPairPrivateKeyArray, new UIntPtr((ulong)keyCertPairCertChainArray.Length), - forceClientAuth ? 1 : 0); + clientCertificateRequest); } protected override bool ReleaseHandle() diff --git a/src/csharp/Grpc.Core/ServerCredentials.cs b/src/csharp/Grpc.Core/ServerCredentials.cs index 703f9ff6b32..056311e0c02 100644 --- a/src/csharp/Grpc.Core/ServerCredentials.cs +++ b/src/csharp/Grpc.Core/ServerCredentials.cs @@ -57,6 +57,60 @@ namespace Grpc.Core } } + /// + /// Modes of requesting client's SSL certificate by the server. + /// Corresponds to grpc_ssl_client_certificate_request_type. + /// + public enum SslClientCertificateRequestType { + /// + /// Server does not request client certificate. + /// The certificate presented by the client is not checked by the server at + /// all. (A client may present a self signed or signed certificate or not + /// present a certificate at all and any of those option would be accepted) + /// + DontRequestClientCertificate = 0, + /// + /// Server requests client certificate but does not enforce that the client + /// presents a certificate. + /// If the client presents a certificate, the client authentication is left to + /// the application (the necessary metadata will be available to the + /// application via authentication context properties, see grpc_auth_context). + /// The client's key certificate pair must be valid for the SSL connection to + /// be established. + /// + RequestClientCertificateButDontVerify, + /// + /// Server requests client certificate but does not enforce that the client + /// presents a certificate. + /// If the client presents a certificate, the client authentication is done by + /// the gRPC framework. (For a successful connection the client needs to either + /// present a certificate that can be verified against the root certificate + /// configured by the server or not present a certificate at all) + /// The client's key certificate pair must be valid for the SSL connection to + /// be established. + /// + RequestClientCertificateAndVerify, + /// + /// Server requests client certificate and enforces that the client presents a + /// certificate. + /// If the client presents a certificate, the client authentication is left to + /// the application (the necessary metadata will be available to the + /// application via authentication context properties, see grpc_auth_context). + /// The client's key certificate pair must be valid for the SSL connection to + /// be established. + /// + RequestAndRequireClientCertificateButDontVerify, + /// + /// Server requests client certificate and enforces that the client presents a + /// certificate. + /// The cerificate presented by the client is verified by the gRPC framework. + /// (For a successful connection the client needs to present a certificate that + /// can be verified against the root certificate configured by the server) + /// The client's key certificate pair must be valid for the SSL connection to + /// be established. + /// + RequestAndRequireClientCertificateAndVerify, + } /// /// Server-side SSL credentials. /// @@ -64,35 +118,45 @@ namespace Grpc.Core { readonly IList keyCertificatePairs; readonly string rootCertificates; - readonly bool forceClientAuth; + readonly SslClientCertificateRequestType clientCertificateRequest; /// /// Creates server-side SSL credentials. /// /// Key-certificates to use. /// PEM encoded client root certificates used to authenticate client. - /// If true, client will be rejected unless it proves its unthenticity using against rootCertificates. + /// Deprecated, use clientCertificateRequest overload instead. public SslServerCredentials(IEnumerable keyCertificatePairs, string rootCertificates, bool forceClientAuth) + : this(keyCertificatePairs, rootCertificates, forceClientAuth ? SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify : SslClientCertificateRequestType.DontRequestClientCertificate) + { + } + + /// + /// Creates server-side SSL credentials. + /// + /// Key-certificates to use. + /// PEM encoded client root certificates used to authenticate client. + /// Options for requesting and verification of client certificate. + public SslServerCredentials(IEnumerable keyCertificatePairs, string rootCertificates, SslClientCertificateRequestType clientCertificateRequest) { this.keyCertificatePairs = new List(keyCertificatePairs).AsReadOnly(); GrpcPreconditions.CheckArgument(this.keyCertificatePairs.Count > 0, "At least one KeyCertificatePair needs to be provided."); - if (forceClientAuth) + if (clientCertificateRequest == SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify) { GrpcPreconditions.CheckNotNull(rootCertificates, - "Cannot force client authentication unless you provide rootCertificates."); + "Cannot require and verify client certificate unless you provide rootCertificates."); } this.rootCertificates = rootCertificates; - this.forceClientAuth = forceClientAuth; + this.clientCertificateRequest = clientCertificateRequest; } /// /// Creates server-side SSL credentials. - /// This constructor should be use if you do not wish to autheticate client - /// using client root certificates. + /// This constructor should be use if you do not wish to autheticate client at all. /// /// Key-certificates to use. - public SslServerCredentials(IEnumerable keyCertificatePairs) : this(keyCertificatePairs, null, false) + public SslServerCredentials(IEnumerable keyCertificatePairs) : this(keyCertificatePairs, null, SslClientCertificateRequestType.DontRequestClientCertificate) { } @@ -119,13 +183,24 @@ namespace Grpc.Core } /// - /// If true, the authenticity of client check will be enforced. + /// Deprecated. If true, the authenticity of client check will be enforced. /// public bool ForceClientAuthentication { get { - return this.forceClientAuth; + return this.clientCertificateRequest == SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify; + } + } + + /// + /// Mode of requesting certificate from client by the server. + /// + public SslClientCertificateRequestType ClientCertificateRequest + { + get + { + return this.clientCertificateRequest; } } @@ -139,7 +214,7 @@ namespace Grpc.Core certChains[i] = keyCertificatePairs[i].CertificateChain; keys[i] = keyCertificatePairs[i].PrivateKey; } - return ServerCredentialsSafeHandle.CreateSslCredentials(rootCertificates, certChains, keys, forceClientAuth); + return ServerCredentialsSafeHandle.CreateSslCredentials(rootCertificates, certChains, keys, clientCertificateRequest); } } } diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs index 152d8feab98..713c4ea72a8 100644 --- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs @@ -37,20 +37,24 @@ namespace Grpc.IntegrationTesting public class SslCredentialsTest { const string Host = "localhost"; + const string IsPeerAuthenticatedMetadataKey = "test_only_is_peer_authenticated"; Server server; Channel channel; TestService.TestServiceClient client; - [OneTimeSetUp] - public void Init() + string rootCert; + KeyCertificatePair keyCertPair; + + public void InitClientAndServer(bool clientAddKeyCertPair, + SslClientCertificateRequestType clientCertRequestType) { - var rootCert = File.ReadAllText(TestCredentials.ClientCertAuthorityPath); - var keyCertPair = new KeyCertificatePair( + rootCert = File.ReadAllText(TestCredentials.ClientCertAuthorityPath); + keyCertPair = new KeyCertificatePair( File.ReadAllText(TestCredentials.ServerCertChainPath), File.ReadAllText(TestCredentials.ServerPrivateKeyPath)); - var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert, true); - var clientCredentials = new SslCredentials(rootCert, keyCertPair); + var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert, clientCertRequestType); + var clientCredentials = clientAddKeyCertPair ? new SslCredentials(rootCert, keyCertPair) : new SslCredentials(rootCert); // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) @@ -72,19 +76,133 @@ namespace Grpc.IntegrationTesting [OneTimeTearDown] public void Cleanup() { - channel.ShutdownAsync().Wait(); - server.ShutdownAsync().Wait(); + if (channel != null) + { + channel.ShutdownAsync().Wait(); + } + if (server != null) + { + server.ShutdownAsync().Wait(); + } } [Test] - public void AuthenticatedClientAndServer() + public async Task NoClientCert_DontRequestClientCertificate_Accepted() { - var response = client.UnaryCall(new SimpleRequest { ResponseSize = 10 }); - Assert.AreEqual(10, response.Payload.Body.Length); + InitClientAndServer( + clientAddKeyCertPair: false, + clientCertRequestType: SslClientCertificateRequestType.DontRequestClientCertificate); + + await CheckAccepted(expectPeerAuthenticated: false); } [Test] - public async Task AuthContextIsPopulated() + public async Task ClientWithCert_DontRequestClientCertificate_AcceptedButPeerNotAuthenticated() + { + InitClientAndServer( + clientAddKeyCertPair: true, + clientCertRequestType: SslClientCertificateRequestType.DontRequestClientCertificate); + + await CheckAccepted(expectPeerAuthenticated: false); + } + + [Test] + public async Task NoClientCert_RequestClientCertificateButDontVerify_Accepted() + { + InitClientAndServer( + clientAddKeyCertPair: false, + clientCertRequestType: SslClientCertificateRequestType.RequestClientCertificateButDontVerify); + + await CheckAccepted(expectPeerAuthenticated: false); + } + + [Test] + public async Task NoClientCert_RequestClientCertificateAndVerify_Accepted() + { + InitClientAndServer( + clientAddKeyCertPair: false, + clientCertRequestType: SslClientCertificateRequestType.RequestClientCertificateAndVerify); + + await CheckAccepted(expectPeerAuthenticated: false); + } + + [Test] + public async Task ClientWithCert_RequestAndRequireClientCertificateButDontVerify_Accepted() + { + InitClientAndServer( + clientAddKeyCertPair: true, + clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireClientCertificateButDontVerify); + + await CheckAccepted(expectPeerAuthenticated: true); + await CheckAuthContextIsPopulated(); + } + + [Test] + public async Task ClientWithCert_RequestAndRequireClientCertificateAndVerify_Accepted() + { + InitClientAndServer( + clientAddKeyCertPair: true, + clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify); + + await CheckAccepted(expectPeerAuthenticated: true); + await CheckAuthContextIsPopulated(); + } + + [Test] + public void NoClientCert_RequestAndRequireClientCertificateButDontVerify_Rejected() + { + InitClientAndServer( + clientAddKeyCertPair: false, + clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireClientCertificateButDontVerify); + + CheckRejected(); + } + + [Test] + public void NoClientCert_RequestAndRequireClientCertificateAndVerify_Rejected() + { + InitClientAndServer( + clientAddKeyCertPair: false, + clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify); + + CheckRejected(); + } + + [Test] + public void Constructor_LegacyForceClientAuth() + { + var creds = new SslServerCredentials(new[] { keyCertPair }, rootCert, true); + Assert.AreEqual(SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify, creds.ClientCertificateRequest); + + var creds2 = new SslServerCredentials(new[] { keyCertPair }, rootCert, false); + Assert.AreEqual(SslClientCertificateRequestType.DontRequestClientCertificate, creds2.ClientCertificateRequest); + } + + [Test] + public void Constructor_NullRootCerts() + { + var keyCertPairs = new[] { keyCertPair }; + new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.DontRequestClientCertificate); + new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestClientCertificateAndVerify); + new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireClientCertificateButDontVerify); + Assert.Throws(typeof(ArgumentNullException), () => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify)); + } + + private async Task CheckAccepted(bool expectPeerAuthenticated) + { + var call = client.UnaryCallAsync(new SimpleRequest { ResponseSize = 10 }); + var response = await call; + Assert.AreEqual(10, response.Payload.Body.Length); + Assert.AreEqual(expectPeerAuthenticated.ToString(), call.GetTrailers().First((entry) => entry.Key == IsPeerAuthenticatedMetadataKey).Value); + } + + private void CheckRejected() + { + var ex = Assert.Throws(() => client.UnaryCall(new SimpleRequest { ResponseSize = 10 })); + Assert.AreEqual(StatusCode.Unavailable, ex.Status.StatusCode); + } + + private async Task CheckAuthContextIsPopulated() { var call = client.StreamingInputCall(); await call.RequestStream.CompleteAsync(); @@ -96,6 +214,7 @@ namespace Grpc.IntegrationTesting { public override Task UnaryCall(SimpleRequest request, ServerCallContext context) { + context.ResponseTrailers.Add(IsPeerAuthenticatedMetadataKey, context.AuthContext.IsPeerAuthenticated.ToString()); return Task.FromResult(new SimpleResponse { Payload = CreateZerosPayload(request.ResponseSize) }); } diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 87a2516f8dc..d20b38c9303 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -964,7 +964,7 @@ GPR_EXPORT grpc_server_credentials* GPR_CALLTYPE grpcsharp_ssl_server_credentials_create( const char* pem_root_certs, const char** key_cert_pair_cert_chain_array, const char** key_cert_pair_private_key_array, size_t num_key_cert_pairs, - int force_client_auth) { + grpc_ssl_client_certificate_request_type client_request_type) { size_t i; grpc_server_credentials* creds; grpc_ssl_pem_key_cert_pair* key_cert_pairs = @@ -981,9 +981,7 @@ grpcsharp_ssl_server_credentials_create( } creds = grpc_ssl_server_credentials_create_ex( pem_root_certs, key_cert_pairs, num_key_cert_pairs, - force_client_auth - ? GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY - : GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, + client_request_type, NULL); gpr_free(key_cert_pairs); return creds; diff --git a/templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template b/templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template index 8ce2a573233..774fc2c56fe 100644 --- a/templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template +++ b/templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template @@ -73,7 +73,7 @@ 'void grpcsharp_redirect_log(GprLogDelegate callback)', 'CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor)', 'void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails)', - 'ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, int forceClientAuth)', + 'ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, SslClientCertificateRequestType clientCertificateRequest)', 'void grpcsharp_server_credentials_release(IntPtr credentials)', 'ServerSafeHandle grpcsharp_server_create(ChannelArgsSafeHandle args)', 'void grpcsharp_server_register_completion_queue(ServerSafeHandle server, CompletionQueueSafeHandle cq)', From d4065b959644e1d7e64c424c4c69926093011c04 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Sep 2018 18:12:59 +0200 Subject: [PATCH 283/546] add constructor for RpcException --- src/csharp/Grpc.Core/RpcException.cs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/csharp/Grpc.Core/RpcException.cs b/src/csharp/Grpc.Core/RpcException.cs index 94429d74ce6..ff898975654 100644 --- a/src/csharp/Grpc.Core/RpcException.cs +++ b/src/csharp/Grpc.Core/RpcException.cs @@ -33,10 +33,8 @@ namespace Grpc.Core /// Creates a new RpcException associated with given status. /// /// Resulting status of a call. - public RpcException(Status status) : base(status.ToString()) + public RpcException(Status status) : this(status, Metadata.Empty, status.ToString()) { - this.status = status; - this.trailers = Metadata.Empty; } /// @@ -44,10 +42,8 @@ namespace Grpc.Core /// /// Resulting status of a call. /// The exception message. - public RpcException(Status status, string message) : base(message) + public RpcException(Status status, string message) : this(status, Metadata.Empty, message) { - this.status = status; - this.trailers = Metadata.Empty; } /// @@ -55,7 +51,17 @@ namespace Grpc.Core /// /// Resulting status of a call. /// Response trailing metadata. - public RpcException(Status status, Metadata trailers) : base(status.ToString()) + public RpcException(Status status, Metadata trailers) : this(status, trailers, status.ToString()) + { + } + + /// + /// Creates a new RpcException associated with given status, message and trailing response metadata. + /// + /// Resulting status of a call. + /// Response trailing metadata. + /// The exception message. + public RpcException(Status status, Metadata trailers, string message) : base(message) { this.status = status; this.trailers = GrpcPreconditions.CheckNotNull(trailers); From b155c314f10fa08b237a96d0a43f0a5ba3689e2a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Sep 2018 16:19:13 +0200 Subject: [PATCH 284/546] handle failures in async call initialization without leaks --- .../Grpc.Core.Tests/Internal/AsyncCallTest.cs | 57 +++++ .../Internal/FakeNativeCall.cs | 22 ++ src/csharp/Grpc.Core/Channel.cs | 6 + src/csharp/Grpc.Core/Internal/AsyncCall.cs | 210 +++++++++++++----- .../Grpc.Core/Internal/AsyncCallBase.cs | 2 +- 5 files changed, 238 insertions(+), 59 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs index 9aab54d2d08..961b75c0b51 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs @@ -106,6 +106,24 @@ namespace Grpc.Core.Internal.Tests AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Internal); } + [Test] + public void AsyncUnary_RequestSerializationExceptionDoesntLeakResources() + { + string nullRequest = null; // will throw when serializing + Assert.Throws(typeof(ArgumentNullException), () => asyncCall.UnaryCallAsync(nullRequest)); + Assert.AreEqual(0, channel.GetCallReferenceCount()); + Assert.IsTrue(fakeCall.IsDisposed); + } + + [Test] + public void AsyncUnary_StartCallFailureDoesntLeakResources() + { + fakeCall.MakeStartCallFail(); + Assert.Throws(typeof(InvalidOperationException), () => asyncCall.UnaryCallAsync("request1")); + Assert.AreEqual(0, channel.GetCallReferenceCount()); + Assert.IsTrue(fakeCall.IsDisposed); + } + [Test] public void ClientStreaming_StreamingReadNotAllowed() { @@ -327,6 +345,15 @@ namespace Grpc.Core.Internal.Tests AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Cancelled); } + [Test] + public void ClientStreaming_StartCallFailureDoesntLeakResources() + { + fakeCall.MakeStartCallFail(); + Assert.Throws(typeof(InvalidOperationException), () => asyncCall.ClientStreamingCallAsync()); + Assert.AreEqual(0, channel.GetCallReferenceCount()); + Assert.IsTrue(fakeCall.IsDisposed); + } + [Test] public void ServerStreaming_StreamingSendNotAllowed() { @@ -401,6 +428,27 @@ namespace Grpc.Core.Internal.Tests AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask3); } + [Test] + public void ServerStreaming_RequestSerializationExceptionDoesntLeakResources() + { + string nullRequest = null; // will throw when serializing + Assert.Throws(typeof(ArgumentNullException), () => asyncCall.StartServerStreamingCall(nullRequest)); + Assert.AreEqual(0, channel.GetCallReferenceCount()); + Assert.IsTrue(fakeCall.IsDisposed); + + var responseStream = new ClientResponseStream(asyncCall); + var readTask = responseStream.MoveNext(); + } + + [Test] + public void ServerStreaming_StartCallFailureDoesntLeakResources() + { + fakeCall.MakeStartCallFail(); + Assert.Throws(typeof(InvalidOperationException), () => asyncCall.StartServerStreamingCall("request1")); + Assert.AreEqual(0, channel.GetCallReferenceCount()); + Assert.IsTrue(fakeCall.IsDisposed); + } + [Test] public void DuplexStreaming_NoRequestNoResponse_Success() { @@ -558,6 +606,15 @@ namespace Grpc.Core.Internal.Tests AssertStreamingResponseError(asyncCall, fakeCall, readTask2, StatusCode.Cancelled); } + [Test] + public void DuplexStreaming_StartCallFailureDoesntLeakResources() + { + fakeCall.MakeStartCallFail(); + Assert.Throws(typeof(InvalidOperationException), () => asyncCall.StartDuplexStreamingCall()); + Assert.AreEqual(0, channel.GetCallReferenceCount()); + Assert.IsTrue(fakeCall.IsDisposed); + } + ClientSideStatus CreateClientSideStatus(StatusCode statusCode) { return new ClientSideStatus(new Status(statusCode, ""), new Metadata()); diff --git a/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs b/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs index 581ac3384be..42536dd0c1a 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs @@ -31,6 +31,7 @@ namespace Grpc.Core.Internal.Tests /// internal class FakeNativeCall : INativeCall { + private bool shouldStartCallFail; public IUnaryResponseClientCallback UnaryResponseClientCallback { get; @@ -102,6 +103,7 @@ namespace Grpc.Core.Internal.Tests public void StartUnary(IUnaryResponseClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { + StartCallMaybeFail(); UnaryResponseClientCallback = callback; } @@ -112,16 +114,19 @@ namespace Grpc.Core.Internal.Tests public void StartClientStreaming(IUnaryResponseClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { + StartCallMaybeFail(); UnaryResponseClientCallback = callback; } public void StartServerStreaming(IReceivedStatusOnClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { + StartCallMaybeFail(); ReceivedStatusOnClientCallback = callback; } public void StartDuplexStreaming(IReceivedStatusOnClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { + StartCallMaybeFail(); ReceivedStatusOnClientCallback = callback; } @@ -165,5 +170,22 @@ namespace Grpc.Core.Internal.Tests { IsDisposed = true; } + + /// + /// Emulate CallSafeHandle.CheckOk() failure for all future attempts + /// to start a call. + /// + public void MakeStartCallFail() + { + shouldStartCallFail = true; + } + + private void StartCallMaybeFail() + { + if (shouldStartCallFail) + { + throw new InvalidOperationException("Start call has failed."); + } + } } } diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs index 7912b06b718..bc236da560e 100644 --- a/src/csharp/Grpc.Core/Channel.cs +++ b/src/csharp/Grpc.Core/Channel.cs @@ -297,6 +297,12 @@ namespace Grpc.Core activeCallCounter.Decrement(); } + // for testing only + internal long GetCallReferenceCount() + { + return activeCallCounter.Count; + } + private ChannelState GetConnectivityState(bool tryToConnect) { try diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 66902f3caae..76743226b3d 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -17,6 +17,7 @@ #endregion using System; +using System.Threading; using System.Threading.Tasks; using Grpc.Core.Logging; using Grpc.Core.Profiling; @@ -34,6 +35,8 @@ namespace Grpc.Core.Internal readonly CallInvocationDetails details; readonly INativeCall injectedNativeCall; // for testing + bool registeredWithChannel; + // Dispose of to de-register cancellation token registration IDisposable cancellationTokenRegistration; @@ -79,42 +82,59 @@ namespace Grpc.Core.Internal { byte[] payload = UnsafeSerialize(msg); - unaryResponseTcs = new TaskCompletionSource(); - - lock (myLock) + bool callStartedOk = false; + try { - GrpcPreconditions.CheckState(!started); - started = true; - Initialize(cq); + unaryResponseTcs = new TaskCompletionSource(); - halfcloseRequested = true; - readingDone = true; - } + lock (myLock) + { + GrpcPreconditions.CheckState(!started); + started = true; + Initialize(cq); - using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) - { - var ctx = details.Channel.Environment.BatchContextPool.Lease(); - try + halfcloseRequested = true; + readingDone = true; + } + + using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) { - call.StartUnary(ctx, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); - var ev = cq.Pluck(ctx.Handle); - bool success = (ev.success != 0); + var ctx = details.Channel.Environment.BatchContextPool.Lease(); try { - using (profiler.NewScope("AsyncCall.UnaryCall.HandleBatch")) + call.StartUnary(ctx, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); + callStartedOk = true; + + var ev = cq.Pluck(ctx.Handle); + bool success = (ev.success != 0); + try + { + using (profiler.NewScope("AsyncCall.UnaryCall.HandleBatch")) + { + HandleUnaryResponse(success, ctx.GetReceivedStatusOnClient(), ctx.GetReceivedMessage(), ctx.GetReceivedInitialMetadata()); + } + } + catch (Exception e) { - HandleUnaryResponse(success, ctx.GetReceivedStatusOnClient(), ctx.GetReceivedMessage(), ctx.GetReceivedInitialMetadata()); + Logger.Error(e, "Exception occurred while invoking completion delegate."); } } - catch (Exception e) + finally { - Logger.Error(e, "Exception occurred while invoking completion delegate."); + ctx.Recycle(); } } - finally + } + catch (Exception) + { + if (!callStartedOk) { - ctx.Recycle(); + lock (myLock) + { + OnFailedToStartCallLocked(); + } } + throw; } // Once the blocking call returns, the result should be available synchronously. @@ -130,22 +150,36 @@ namespace Grpc.Core.Internal { lock (myLock) { - GrpcPreconditions.CheckState(!started); - started = true; + bool callStartedOk = false; + try + { + GrpcPreconditions.CheckState(!started); + started = true; - Initialize(details.Channel.CompletionQueue); + Initialize(details.Channel.CompletionQueue); - halfcloseRequested = true; - readingDone = true; + halfcloseRequested = true; + readingDone = true; - byte[] payload = UnsafeSerialize(msg); + byte[] payload = UnsafeSerialize(msg); - unaryResponseTcs = new TaskCompletionSource(); - using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) + unaryResponseTcs = new TaskCompletionSource(); + using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) + { + call.StartUnary(UnaryResponseClientCallback, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); + callStartedOk = true; + } + + return unaryResponseTcs.Task; + } + catch (Exception) { - call.StartUnary(UnaryResponseClientCallback, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); + if (!callStartedOk) + { + OnFailedToStartCallLocked(); + } + throw; } - return unaryResponseTcs.Task; } } @@ -157,20 +191,33 @@ namespace Grpc.Core.Internal { lock (myLock) { - GrpcPreconditions.CheckState(!started); - started = true; + bool callStartedOk = false; + try + { + GrpcPreconditions.CheckState(!started); + started = true; - Initialize(details.Channel.CompletionQueue); + Initialize(details.Channel.CompletionQueue); - readingDone = true; + readingDone = true; - unaryResponseTcs = new TaskCompletionSource(); - using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) + unaryResponseTcs = new TaskCompletionSource(); + using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) + { + call.StartClientStreaming(UnaryResponseClientCallback, metadataArray, details.Options.Flags); + callStartedOk = true; + } + + return unaryResponseTcs.Task; + } + catch (Exception) { - call.StartClientStreaming(UnaryResponseClientCallback, metadataArray, details.Options.Flags); + if (!callStartedOk) + { + OnFailedToStartCallLocked(); + } + throw; } - - return unaryResponseTcs.Task; } } @@ -181,21 +228,34 @@ namespace Grpc.Core.Internal { lock (myLock) { - GrpcPreconditions.CheckState(!started); - started = true; + bool callStartedOk = false; + try + { + GrpcPreconditions.CheckState(!started); + started = true; - Initialize(details.Channel.CompletionQueue); + Initialize(details.Channel.CompletionQueue); - halfcloseRequested = true; + halfcloseRequested = true; - byte[] payload = UnsafeSerialize(msg); + byte[] payload = UnsafeSerialize(msg); - streamingResponseCallFinishedTcs = new TaskCompletionSource(); - using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) + streamingResponseCallFinishedTcs = new TaskCompletionSource(); + using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) + { + call.StartServerStreaming(ReceivedStatusOnClientCallback, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); + callStartedOk = true; + } + call.StartReceiveInitialMetadata(ReceivedResponseHeadersCallback); + } + catch (Exception) { - call.StartServerStreaming(ReceivedStatusOnClientCallback, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); + if (!callStartedOk) + { + OnFailedToStartCallLocked(); + } + throw; } - call.StartReceiveInitialMetadata(ReceivedResponseHeadersCallback); } } @@ -207,17 +267,30 @@ namespace Grpc.Core.Internal { lock (myLock) { - GrpcPreconditions.CheckState(!started); - started = true; + bool callStartedOk = false; + try + { + GrpcPreconditions.CheckState(!started); + started = true; - Initialize(details.Channel.CompletionQueue); + Initialize(details.Channel.CompletionQueue); - streamingResponseCallFinishedTcs = new TaskCompletionSource(); - using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) + streamingResponseCallFinishedTcs = new TaskCompletionSource(); + using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) + { + call.StartDuplexStreaming(ReceivedStatusOnClientCallback, metadataArray, details.Options.Flags); + callStartedOk = true; + } + call.StartReceiveInitialMetadata(ReceivedResponseHeadersCallback); + } + catch (Exception) { - call.StartDuplexStreaming(ReceivedStatusOnClientCallback, metadataArray, details.Options.Flags); + if (!callStartedOk) + { + OnFailedToStartCallLocked(); + } + throw; } - call.StartReceiveInitialMetadata(ReceivedResponseHeadersCallback); } } @@ -327,7 +400,11 @@ namespace Grpc.Core.Internal protected override void OnAfterReleaseResourcesLocked() { - details.Channel.RemoveCallReference(this); + if (registeredWithChannel) + { + details.Channel.RemoveCallReference(this); + registeredWithChannel = false; + } } protected override void OnAfterReleaseResourcesUnlocked() @@ -394,10 +471,27 @@ namespace Grpc.Core.Internal var call = CreateNativeCall(cq); details.Channel.AddCallReference(this); + registeredWithChannel = true; InitializeInternal(call); + RegisterCancellationCallback(); } + private void OnFailedToStartCallLocked() + { + ReleaseResources(); + + // We need to execute the hook that disposes the cancellation token + // registration, but it cannot be done from under a lock. + // To make things simple, we just schedule the unregistering + // on a threadpool. + // - Once the native call is disposed, the Cancel() calls are ignored anyway + // - We don't care about the overhead as OnFailedToStartCallLocked() only happens + // when something goes very bad when initializing a call and that should + // never happen when gRPC is used correctly. + ThreadPool.QueueUserWorkItem((state) => OnAfterReleaseResourcesUnlocked()); + } + private INativeCall CreateNativeCall(CompletionQueueSafeHandle cq) { if (injectedNativeCall != null) diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs index 5a53049e4bd..a93dc346205 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs @@ -189,7 +189,7 @@ namespace Grpc.Core.Internal /// protected abstract Exception GetRpcExceptionClientOnly(); - private void ReleaseResources() + protected void ReleaseResources() { if (call != null) { From ee510fb328a7548601d227dc99c62ab30fa69a2f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Sep 2018 17:59:03 +0200 Subject: [PATCH 285/546] make sync unary call behave more like async unary --- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 76743226b3d..0953f59a189 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -80,8 +80,6 @@ namespace Grpc.Core.Internal using (profiler.NewScope("AsyncCall.UnaryCall")) using (CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.CreateSync()) { - byte[] payload = UnsafeSerialize(msg); - bool callStartedOk = false; try { @@ -97,6 +95,8 @@ namespace Grpc.Core.Internal readingDone = true; } + byte[] payload = UnsafeSerialize(msg); + using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) { var ctx = details.Channel.Environment.BatchContextPool.Lease(); From 603a9a06353f5e53092e6d0bd2db2ec995ae1731 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 3 Sep 2018 17:59:38 +0200 Subject: [PATCH 286/546] add tests for sync unary --- .../Grpc.Core.Tests/Internal/AsyncCallTest.cs | 18 ++++++++++++++++++ .../Grpc.Core.Tests/Internal/FakeNativeCall.cs | 1 + 2 files changed, 19 insertions(+) diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs index 961b75c0b51..775849d89b6 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs @@ -124,6 +124,24 @@ namespace Grpc.Core.Internal.Tests Assert.IsTrue(fakeCall.IsDisposed); } + [Test] + public void SyncUnary_RequestSerializationExceptionDoesntLeakResources() + { + string nullRequest = null; // will throw when serializing + Assert.Throws(typeof(ArgumentNullException), () => asyncCall.UnaryCall(nullRequest)); + Assert.AreEqual(0, channel.GetCallReferenceCount()); + Assert.IsTrue(fakeCall.IsDisposed); + } + + [Test] + public void SyncUnary_StartCallFailureDoesntLeakResources() + { + fakeCall.MakeStartCallFail(); + Assert.Throws(typeof(InvalidOperationException), () => asyncCall.UnaryCall("request1")); + Assert.AreEqual(0, channel.GetCallReferenceCount()); + Assert.IsTrue(fakeCall.IsDisposed); + } + [Test] public void ClientStreaming_StreamingReadNotAllowed() { diff --git a/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs b/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs index 42536dd0c1a..ef67918dabb 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs @@ -109,6 +109,7 @@ namespace Grpc.Core.Internal.Tests public void StartUnary(BatchContextSafeHandle ctx, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { + StartCallMaybeFail(); throw new NotImplementedException(); } From 1abe2aeb9fe40effca9d66a9bd02a65821913199 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 4 Sep 2018 11:44:46 -0700 Subject: [PATCH 287/546] c#: expose TryWaitForStateChangedAsync --- .../Grpc.Core.Tests/ChannelConnectivityTest.cs | 18 ++++++++++++++++++ src/csharp/Grpc.Core/Channel.cs | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/ChannelConnectivityTest.cs b/src/csharp/Grpc.Core.Tests/ChannelConnectivityTest.cs index a43040f01a3..b4b3b2d5ac4 100644 --- a/src/csharp/Grpc.Core.Tests/ChannelConnectivityTest.cs +++ b/src/csharp/Grpc.Core.Tests/ChannelConnectivityTest.cs @@ -73,6 +73,24 @@ namespace Grpc.Core.Tests Assert.AreEqual(ChannelState.Ready, channel.State); } + [Test] + public async Task Channel_TryWaitForStateChangedAsync() + { + helper.UnaryHandler = new UnaryServerMethod((request, context) => + { + return Task.FromResult(request); + }); + + Assert.IsFalse(await channel.TryWaitForStateChangedAsync(channel.State, DateTime.UtcNow.AddMilliseconds(10))); + + var stateChangedTask = channel.TryWaitForStateChangedAsync(channel.State); + + await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc"); + + Assert.IsTrue(await stateChangedTask); + Assert.AreEqual(ChannelState.Ready, channel.State); + } + [Test] public async Task Channel_ConnectAsync() { diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs index 7912b06b718..4c89ed7393f 100644 --- a/src/csharp/Grpc.Core/Channel.cs +++ b/src/csharp/Grpc.Core/Channel.cs @@ -136,7 +136,7 @@ namespace Grpc.Core /// public async Task WaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null) { - var result = await WaitForStateChangedInternalAsync(lastObservedState, deadline).ConfigureAwait(false); + var result = await TryWaitForStateChangedAsync(lastObservedState, deadline).ConfigureAwait(false); if (!result) { throw new TaskCanceledException("Reached deadline."); @@ -147,7 +147,7 @@ namespace Grpc.Core /// Returned tasks completes once channel state has become different from /// given lastObservedState (true is returned) or if the wait has timed out (false is returned). /// - internal Task WaitForStateChangedInternalAsync(ChannelState lastObservedState, DateTime? deadline = null) + public Task TryWaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null) { GrpcPreconditions.CheckArgument(lastObservedState != ChannelState.Shutdown, "Shutdown is a terminal state. No further state changes can occur."); From 6e7e29aaae698d03dab71715c1913a5f813337ef Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 4 Sep 2018 12:47:09 -0700 Subject: [PATCH 288/546] WIP. Created static data for size of metadata and callouts index --- src/core/lib/transport/metadata.cc | 65 ++++++++++++++++++++++++++++++ src/core/lib/transport/metadata.h | 11 ++++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index d10194a2fe7..793a1fcd53b 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -69,6 +69,71 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_metadata(false, "metadata"); #define TABLE_IDX(hash, capacity) (((hash) >> (LOG2_SHARD_COUNT)) % (capacity)) #define SHARD_IDX(hash) ((hash) & ((1 << (LOG2_SHARD_COUNT)) - 1)) +static_hpack_table_metadata_info static_hpack_table_metadata[] = { + {0, 0, 0}, // NOT USED + {GRPC_MDELEM_AUTHORITY_EMPTY_INDEX, 10 + 32, 3}, + {GRPC_MDELEM_METHOD_GET_INDEX, 10 + 32, 1}, + {GRPC_MDELEM_METHOD_POST_INDEX, 11 + 32, 1}, + {GRPC_MDELEM_PATH_SLASH_INDEX, 6 + 32, 0}, + {GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML_INDEX, 16 + 32, 0}, + {GRPC_MDELEM_SCHEME_HTTP_INDEX, 11 + 32, 4}, + {GRPC_MDELEM_SCHEME_HTTPS_INDEX, 12 + 32, 4}, + {GRPC_MDELEM_STATUS_200_INDEX, 10 + 32, 2}, + {GRPC_MDELEM_STATUS_204_INDEX, 10 + 32, 2}, + {GRPC_MDELEM_STATUS_206_INDEX, 10 + 32, 2}, + {GRPC_MDELEM_STATUS_304_INDEX, 10 + 32, 2}, + {GRPC_MDELEM_STATUS_400_INDEX, 10 + 32, 2}, + {GRPC_MDELEM_STATUS_404_INDEX, 10 + 32, 2}, + {GRPC_MDELEM_STATUS_500_INDEX, 10 + 32, 2}, + {GRPC_MDELEM_ACCEPT_CHARSET_EMPTY_INDEX, 14 + 32, 24}, // Not a callout + {GRPC_MDELEM_ACCEPT_ENCODING_GZIP_DEFLATE_INDEX, 28 + 32, 16}, + {GRPC_MDELEM_MDELEM_ACCEPT_LANGUAGE_EMPTY_INDEX, 15 + 32, 24}, // Not a callout + {GRPC_MDELEM_MDELEM_ACCEPT_RANGES_EMPTY_INDEX, 13 + 32, 24}, // Not a callout + {GRPC_MDELEM_ACCEPT_EMPTY_INDEX, 6 + 32, 24}, // Not a callout + {GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY_INDEX, 27 + 32, 24}, // Not a callout + {GRPC_MDELEM_AGE_EMPTY_INDEX, 3 + 32, 24}, // Not a callout + {GRPC_MDELEM_ALLOW_EMPTY_INDEX, 5 + 32, 24}, // Not a callout + {GRPC_MDELEM_AUTHORIZATION_EMPTY_INDEX, 13 + 32, 24}, // Not a callout + {GRPC_MDELEM_CACHE_CONTROL_EMPTY_INDEX, 13 + 32, 24}, // Not a callout + {GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY_INDEX, 19 + 32, 24}, // Not a callout + {GRPC_MDELEM_CONTENT_ENCODING_EMPTY_INDEX, 16 + 32, 15}, + {GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY_INDEX, 16 + 32, 24}, // Not a callout + {GRPC_MDELEM_CONTENT_LENGTH_EMPTY_INDEX, 14 + 32, 24}, // Not a callout + {GRPC_MDELEM_CONTENT_LOCATION_EMPTY_INDEX, 16 + 32, 24}, // Not a callout + {GRPC_MDELEM_CONTENT_RANGE_EMPTY_INDEX, 13 + 32, 24}, // Not a callout + {GRPC_MDELEM_CONTENT_TYPE_EMPTY_INDEX, 12 + 32, 15}, + {GRPC_MDELEM_COOKIE_EMPTY_INDEX, 6 + 32, 24}, // Not a callout + {GRPC_MDELEM_DATE_EMPTY_INDEX, 4 + 32, 24}, // Not a callout + {GRPC_MDELEM_ETAG_EMPTY_INDEX, 4 + 32, 24}, // Not a callout + {GRPC_MDELEM_EXPECT_EMPTY_INDEX, 6 + 32, 24}, // Not a callout + {GRPC_MDELEM_EXPIRES_EMPTY_INDEX, 7 + 32, 24}, // Not a callout + {GRPC_MDELEM_FROM_EMPTY_INDEX, 4 + 32, 24}, // Not a callout + {GRPC_MDELEM_HOST_EMPTY_INDEX, 4 + 32, 20}, + {GRPC_MDELEM_IF_MATCH_EMPTY_INDEX, 8 + 32, 24}, // Not a callout + {GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY_INDEX, 17 + 32, 24}, // Not a callout + {GRPC_MDELEM_IF_NONE_MATCH_EMPTY_INDEX, 13 + 32, 24}, // Not a callout + {GRPC_MDELEM_IF_RANGE_EMPTY_INDEX, 8 + 32, 24}, // Not a callout + {GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY_INDEX, 19 + 32, 24}, // Not a callout + {GRPC_MDELEM_LAST_MODIFIED_EMPTY_INDEX, 13 + 32, 24}, // Not a callout + {GRPC_MDELEM_LINK_EMPTY_INDEX, 4 + 32, 24}, // Not a callout + {GRPC_MDELEM_LOCATION_EMPTY_INDEX, 8 + 32, 24}, // Not a callout + {GRPC_MDELEM_MAX_FORWARDS_EMPTY_INDEX, 12 + 32, 24}, // Not a callout + {GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY_INDEX, 18 + 32, 24}, // Not a callout + {GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY_INDEX, 19 + 32, 24}, // Not a callout + {GRPC_MDELEM_RANGE_EMPTY_INDEX, 5 + 32, 24}, // Not a callout + {GRPC_MDELEM_REFERER_EMPTY_INDEX, 7 + 32, 24}, // Not a callout + {GRPC_MDELEM_REFRESH_EMPTY_INDEX, 7 + 32, 24}, // Not a callout + {GRPC_MDELEM_RETRY_AFTER_EMPTY_INDEX, 11 + 32, 24}, // Not a callout + {GRPC_MDELEM_SERVER_EMPTY_INDEX, 6 + 32, 24}, // Not a callout + {GRPC_MDELEM_SET_COOKIE_EMPTY_INDEX, 10 + 32, 24}, // Not a callout + {GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY_INDEX, 25 + 32, 24}, // Not a callout + {GRPC_MDELEM_TRANSFER_ENCODING_EMPTY_INDEX, 17 + 32, 24}, // Not a callout + {GRPC_MDELEM_USER_AGENT_EMPTY_INDEX, 10 + 32, 19}, + {GRPC_MDELEM_VARY_EMPTY_INDEX, 4 + 32, 24}, // Not a callout + {GRPC_MDELEM_VIA_EMPTY_INDEX, 3 + 32, 24}, // Not a callout + {GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY_INDEX, 16 + 32, 24}, // Not a callout + }; + typedef void (*destroy_user_data_func)(void* user_data); /* Shadow structure for grpc_mdelem_data for interned elements */ diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index eeb09aff974..998d2fc64a2 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -165,8 +165,6 @@ void grpc_mdctx_global_shutdown(); #define MIN_STATIC_HPACK_TABLE_IDX 1 #define MAX_STATIC_HPACK_TABLE_IDX 61 -/* Static hpack table metadata indices */ - /* {:authority, ""} */ #define GRPC_MDELEM_AUTHORITY_EMPTY_INDEX 1 @@ -350,6 +348,15 @@ void grpc_mdctx_global_shutdown(); /* {"www-authenticate", ""} */ #define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY_INDEX 61 +/* Static hpack table metadata info */ +typedef struct static_hpack_table_metadata_info { + uint8_t index; // Index in the static hpack table + uint8_t size; // Size of the metadata per RFC-7540 section 6.5.2., including 32 bytes of padding + uint8_t callouts_index; // For duplicate metadata detection. If GRPC_BATCH_CALLOUTS_COUNT, then the metadata is not one of the callouts. +} static_hpack_table_metadata_info; + +extern static_hpack_table_metadata_info static_hpack_table_metadata[]; + /* Forward declarations */ typedef struct grpc_mdelem grpc_mdelem; #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */ From 5e054bf11e58049d988746cb76238f8099ac1faa Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 4 Sep 2018 13:01:34 -0700 Subject: [PATCH 289/546] Stop unconditionally surfacing user agent to server --- src/core/ext/filters/http/server/http_server_filter.cc | 4 ++++ 1 file changed, 4 insertions(+) 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 926afeec84f..a238d5f989f 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -262,6 +262,10 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":authority"))); } + if (b->idx.named.user_agent != nullptr) { + grpc_metadata_batch_remove(b, b->idx.named.user_agent); + } + return error; } From 113f5bd2e818859ee7b1b5bf50b96d9d559566a2 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 4 Sep 2018 13:07:49 -0700 Subject: [PATCH 290/546] exception handling in native callback --- .../Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs index 36e8cbbf314..faeb51e6f7a 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs @@ -68,9 +68,8 @@ namespace Grpc.Core.Internal } catch (Exception e) { - var detail = GetMetadataExceptionStatusMsg + " " + e.ToString(); - Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, detail); - Logger.Error(e, GetMetadataExceptionLogMsg); + // eat the exception, we must not throw when inside callback from native code. + Logger.Error(e, "Exception occurred while invoking native metadata interceptor handler."); } } From e361d0f6910db66e081d125e45e58b96e22d3e11 Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Fri, 31 Aug 2018 11:30:28 -0700 Subject: [PATCH 291/546] Turn loading system root certificate as default --- .../security_connector/security_connector.cc | 14 +++++++------- test/core/security/linux_system_roots_test.cc | 6 ------ test/core/security/security_connector_test.cc | 1 + 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 04b4c87c713..6246613e7b3 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -59,8 +59,8 @@ static const char* installed_roots_path = /** Environment variable used as a flag to enable/disable loading system root certificates from the OS trust store. */ -#ifndef GRPC_USE_SYSTEM_SSL_ROOTS_ENV_VAR -#define GRPC_USE_SYSTEM_SSL_ROOTS_ENV_VAR "GRPC_USE_SYSTEM_SSL_ROOTS" +#ifndef GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR +#define GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR "GRPC_NOT_USE_SYSTEM_SSL_ROOTS" #endif #ifndef TSI_OPENSSL_ALPN_SUPPORT @@ -1192,10 +1192,10 @@ const char* DefaultSslRootStore::GetPemRootCerts() { grpc_slice DefaultSslRootStore::ComputePemRootCerts() { grpc_slice result = grpc_empty_slice(); - char* use_system_roots_env_value = - gpr_getenv(GRPC_USE_SYSTEM_SSL_ROOTS_ENV_VAR); - const bool use_system_roots = gpr_is_true(use_system_roots_env_value); - gpr_free(use_system_roots_env_value); + char* not_use_system_roots_env_value = + gpr_getenv(GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR); + const bool not_use_system_roots = gpr_is_true(not_use_system_roots_env_value); + gpr_free(not_use_system_roots_env_value); // First try to load the roots from the environment. char* default_root_certs_path = gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); @@ -1218,7 +1218,7 @@ grpc_slice DefaultSslRootStore::ComputePemRootCerts() { gpr_free(pem_root_certs); } // Try loading roots from OS trust store if flag is enabled. - if (GRPC_SLICE_IS_EMPTY(result) && use_system_roots) { + if (GRPC_SLICE_IS_EMPTY(result) && !not_use_system_roots) { result = LoadSystemRootCerts(); } // Fallback to roots manually shipped with gRPC. diff --git a/test/core/security/linux_system_roots_test.cc b/test/core/security/linux_system_roots_test.cc index fce9c8dcc5d..24d446de359 100644 --- a/test/core/security/linux_system_roots_test.cc +++ b/test/core/security/linux_system_roots_test.cc @@ -41,10 +41,6 @@ #include "gtest/gtest.h" -#ifndef GRPC_USE_SYSTEM_SSL_ROOTS_ENV_VAR -#define GRPC_USE_SYSTEM_SSL_ROOTS_ENV_VAR "GRPC_USE_SYSTEM_SSL_ROOTS" -#endif - namespace grpc { namespace { @@ -68,7 +64,6 @@ TEST(CreateRootCertsBundleTest, ReturnsEmpty) { } TEST(CreateRootCertsBundleTest, BundlesCorrectly) { - gpr_setenv(GRPC_USE_SYSTEM_SSL_ROOTS_ENV_VAR, "true"); // Test that CreateRootCertsBundle returns a correct slice. grpc_slice roots_bundle = grpc_empty_slice(); GRPC_LOG_IF_ERROR( @@ -81,7 +76,6 @@ TEST(CreateRootCertsBundleTest, BundlesCorrectly) { char* bundle_str = grpc_slice_to_c_string(roots_bundle); EXPECT_STREQ(result_str, bundle_str); // Clean up. - unsetenv(GRPC_USE_SYSTEM_SSL_ROOTS_ENV_VAR); gpr_free(result_str); gpr_free(bundle_str); grpc_slice_unref(roots_bundle); diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index 82d77eef8bd..9dd37b975b5 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -415,6 +415,7 @@ static void test_default_ssl_roots(void) { /* Now setup a permanent failure for the overridden roots and we should get an empty slice. */ + gpr_setenv("GRPC_NOT_USE_SYSTEM_SSL_ROOTS", "true"); grpc_set_ssl_roots_override_callback(override_roots_permanent_failure); roots = grpc_core::TestDefaultSslRootStore::ComputePemRootCertsForTesting(); GPR_ASSERT(GRPC_SLICE_IS_EMPTY(roots)); From dcc0a223c63f67d20854459155eee14aa4833a13 Mon Sep 17 00:00:00 2001 From: Ruslan Nigmatullin Date: Tue, 4 Sep 2018 23:16:58 +0000 Subject: [PATCH 292/546] [bazel] Fix python BUILD rules * Add missing cython sources * Make grpcio a library as it is not a binary --- src/python/grpcio/grpc/BUILD.bazel | 3 +-- src/python/grpcio/grpc/_cython/BUILD.bazel | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/BUILD.bazel b/src/python/grpcio/grpc/BUILD.bazel index 3f214bf3b05..2e6839ef2d8 100644 --- a/src/python/grpcio/grpc/BUILD.bazel +++ b/src/python/grpcio/grpc/BUILD.bazel @@ -2,7 +2,7 @@ load("@grpc_python_dependencies//:requirements.bzl", "requirement") package(default_visibility = ["//visibility:public"]) -py_binary( +py_library( name = "grpcio", srcs = ["__init__.py"], deps = [ @@ -22,7 +22,6 @@ py_binary( data = [ "//:grpc", ], - main = "__init__.py", imports = ["../",], ) diff --git a/src/python/grpcio/grpc/_cython/BUILD.bazel b/src/python/grpcio/grpc/_cython/BUILD.bazel index 7124e83dee7..cfd3a51d9bb 100644 --- a/src/python/grpcio/grpc/_cython/BUILD.bazel +++ b/src/python/grpcio/grpc/_cython/BUILD.bazel @@ -8,6 +8,7 @@ pyx_library( "__init__.py", "cygrpc.pxd", "cygrpc.pyx", + "_cygrpc/_hooks.pyx.pxi", "_cygrpc/grpc_string.pyx.pxi", "_cygrpc/arguments.pyx.pxi", "_cygrpc/call.pyx.pxi", @@ -15,6 +16,7 @@ pyx_library( "_cygrpc/credentials.pyx.pxi", "_cygrpc/completion_queue.pyx.pxi", "_cygrpc/event.pyx.pxi", + "_cygrpc/fork_posix.pyx.pxi", "_cygrpc/metadata.pyx.pxi", "_cygrpc/operation.pyx.pxi", "_cygrpc/records.pyx.pxi", @@ -24,12 +26,14 @@ pyx_library( "_cygrpc/time.pyx.pxi", "_cygrpc/grpc_gevent.pyx.pxi", "_cygrpc/grpc.pxi", + "_cygrpc/_hooks.pxd.pxi", "_cygrpc/arguments.pxd.pxi", "_cygrpc/call.pxd.pxi", "_cygrpc/channel.pxd.pxi", "_cygrpc/credentials.pxd.pxi", "_cygrpc/completion_queue.pxd.pxi", "_cygrpc/event.pxd.pxi", + "_cygrpc/fork_posix.pxd.pxi", "_cygrpc/metadata.pxd.pxi", "_cygrpc/operation.pxd.pxi", "_cygrpc/records.pxd.pxi", From dd95194a086b81966fd94726c04f53d279e247d8 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 4 Sep 2018 16:26:14 -0700 Subject: [PATCH 293/546] Prefer grpc status over http status test --- .../ext/transport/chttp2/transport/parsing.cc | 2 ++ src/core/lib/surface/call.cc | 4 ++-- test/core/end2end/tests/filter_status_code.cc | 20 ++++++++++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc index 1e491d2ef86..205fb8c3700 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/src/core/ext/transport/chttp2/transport/parsing.cc @@ -393,6 +393,7 @@ error_handler: static void free_timeout(void* p) { gpr_free(p); } static void on_initial_header(void* tp, grpc_mdelem md) { + gpr_log(GPR_INFO, "on initial header"); GPR_TIMER_SCOPE("on_initial_header", 0); grpc_chttp2_transport* t = static_cast(tp); @@ -475,6 +476,7 @@ static void on_initial_header(void* tp, grpc_mdelem md) { } static void on_trailing_header(void* tp, grpc_mdelem md) { + gpr_log(GPR_INFO, "on_trailing_header"); GPR_TIMER_SCOPE("on_trailing_header", 0); grpc_chttp2_transport* t = static_cast(tp); diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index b07c4d6c10b..496de1150a2 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -685,10 +685,10 @@ static void cancel_with_status(grpc_call* c, grpc_status_code status, } static void set_final_status(grpc_call* call, grpc_error* error) { - if (grpc_call_error_trace.enabled()) { + //if (grpc_call_error_trace.enabled()) { gpr_log(GPR_DEBUG, "set_final_status %s", call->is_client ? "CLI" : "SVR"); gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); - } + //} if (call->is_client) { grpc_error_get_status(error, call->send_deadline, call->final_op.client.status, diff --git a/test/core/end2end/tests/filter_status_code.cc b/test/core/end2end/tests/filter_status_code.cc index ba3cbfa6d11..447ff520ee2 100644 --- a/test/core/end2end/tests/filter_status_code.cc +++ b/test/core/end2end/tests/filter_status_code.cc @@ -249,6 +249,24 @@ typedef struct final_status_data { grpc_call_stack* call; } final_status_data; +static void start_transport_stream_op_batch(grpc_call_element *elem, + grpc_transport_stream_op_batch *op) { + auto* data = static_cast(elem->call_data); + if(data->call == g_server_call_stack) { + gpr_log(GPR_INFO, "here"); + } + if(op->send_initial_metadata) { + auto *batch = op->payload->send_initial_metadata.send_initial_metadata; + gpr_log(GPR_INFO, "init %p %p", batch->idx.named.status, batch->idx.named.grpc_status); + grpc_metadata_batch_substitute(batch, batch->idx.named.status, GRPC_MDELEM_STATUS_404); + } + if(op->send_trailing_metadata) { + auto *batch = op->payload->send_trailing_metadata.send_trailing_metadata; + gpr_log(GPR_INFO, "trai %p %p", batch->idx.named.status, batch->idx.named.grpc_status); + } + grpc_call_next_op(elem, op); +} + static grpc_error* init_call_elem(grpc_call_element* elem, const grpc_call_element_args* args) { final_status_data* data = static_cast(elem->call_data); @@ -307,7 +325,7 @@ static const grpc_channel_filter test_client_filter = { "client_filter_status_code"}; static const grpc_channel_filter test_server_filter = { - grpc_call_next_op, + start_transport_stream_op_batch, grpc_channel_next_op, sizeof(final_status_data), init_call_elem, From 3a41245e465e176dc2cae642cf701f5b476188b6 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 4 Sep 2018 19:18:15 -0700 Subject: [PATCH 294/546] Rectify the condition and add a test --- .../filters/http/client/http_client_filter.cc | 7 +++- .../ext/transport/chttp2/transport/parsing.cc | 2 -- src/core/lib/surface/call.cc | 4 +-- test/core/end2end/tests/filter_status_code.cc | 34 +++++++++++-------- 4 files changed, 28 insertions(+), 19 deletions(-) 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 f44dc032a7e..91fa163fecb 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -79,7 +79,12 @@ struct channel_data { static grpc_error* client_filter_incoming_metadata(grpc_call_element* elem, grpc_metadata_batch* b) { if (b->idx.named.status != nullptr) { - if (grpc_mdelem_eq(b->idx.named.status->md, GRPC_MDELEM_STATUS_200)) { + /* If both gRPC status and HTTP status are provided in the response, we + * should prefer the gRPC status code, as mentioned in + * https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md. + */ + if (b->idx.named.grpc_status != nullptr || + grpc_mdelem_eq(b->idx.named.status->md, GRPC_MDELEM_STATUS_200)) { grpc_metadata_batch_remove(b, b->idx.named.status); } else { char* val = grpc_dump_slice(GRPC_MDVALUE(b->idx.named.status->md), diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc index 205fb8c3700..1e491d2ef86 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/src/core/ext/transport/chttp2/transport/parsing.cc @@ -393,7 +393,6 @@ error_handler: static void free_timeout(void* p) { gpr_free(p); } static void on_initial_header(void* tp, grpc_mdelem md) { - gpr_log(GPR_INFO, "on initial header"); GPR_TIMER_SCOPE("on_initial_header", 0); grpc_chttp2_transport* t = static_cast(tp); @@ -476,7 +475,6 @@ static void on_initial_header(void* tp, grpc_mdelem md) { } static void on_trailing_header(void* tp, grpc_mdelem md) { - gpr_log(GPR_INFO, "on_trailing_header"); GPR_TIMER_SCOPE("on_trailing_header", 0); grpc_chttp2_transport* t = static_cast(tp); diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 496de1150a2..b07c4d6c10b 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -685,10 +685,10 @@ static void cancel_with_status(grpc_call* c, grpc_status_code status, } static void set_final_status(grpc_call* call, grpc_error* error) { - //if (grpc_call_error_trace.enabled()) { + if (grpc_call_error_trace.enabled()) { gpr_log(GPR_DEBUG, "set_final_status %s", call->is_client ? "CLI" : "SVR"); gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); - //} + } if (call->is_client) { grpc_error_get_status(error, call->send_deadline, call->final_op.client.status, diff --git a/test/core/end2end/tests/filter_status_code.cc b/test/core/end2end/tests/filter_status_code.cc index 447ff520ee2..5ffc3d00a3f 100644 --- a/test/core/end2end/tests/filter_status_code.cc +++ b/test/core/end2end/tests/filter_status_code.cc @@ -16,6 +16,14 @@ * */ +/* This test verifies - + * 1) grpc_call_final_info passed to the filters on destroying a call contains + * the proper status. + * 2) If the response has both an HTTP status code and a gRPC status code, then + * we should prefer the gRPC status code as mentioned in + * https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md + */ + #include "test/core/end2end/end2end_tests.h" #include @@ -249,20 +257,18 @@ typedef struct final_status_data { grpc_call_stack* call; } final_status_data; -static void start_transport_stream_op_batch(grpc_call_element *elem, - grpc_transport_stream_op_batch *op) { +static void server_start_transport_stream_op_batch( + grpc_call_element* elem, grpc_transport_stream_op_batch* op) { auto* data = static_cast(elem->call_data); - if(data->call == g_server_call_stack) { - gpr_log(GPR_INFO, "here"); - } - if(op->send_initial_metadata) { - auto *batch = op->payload->send_initial_metadata.send_initial_metadata; - gpr_log(GPR_INFO, "init %p %p", batch->idx.named.status, batch->idx.named.grpc_status); - grpc_metadata_batch_substitute(batch, batch->idx.named.status, GRPC_MDELEM_STATUS_404); - } - if(op->send_trailing_metadata) { - auto *batch = op->payload->send_trailing_metadata.send_trailing_metadata; - gpr_log(GPR_INFO, "trai %p %p", batch->idx.named.status, batch->idx.named.grpc_status); + if (data->call == g_server_call_stack) { + if (op->send_initial_metadata) { + auto* batch = op->payload->send_initial_metadata.send_initial_metadata; + if (batch->idx.named.status != nullptr) { + /* Replace the HTTP status with 404 */ + grpc_metadata_batch_substitute(batch, batch->idx.named.status, + GRPC_MDELEM_STATUS_404); + } + } } grpc_call_next_op(elem, op); } @@ -325,7 +331,7 @@ static const grpc_channel_filter test_client_filter = { "client_filter_status_code"}; static const grpc_channel_filter test_server_filter = { - start_transport_stream_op_batch, + server_start_transport_stream_op_batch, grpc_channel_next_op, sizeof(final_status_data), init_call_elem, From 7557c270a3f27a72be88dfcb2ae9efaeca527de4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Sep 2018 16:41:57 +0200 Subject: [PATCH 295/546] clang format --- src/csharp/ext/grpc_csharp_ext.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index d20b38c9303..ed002ae1fff 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -979,10 +979,9 @@ grpcsharp_ssl_server_credentials_create( key_cert_pairs[i].private_key = key_cert_pair_private_key_array[i]; } } - creds = grpc_ssl_server_credentials_create_ex( - pem_root_certs, key_cert_pairs, num_key_cert_pairs, - client_request_type, - NULL); + creds = grpc_ssl_server_credentials_create_ex(pem_root_certs, key_cert_pairs, + num_key_cert_pairs, + client_request_type, NULL); gpr_free(key_cert_pairs); return creds; } From bc3e95c6b29860cc61de2f535355f24fde47e329 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 5 Sep 2018 08:10:52 -0700 Subject: [PATCH 296/546] simplify ChannelConnectivityTest --- .../ChannelConnectivityTest.cs | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/ChannelConnectivityTest.cs b/src/csharp/Grpc.Core.Tests/ChannelConnectivityTest.cs index b4b3b2d5ac4..0834ddadda9 100644 --- a/src/csharp/Grpc.Core.Tests/ChannelConnectivityTest.cs +++ b/src/csharp/Grpc.Core.Tests/ChannelConnectivityTest.cs @@ -57,18 +57,11 @@ namespace Grpc.Core.Tests [Test] public async Task Channel_WaitForStateChangedAsync() { - helper.UnaryHandler = new UnaryServerMethod((request, context) => - { - return Task.FromResult(request); - }); - Assert.ThrowsAsync(typeof(TaskCanceledException), - async () => await channel.WaitForStateChangedAsync(channel.State, DateTime.UtcNow.AddMilliseconds(10))); + async () => await channel.WaitForStateChangedAsync(channel.State, DateTime.UtcNow.AddMilliseconds(0))); var stateChangedTask = channel.WaitForStateChangedAsync(channel.State); - - await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc"); - + await channel.ConnectAsync(DateTime.UtcNow.AddMilliseconds(5000)); await stateChangedTask; Assert.AreEqual(ChannelState.Ready, channel.State); } @@ -76,17 +69,10 @@ namespace Grpc.Core.Tests [Test] public async Task Channel_TryWaitForStateChangedAsync() { - helper.UnaryHandler = new UnaryServerMethod((request, context) => - { - return Task.FromResult(request); - }); - - Assert.IsFalse(await channel.TryWaitForStateChangedAsync(channel.State, DateTime.UtcNow.AddMilliseconds(10))); + Assert.IsFalse(await channel.TryWaitForStateChangedAsync(channel.State, DateTime.UtcNow.AddMilliseconds(0))); var stateChangedTask = channel.TryWaitForStateChangedAsync(channel.State); - - await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "abc"); - + await channel.ConnectAsync(DateTime.UtcNow.AddMilliseconds(5000)); Assert.IsTrue(await stateChangedTask); Assert.AreEqual(ChannelState.Ready, channel.State); } From 6d2c8f807228c69236ff2b890ac9ab77027d2a90 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 5 Sep 2018 10:27:54 -0700 Subject: [PATCH 297/546] Revert "Merge pull request #16512 from grpc/revert-16351-health_checking_service" This reverts commit 4ee0f4c790f3b13dcfc8d55b21869140964d6de2, reversing changes made to 5ee9b5e7b547d0a82c84cc3767236ace8d5cd469. --- .../grpcpp/impl/codegen/completion_queue.h | 1 + .../health/default_health_check_service.cc | 484 +++++++++++++++--- .../health/default_health_check_service.h | 242 ++++++++- src/cpp/server/health/health.pb.c | 1 - src/cpp/server/health/health.pb.h | 7 +- src/cpp/server/server_cc.cc | 27 +- src/proto/grpc/health/v1/health.proto | 20 + .../end2end/health_service_end2end_test.cc | 76 ++- tools/distrib/check_nanopb_output.sh | 18 + 9 files changed, 771 insertions(+), 105 deletions(-) diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 3f7d4fb765f..6c8428ebde6 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -384,6 +384,7 @@ class ServerCompletionQueue : public CompletionQueue { grpc_cq_polling_type polling_type_; friend class ServerBuilder; + friend class Server; }; } // namespace grpc diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index bfda67d0864..670da63a4a0 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -30,29 +30,162 @@ #include "src/cpp/server/health/health.pb.h" namespace grpc { + +// +// DefaultHealthCheckService +// + +DefaultHealthCheckService::DefaultHealthCheckService() { + services_map_[""].SetServingStatus(SERVING); +} + +void DefaultHealthCheckService::SetServingStatus( + const grpc::string& service_name, bool serving) { + std::unique_lock lock(mu_); + services_map_[service_name].SetServingStatus(serving ? SERVING : NOT_SERVING); +} + +void DefaultHealthCheckService::SetServingStatus(bool serving) { + const ServingStatus status = serving ? SERVING : NOT_SERVING; + std::unique_lock lock(mu_); + for (auto& p : services_map_) { + ServiceData& service_data = p.second; + service_data.SetServingStatus(status); + } +} + +DefaultHealthCheckService::ServingStatus +DefaultHealthCheckService::GetServingStatus( + const grpc::string& service_name) const { + std::lock_guard lock(mu_); + auto it = services_map_.find(service_name); + if (it == services_map_.end()) { + return NOT_FOUND; + } + const ServiceData& service_data = it->second; + return service_data.GetServingStatus(); +} + +void DefaultHealthCheckService::RegisterCallHandler( + const grpc::string& service_name, + std::shared_ptr handler) { + std::unique_lock lock(mu_); + ServiceData& service_data = services_map_[service_name]; + service_data.AddCallHandler(handler /* copies ref */); + handler->SendHealth(std::move(handler), service_data.GetServingStatus()); +} + +void DefaultHealthCheckService::UnregisterCallHandler( + const grpc::string& service_name, + std::shared_ptr handler) { + std::unique_lock lock(mu_); + auto it = services_map_.find(service_name); + if (it == services_map_.end()) return; + ServiceData& service_data = it->second; + service_data.RemoveCallHandler(std::move(handler)); + if (service_data.Unused()) { + services_map_.erase(it); + } +} + +DefaultHealthCheckService::HealthCheckServiceImpl* +DefaultHealthCheckService::GetHealthCheckService( + std::unique_ptr cq) { + GPR_ASSERT(impl_ == nullptr); + impl_.reset(new HealthCheckServiceImpl(this, std::move(cq))); + return impl_.get(); +} + +// +// DefaultHealthCheckService::ServiceData +// + +void DefaultHealthCheckService::ServiceData::SetServingStatus( + ServingStatus status) { + status_ = status; + for (auto& call_handler : call_handlers_) { + call_handler->SendHealth(call_handler /* copies ref */, status); + } +} + +void DefaultHealthCheckService::ServiceData::AddCallHandler( + std::shared_ptr handler) { + call_handlers_.insert(std::move(handler)); +} + +void DefaultHealthCheckService::ServiceData::RemoveCallHandler( + std::shared_ptr handler) { + call_handlers_.erase(std::move(handler)); +} + +// +// DefaultHealthCheckService::HealthCheckServiceImpl +// + namespace { const char kHealthCheckMethodName[] = "/grpc.health.v1.Health/Check"; +const char kHealthWatchMethodName[] = "/grpc.health.v1.Health/Watch"; } // namespace DefaultHealthCheckService::HealthCheckServiceImpl::HealthCheckServiceImpl( - DefaultHealthCheckService* service) - : service_(service), method_(nullptr) { - internal::MethodHandler* handler = - new internal::RpcMethodHandler( - std::mem_fn(&HealthCheckServiceImpl::Check), this); - method_ = new internal::RpcServiceMethod( - kHealthCheckMethodName, internal::RpcMethod::NORMAL_RPC, handler); - AddMethod(method_); -} - -Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( - ServerContext* context, const ByteBuffer* request, ByteBuffer* response) { - // Decode request. - std::vector slices; - if (!request->Dump(&slices).ok()) { - return Status(StatusCode::INVALID_ARGUMENT, ""); + DefaultHealthCheckService* database, + std::unique_ptr cq) + : database_(database), cq_(std::move(cq)) { + // Add Check() method. + check_method_ = new internal::RpcServiceMethod( + kHealthCheckMethodName, internal::RpcMethod::NORMAL_RPC, nullptr); + AddMethod(check_method_); + // Add Watch() method. + watch_method_ = new internal::RpcServiceMethod( + kHealthWatchMethodName, internal::RpcMethod::SERVER_STREAMING, nullptr); + AddMethod(watch_method_); + // Create serving thread. + thread_ = std::unique_ptr<::grpc_core::Thread>( + new ::grpc_core::Thread("grpc_health_check_service", Serve, this)); +} + +DefaultHealthCheckService::HealthCheckServiceImpl::~HealthCheckServiceImpl() { + // We will reach here after the server starts shutting down. + shutdown_ = true; + { + std::unique_lock lock(cq_shutdown_mu_); + cq_->Shutdown(); + } + thread_->Join(); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::StartServingThread() { + thread_->Start(); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::Serve(void* arg) { + HealthCheckServiceImpl* service = + reinterpret_cast(arg); + // TODO(juanlishen): This is a workaround to wait for the cq to be ready. + // Need to figure out why cq is not ready after service starts. + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_seconds(1, GPR_TIMESPAN))); + CheckCallHandler::CreateAndStart(service->cq_.get(), service->database_, + service); + WatchCallHandler::CreateAndStart(service->cq_.get(), service->database_, + service); + void* tag; + bool ok; + while (true) { + if (!service->cq_->Next(&tag, &ok)) { + // The completion queue is shutting down. + GPR_ASSERT(service->shutdown_); + break; + } + auto* next_step = static_cast(tag); + next_step->Run(ok); } +} + +bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest( + const ByteBuffer& request, grpc::string* service_name) { + std::vector slices; + if (!request.Dump(&slices).ok()) return false; uint8_t* request_bytes = nullptr; bool request_bytes_owned = false; size_t request_size = 0; @@ -64,14 +197,13 @@ Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( request_size = slices[0].size(); } else { request_bytes_owned = true; - request_bytes = static_cast(gpr_malloc(request->Length())); + request_bytes = static_cast(gpr_malloc(request.Length())); uint8_t* copy_to = request_bytes; for (size_t i = 0; i < slices.size(); i++) { memcpy(copy_to, slices[i].begin(), slices[i].size()); copy_to += slices[i].size(); } } - if (request_bytes != nullptr) { pb_istream_t istream = pb_istream_from_buffer(request_bytes, request_size); bool decode_status = pb_decode( @@ -79,26 +211,22 @@ Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( if (request_bytes_owned) { gpr_free(request_bytes); } - if (!decode_status) { - return Status(StatusCode::INVALID_ARGUMENT, ""); - } - } - - // Check status from the associated default health checking service. - DefaultHealthCheckService::ServingStatus serving_status = - service_->GetServingStatus( - request_struct.has_service ? request_struct.service : ""); - if (serving_status == DefaultHealthCheckService::NOT_FOUND) { - return Status(StatusCode::NOT_FOUND, ""); + if (!decode_status) return false; } + *service_name = request_struct.has_service ? request_struct.service : ""; + return true; +} - // Encode response +bool DefaultHealthCheckService::HealthCheckServiceImpl::EncodeResponse( + ServingStatus status, ByteBuffer* response) { grpc_health_v1_HealthCheckResponse response_struct; response_struct.has_status = true; response_struct.status = - serving_status == DefaultHealthCheckService::SERVING - ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING - : grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING; + status == NOT_FOUND + ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN + : status == SERVING + ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING + : grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING; pb_ostream_t ostream; memset(&ostream, 0, sizeof(ostream)); pb_encode(&ostream, grpc_health_v1_HealthCheckResponse_fields, @@ -108,48 +236,282 @@ Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( GRPC_SLICE_LENGTH(response_slice)); bool encode_status = pb_encode( &ostream, grpc_health_v1_HealthCheckResponse_fields, &response_struct); - if (!encode_status) { - return Status(StatusCode::INTERNAL, "Failed to encode response."); - } + if (!encode_status) return false; Slice encoded_response(response_slice, Slice::STEAL_REF); ByteBuffer response_buffer(&encoded_response, 1); response->Swap(&response_buffer); - return Status::OK; + return true; } -DefaultHealthCheckService::DefaultHealthCheckService() { - services_map_.emplace("", true); +// +// DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler +// + +void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: + CreateAndStart(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service) { + std::shared_ptr self = + std::make_shared(cq, database, service); + CheckCallHandler* handler = static_cast(self.get()); + { + std::unique_lock lock(service->cq_shutdown_mu_); + if (service->shutdown_) return; + // Request a Check() call. + handler->next_ = + CallableTag(std::bind(&CheckCallHandler::OnCallReceived, handler, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + service->RequestAsyncUnary(0, &handler->ctx_, &handler->request_, + &handler->writer_, cq, cq, &handler->next_); + } } -void DefaultHealthCheckService::SetServingStatus( - const grpc::string& service_name, bool serving) { - std::lock_guard lock(mu_); - services_map_[service_name] = serving; +DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: + CheckCallHandler(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service) + : cq_(cq), database_(database), service_(service), writer_(&ctx_) {} + +void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: + OnCallReceived(std::shared_ptr self, bool ok) { + if (!ok) { + // The value of ok being false means that the server is shutting down. + return; + } + // Spawn a new handler instance to serve the next new client. Every handler + // instance will deallocate itself when it's done. + CreateAndStart(cq_, database_, service_); + // Process request. + gpr_log(GPR_DEBUG, "[HCS %p] Health check started for handler %p", service_, + this); + grpc::string service_name; + grpc::Status status = Status::OK; + ByteBuffer response; + if (!service_->DecodeRequest(request_, &service_name)) { + status = Status(INVALID_ARGUMENT, ""); + } else { + ServingStatus serving_status = database_->GetServingStatus(service_name); + if (serving_status == NOT_FOUND) { + status = Status(StatusCode::NOT_FOUND, "service name unknown"); + } else if (!service_->EncodeResponse(serving_status, &response)) { + status = Status(INTERNAL, ""); + } + } + // Send response. + { + std::unique_lock lock(service_->cq_shutdown_mu_); + if (!service_->shutdown_) { + next_ = + CallableTag(std::bind(&CheckCallHandler::OnFinishDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + if (status.ok()) { + writer_.Finish(response, status, &next_); + } else { + writer_.FinishWithError(status, &next_); + } + } + } } -void DefaultHealthCheckService::SetServingStatus(bool serving) { - std::lock_guard lock(mu_); - for (auto iter = services_map_.begin(); iter != services_map_.end(); ++iter) { - iter->second = serving; +void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: + OnFinishDone(std::shared_ptr self, bool ok) { + if (ok) { + gpr_log(GPR_DEBUG, "[HCS %p] Health check call finished for handler %p", + service_, this); } } -DefaultHealthCheckService::ServingStatus -DefaultHealthCheckService::GetServingStatus( - const grpc::string& service_name) const { - std::lock_guard lock(mu_); - const auto& iter = services_map_.find(service_name); - if (iter == services_map_.end()) { - return NOT_FOUND; +// +// DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler +// + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + CreateAndStart(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service) { + std::shared_ptr self = + std::make_shared(cq, database, service); + WatchCallHandler* handler = static_cast(self.get()); + { + std::unique_lock lock(service->cq_shutdown_mu_); + if (service->shutdown_) return; + // Request AsyncNotifyWhenDone(). + handler->on_done_notified_ = + CallableTag(std::bind(&WatchCallHandler::OnDoneNotified, handler, + std::placeholders::_1, std::placeholders::_2), + self /* copies ref */); + handler->ctx_.AsyncNotifyWhenDone(&handler->on_done_notified_); + // Request a Watch() call. + handler->next_ = + CallableTag(std::bind(&WatchCallHandler::OnCallReceived, handler, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + service->RequestAsyncServerStreaming(1, &handler->ctx_, &handler->request_, + &handler->stream_, cq, cq, + &handler->next_); } - return iter->second ? SERVING : NOT_SERVING; } -DefaultHealthCheckService::HealthCheckServiceImpl* -DefaultHealthCheckService::GetHealthCheckService() { - GPR_ASSERT(impl_ == nullptr); - impl_.reset(new HealthCheckServiceImpl(this)); - return impl_.get(); +DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + WatchCallHandler(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service) + : cq_(cq), + database_(database), + service_(service), + stream_(&ctx_), + call_state_(WAITING_FOR_CALL) {} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + OnCallReceived(std::shared_ptr self, bool ok) { + if (ok) { + call_state_ = CALL_RECEIVED; + } else { + // AsyncNotifyWhenDone() needs to be called before the call starts, but the + // tag will not pop out if the call never starts ( + // https://github.com/grpc/grpc/issues/10136). So we need to manually + // release the ownership of the handler in this case. + GPR_ASSERT(on_done_notified_.ReleaseHandler() != nullptr); + } + if (!ok || shutdown_) { + // The value of ok being false means that the server is shutting down. + Shutdown(std::move(self), "OnCallReceived"); + return; + } + // Spawn a new handler instance to serve the next new client. Every handler + // instance will deallocate itself when it's done. + CreateAndStart(cq_, database_, service_); + // Parse request. + if (!service_->DecodeRequest(request_, &service_name_)) { + on_finish_done_ = + CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + stream_.Finish(Status(INVALID_ARGUMENT, ""), &on_finish_done_); + call_state_ = FINISH_CALLED; + return; + } + // Register the call for updates to the service. + gpr_log(GPR_DEBUG, + "[HCS %p] Health check watch started for service \"%s\" " + "(handler: %p)", + service_, service_name_.c_str(), this); + database_->RegisterCallHandler(service_name_, std::move(self)); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + SendHealth(std::shared_ptr self, ServingStatus status) { + std::unique_lock lock(mu_); + // If there's already a send in flight, cache the new status, and + // we'll start a new send for it when the one in flight completes. + if (send_in_flight_) { + pending_status_ = status; + return; + } + // Start a send. + SendHealthLocked(std::move(self), status); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + SendHealthLocked(std::shared_ptr self, ServingStatus status) { + std::unique_lock cq_lock(service_->cq_shutdown_mu_); + if (service_->shutdown_) { + cq_lock.release()->unlock(); + Shutdown(std::move(self), "SendHealthLocked"); + return; + } + send_in_flight_ = true; + call_state_ = SEND_MESSAGE_PENDING; + // Construct response. + ByteBuffer response; + if (!service_->EncodeResponse(status, &response)) { + on_finish_done_ = + CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + stream_.Finish(Status(INTERNAL, ""), &on_finish_done_); + return; + } + next_ = CallableTag(std::bind(&WatchCallHandler::OnSendHealthDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + stream_.Write(response, &next_); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + OnSendHealthDone(std::shared_ptr self, bool ok) { + if (!ok || shutdown_) { + Shutdown(std::move(self), "OnSendHealthDone"); + return; + } + call_state_ = CALL_RECEIVED; + { + std::unique_lock lock(mu_); + send_in_flight_ = false; + // If we got a new status since we started the last send, start a + // new send for it. + if (pending_status_ != NOT_FOUND) { + auto status = pending_status_; + pending_status_ = NOT_FOUND; + SendHealthLocked(std::move(self), status); + } + } +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + OnDoneNotified(std::shared_ptr self, bool ok) { + GPR_ASSERT(ok); + done_notified_ = true; + if (ctx_.IsCancelled()) { + is_cancelled_ = true; + } + gpr_log(GPR_DEBUG, + "[HCS %p] Healt check call is notified done (handler: %p, " + "is_cancelled: %d).", + service_, this, static_cast(is_cancelled_)); + Shutdown(std::move(self), "OnDoneNotified"); +} + +// TODO(roth): This method currently assumes that there will be only one +// thread polling the cq and invoking the corresponding callbacks. If +// that changes, we will need to add synchronization here. +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + Shutdown(std::shared_ptr self, const char* reason) { + if (!shutdown_) { + gpr_log(GPR_DEBUG, + "[HCS %p] Shutting down the handler (service_name: \"%s\", " + "handler: %p, reason: %s).", + service_, service_name_.c_str(), this, reason); + shutdown_ = true; + } + // OnCallReceived() may be called after OnDoneNotified(), so we need to + // try to Finish() every time we are in Shutdown(). + if (call_state_ >= CALL_RECEIVED && call_state_ < FINISH_CALLED) { + std::unique_lock lock(service_->cq_shutdown_mu_); + if (!service_->shutdown_) { + on_finish_done_ = + CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + // TODO(juanlishen): Maybe add a message proto for the client to + // explicitly cancel the stream so that we can return OK status in such + // cases. + stream_.Finish(Status::CANCELLED, &on_finish_done_); + call_state_ = FINISH_CALLED; + } + } +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + OnFinishDone(std::shared_ptr self, bool ok) { + if (ok) { + gpr_log(GPR_DEBUG, + "[HCS %p] Health check call finished (service_name: \"%s\", " + "handler: %p).", + service_, service_name_.c_str(), this); + } } } // namespace grpc diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index a1ce5aa64ec..edad5949362 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -19,42 +19,268 @@ #ifndef GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H #define GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H +#include #include +#include +#include +#include #include +#include +#include #include #include +#include "src/core/lib/gprpp/thd.h" + namespace grpc { // Default implementation of HealthCheckServiceInterface. Server will create and // own it. class DefaultHealthCheckService final : public HealthCheckServiceInterface { public: + enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; + // The service impl to register with the server. class HealthCheckServiceImpl : public Service { public: - explicit HealthCheckServiceImpl(DefaultHealthCheckService* service); + // Base class for call handlers. + class CallHandler { + public: + virtual ~CallHandler() = default; + virtual void SendHealth(std::shared_ptr self, + ServingStatus status) = 0; + }; - Status Check(ServerContext* context, const ByteBuffer* request, - ByteBuffer* response); + HealthCheckServiceImpl(DefaultHealthCheckService* database, + std::unique_ptr cq); + + ~HealthCheckServiceImpl(); + + void StartServingThread(); private: - const DefaultHealthCheckService* const service_; - internal::RpcServiceMethod* method_; + // A tag that can be called with a bool argument. It's tailored for + // CallHandler's use. Before being used, it should be constructed with a + // method of CallHandler and a shared pointer to the handler. The + // shared pointer will be moved to the invoked function and the function + // can only be invoked once. That makes ref counting of the handler easier, + // because the shared pointer is not bound to the function and can be gone + // once the invoked function returns (if not used any more). + class CallableTag { + public: + using HandlerFunction = + std::function, bool)>; + + CallableTag() {} + + CallableTag(HandlerFunction func, std::shared_ptr handler) + : handler_function_(std::move(func)), handler_(std::move(handler)) { + GPR_ASSERT(handler_function_ != nullptr); + GPR_ASSERT(handler_ != nullptr); + } + + // Runs the tag. This should be called only once. The handler is no + // longer owned by this tag after this method is invoked. + void Run(bool ok) { + GPR_ASSERT(handler_function_ != nullptr); + GPR_ASSERT(handler_ != nullptr); + handler_function_(std::move(handler_), ok); + } + + // Releases and returns the shared pointer to the handler. + std::shared_ptr ReleaseHandler() { + return std::move(handler_); + } + + private: + HandlerFunction handler_function_ = nullptr; + std::shared_ptr handler_; + }; + + // Call handler for Check method. + // Each handler takes care of one call. It contains per-call data and it + // will access the members of the parent class (i.e., + // DefaultHealthCheckService) for per-service health data. + class CheckCallHandler : public CallHandler { + public: + // Instantiates a CheckCallHandler and requests the next health check + // call. The handler object will manage its own lifetime, so no action is + // needed from the caller any more regarding that object. + static void CreateAndStart(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service); + + // This ctor is public because we want to use std::make_shared<> in + // CreateAndStart(). This ctor shouldn't be used elsewhere. + CheckCallHandler(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service); + + // Not used for Check. + void SendHealth(std::shared_ptr self, + ServingStatus status) override {} + + private: + // Called when we receive a call. + // Spawns a new handler so that we can keep servicing future calls. + void OnCallReceived(std::shared_ptr self, bool ok); + + // Called when Finish() is done. + void OnFinishDone(std::shared_ptr self, bool ok); + + // The members passed down from HealthCheckServiceImpl. + ServerCompletionQueue* cq_; + DefaultHealthCheckService* database_; + HealthCheckServiceImpl* service_; + + ByteBuffer request_; + GenericServerAsyncResponseWriter writer_; + ServerContext ctx_; + + CallableTag next_; + }; + + // Call handler for Watch method. + // Each handler takes care of one call. It contains per-call data and it + // will access the members of the parent class (i.e., + // DefaultHealthCheckService) for per-service health data. + class WatchCallHandler : public CallHandler { + public: + // Instantiates a WatchCallHandler and requests the next health check + // call. The handler object will manage its own lifetime, so no action is + // needed from the caller any more regarding that object. + static void CreateAndStart(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service); + + // This ctor is public because we want to use std::make_shared<> in + // CreateAndStart(). This ctor shouldn't be used elsewhere. + WatchCallHandler(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service); + + void SendHealth(std::shared_ptr self, + ServingStatus status) override; + + private: + // Called when we receive a call. + // Spawns a new handler so that we can keep servicing future calls. + void OnCallReceived(std::shared_ptr self, bool ok); + + // Requires holding mu_. + void SendHealthLocked(std::shared_ptr self, + ServingStatus status); + + // When sending a health result finishes. + void OnSendHealthDone(std::shared_ptr self, bool ok); + + // Called when Finish() is done. + void OnFinishDone(std::shared_ptr self, bool ok); + + // Called when AsyncNotifyWhenDone() notifies us. + void OnDoneNotified(std::shared_ptr self, bool ok); + + void Shutdown(std::shared_ptr self, const char* reason); + + // The members passed down from HealthCheckServiceImpl. + ServerCompletionQueue* cq_; + DefaultHealthCheckService* database_; + HealthCheckServiceImpl* service_; + + ByteBuffer request_; + grpc::string service_name_; + GenericServerAsyncWriter stream_; + ServerContext ctx_; + + std::mutex mu_; + bool send_in_flight_ = false; // Guarded by mu_. + ServingStatus pending_status_ = NOT_FOUND; // Guarded by mu_. + + // The state of the RPC progress. + enum CallState { + WAITING_FOR_CALL, + CALL_RECEIVED, + SEND_MESSAGE_PENDING, + FINISH_CALLED + } call_state_; + + bool shutdown_ = false; + bool done_notified_ = false; + bool is_cancelled_ = false; + CallableTag next_; + CallableTag on_done_notified_; + CallableTag on_finish_done_; + }; + + // Handles the incoming requests and drives the completion queue in a loop. + static void Serve(void* arg); + + // Returns true on success. + static bool DecodeRequest(const ByteBuffer& request, + grpc::string* service_name); + static bool EncodeResponse(ServingStatus status, ByteBuffer* response); + + // Needed to appease Windows compilers, which don't seem to allow + // nested classes to access protected members in the parent's + // superclass. + using Service::RequestAsyncServerStreaming; + using Service::RequestAsyncUnary; + + DefaultHealthCheckService* database_; + std::unique_ptr cq_; + internal::RpcServiceMethod* check_method_; + internal::RpcServiceMethod* watch_method_; + + // To synchronize the operations related to shutdown state of cq_, so that + // we don't enqueue new tags into cq_ after it is already shut down. + std::mutex cq_shutdown_mu_; + std::atomic_bool shutdown_{false}; + std::unique_ptr<::grpc_core::Thread> thread_; }; DefaultHealthCheckService(); + void SetServingStatus(const grpc::string& service_name, bool serving) override; void SetServingStatus(bool serving) override; - enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; + ServingStatus GetServingStatus(const grpc::string& service_name) const; - HealthCheckServiceImpl* GetHealthCheckService(); + + HealthCheckServiceImpl* GetHealthCheckService( + std::unique_ptr cq); private: + // Stores the current serving status of a service and any call + // handlers registered for updates when the service's status changes. + class ServiceData { + public: + void SetServingStatus(ServingStatus status); + ServingStatus GetServingStatus() const { return status_; } + void AddCallHandler( + std::shared_ptr handler); + void RemoveCallHandler( + std::shared_ptr handler); + bool Unused() const { + return call_handlers_.empty() && status_ == NOT_FOUND; + } + + private: + ServingStatus status_ = NOT_FOUND; + std::set> + call_handlers_; + }; + + void RegisterCallHandler( + const grpc::string& service_name, + std::shared_ptr handler); + + void UnregisterCallHandler( + const grpc::string& service_name, + std::shared_ptr handler); + mutable std::mutex mu_; - std::map services_map_; + std::map services_map_; // Guarded by mu_. std::unique_ptr impl_; }; diff --git a/src/cpp/server/health/health.pb.c b/src/cpp/server/health/health.pb.c index 09bd98a3d97..5c214c7160f 100644 --- a/src/cpp/server/health/health.pb.c +++ b/src/cpp/server/health/health.pb.c @@ -2,7 +2,6 @@ /* Generated by nanopb-0.3.7-dev */ #include "src/cpp/server/health/health.pb.h" - /* @@protoc_insertion_point(includes) */ #if PB_PROTO_HEADER_VERSION != 30 #error Regenerate this file with the current version of nanopb generator. diff --git a/src/cpp/server/health/health.pb.h b/src/cpp/server/health/health.pb.h index 29e1f3bacb1..9d54ccd6182 100644 --- a/src/cpp/server/health/health.pb.h +++ b/src/cpp/server/health/health.pb.h @@ -17,11 +17,12 @@ extern "C" { typedef enum _grpc_health_v1_HealthCheckResponse_ServingStatus { grpc_health_v1_HealthCheckResponse_ServingStatus_UNKNOWN = 0, grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING = 1, - grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING = 2 + grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING = 2, + grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN = 3 } grpc_health_v1_HealthCheckResponse_ServingStatus; #define _grpc_health_v1_HealthCheckResponse_ServingStatus_MIN grpc_health_v1_HealthCheckResponse_ServingStatus_UNKNOWN -#define _grpc_health_v1_HealthCheckResponse_ServingStatus_MAX grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING -#define _grpc_health_v1_HealthCheckResponse_ServingStatus_ARRAYSIZE ((grpc_health_v1_HealthCheckResponse_ServingStatus)(grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING+1)) +#define _grpc_health_v1_HealthCheckResponse_ServingStatus_MAX grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN +#define _grpc_health_v1_HealthCheckResponse_ServingStatus_ARRAYSIZE ((grpc_health_v1_HealthCheckResponse_ServingStatus)(grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN+1)) /* Struct definitions */ typedef struct _grpc_health_v1_HealthCheckRequest { diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index b8ba7042d90..48f0f110a6c 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -559,16 +559,20 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { // Only create default health check service when user did not provide an // explicit one. + ServerCompletionQueue* health_check_cq = nullptr; + DefaultHealthCheckService::HealthCheckServiceImpl* + default_health_check_service_impl = nullptr; if (health_check_service_ == nullptr && !health_check_service_disabled_ && DefaultHealthCheckServiceEnabled()) { - if (sync_server_cqs_ == nullptr || sync_server_cqs_->empty()) { - gpr_log(GPR_INFO, - "Default health check service disabled at async-only server."); - } else { - auto* default_hc_service = new DefaultHealthCheckService; - health_check_service_.reset(default_hc_service); - RegisterService(nullptr, default_hc_service->GetHealthCheckService()); - } + auto* default_hc_service = new DefaultHealthCheckService; + health_check_service_.reset(default_hc_service); + health_check_cq = new ServerCompletionQueue(GRPC_CQ_DEFAULT_POLLING); + grpc_server_register_completion_queue(server_, health_check_cq->cq(), + nullptr); + default_health_check_service_impl = + default_hc_service->GetHealthCheckService( + std::unique_ptr(health_check_cq)); + RegisterService(nullptr, default_health_check_service_impl); } grpc_server_start(server_); @@ -583,6 +587,9 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { new UnimplementedAsyncRequest(this, cqs[i]); } } + if (health_check_cq != nullptr) { + new UnimplementedAsyncRequest(this, health_check_cq); + } } // If this server has any support for synchronous methods (has any sync @@ -595,6 +602,10 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { (*it)->Start(); } + + if (default_health_check_service_impl != nullptr) { + default_health_check_service_impl->StartServingThread(); + } } void Server::ShutdownInternal(gpr_timespec deadline) { diff --git a/src/proto/grpc/health/v1/health.proto b/src/proto/grpc/health/v1/health.proto index 4b4677b8a4d..38843ff1e73 100644 --- a/src/proto/grpc/health/v1/health.proto +++ b/src/proto/grpc/health/v1/health.proto @@ -34,10 +34,30 @@ message HealthCheckResponse { UNKNOWN = 0; SERVING = 1; NOT_SERVING = 2; + SERVICE_UNKNOWN = 3; // Used only by the Watch method. } ServingStatus status = 1; } service Health { + // If the requested service is unknown, the call will fail with status + // NOT_FOUND. rpc Check(HealthCheckRequest) returns (HealthCheckResponse); + + // Performs a watch for the serving status of the requested service. + // The server will immediately send back a message indicating the current + // serving status. It will then subsequently send a new message whenever + // the service's serving status changes. + // + // If the requested service is unknown when the call is received, the + // server will send a message setting the serving status to + // SERVICE_UNKNOWN but will *not* terminate the call. If at some + // future point, the serving status of the service becomes known, the + // server will send a new message with the service's serving status. + // + // If the call terminates with status UNIMPLEMENTED, then clients + // should assume this method is not supported and should not retry the + // call. If the call terminates with any other status (including OK), + // clients should retry the call with appropriate exponential backoff. + rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); } diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index 1c48b9d151a..fca65dfc13b 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -64,6 +64,29 @@ class HealthCheckServiceImpl : public ::grpc::health::v1::Health::Service { return Status::OK; } + Status Watch(ServerContext* context, const HealthCheckRequest* request, + ::grpc::ServerWriter* writer) override { + auto last_state = HealthCheckResponse::UNKNOWN; + while (!context->IsCancelled()) { + { + std::lock_guard lock(mu_); + HealthCheckResponse response; + auto iter = status_map_.find(request->service()); + if (iter == status_map_.end()) { + response.set_status(response.SERVICE_UNKNOWN); + } else { + response.set_status(iter->second); + } + if (response.status() != last_state) { + writer->Write(response, ::grpc::WriteOptions()); + } + } + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis(1000, GPR_TIMESPAN))); + } + return Status::OK; + } + void SetStatus(const grpc::string& service_name, HealthCheckResponse::ServingStatus status) { std::lock_guard lock(mu_); @@ -106,14 +129,6 @@ class CustomHealthCheckService : public HealthCheckServiceInterface { HealthCheckServiceImpl* impl_; // not owned }; -void LoopCompletionQueue(ServerCompletionQueue* cq) { - void* tag; - bool ok; - while (cq->Next(&tag, &ok)) { - abort(); // Nothing should come out of the cq. - } -} - class HealthServiceEnd2endTest : public ::testing::Test { protected: HealthServiceEnd2endTest() {} @@ -218,6 +233,33 @@ class HealthServiceEnd2endTest : public ::testing::Test { Status(StatusCode::NOT_FOUND, "")); } + void VerifyHealthCheckServiceStreaming() { + const grpc::string kServiceName("service_name"); + HealthCheckServiceInterface* service = server_->GetHealthCheckService(); + // Start Watch for service. + ClientContext context; + HealthCheckRequest request; + request.set_service(kServiceName); + std::unique_ptr<::grpc::ClientReaderInterface> reader = + hc_stub_->Watch(&context, request); + // Initial response will be SERVICE_UNKNOWN. + HealthCheckResponse response; + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.SERVICE_UNKNOWN, response.status()); + response.Clear(); + // Now set service to NOT_SERVING and make sure we get an update. + service->SetServingStatus(kServiceName, false); + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.NOT_SERVING, response.status()); + response.Clear(); + // Now set service to SERVING and make sure we get another update. + service->SetServingStatus(kServiceName, true); + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.SERVING, response.status()); + // Finish call. + context.TryCancel(); + } + TestServiceImpl echo_test_service_; HealthCheckServiceImpl health_check_service_impl_; std::unique_ptr hc_stub_; @@ -245,6 +287,7 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); SetUpServer(true, false, false, nullptr); VerifyHealthCheckService(); + VerifyHealthCheckServiceStreaming(); // The default service has a size limit of the service name. const grpc::string kTooLongServiceName(201, 'x'); @@ -252,22 +295,6 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { Status(StatusCode::INVALID_ARGUMENT, "")); } -// The server has no sync service. -TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceAsyncOnly) { - EnableDefaultHealthCheckService(true); - EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); - SetUpServer(false, true, false, nullptr); - cq_thread_ = std::thread(LoopCompletionQueue, cq_.get()); - - HealthCheckServiceInterface* default_service = - server_->GetHealthCheckService(); - EXPECT_TRUE(default_service == nullptr); - - ResetStubs(); - - SendHealthCheckRpc("", Status(StatusCode::UNIMPLEMENTED, "")); -} - // Provide an empty service to disable the default service. TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) { EnableDefaultHealthCheckService(true); @@ -296,6 +323,7 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) { ResetStubs(); VerifyHealthCheckService(); + VerifyHealthCheckServiceStreaming(); } } // namespace diff --git a/tools/distrib/check_nanopb_output.sh b/tools/distrib/check_nanopb_output.sh index 6b98619c320..1c2ef9b7686 100755 --- a/tools/distrib/check_nanopb_output.sh +++ b/tools/distrib/check_nanopb_output.sh @@ -16,6 +16,7 @@ set -ex readonly NANOPB_ALTS_TMP_OUTPUT="$(mktemp -d)" +readonly NANOPB_HEALTH_TMP_OUTPUT="$(mktemp -d)" readonly NANOPB_TMP_OUTPUT="$(mktemp -d)" readonly PROTOBUF_INSTALL_PREFIX="$(mktemp -d)" @@ -67,6 +68,23 @@ if ! diff -r "$NANOPB_TMP_OUTPUT" src/core/ext/filters/client_channel/lb_policy/ exit 2 fi +# +# checks for health.proto +# +readonly HEALTH_GRPC_OUTPUT_PATH='src/cpp/server/health' +# nanopb-compile the proto to a temp location +./tools/codegen/core/gen_nano_proto.sh \ + src/proto/grpc/health/v1/health.proto \ + "$NANOPB_HEALTH_TMP_OUTPUT" \ + "$HEALTH_GRPC_OUTPUT_PATH" +# compare outputs to checked compiled code +for NANOPB_OUTPUT_FILE in $NANOPB_HEALTH_TMP_OUTPUT/*.pb.*; do + if ! diff "$NANOPB_OUTPUT_FILE" "src/cpp/server/health/$(basename $NANOPB_OUTPUT_FILE)"; then + echo "Outputs differ: $NANOPB_HEALTH_TMP_OUTPUT vs $HEALTH_GRPC_OUTPUT_PATH" + exit 2 + fi +done + # # Checks for handshaker.proto and transport_security_common.proto # From 7975c6ad98daef400ec755b215f9a7de4b32f511 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 5 Sep 2018 10:33:38 -0700 Subject: [PATCH 298/546] Fix internal build breakage from #16351. --- src/cpp/server/health/default_health_check_service.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index 670da63a4a0..fc3db1bba73 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -289,13 +289,13 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: grpc::Status status = Status::OK; ByteBuffer response; if (!service_->DecodeRequest(request_, &service_name)) { - status = Status(INVALID_ARGUMENT, ""); + status = Status(StatusCode::INVALID_ARGUMENT, ""); } else { ServingStatus serving_status = database_->GetServingStatus(service_name); if (serving_status == NOT_FOUND) { status = Status(StatusCode::NOT_FOUND, "service name unknown"); } else if (!service_->EncodeResponse(serving_status, &response)) { - status = Status(INTERNAL, ""); + status = Status(StatusCode::INTERNAL, ""); } } // Send response. @@ -389,7 +389,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, std::placeholders::_1, std::placeholders::_2), std::move(self)); - stream_.Finish(Status(INVALID_ARGUMENT, ""), &on_finish_done_); + stream_.Finish(Status(StatusCode::INVALID_ARGUMENT, ""), &on_finish_done_); call_state_ = FINISH_CALLED; return; } @@ -431,7 +431,7 @@ void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, std::placeholders::_1, std::placeholders::_2), std::move(self)); - stream_.Finish(Status(INTERNAL, ""), &on_finish_done_); + stream_.Finish(Status(StatusCode::INTERNAL, ""), &on_finish_done_); return; } next_ = CallableTag(std::bind(&WatchCallHandler::OnSendHealthDone, this, From 605a42d90a01bc9cc7d34f53de39c25d59c09269 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 1 Sep 2018 13:48:05 +0200 Subject: [PATCH 299/546] fix #13939 --- include/grpcpp/impl/codegen/async_stream.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index b2134590c3c..b306cd3604f 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -195,6 +195,13 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface { assert(size == sizeof(ClientAsyncReader)); } + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + void StartCall(void* tag) override { assert(!started_); started_ = true; @@ -336,6 +343,13 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface { assert(size == sizeof(ClientAsyncWriter)); } + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + void StartCall(void* tag) override { assert(!started_); started_ = true; @@ -496,6 +510,13 @@ class ClientAsyncReaderWriter final assert(size == sizeof(ClientAsyncReaderWriter)); } + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + void StartCall(void* tag) override { assert(!started_); started_ = true; From 1c24373821d2fba434dc6bf4174bd88e9a4d4de9 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 5 Sep 2018 14:49:38 -0700 Subject: [PATCH 300/546] excluded asan and tsan for qps tests --- tools/internal_ci/linux/grpc_asan_on_foundry.sh | 3 ++- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 3 ++- tools/internal_ci/linux/grpc_tsan_on_foundry.sh | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) mode change 100644 => 100755 tools/internal_ci/linux/grpc_asan_on_foundry.sh diff --git a/tools/internal_ci/linux/grpc_asan_on_foundry.sh b/tools/internal_ci/linux/grpc_asan_on_foundry.sh old mode 100644 new mode 100755 index a6367ad9628..d90a37305f8 --- a/tools/internal_ci/linux/grpc_asan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_asan_on_foundry.sh @@ -15,5 +15,6 @@ export UPLOAD_TEST_RESULTS=true EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address --test_timeout=3600 --cache_test_results=no" -github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" +EXCLUDE_TESTS="-//test/cpp/qps/..." +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 8b427793664..3fa1b2a10d5 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -61,7 +61,8 @@ export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instan --test_env=GRPC_VERBOSITY=debug \ --remote_instance_name=projects/grpc-testing/instances/default_instance \ $1 \ - -- //test/... || FAILED="true" + -- //test/... \ + $2 || FAILED="true" if [ "$UPLOAD_TEST_RESULTS" != "" ] then diff --git a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh index 2ba7d469ecf..eaeaca914ad 100644 --- a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh @@ -15,4 +15,5 @@ export UPLOAD_TEST_RESULTS=true EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=thread --linkopt=-fsanitize=thread --test_timeout=3600 --action_env=TSAN_OPTIONS=suppressions=test/core/util/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1 --cache_test_results=no" -github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" +EXCLUDE_TESTS="-//test/cpp/qps/..." +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" From 888ffabd80b5597a139f1c280d8c82c5ac2124f5 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Wed, 5 Sep 2018 15:33:01 -0700 Subject: [PATCH 301/546] appended exclusion rules to pull_request scripts --- tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh | 3 ++- tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh index 2aebb65552e..4c788a4a722 100644 --- a/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh @@ -14,5 +14,6 @@ # limitations under the License. EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address --test_timeout=3600" -github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" +EXCLUDE_TESTS="-//test/cpp/qps/..." +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" diff --git a/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh index edd8f929753..9a78663ab4e 100644 --- a/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh @@ -14,4 +14,5 @@ # limitations under the License. EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=thread --linkopt=-fsanitize=thread --test_timeout=3600 --action_env=TSAN_OPTIONS=suppressions=test/core/util/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1" -github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" +EXCLUDE_TESTS="-//test/cpp/qps/..." +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" From c9e300d5b044351c6e09221b09ba49e53d211643 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 5 Sep 2018 17:08:01 -0700 Subject: [PATCH 302/546] Add channel arg control for user agent --- include/grpc/impl/codegen/grpc_types.h | 2 ++ .../ext/filters/http/server/http_server_filter.cc | 15 +++++++++++++-- .../tests/workaround_cronet_compression.cc | 9 +++++++++ test/cpp/end2end/end2end_test.cc | 13 ++++++++++--- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index b5353c1dea8..9097984a96b 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -342,6 +342,8 @@ typedef struct { "grpc.disable_client_authority_filter" /** If set to zero, disables use of http proxies. Enabled by default. */ #define GRPC_ARG_ENABLE_HTTP_PROXY "grpc.enable_http_proxy" +/** If set to non zero, surfaces the user agent string to the server. */ +#define GRPC_ARG_SURFACE_USER_AGENT "grpc.surface_user_agent" /** \} */ /** Result of a grpc call. If the caller satisfies the prerequisites of a 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 a238d5f989f..53cd059aa80 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -23,6 +23,7 @@ #include #include #include +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/b64.h" @@ -66,6 +67,10 @@ struct call_data { grpc_closure* original_recv_trailing_metadata_ready; }; +struct channel_data { + bool surface_user_agent; +}; + } // namespace static grpc_error* hs_filter_outgoing_metadata(grpc_call_element* elem, @@ -262,7 +267,8 @@ static grpc_error* hs_filter_incoming_metadata(grpc_call_element* elem, GRPC_ERROR_STR_KEY, grpc_slice_from_static_string(":authority"))); } - if (b->idx.named.user_agent != nullptr) { + channel_data* chand = static_cast(elem->channel_data); + if (!chand->surface_user_agent && b->idx.named.user_agent != nullptr) { grpc_metadata_batch_remove(b, b->idx.named.user_agent); } @@ -434,7 +440,12 @@ static void hs_destroy_call_elem(grpc_call_element* elem, /* Constructor for channel_data */ static grpc_error* hs_init_channel_elem(grpc_channel_element* elem, grpc_channel_element_args* args) { + channel_data* chand = static_cast(elem->channel_data); GPR_ASSERT(!args->is_last); + chand->surface_user_agent = grpc_channel_arg_get_bool( + grpc_channel_args_find(args->channel_args, + const_cast(GRPC_ARG_SURFACE_USER_AGENT)), + false); return GRPC_ERROR_NONE; } @@ -448,7 +459,7 @@ const grpc_channel_filter grpc_http_server_filter = { hs_init_call_elem, grpc_call_stack_ignore_set_pollset_or_pollset_set, hs_destroy_call_elem, - 0, + sizeof(channel_data), hs_init_channel_elem, hs_destroy_channel_elem, grpc_channel_next_get_info, diff --git a/test/core/end2end/tests/workaround_cronet_compression.cc b/test/core/end2end/tests/workaround_cronet_compression.cc index f44ddca3b10..e1bce603fa7 100644 --- a/test/core/end2end/tests/workaround_cronet_compression.cc +++ b/test/core/end2end/tests/workaround_cronet_compression.cc @@ -149,6 +149,15 @@ static void request_with_payload_template( arg.value.string = user_agent_override; client_args = grpc_channel_args_copy_and_add(client_args_old, &arg, 1); grpc_channel_args_destroy(client_args_old); + // force grpc lib to pass the user agent back up to server. + grpc_channel_args* server_args_old = server_args; + grpc_arg server_arg; + server_arg.key = const_cast(GRPC_ARG_SURFACE_USER_AGENT); + server_arg.type = GRPC_ARG_INTEGER; + server_arg.value.integer = 1; + server_args = + grpc_channel_args_copy_and_add(server_args_old, &server_arg, 1); + grpc_channel_args_destroy(server_args_old); } f = begin_test(config, test_name, client_args, server_args); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index fc07681535f..e835f557383 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -244,15 +244,17 @@ class End2endTest : public ::testing::TestWithParam { BuildAndStartServer(processor); } - void RestartServer(const std::shared_ptr& processor) { + void RestartServer(const std::shared_ptr& processor, + bool surface_user_agent = false) { if (is_server_started_) { server_->Shutdown(); - BuildAndStartServer(processor); + BuildAndStartServer(processor, surface_user_agent); } } void BuildAndStartServer( - const std::shared_ptr& processor) { + const std::shared_ptr& processor, + bool surface_user_agent = false) { ServerBuilder builder; ConfigureServerBuilder(&builder); auto server_creds = GetCredentialsProvider()->GetServerCredentials( @@ -268,6 +270,9 @@ class End2endTest : public ::testing::TestWithParam { builder.SetSyncServerOption(ServerBuilder::SyncServerOption::NUM_CQS, 4); builder.SetSyncServerOption( ServerBuilder::SyncServerOption::CQ_TIMEOUT_MSEC, 10); + if (surface_user_agent) { + builder.AddChannelArgument(GRPC_ARG_SURFACE_USER_AGENT, 1); + } server_ = builder.BuildAndStart(); is_server_started_ = true; @@ -664,6 +669,8 @@ TEST_P(End2endTest, SimpleRpcWithCustomUserAgentPrefix) { } user_agent_prefix_ = "custom_prefix"; ResetStub(); + RestartServer(std::shared_ptr(), true); + ResetChannel(); EchoRequest request; EchoResponse response; request.set_message("Hello hello hello hello"); From 16f53ff583c23b3b2a260ba0935fd0c30b479acf Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 5 Sep 2018 18:16:13 -0700 Subject: [PATCH 303/546] Surface user agent by default --- include/grpc/impl/codegen/grpc_types.h | 3 ++- .../ext/filters/http/server/http_server_filter.cc | 2 +- .../end2end/tests/workaround_cronet_compression.cc | 9 --------- test/cpp/end2end/end2end_test.cc | 13 +++---------- 4 files changed, 6 insertions(+), 21 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 9097984a96b..5f3b96f40b5 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -342,7 +342,8 @@ typedef struct { "grpc.disable_client_authority_filter" /** If set to zero, disables use of http proxies. Enabled by default. */ #define GRPC_ARG_ENABLE_HTTP_PROXY "grpc.enable_http_proxy" -/** If set to non zero, surfaces the user agent string to the server. */ +/** If set to non zero, surfaces the user agent string to the server. User + agent is surfaced by default. */ #define GRPC_ARG_SURFACE_USER_AGENT "grpc.surface_user_agent" /** \} */ 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 53cd059aa80..1b3426b1200 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -445,7 +445,7 @@ static grpc_error* hs_init_channel_elem(grpc_channel_element* elem, chand->surface_user_agent = grpc_channel_arg_get_bool( grpc_channel_args_find(args->channel_args, const_cast(GRPC_ARG_SURFACE_USER_AGENT)), - false); + true); return GRPC_ERROR_NONE; } diff --git a/test/core/end2end/tests/workaround_cronet_compression.cc b/test/core/end2end/tests/workaround_cronet_compression.cc index e1bce603fa7..f44ddca3b10 100644 --- a/test/core/end2end/tests/workaround_cronet_compression.cc +++ b/test/core/end2end/tests/workaround_cronet_compression.cc @@ -149,15 +149,6 @@ static void request_with_payload_template( arg.value.string = user_agent_override; client_args = grpc_channel_args_copy_and_add(client_args_old, &arg, 1); grpc_channel_args_destroy(client_args_old); - // force grpc lib to pass the user agent back up to server. - grpc_channel_args* server_args_old = server_args; - grpc_arg server_arg; - server_arg.key = const_cast(GRPC_ARG_SURFACE_USER_AGENT); - server_arg.type = GRPC_ARG_INTEGER; - server_arg.value.integer = 1; - server_args = - grpc_channel_args_copy_and_add(server_args_old, &server_arg, 1); - grpc_channel_args_destroy(server_args_old); } f = begin_test(config, test_name, client_args, server_args); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index e835f557383..fc07681535f 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -244,17 +244,15 @@ class End2endTest : public ::testing::TestWithParam { BuildAndStartServer(processor); } - void RestartServer(const std::shared_ptr& processor, - bool surface_user_agent = false) { + void RestartServer(const std::shared_ptr& processor) { if (is_server_started_) { server_->Shutdown(); - BuildAndStartServer(processor, surface_user_agent); + BuildAndStartServer(processor); } } void BuildAndStartServer( - const std::shared_ptr& processor, - bool surface_user_agent = false) { + const std::shared_ptr& processor) { ServerBuilder builder; ConfigureServerBuilder(&builder); auto server_creds = GetCredentialsProvider()->GetServerCredentials( @@ -270,9 +268,6 @@ class End2endTest : public ::testing::TestWithParam { builder.SetSyncServerOption(ServerBuilder::SyncServerOption::NUM_CQS, 4); builder.SetSyncServerOption( ServerBuilder::SyncServerOption::CQ_TIMEOUT_MSEC, 10); - if (surface_user_agent) { - builder.AddChannelArgument(GRPC_ARG_SURFACE_USER_AGENT, 1); - } server_ = builder.BuildAndStart(); is_server_started_ = true; @@ -669,8 +664,6 @@ TEST_P(End2endTest, SimpleRpcWithCustomUserAgentPrefix) { } user_agent_prefix_ = "custom_prefix"; ResetStub(); - RestartServer(std::shared_ptr(), true); - ResetChannel(); EchoRequest request; EchoResponse response; request.set_message("Hello hello hello hello"); From 8a8ed0e7115a4c21fbdd40968d688faaba379f2c Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 6 Sep 2018 11:56:12 -0700 Subject: [PATCH 304/546] WIP. Handling error conditions such as duplicate metadata, metadata size limit, and default count. Clang tidy. --- .../chttp2/transport/hpack_encoder.cc | 2 +- src/core/lib/transport/metadata.cc | 65 ------ src/core/lib/transport/metadata.h | 9 - src/core/lib/transport/metadata_batch.cc | 188 ++++++++++++++++-- src/core/lib/transport/metadata_batch.h | 25 ++- 5 files changed, 187 insertions(+), 102 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 4ce139eb0d3..9842131d962 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -37,7 +37,7 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/transport/metadata.h" +#include "src/core/lib/transport/metadata_batch.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/timeout_encoding.h" diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index 793a1fcd53b..d10194a2fe7 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -69,71 +69,6 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_metadata(false, "metadata"); #define TABLE_IDX(hash, capacity) (((hash) >> (LOG2_SHARD_COUNT)) % (capacity)) #define SHARD_IDX(hash) ((hash) & ((1 << (LOG2_SHARD_COUNT)) - 1)) -static_hpack_table_metadata_info static_hpack_table_metadata[] = { - {0, 0, 0}, // NOT USED - {GRPC_MDELEM_AUTHORITY_EMPTY_INDEX, 10 + 32, 3}, - {GRPC_MDELEM_METHOD_GET_INDEX, 10 + 32, 1}, - {GRPC_MDELEM_METHOD_POST_INDEX, 11 + 32, 1}, - {GRPC_MDELEM_PATH_SLASH_INDEX, 6 + 32, 0}, - {GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML_INDEX, 16 + 32, 0}, - {GRPC_MDELEM_SCHEME_HTTP_INDEX, 11 + 32, 4}, - {GRPC_MDELEM_SCHEME_HTTPS_INDEX, 12 + 32, 4}, - {GRPC_MDELEM_STATUS_200_INDEX, 10 + 32, 2}, - {GRPC_MDELEM_STATUS_204_INDEX, 10 + 32, 2}, - {GRPC_MDELEM_STATUS_206_INDEX, 10 + 32, 2}, - {GRPC_MDELEM_STATUS_304_INDEX, 10 + 32, 2}, - {GRPC_MDELEM_STATUS_400_INDEX, 10 + 32, 2}, - {GRPC_MDELEM_STATUS_404_INDEX, 10 + 32, 2}, - {GRPC_MDELEM_STATUS_500_INDEX, 10 + 32, 2}, - {GRPC_MDELEM_ACCEPT_CHARSET_EMPTY_INDEX, 14 + 32, 24}, // Not a callout - {GRPC_MDELEM_ACCEPT_ENCODING_GZIP_DEFLATE_INDEX, 28 + 32, 16}, - {GRPC_MDELEM_MDELEM_ACCEPT_LANGUAGE_EMPTY_INDEX, 15 + 32, 24}, // Not a callout - {GRPC_MDELEM_MDELEM_ACCEPT_RANGES_EMPTY_INDEX, 13 + 32, 24}, // Not a callout - {GRPC_MDELEM_ACCEPT_EMPTY_INDEX, 6 + 32, 24}, // Not a callout - {GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY_INDEX, 27 + 32, 24}, // Not a callout - {GRPC_MDELEM_AGE_EMPTY_INDEX, 3 + 32, 24}, // Not a callout - {GRPC_MDELEM_ALLOW_EMPTY_INDEX, 5 + 32, 24}, // Not a callout - {GRPC_MDELEM_AUTHORIZATION_EMPTY_INDEX, 13 + 32, 24}, // Not a callout - {GRPC_MDELEM_CACHE_CONTROL_EMPTY_INDEX, 13 + 32, 24}, // Not a callout - {GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY_INDEX, 19 + 32, 24}, // Not a callout - {GRPC_MDELEM_CONTENT_ENCODING_EMPTY_INDEX, 16 + 32, 15}, - {GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY_INDEX, 16 + 32, 24}, // Not a callout - {GRPC_MDELEM_CONTENT_LENGTH_EMPTY_INDEX, 14 + 32, 24}, // Not a callout - {GRPC_MDELEM_CONTENT_LOCATION_EMPTY_INDEX, 16 + 32, 24}, // Not a callout - {GRPC_MDELEM_CONTENT_RANGE_EMPTY_INDEX, 13 + 32, 24}, // Not a callout - {GRPC_MDELEM_CONTENT_TYPE_EMPTY_INDEX, 12 + 32, 15}, - {GRPC_MDELEM_COOKIE_EMPTY_INDEX, 6 + 32, 24}, // Not a callout - {GRPC_MDELEM_DATE_EMPTY_INDEX, 4 + 32, 24}, // Not a callout - {GRPC_MDELEM_ETAG_EMPTY_INDEX, 4 + 32, 24}, // Not a callout - {GRPC_MDELEM_EXPECT_EMPTY_INDEX, 6 + 32, 24}, // Not a callout - {GRPC_MDELEM_EXPIRES_EMPTY_INDEX, 7 + 32, 24}, // Not a callout - {GRPC_MDELEM_FROM_EMPTY_INDEX, 4 + 32, 24}, // Not a callout - {GRPC_MDELEM_HOST_EMPTY_INDEX, 4 + 32, 20}, - {GRPC_MDELEM_IF_MATCH_EMPTY_INDEX, 8 + 32, 24}, // Not a callout - {GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY_INDEX, 17 + 32, 24}, // Not a callout - {GRPC_MDELEM_IF_NONE_MATCH_EMPTY_INDEX, 13 + 32, 24}, // Not a callout - {GRPC_MDELEM_IF_RANGE_EMPTY_INDEX, 8 + 32, 24}, // Not a callout - {GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY_INDEX, 19 + 32, 24}, // Not a callout - {GRPC_MDELEM_LAST_MODIFIED_EMPTY_INDEX, 13 + 32, 24}, // Not a callout - {GRPC_MDELEM_LINK_EMPTY_INDEX, 4 + 32, 24}, // Not a callout - {GRPC_MDELEM_LOCATION_EMPTY_INDEX, 8 + 32, 24}, // Not a callout - {GRPC_MDELEM_MAX_FORWARDS_EMPTY_INDEX, 12 + 32, 24}, // Not a callout - {GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY_INDEX, 18 + 32, 24}, // Not a callout - {GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY_INDEX, 19 + 32, 24}, // Not a callout - {GRPC_MDELEM_RANGE_EMPTY_INDEX, 5 + 32, 24}, // Not a callout - {GRPC_MDELEM_REFERER_EMPTY_INDEX, 7 + 32, 24}, // Not a callout - {GRPC_MDELEM_REFRESH_EMPTY_INDEX, 7 + 32, 24}, // Not a callout - {GRPC_MDELEM_RETRY_AFTER_EMPTY_INDEX, 11 + 32, 24}, // Not a callout - {GRPC_MDELEM_SERVER_EMPTY_INDEX, 6 + 32, 24}, // Not a callout - {GRPC_MDELEM_SET_COOKIE_EMPTY_INDEX, 10 + 32, 24}, // Not a callout - {GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY_INDEX, 25 + 32, 24}, // Not a callout - {GRPC_MDELEM_TRANSFER_ENCODING_EMPTY_INDEX, 17 + 32, 24}, // Not a callout - {GRPC_MDELEM_USER_AGENT_EMPTY_INDEX, 10 + 32, 19}, - {GRPC_MDELEM_VARY_EMPTY_INDEX, 4 + 32, 24}, // Not a callout - {GRPC_MDELEM_VIA_EMPTY_INDEX, 3 + 32, 24}, // Not a callout - {GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY_INDEX, 16 + 32, 24}, // Not a callout - }; - typedef void (*destroy_user_data_func)(void* user_data); /* Shadow structure for grpc_mdelem_data for interned elements */ diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 998d2fc64a2..74c6672fd20 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -348,15 +348,6 @@ void grpc_mdctx_global_shutdown(); /* {"www-authenticate", ""} */ #define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY_INDEX 61 -/* Static hpack table metadata info */ -typedef struct static_hpack_table_metadata_info { - uint8_t index; // Index in the static hpack table - uint8_t size; // Size of the metadata per RFC-7540 section 6.5.2., including 32 bytes of padding - uint8_t callouts_index; // For duplicate metadata detection. If GRPC_BATCH_CALLOUTS_COUNT, then the metadata is not one of the callouts. -} static_hpack_table_metadata_info; - -extern static_hpack_table_metadata_info static_hpack_table_metadata[]; - /* Forward declarations */ typedef struct grpc_mdelem grpc_mdelem; #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */ diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index 6cad7c90284..604ace5751e 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -25,11 +25,103 @@ #include #include +#include #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" +static_hpack_table_metadata_info static_hpack_table_metadata[] = { + {0, 0, GRPC_BATCH_CALLOUTS_COUNT}, // NOT USED + {GRPC_MDELEM_AUTHORITY_EMPTY_INDEX, 10 + 32, GRPC_BATCH_AUTHORITY}, + {GRPC_MDELEM_METHOD_GET_INDEX, 10 + 32, GRPC_BATCH_METHOD}, + {GRPC_MDELEM_METHOD_POST_INDEX, 11 + 32, GRPC_BATCH_METHOD}, + {GRPC_MDELEM_PATH_SLASH_INDEX, 6 + 32, GRPC_BATCH_PATH}, + {GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML_INDEX, 16 + 32, GRPC_BATCH_PATH}, + {GRPC_MDELEM_SCHEME_HTTP_INDEX, 11 + 32, GRPC_BATCH_SCHEME}, + {GRPC_MDELEM_SCHEME_HTTPS_INDEX, 12 + 32, GRPC_BATCH_SCHEME}, + {GRPC_MDELEM_STATUS_200_INDEX, 10 + 32, GRPC_BATCH_STATUS}, + {GRPC_MDELEM_STATUS_204_INDEX, 10 + 32, GRPC_BATCH_STATUS}, + {GRPC_MDELEM_STATUS_206_INDEX, 10 + 32, GRPC_BATCH_STATUS}, + {GRPC_MDELEM_STATUS_304_INDEX, 10 + 32, GRPC_BATCH_STATUS}, + {GRPC_MDELEM_STATUS_400_INDEX, 10 + 32, GRPC_BATCH_STATUS}, + {GRPC_MDELEM_STATUS_404_INDEX, 10 + 32, GRPC_BATCH_STATUS}, + {GRPC_MDELEM_STATUS_500_INDEX, 10 + 32, GRPC_BATCH_STATUS}, + {GRPC_MDELEM_ACCEPT_CHARSET_EMPTY_INDEX, 14 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_ACCEPT_ENCODING_GZIP_DEFLATE_INDEX, 28 + 32, + GRPC_BATCH_ACCEPT_ENCODING}, + {GRPC_MDELEM_MDELEM_ACCEPT_LANGUAGE_EMPTY_INDEX, 15 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_MDELEM_ACCEPT_RANGES_EMPTY_INDEX, 13 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_ACCEPT_EMPTY_INDEX, 6 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY_INDEX, 27 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_AGE_EMPTY_INDEX, 3 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_ALLOW_EMPTY_INDEX, 5 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_AUTHORIZATION_EMPTY_INDEX, 13 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_CACHE_CONTROL_EMPTY_INDEX, 13 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY_INDEX, 19 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_CONTENT_ENCODING_EMPTY_INDEX, 16 + 32, + GRPC_BATCH_CONTENT_ENCODING}, + {GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY_INDEX, 16 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_CONTENT_LENGTH_EMPTY_INDEX, 14 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_CONTENT_LOCATION_EMPTY_INDEX, 16 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_CONTENT_RANGE_EMPTY_INDEX, 13 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_CONTENT_TYPE_EMPTY_INDEX, 12 + 32, GRPC_BATCH_CONTENT_TYPE}, + {GRPC_MDELEM_COOKIE_EMPTY_INDEX, 6 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_DATE_EMPTY_INDEX, 4 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_ETAG_EMPTY_INDEX, 4 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_EXPECT_EMPTY_INDEX, 6 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_EXPIRES_EMPTY_INDEX, 7 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_FROM_EMPTY_INDEX, 4 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_HOST_EMPTY_INDEX, 4 + 32, GRPC_BATCH_HOST}, + {GRPC_MDELEM_IF_MATCH_EMPTY_INDEX, 8 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY_INDEX, 17 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_IF_NONE_MATCH_EMPTY_INDEX, 13 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_IF_RANGE_EMPTY_INDEX, 8 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY_INDEX, 19 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_LAST_MODIFIED_EMPTY_INDEX, 13 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_LINK_EMPTY_INDEX, 4 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_LOCATION_EMPTY_INDEX, 8 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_MAX_FORWARDS_EMPTY_INDEX, 12 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY_INDEX, 18 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY_INDEX, 19 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_RANGE_EMPTY_INDEX, 5 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_REFERER_EMPTY_INDEX, 7 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_REFRESH_EMPTY_INDEX, 7 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_RETRY_AFTER_EMPTY_INDEX, 11 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_SERVER_EMPTY_INDEX, 6 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_COOKIE_EMPTY_INDEX, 10 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY_INDEX, 25 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_TRANSFER_ENCODING_EMPTY_INDEX, 17 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_USER_AGENT_EMPTY_INDEX, 10 + 32, GRPC_BATCH_USER_AGENT}, + {GRPC_MDELEM_VARY_EMPTY_INDEX, 4 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_VIA_EMPTY_INDEX, 3 + 32, GRPC_BATCH_CALLOUTS_COUNT}, + {GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY_INDEX, 16 + 32, + GRPC_BATCH_CALLOUTS_COUNT}, +}; + +/* This is a faster check for seeing if a mdelem index is used or not. To verify + that the index value is valid, use 'is_valid_mdelem_index' */ +static bool is_mdelem_index_used(uint8_t index); + +static void set_mdelem_index_unused(uint8_t* index); + +static grpc_metadata_batch_callouts_index get_callouts_index( + grpc_linked_mdelem* storage); + static void assert_valid_list(grpc_mdelem_list* list) { #ifndef NDEBUG grpc_linked_mdelem* l; @@ -56,13 +148,21 @@ static void assert_valid_list(grpc_mdelem_list* list) { static void assert_valid_callouts(grpc_metadata_batch* batch) { #ifndef NDEBUG for (grpc_linked_mdelem* l = batch->list.head; l != nullptr; l = l->next) { - grpc_slice key_interned = grpc_slice_intern(GRPC_MDKEY(l->md)); - grpc_metadata_batch_callouts_index callout_idx = - GRPC_BATCH_INDEX_OF(key_interned); - if (callout_idx != GRPC_BATCH_CALLOUTS_COUNT) { - GPR_ASSERT(batch->idx.array[callout_idx] == l); + grpc_metadata_batch_callouts_index callout_idx; + if (is_mdelem_index_used(l->md_index)) { + GPR_ASSERT(is_valid_mdelem_index(l->md_index)); + callout_idx = get_callouts_index(l->md_index); + if (callout_idx != GRPC_BATCH_CALLOUTS_COUNT) { + GPR_ASSERT(batch->idx.array[callout_idx] == l); + } + } else { + grpc_slice key_interned = grpc_slice_intern(GRPC_MDKEY(l->md)); + callout_idx = GRPC_BATCH_INDEX_OF(key_interned); + if (callout_idx != GRPC_BATCH_CALLOUTS_COUNT) { + GPR_ASSERT(batch->idx.array[callout_idx] == l); + } + grpc_slice_unref_internal(key_interned); } - grpc_slice_unref_internal(key_interned); } #endif } @@ -81,7 +181,9 @@ void grpc_metadata_batch_init(grpc_metadata_batch* batch) { void grpc_metadata_batch_destroy(grpc_metadata_batch* batch) { grpc_linked_mdelem* l; for (l = batch->list.head; l; l = l->next) { - GRPC_MDELEM_UNREF(l->md); + if (!is_mdelem_index_used(l->md_index)) { + GRPC_MDELEM_UNREF(l->md); + } } } @@ -93,14 +195,22 @@ grpc_error* grpc_attach_md_to_error(grpc_error* src, grpc_mdelem md) { return out; } +static grpc_metadata_batch_callouts_index get_callouts_index( + grpc_linked_mdelem* storage) { + if (is_mdelem_index_used(storage->md_index)) { + return static_hpack_table_metadata[storage->md_index].callouts_index; + } else { + return GRPC_BATCH_INDEX_OF(GRPC_MDKEY(storage->md)); + } +} + static grpc_error* maybe_link_callout(grpc_metadata_batch* batch, grpc_linked_mdelem* storage) GRPC_MUST_USE_RESULT; static grpc_error* maybe_link_callout(grpc_metadata_batch* batch, grpc_linked_mdelem* storage) { - grpc_metadata_batch_callouts_index idx = - GRPC_BATCH_INDEX_OF(GRPC_MDKEY(storage->md)); + grpc_metadata_batch_callouts_index idx = get_callouts_index(storage); if (idx == GRPC_BATCH_CALLOUTS_COUNT) { return GRPC_ERROR_NONE; } @@ -109,15 +219,27 @@ static grpc_error* maybe_link_callout(grpc_metadata_batch* batch, batch->idx.array[idx] = storage; return GRPC_ERROR_NONE; } - return grpc_attach_md_to_error( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Unallowed duplicate metadata"), - storage->md); + + grpc_error* err; + if (is_mdelem_index_used(storage->md_index)) { + char* message; + gpr_asprintf(&message, + "Unallowed duplicate metadata with static hpack table index " + "%d and callouts index %d", + storage->md_index, idx); + err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(message); + gpr_free(message); + } else { + err = grpc_attach_md_to_error( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Unallowed duplicate metadata"), + storage->md); + } + return err; } static void maybe_unlink_callout(grpc_metadata_batch* batch, grpc_linked_mdelem* storage) { - grpc_metadata_batch_callouts_index idx = - GRPC_BATCH_INDEX_OF(GRPC_MDKEY(storage->md)); + grpc_metadata_batch_callouts_index idx = get_callouts_index(storage); if (idx == GRPC_BATCH_CALLOUTS_COUNT) { return; } @@ -126,11 +248,18 @@ static void maybe_unlink_callout(grpc_metadata_batch* batch, batch->idx.array[idx] = nullptr; } -bool is_valid_mdelem_index(int64_t index) { +bool is_valid_mdelem_index(uint8_t index) { return index >= MIN_STATIC_HPACK_TABLE_IDX && index <= MAX_STATIC_HPACK_TABLE_IDX; } +bool is_mdelem_index_used(uint8_t index) { return index != 0; } + +void set_mdelem_index_unused(uint8_t* index) { + GPR_ASSERT(index != nullptr); + *index = 0; +} + grpc_error* grpc_metadata_batch_add_head(grpc_metadata_batch* batch, grpc_linked_mdelem* storage, grpc_mdelem elem_to_add) { @@ -141,7 +270,7 @@ grpc_error* grpc_metadata_batch_add_head(grpc_metadata_batch* batch, grpc_error* grpc_metadata_batch_add_head_index(grpc_metadata_batch* batch, grpc_linked_mdelem* storage, - int64_t index_to_add) { + uint8_t index_to_add) { GPR_ASSERT(is_valid_mdelem_index(index_to_add)); storage->md_index = index_to_add; return grpc_metadata_batch_link_head(batch, storage); @@ -186,7 +315,7 @@ grpc_error* grpc_metadata_batch_add_tail(grpc_metadata_batch* batch, grpc_error* grpc_metadata_batch_add_tail_index(grpc_metadata_batch* batch, grpc_linked_mdelem* storage, - int64_t index_to_add) { + uint8_t index_to_add) { GPR_ASSERT(is_valid_mdelem_index(index_to_add)); storage->md_index = index_to_add; return grpc_metadata_batch_link_tail(batch, storage); @@ -244,12 +373,15 @@ void grpc_metadata_batch_remove(grpc_metadata_batch* batch, assert_valid_callouts(batch); maybe_unlink_callout(batch, storage); unlink_storage(&batch->list, storage); - GRPC_MDELEM_UNREF(storage->md); + if (!is_mdelem_index_used(storage->md_index)) { + GRPC_MDELEM_UNREF(storage->md); + } assert_valid_callouts(batch); } void grpc_metadata_batch_set_value(grpc_linked_mdelem* storage, grpc_slice value) { + set_mdelem_index_unused(&storage->md_index); grpc_mdelem old_mdelem = storage->md; grpc_mdelem new_mdelem = grpc_mdelem_from_slices( grpc_slice_ref_internal(GRPC_MDKEY(old_mdelem)), value); @@ -263,18 +395,26 @@ grpc_error* grpc_metadata_batch_substitute(grpc_metadata_batch* batch, assert_valid_callouts(batch); grpc_error* error = GRPC_ERROR_NONE; grpc_mdelem old_mdelem = storage->md; - if (!grpc_slice_eq(GRPC_MDKEY(new_mdelem), GRPC_MDKEY(old_mdelem))) { + bool is_index_used = is_mdelem_index_used(storage->md_index); + if (is_index_used || + !grpc_slice_eq(GRPC_MDKEY(new_mdelem), GRPC_MDKEY(old_mdelem))) { maybe_unlink_callout(batch, storage); storage->md = new_mdelem; + set_mdelem_index_unused(&storage->md_index); error = maybe_link_callout(batch, storage); if (error != GRPC_ERROR_NONE) { unlink_storage(&batch->list, storage); - GRPC_MDELEM_UNREF(storage->md); + if (!is_index_used) { + GRPC_MDELEM_UNREF(storage->md); + } } } else { storage->md = new_mdelem; } - GRPC_MDELEM_UNREF(old_mdelem); + + if (!is_index_used) { + GRPC_MDELEM_UNREF(old_mdelem); + } assert_valid_callouts(batch); return error; } @@ -293,7 +433,11 @@ size_t grpc_metadata_batch_size(grpc_metadata_batch* batch) { size_t size = 0; for (grpc_linked_mdelem* elem = batch->list.head; elem != nullptr; elem = elem->next) { - size += GRPC_MDELEM_LENGTH(elem->md); + if (!is_mdelem_index_used(elem->md_index)) { + size += GRPC_MDELEM_LENGTH(elem->md); + } else { // Mdelem is represented by static hpack table index + size += static_hpack_table_metadata[elem->md_index].size; + } } return size; } diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index f1c199489fa..25f9d0c14c1 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -32,13 +32,13 @@ /** Each grpc_linked_mdelem refers to a particular metadata element by either: 1) grpc_mdelem md - 2) int64_t md_index + 2) uint8_t md_index md_index is an optional optimization. It can only be used for metadata in the hpack static table and is equivalent to the metadata's index in the table. If a metadata elem is not contained in the hpack static table, then md must be used instead. */ typedef struct grpc_linked_mdelem { - int64_t md_index; // If -1, not used. Else, use this field instead of md. + uint8_t md_index; // If 0, not used. Else, use this field instead of md. grpc_mdelem md; // If md_index is 0, use this field instead of md_index. struct grpc_linked_mdelem* next; struct grpc_linked_mdelem* prev; @@ -115,7 +115,7 @@ grpc_error* grpc_metadata_batch_add_head( be a valid static hpack table index */ grpc_error* grpc_metadata_batch_add_head_index( grpc_metadata_batch* batch, grpc_linked_mdelem* storage, - int64_t index_to_add) GRPC_MUST_USE_RESULT; + uint8_t index_to_add) GRPC_MUST_USE_RESULT; /** Add \a elem_to_add as the last element in \a batch, using \a storage as backing storage for the linked list element. @@ -132,11 +132,26 @@ grpc_error* grpc_metadata_batch_add_tail( be a valid static hpack table index */ grpc_error* grpc_metadata_batch_add_head_index( grpc_metadata_batch* batch, grpc_linked_mdelem* storage, - int64_t index_to_add) GRPC_MUST_USE_RESULT; + uint8_t index_to_add) GRPC_MUST_USE_RESULT; grpc_error* grpc_attach_md_to_error(grpc_error* src, grpc_mdelem md); -bool is_valid_mdelem_index(int64_t index); +/** Returns if the index is a valid static hpack table index, and thus if the + grpc_linked_mdelem stores the index rather than the actual grpc_mdelem **/ +bool is_valid_mdelem_index(uint8_t index); + +/* Static hpack table metadata info */ +typedef struct static_hpack_table_metadata_info { + uint8_t index; // Index in the static hpack table + uint8_t size; // Size of the metadata per RFC-7540 section 6.5.2., including + // 32 bytes of padding + grpc_metadata_batch_callouts_index + callouts_index; // For duplicate metadata detection. If + // GRPC_BATCH_CALLOUTS_COUNT, then the metadata is not + // one of the callouts. +} static_hpack_table_metadata_info; + +extern static_hpack_table_metadata_info static_hpack_table_metadata[]; typedef struct { grpc_error* error; From 3fb62ae92c1154b3bae0104a7eaea4520ac3cfa2 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 6 Sep 2018 13:41:02 -0700 Subject: [PATCH 305/546] exclude less tests from qps --- test/cpp/qps/qps_benchmark_script.bzl | 10 ++++++++-- tools/internal_ci/linux/grpc_asan_on_foundry.sh | 2 +- tools/internal_ci/linux/grpc_tsan_on_foundry.sh | 2 +- .../linux/pull_request/grpc_asan_on_foundry.sh | 2 +- .../linux/pull_request/grpc_tsan_on_foundry.sh | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/test/cpp/qps/qps_benchmark_script.bzl b/test/cpp/qps/qps_benchmark_script.bzl index 0904ceb0364..2435502c85e 100644 --- a/test/cpp/qps/qps_benchmark_script.bzl +++ b/test/cpp/qps/qps_benchmark_script.bzl @@ -32,7 +32,7 @@ load("//test/cpp/qps:json_run_localhost_scenarios.bzl", "JSON_RUN_LOCALHOST_SCEN def qps_json_driver_batch(): for scenario in QPS_JSON_DRIVER_SCENARIOS: grpc_cc_test( - name = "qps_json_driver_test_%s" % scenario, + name = "qps_json_driver_test/%s" % scenario, srcs = ["qps_json_driver.cc"], args = [ "--run_inproc", @@ -49,12 +49,15 @@ def qps_json_driver_batch(): "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], + tags = [ + "qps_json_driver", + ], ) def json_run_localhost_batch(): for scenario in JSON_RUN_LOCALHOST_SCENARIOS: grpc_cc_test( - name = "json_run_localhost_%s" % scenario, + name = "json_run_localhost/%s" % scenario, srcs = ["json_run_localhost.cc"], args = [ "--scenarios_json", @@ -71,4 +74,7 @@ def json_run_localhost_batch(): "//test/cpp/util:test_config", "//test/cpp/util:test_util", ], + tags = [ + "json_run_localhost", + ], ) diff --git a/tools/internal_ci/linux/grpc_asan_on_foundry.sh b/tools/internal_ci/linux/grpc_asan_on_foundry.sh index d90a37305f8..dfef004a608 100755 --- a/tools/internal_ci/linux/grpc_asan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_asan_on_foundry.sh @@ -15,6 +15,6 @@ export UPLOAD_TEST_RESULTS=true EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address --test_timeout=3600 --cache_test_results=no" -EXCLUDE_TESTS="-//test/cpp/qps/..." +EXCLUDE_TESTS="--test_tag_filters=-qps_json_driver,-json_run_localhost" github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" diff --git a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh index eaeaca914ad..366b5cbe347 100644 --- a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh @@ -15,5 +15,5 @@ export UPLOAD_TEST_RESULTS=true EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=thread --linkopt=-fsanitize=thread --test_timeout=3600 --action_env=TSAN_OPTIONS=suppressions=test/core/util/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1 --cache_test_results=no" -EXCLUDE_TESTS="-//test/cpp/qps/..." +EXCLUDE_TESTS="--test_tag_filters=-qps_json_driver,-json_run_localhost" github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" diff --git a/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh index 4c788a4a722..39c991f2913 100644 --- a/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh @@ -14,6 +14,6 @@ # limitations under the License. EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address --test_timeout=3600" -EXCLUDE_TESTS="-//test/cpp/qps/..." +EXCLUDE_TESTS="--test_tag_filters=-qps_json_driver,-json_run_localhost" github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" diff --git a/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh index 9a78663ab4e..3dee1153001 100644 --- a/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh @@ -14,5 +14,5 @@ # limitations under the License. EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=thread --linkopt=-fsanitize=thread --test_timeout=3600 --action_env=TSAN_OPTIONS=suppressions=test/core/util/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1" -EXCLUDE_TESTS="-//test/cpp/qps/..." +EXCLUDE_TESTS="--test_tag_filters=-qps_json_driver,-json_run_localhost" github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" From 33d87e3ffdedaef7c3d1a7a466d3a69fa51b23d1 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 6 Sep 2018 13:44:51 -0700 Subject: [PATCH 306/546] Fix internal_data to be the same size as the new grpc_linked_mdelem --- include/grpc/impl/codegen/grpc_types.h | 1 + .../ext/transport/chttp2/transport/hpack_encoder.cc | 9 +++++++-- .../ext/transport/chttp2/transport/hpack_encoder.h | 2 +- src/core/ext/transport/chttp2/transport/writing.cc | 6 +++--- src/core/lib/transport/metadata_batch.cc | 2 +- test/core/end2end/tests/authority_not_supported.cc | 4 ++-- test/core/end2end/tests/binary_metadata.cc | 8 ++++---- test/core/end2end/tests/simple_cacheable_request.cc | 8 ++++---- test/core/end2end/tests/simple_metadata.cc | 8 ++++---- test/core/end2end/tests/trailing_metadata.cc | 12 ++++++------ 10 files changed, 33 insertions(+), 27 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index b5353c1dea8..d0f77f977be 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -438,6 +438,7 @@ typedef struct grpc_metadata { There is no need to initialize them, and they will be set to garbage during calls to grpc. */ struct /* internal */ { + uint8_t obfuscated_byte; void* obfuscated[4]; } internal_data; } grpc_metadata; diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 9842131d962..c9ba74bf642 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -663,7 +663,7 @@ void grpc_chttp2_hpack_compressor_set_max_table_size( } void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, - grpc_mdelem** extra_headers, + grpc_linked_mdelem** extra_headers, size_t extra_headers_size, grpc_metadata_batch* metadata, const grpc_encode_header_options* options, @@ -688,7 +688,12 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, emit_advertise_table_size_change(c, &st); } for (size_t i = 0; i < extra_headers_size; ++i) { - hpack_enc(c, *extra_headers[i], &st); + grpc_linked_mdelem* linked_md = extra_headers[i]; + if (is_valid_mdelem_index(linked_md->md_index)) { + emit_indexed(c, linked_md->md_index, &st); + } else { + hpack_enc(c, linked_md->md, &st); + } } grpc_metadata_batch_assert_ok(metadata); for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) { diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h index e31a7399d78..0994eeb45f4 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h @@ -87,7 +87,7 @@ typedef struct { } grpc_encode_header_options; void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, - grpc_mdelem** extra_headers, + grpc_linked_mdelem** extra_headers, size_t extra_headers_size, grpc_metadata_batch* metadata, const grpc_encode_header_options* options, diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 8b73b01dea2..9eabdb4da48 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -557,12 +557,12 @@ class StreamWriteContext { if (s_->send_initial_metadata->idx.named.status != nullptr) { extra_headers_for_trailing_metadata_ [num_extra_headers_for_trailing_metadata_++] = - &s_->send_initial_metadata->idx.named.status->md; + s_->send_initial_metadata->idx.named.status; } if (s_->send_initial_metadata->idx.named.content_type != nullptr) { extra_headers_for_trailing_metadata_ [num_extra_headers_for_trailing_metadata_++] = - &s_->send_initial_metadata->idx.named.content_type->md; + s_->send_initial_metadata->idx.named.content_type; } } @@ -583,7 +583,7 @@ class StreamWriteContext { grpc_chttp2_transport* const t_; grpc_chttp2_stream* const s_; bool stream_became_writable_ = false; - grpc_mdelem* extra_headers_for_trailing_metadata_[2]; + grpc_linked_mdelem* extra_headers_for_trailing_metadata_[2]; size_t num_extra_headers_for_trailing_metadata_ = 0; }; } // namespace diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index 604ace5751e..304a5d510d8 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -151,7 +151,7 @@ static void assert_valid_callouts(grpc_metadata_batch* batch) { grpc_metadata_batch_callouts_index callout_idx; if (is_mdelem_index_used(l->md_index)) { GPR_ASSERT(is_valid_mdelem_index(l->md_index)); - callout_idx = get_callouts_index(l->md_index); + callout_idx = get_callouts_index(l); if (callout_idx != GRPC_BATCH_CALLOUTS_COUNT) { GPR_ASSERT(batch->idx.array[callout_idx] == l); } diff --git a/test/core/end2end/tests/authority_not_supported.cc b/test/core/end2end/tests/authority_not_supported.cc index 01a95e4e10b..4ccdb5e72a2 100644 --- a/test/core/end2end/tests/authority_not_supported.cc +++ b/test/core/end2end/tests/authority_not_supported.cc @@ -93,11 +93,11 @@ static void test_with_authority_header(grpc_end2end_test_config config) { grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), grpc_slice_from_static_string("val1"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}, + {0, {nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key2"), grpc_slice_from_static_string("val2"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}}; + {0, {nullptr, nullptr, nullptr, nullptr}}}}; grpc_end2end_test_fixture f = begin_test(config, "test_with_authority_header", nullptr, nullptr); cq_verifier* cqv = cq_verifier_create(f.cq); diff --git a/test/core/end2end/tests/binary_metadata.cc b/test/core/end2end/tests/binary_metadata.cc index cdf5b1eb94d..2ce050355d6 100644 --- a/test/core/end2end/tests/binary_metadata.cc +++ b/test/core/end2end/tests/binary_metadata.cc @@ -101,23 +101,23 @@ static void test_request_response_with_metadata_and_payload( grpc_slice_from_static_string( "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}, + {0, {nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key2-bin"), grpc_slice_from_static_string( "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}}; + {0, {nullptr, nullptr, nullptr, nullptr}}}}; grpc_metadata meta_s[2] = { {grpc_slice_from_static_string("key3-bin"), grpc_slice_from_static_string( "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}, + {0, {nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key4-bin"), grpc_slice_from_static_string( "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}}; + {0, {nullptr, nullptr, nullptr, nullptr}}}}; grpc_end2end_test_fixture f = begin_test(config, "test_request_response_with_metadata_and_payload", nullptr, nullptr); diff --git a/test/core/end2end/tests/simple_cacheable_request.cc b/test/core/end2end/tests/simple_cacheable_request.cc index be6d16ecad7..7493818a271 100644 --- a/test/core/end2end/tests/simple_cacheable_request.cc +++ b/test/core/end2end/tests/simple_cacheable_request.cc @@ -101,19 +101,19 @@ static void test_cacheable_request_response_with_metadata_and_payload( grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), grpc_slice_from_static_string("val1"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}, + {0, {nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key2"), grpc_slice_from_static_string("val2"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}}; + {0, {nullptr, nullptr, nullptr, nullptr}}}}; grpc_metadata meta_s[2] = {{grpc_slice_from_static_string("key3"), grpc_slice_from_static_string("val3"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}, + {0, {nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key4"), grpc_slice_from_static_string("val4"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}}; + {0, {nullptr, nullptr, nullptr, nullptr}}}}; grpc_end2end_test_fixture f = begin_test( config, "test_cacheable_request_response_with_metadata_and_payload", nullptr, nullptr); diff --git a/test/core/end2end/tests/simple_metadata.cc b/test/core/end2end/tests/simple_metadata.cc index 3e476c2129d..a9e86bda3a1 100644 --- a/test/core/end2end/tests/simple_metadata.cc +++ b/test/core/end2end/tests/simple_metadata.cc @@ -99,19 +99,19 @@ static void test_request_response_with_metadata_and_payload( grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), grpc_slice_from_static_string("val1"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}, + {0, {nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key2"), grpc_slice_from_static_string("val2"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}}; + {0, {nullptr, nullptr, nullptr, nullptr}}}}; grpc_metadata meta_s[2] = {{grpc_slice_from_static_string("key3"), grpc_slice_from_static_string("val3"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}, + {0, {nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key4"), grpc_slice_from_static_string("val4"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}}; + {0, {nullptr, nullptr, nullptr, nullptr}}}}; grpc_end2end_test_fixture f = begin_test(config, "test_request_response_with_metadata_and_payload", nullptr, nullptr); diff --git a/test/core/end2end/tests/trailing_metadata.cc b/test/core/end2end/tests/trailing_metadata.cc index 5cf6f2bb115..1fb9683ee5f 100644 --- a/test/core/end2end/tests/trailing_metadata.cc +++ b/test/core/end2end/tests/trailing_metadata.cc @@ -99,27 +99,27 @@ static void test_request_response_with_metadata_and_payload( grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), grpc_slice_from_static_string("val1"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}, + {0, {nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key2"), grpc_slice_from_static_string("val2"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}}; + {0, {nullptr, nullptr, nullptr, nullptr}}}}; grpc_metadata meta_s[2] = {{grpc_slice_from_static_string("key3"), grpc_slice_from_static_string("val3"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}, + {0, {nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key4"), grpc_slice_from_static_string("val4"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}}; + {0, {nullptr, nullptr, nullptr, nullptr}}}}; grpc_metadata meta_t[2] = {{grpc_slice_from_static_string("key5"), grpc_slice_from_static_string("val5"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}, + {0, {nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key6"), grpc_slice_from_static_string("val6"), 0, - {{nullptr, nullptr, nullptr, nullptr}}}}; + {0, {nullptr, nullptr, nullptr, nullptr}}}}; grpc_end2end_test_fixture f = begin_test(config, "test_request_response_with_metadata_and_payload", nullptr, nullptr); From d75415ccfd5277d27c222ddb27608c1acccaedac Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 6 Sep 2018 14:24:59 -0700 Subject: [PATCH 307/546] Fix assertion in debugging code --- src/core/lib/transport/metadata_batch.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index 304a5d510d8..788681f006c 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -134,7 +134,7 @@ static void assert_valid_list(grpc_mdelem_list* list) { size_t verified_count = 0; for (l = list->head; l; l = l->next) { - GPR_ASSERT(!GRPC_MDISNULL(l->md)); + GPR_ASSERT(is_mdelem_index_used(l->md_index) || !GRPC_MDISNULL(l->md)); GPR_ASSERT((l->prev == nullptr) == (l == list->head)); GPR_ASSERT((l->next == nullptr) == (l == list->tail)); if (l->next) GPR_ASSERT(l->next->prev == l); From b7bbc350b85b390c74a1a1190877478fbfe03e3b Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 6 Sep 2018 14:33:32 -0700 Subject: [PATCH 308/546] naming bugfix --- test/cpp/qps/qps_benchmark_script.bzl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/qps/qps_benchmark_script.bzl b/test/cpp/qps/qps_benchmark_script.bzl index 2435502c85e..b2b67d988ce 100644 --- a/test/cpp/qps/qps_benchmark_script.bzl +++ b/test/cpp/qps/qps_benchmark_script.bzl @@ -32,7 +32,7 @@ load("//test/cpp/qps:json_run_localhost_scenarios.bzl", "JSON_RUN_LOCALHOST_SCEN def qps_json_driver_batch(): for scenario in QPS_JSON_DRIVER_SCENARIOS: grpc_cc_test( - name = "qps_json_driver_test/%s" % scenario, + name = "qps_json_driver_test_%s" % scenario, srcs = ["qps_json_driver.cc"], args = [ "--run_inproc", @@ -57,7 +57,7 @@ def qps_json_driver_batch(): def json_run_localhost_batch(): for scenario in JSON_RUN_LOCALHOST_SCENARIOS: grpc_cc_test( - name = "json_run_localhost/%s" % scenario, + name = "json_run_localhost_%s" % scenario, srcs = ["json_run_localhost.cc"], args = [ "--scenarios_json", From 3c1a3d9f1b4c8ac573c0234f71534fd74cf2ec4b Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 6 Sep 2018 15:06:17 -0700 Subject: [PATCH 309/546] Fix subchannel key comparison if forcing creation --- src/core/ext/filters/client_channel/subchannel_index.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc index cb02b1a7480..4e155a28300 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ b/src/core/ext/filters/client_channel/subchannel_index.cc @@ -73,7 +73,8 @@ static grpc_subchannel_key* subchannel_key_copy(grpc_subchannel_key* k) { int grpc_subchannel_key_compare(const grpc_subchannel_key* a, const grpc_subchannel_key* b) { - if (g_force_creation) return false; + // To pretend the keys are different, return a non-zero value. + if (g_force_creation) return 1; int c = GPR_ICMP(a->args.filter_count, b->args.filter_count); if (c != 0) return c; if (a->args.filter_count > 0) { From 2a6f71ea5bc7a90742d89a7edb062dcad7ea6f08 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Thu, 6 Sep 2018 15:13:47 -0700 Subject: [PATCH 310/546] flipped script argument order --- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 3fa1b2a10d5..0b29a5f3873 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -60,9 +60,8 @@ export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instan --platforms=//third_party/toolchains:rbe_ubuntu1604 \ --test_env=GRPC_VERBOSITY=debug \ --remote_instance_name=projects/grpc-testing/instances/default_instance \ - $1 \ - -- //test/... \ - $2 || FAILED="true" + $1 $2\ + -- //test/... || FAILED="true" if [ "$UPLOAD_TEST_RESULTS" != "" ] then From b91da3f4bf4ab30428e50a0c6734fcb931e3d85e Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 6 Sep 2018 15:26:36 -0700 Subject: [PATCH 311/546] Add support for reading channel args --- src/core/lib/iomgr/port.h | 1 - .../lib/iomgr/socket_utils_common_posix.cc | 87 ++++++++++++++++--- src/core/lib/iomgr/socket_utils_posix.h | 8 +- src/core/lib/iomgr/tcp_client_posix.cc | 3 +- .../iomgr/tcp_server_utils_posix_common.cc | 3 +- 5 files changed, 83 insertions(+), 19 deletions(-) diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index bc58ed13c07..807b9bf85ae 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -77,7 +77,6 @@ #define GRPC_LINUX_SOCKETUTILS 1 #endif #endif -#include #ifdef LINUX_VERSION_CODE #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) #define GRPC_HAVE_TCP_USER_TIMEOUT diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc index b7fc833608b..4ef3d8319fd 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.cc +++ b/src/core/lib/iomgr/socket_utils_common_posix.cc @@ -41,6 +41,7 @@ #include #include +#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/iomgr/sockaddr.h" @@ -222,25 +223,83 @@ grpc_error* grpc_set_socket_low_latency(int fd, int low_latency) { return GRPC_ERROR_NONE; } -#define DEFAULT_TCP_USER_TIMEOUT 20000 /* 20 seconds */ +/* The default values for TCP_USER_TIMEOUT are currently configured to be in + * line with the default values of KEEPALIVE_TIMEOUT as proposed in + * https://github.com/grpc/proposal/blob/master/A18-tcp-user-timeout.md */ +#define DEFAULT_CLIENT_TCP_USER_TIMEOUT_MS 20000 /* 20 seconds */ +#define DEFAULT_SERVER_TCP_USER_TIMEOUT_MS 20000 /* 20 seconds */ + +static int g_default_client_tcp_user_timeout_ms = + DEFAULT_CLIENT_TCP_USER_TIMEOUT_MS; +static int g_default_server_tcp_user_timeout_ms = + DEFAULT_SERVER_TCP_USER_TIMEOUT_MS; +static bool g_default_client_tcp_user_timeout_enabled = false; +static bool g_default_server_tcp_user_timeout_enabled = true; + +void config_default_tcp_user_timeout(bool enable, int timeout, bool is_client) { + if (is_client) { + g_default_client_tcp_user_timeout_enabled = enable; + if (timeout > 0) { + g_default_client_tcp_user_timeout_ms = timeout; + } + } else { + g_default_server_tcp_user_timeout_enabled = enable; + if (timeout > 0) { + g_default_server_tcp_user_timeout_ms = timeout; + } + } +} /* Set TCP_USER_TIMEOUT */ -grpc_error* grpc_set_socket_tcp_user_timeout(int fd, int val) { +grpc_error* grpc_set_socket_tcp_user_timeout( + int fd, const grpc_channel_args* channel_args, bool is_client) { #ifdef GRPC_HAVE_TCP_USER_TIMEOUT - int newval; - socklen_t len = sizeof(newval); - if (val == 0) { - val = DEFAULT_TCP_USER_TIMEOUT; - } - if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &val, sizeof(val))) { - return GRPC_OS_ERROR(errno, "setsockopt(TCP_USER_TIMEOUT)"); + bool enable; + int timeout; + if (is_client) { + enable = g_default_client_tcp_user_timeout_enabled; + timeout = g_default_client_tcp_user_timeout_ms; + } else { + enable = g_default_server_tcp_user_timeout_enabled; + timeout = g_default_server_tcp_user_timeout_ms; } - if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len)) { - return GRPC_OS_ERROR(errno, "getsockopt(TCP_USER_TIMEOUT)"); + if (channel_args) { + for (unsigned int i = 0; i < channel_args->num_args; i++) { + if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_KEEPALIVE_TIME_MS)) { + const int value = grpc_channel_arg_get_integer( + &channel_args->args[i], grpc_integer_options{0, 1, INT_MAX}); + /* Continue using default if value is 0 */ + if (value == 0) { + continue; + } + /* Disable if value is INT_MAX */ + enable = value != INT_MAX; + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_KEEPALIVE_TIMEOUT_MS)) { + const int value = grpc_channel_arg_get_integer( + &channel_args->args[i], grpc_integer_options{0, 1, INT_MAX}); + /* Continue using default if value is 0 */ + if (value == 0) { + continue; + } + timeout = value; + } + } } - if (newval != val) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Failed to set TCP_USER_TIMEOUT"); + if (enable) { + int newval; + socklen_t len = sizeof(newval); + if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout, + sizeof(timeout))) { + return GRPC_OS_ERROR(errno, "setsockopt(TCP_USER_TIMEOUT)"); + } + if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len)) { + return GRPC_OS_ERROR(errno, "getsockopt(TCP_USER_TIMEOUT)"); + } + if (newval != timeout) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Failed to set TCP_USER_TIMEOUT"); + } } #else gpr_log(GPR_INFO, "TCP_USER_TIMEOUT not supported for this platform"); diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h index 8550bd1324d..71a304dc4ef 100644 --- a/src/core/lib/iomgr/socket_utils_posix.h +++ b/src/core/lib/iomgr/socket_utils_posix.h @@ -53,8 +53,12 @@ grpc_error* grpc_set_socket_low_latency(int fd, int low_latency); /* set SO_REUSEPORT */ grpc_error* grpc_set_socket_reuse_port(int fd, int reuse); -/* Set TCP_USER_TIMEOUT to val, or the default value if val is 0. */ -grpc_error* grpc_set_socket_tcp_user_timeout(int fd, int val); +/* Configure the default values for TCP_USER_TIMEOUT */ +void config_default_tcp_user_timeout(bool enable, int timeout, bool is_client); + +/* Set TCP_USER_TIMEOUT */ +grpc_error* grpc_set_socket_tcp_user_timeout( + int fd, const grpc_channel_args* channel_args, bool is_client); /* Returns true if this system can create AF_INET6 sockets bound to ::1. The value is probed once, and cached for the life of the process. diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc index c2a08922116..b71f5570940 100644 --- a/src/core/lib/iomgr/tcp_client_posix.cc +++ b/src/core/lib/iomgr/tcp_client_posix.cc @@ -76,7 +76,8 @@ static grpc_error* prepare_socket(const grpc_resolved_address* addr, int fd, if (!grpc_is_unix_socket(addr)) { err = grpc_set_socket_low_latency(fd, 1); if (err != GRPC_ERROR_NONE) goto error; - err = grpc_set_socket_tcp_user_timeout(fd, 0 /* set to gRPC default */); + err = grpc_set_socket_tcp_user_timeout(fd, channel_args, + true /* is_client */); if (err != GRPC_ERROR_NONE) goto error; } err = grpc_set_socket_no_sigpipe_if_possible(fd); 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 20b9037c68f..6cebc840241 100644 --- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc @@ -166,7 +166,8 @@ grpc_error* grpc_tcp_server_prepare_socket(grpc_tcp_server* s, int fd, if (err != GRPC_ERROR_NONE) goto error; err = grpc_set_socket_reuse_addr(fd, 1); if (err != GRPC_ERROR_NONE) goto error; - err = grpc_set_socket_tcp_user_timeout(fd, 0 /* set to gRPC default */); + err = grpc_set_socket_tcp_user_timeout(fd, s->channel_args, + false /* is_client */); if (err != GRPC_ERROR_NONE) goto error; } err = grpc_set_socket_no_sigpipe_if_possible(fd); From 4099c40d9fc97c70a8aaae74d9af5a64c0113da2 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 6 Sep 2018 20:05:16 -0700 Subject: [PATCH 312/546] Zero out md_index when linked_mdelem is created to fix bug --- src/core/lib/surface/call.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 2923a86646a..def99f5a222 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -954,6 +954,7 @@ static int prepare_application_metadata(grpc_call* call, int count, const grpc_metadata* md = get_md_elem(metadata, additional_metadata, i, count); grpc_linked_mdelem* l = linked_from_md(md); + l->md_index = 0; GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data)); if (!GRPC_LOG_IF_ERROR("validate_metadata", grpc_validate_header_key_is_legal(md->key))) { From 4181c8cd37d95421a7521b5d7ce382966c13c0c6 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 6 Sep 2018 20:41:06 -0700 Subject: [PATCH 313/546] Zero out linked_mdelem when created in test --- test/core/transport/chttp2/hpack_encoder_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/transport/chttp2/hpack_encoder_test.cc b/test/core/transport/chttp2/hpack_encoder_test.cc index 2a57198ab64..39a7973da9e 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.cc +++ b/test/core/transport/chttp2/hpack_encoder_test.cc @@ -59,7 +59,7 @@ static void verify(const verify_params params, const char* expected, size_t i; va_list l; grpc_linked_mdelem* e = - static_cast(gpr_malloc(sizeof(*e) * nheaders)); + static_cast(gpr_zalloc(sizeof(*e) * nheaders)); grpc_metadata_batch b; grpc_metadata_batch_init(&b); From 3943790e099016383550b89c32e4b060a7875d70 Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Fri, 7 Sep 2018 10:19:32 -0700 Subject: [PATCH 314/546] simplified argument packing --- tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index 0b29a5f3873..bb2a85138c6 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -60,7 +60,7 @@ export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instan --platforms=//third_party/toolchains:rbe_ubuntu1604 \ --test_env=GRPC_VERBOSITY=debug \ --remote_instance_name=projects/grpc-testing/instances/default_instance \ - $1 $2\ + $@ \ -- //test/... || FAILED="true" if [ "$UPLOAD_TEST_RESULTS" != "" ] From 917af9a47f6141b897e1288a71e846f054941a39 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 7 Sep 2018 13:13:27 -0700 Subject: [PATCH 315/546] use finally instead of catch-throw --- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 0953f59a189..4cdf0ee6a72 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -125,7 +125,7 @@ namespace Grpc.Core.Internal } } } - catch (Exception) + finally { if (!callStartedOk) { @@ -134,7 +134,6 @@ namespace Grpc.Core.Internal OnFailedToStartCallLocked(); } } - throw; } // Once the blocking call returns, the result should be available synchronously. @@ -172,13 +171,12 @@ namespace Grpc.Core.Internal return unaryResponseTcs.Task; } - catch (Exception) + finally { if (!callStartedOk) { OnFailedToStartCallLocked(); } - throw; } } } @@ -210,13 +208,12 @@ namespace Grpc.Core.Internal return unaryResponseTcs.Task; } - catch (Exception) + finally { if (!callStartedOk) { OnFailedToStartCallLocked(); } - throw; } } } @@ -248,13 +245,12 @@ namespace Grpc.Core.Internal } call.StartReceiveInitialMetadata(ReceivedResponseHeadersCallback); } - catch (Exception) + finally { if (!callStartedOk) { OnFailedToStartCallLocked(); } - throw; } } } @@ -283,13 +279,12 @@ namespace Grpc.Core.Internal } call.StartReceiveInitialMetadata(ReceivedResponseHeadersCallback); } - catch (Exception) + finally { if (!callStartedOk) { OnFailedToStartCallLocked(); } - throw; } } } From 209aee1c69aceeafd7d05208e76d3c1059edc720 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 7 Sep 2018 13:43:36 -0700 Subject: [PATCH 316/546] address review comments --- src/csharp/Grpc.Core/ServerCredentials.cs | 5 +++-- src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/csharp/Grpc.Core/ServerCredentials.cs b/src/csharp/Grpc.Core/ServerCredentials.cs index 056311e0c02..dc86f37a42c 100644 --- a/src/csharp/Grpc.Core/ServerCredentials.cs +++ b/src/csharp/Grpc.Core/ServerCredentials.cs @@ -136,7 +136,7 @@ namespace Grpc.Core /// /// Key-certificates to use. /// PEM encoded client root certificates used to authenticate client. - /// Options for requesting and verification of client certificate. + /// Options for requesting and verifying client certificate. public SslServerCredentials(IEnumerable keyCertificatePairs, string rootCertificates, SslClientCertificateRequestType clientCertificateRequest) { this.keyCertificatePairs = new List(keyCertificatePairs).AsReadOnly(); @@ -153,7 +153,8 @@ namespace Grpc.Core /// /// Creates server-side SSL credentials. - /// This constructor should be use if you do not wish to autheticate client at all. + /// This constructor should be used if you do not wish to authenticate the client. + /// (client certificate won't be requested and checked by the server at all). /// /// Key-certificates to use. public SslServerCredentials(IEnumerable keyCertificatePairs) : this(keyCertificatePairs, null, SslClientCertificateRequestType.DontRequestClientCertificate) diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs index 713c4ea72a8..1a6054f4cf6 100644 --- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs @@ -182,9 +182,9 @@ namespace Grpc.IntegrationTesting public void Constructor_NullRootCerts() { var keyCertPairs = new[] { keyCertPair }; - new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.DontRequestClientCertificate); - new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestClientCertificateAndVerify); - new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireClientCertificateButDontVerify); + Assert.DoesNotThrow(() => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.DontRequestClientCertificate)); + Assert.DoesNotThrow(() => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestClientCertificateAndVerify)); + Assert.DoesNotThrow(() => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireClientCertificateButDontVerify)); Assert.Throws(typeof(ArgumentNullException), () => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify)); } From 71ee19cb1663125d37e4d99abc17627cd5cd7504 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 7 Sep 2018 23:26:48 +0200 Subject: [PATCH 317/546] fix interop docker build --- .../interoptest/grpc_interop_dart/Dockerfile.template | 2 +- tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template index 4fb7b4642d4..34ea645cfa0 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile.template @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. - FROM google/dart:latest + FROM google/dart:2.0 # Upgrade Dart to version 2. RUN apt-get update && apt-get upgrade -y dart diff --git a/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile index bff20b5d064..897354891c1 100644 --- a/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_dart/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM google/dart:latest +FROM google/dart:2.0 # Upgrade Dart to version 2. RUN apt-get update && apt-get upgrade -y dart From bf53d1c8803b2b43bfb1756ce1c7f85326342418 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 7 Sep 2018 14:21:41 -0700 Subject: [PATCH 318/546] Fix subchannel key comparison --- src/core/ext/filters/client_channel/subchannel_index.cc | 6 +++--- src/core/ext/filters/client_channel/subchannel_index.h | 5 +---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc index 4e155a28300..f2b6c24e8ee 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ b/src/core/ext/filters/client_channel/subchannel_index.cc @@ -42,7 +42,7 @@ struct grpc_subchannel_key { grpc_subchannel_args args; }; -static bool g_force_creation = false; +static gpr_atm g_force_creation = false; static grpc_subchannel_key* create_key( const grpc_subchannel_args* args, @@ -74,7 +74,7 @@ static grpc_subchannel_key* subchannel_key_copy(grpc_subchannel_key* k) { int grpc_subchannel_key_compare(const grpc_subchannel_key* a, const grpc_subchannel_key* b) { // To pretend the keys are different, return a non-zero value. - if (g_force_creation) return 1; + if (GPR_UNLIKELY(gpr_atm_no_barrier_load(&g_force_creation))) return 1; int c = GPR_ICMP(a->args.filter_count, b->args.filter_count); if (c != 0) return c; if (a->args.filter_count > 0) { @@ -251,5 +251,5 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key, } void grpc_subchannel_index_test_only_set_force_creation(bool force_creation) { - g_force_creation = force_creation; + gpr_atm_no_barrier_store(&g_force_creation, force_creation); } diff --git a/src/core/ext/filters/client_channel/subchannel_index.h b/src/core/ext/filters/client_channel/subchannel_index.h index a7dae9d47d3..c135613d26b 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.h +++ b/src/core/ext/filters/client_channel/subchannel_index.h @@ -65,13 +65,10 @@ void grpc_subchannel_index_ref(void); void grpc_subchannel_index_unref(void); /** \em TEST ONLY. - * If \a force_creation is true, all key comparisons will be false, resulting in + * If \a force_creation is true, all keys are regarded different, resulting in * new subchannels always being created. Otherwise, the keys will be compared as * usual. * - * This function is *not* threadsafe on purpose: it should *only* be used in - * test code. - * * Tests using this function \em MUST run tests with and without \a * force_creation set. */ void grpc_subchannel_index_test_only_set_force_creation(bool force_creation); From be8844bcdb704cff6a70507f5093e4bb26320ea3 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 7 Sep 2018 15:44:59 -0700 Subject: [PATCH 319/546] reviewer feedback --- .../filters/client_channel/client_channel.cc | 133 +++++++++--------- src/core/lib/channel/channelz.h | 7 +- src/core/lib/channel/connected_channel.cc | 6 +- src/core/lib/surface/call.cc | 8 +- test/core/channel/channel_trace_test.cc | 4 +- test/core/channel/channelz_test.cc | 4 +- 6 files changed, 78 insertions(+), 84 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index d015ceb3359..000cf82c6cb 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -937,7 +937,7 @@ typedef struct client_channel_call_data { // state needed to support channelz interception of recv trailing metadata. grpc_closure recv_trailing_metadata_ready_channelz; grpc_closure* original_recv_trailing_metadata; - grpc_transport_stream_op_batch* recv_trailing_metadata_batch; + grpc_metadata_batch* recv_trailing_metadata_batch; grpc_polling_entity* pollent; bool pollent_added_to_interested_parties; @@ -1000,14 +1000,8 @@ 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 start_pick_locked(void* arg, grpc_error* ignored); -template -static pending_batch* pending_batch_find(grpc_call_element* elem, - const char* log_message, - Predicate predicate); -static void get_call_status(grpc_call_element* elem, - grpc_metadata_batch* md_batch, grpc_error* error, - grpc_status_code* status, - grpc_mdelem** server_pushback_md); +static void maybe_intercept_metadata_for_channelz( + grpc_call_element* elem, grpc_transport_stream_op_batch* batch); // // send op data caching @@ -1282,66 +1276,6 @@ static void resume_pending_batch_in_call_combiner(void* arg, grpc_subchannel_call_process_op(subchannel_call, batch); } -static void recv_trailing_metadata_ready_channelz(void* arg, - grpc_error* error) { - grpc_call_element* elem = static_cast(arg); - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: got recv_trailing_metadata_ready_channelz, " - "error=%s", - chand, calld, grpc_error_string(error)); - } - GPR_ASSERT(calld->recv_trailing_metadata_batch != nullptr); - grpc_status_code status = GRPC_STATUS_OK; - grpc_metadata_batch* md_batch = - calld->recv_trailing_metadata_batch->payload->recv_trailing_metadata - .recv_trailing_metadata; - get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, nullptr); - grpc_core::channelz::SubchannelNode* channelz_subchannel = - calld->pick.connected_subchannel->channelz_subchannel(); - GPR_ASSERT(channelz_subchannel != nullptr); - if (status == GRPC_STATUS_OK) { - channelz_subchannel->RecordCallSucceeded(); - } else { - channelz_subchannel->RecordCallFailed(); - } - calld->recv_trailing_metadata_batch = nullptr; - GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata, error); -} - -// If channelz is enabled, intercept recv_trailing so that we may check the -// status and associate it to a subchannel. -// Returns true if callback was intercepted, false otherwise. -static void maybe_intercept_recv_trailing_for_channelz( - grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { - call_data* calld = static_cast(elem->call_data); - // only intercept payloads with recv trailing. - if (!batch->recv_trailing_metadata) { - return; - } - // only add interceptor is channelz is enabled. - if (calld->pick.connected_subchannel->channelz_subchannel() == nullptr) { - return; - } - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "calld=%p batch=%p: intercepting recv trailing for channelz", calld, - batch); - } - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_channelz, - recv_trailing_metadata_ready_channelz, elem, - grpc_schedule_on_exec_ctx); - // save some state needed for the interception callback. - GPR_ASSERT(calld->recv_trailing_metadata_batch == nullptr); - calld->recv_trailing_metadata_batch = batch; - calld->original_recv_trailing_metadata = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &calld->recv_trailing_metadata_ready_channelz; -} - // This is called via the call combiner, so access to calld is synchronized. static void pending_batches_resume(grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); @@ -1366,7 +1300,7 @@ static void pending_batches_resume(grpc_call_element* elem) { pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { - maybe_intercept_recv_trailing_for_channelz(elem, batch); + maybe_intercept_metadata_for_channelz(elem, batch); batch->handler_private.extra_arg = calld->subchannel_call; GRPC_CLOSURE_INIT(&batch->handler_private.closure, resume_pending_batch_in_call_combiner, batch, @@ -2736,6 +2670,65 @@ static void pick_done(void* arg, grpc_error* error) { } } +static void recv_trailing_metadata_ready_channelz(void* arg, + grpc_error* error) { + grpc_call_element* elem = static_cast(arg); + channel_data* chand = static_cast(elem->channel_data); + call_data* calld = static_cast(elem->call_data); + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: got recv_trailing_metadata_ready_channelz, " + "error=%s", + chand, calld, grpc_error_string(error)); + } + GPR_ASSERT(calld->recv_trailing_metadata_batch != nullptr); + grpc_status_code status = GRPC_STATUS_OK; + grpc_metadata_batch* md_batch = calld->recv_trailing_metadata_batch; + get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, nullptr); + grpc_core::channelz::SubchannelNode* channelz_subchannel = + calld->pick.connected_subchannel->channelz_subchannel(); + GPR_ASSERT(channelz_subchannel != nullptr); + if (status == GRPC_STATUS_OK) { + channelz_subchannel->RecordCallSucceeded(); + } else { + channelz_subchannel->RecordCallFailed(); + } + calld->recv_trailing_metadata_batch = nullptr; + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata, error); +} + +// If channelz is enabled, intercept recv_trailing so that we may check the +// status and associate it to a subchannel. +// Returns true if callback was intercepted, false otherwise. +static void maybe_intercept_metadata_for_channelz( + grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { + call_data* calld = static_cast(elem->call_data); + // only intercept payloads with recv trailing. + if (!batch->recv_trailing_metadata) { + return; + } + // only add interceptor is channelz is enabled. + if (calld->pick.connected_subchannel->channelz_subchannel() == nullptr) { + return; + } + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, + "calld=%p batch=%p: intercepting recv trailing for channelz", calld, + batch); + } + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_channelz, + recv_trailing_metadata_ready_channelz, elem, + grpc_schedule_on_exec_ctx); + // save some state needed for the interception callback. + GPR_ASSERT(calld->recv_trailing_metadata_batch == nullptr); + calld->recv_trailing_metadata_batch = + batch->payload->recv_trailing_metadata.recv_trailing_metadata; + calld->original_recv_trailing_metadata = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->recv_trailing_metadata_ready_channelz; +} + static void maybe_add_call_to_channel_interested_parties_locked( grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index bd2735929c8..db5d05140db 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -79,7 +79,7 @@ class BaseNode : public RefCounted { const intptr_t uuid_; }; -// This class is a helper class for channelz entities that deal with Channels +// This class is a helper class for channelz entities that deal with Channels, // Subchannels, and Servers, since those have similar proto definitions. // This class has the ability to: // - track calls_{started,succeeded,failed} @@ -133,6 +133,9 @@ class ChannelNode : public BaseNode { // so it leaves these implementations blank. // // This is utilizing the template method design pattern. + // + // TODO(ncteisen): remove these template methods in favor of manual traversal + // and mutation of the grpc_json object. virtual void PopulateConnectivityState(grpc_json* json) {} virtual void PopulateChildRefs(grpc_json* json) {} @@ -158,7 +161,7 @@ class ChannelNode : public BaseNode { void RecordCallSucceeded() { call_counter_.RecordCallSucceeded(); } private: - // to allow the channel trace test to access trace(); + // to allow the channel trace test to access trace_. friend class testing::ChannelNodePeer; grpc_channel* channel_ = nullptr; UniquePtr target_; diff --git a/src/core/lib/channel/connected_channel.cc b/src/core/lib/channel/connected_channel.cc index 90a02546633..4a4f0e49d00 100644 --- a/src/core/lib/channel/connected_channel.cc +++ b/src/core/lib/channel/connected_channel.cc @@ -104,18 +104,18 @@ static void con_start_transport_stream_op_batch( if (batch->recv_initial_metadata) { callback_state* state = &calld->recv_initial_metadata_ready; intercept_callback( - calld, state, false, "connected_recv_initial_metadata_ready", + calld, state, false, "recv_initial_metadata_ready", &batch->payload->recv_initial_metadata.recv_initial_metadata_ready); } if (batch->recv_message) { callback_state* state = &calld->recv_message_ready; - intercept_callback(calld, state, false, "connected_recv_message_ready", + intercept_callback(calld, state, false, "recv_message_ready", &batch->payload->recv_message.recv_message_ready); } if (batch->recv_trailing_metadata) { callback_state* state = &calld->recv_trailing_metadata_ready; intercept_callback( - calld, state, false, "connected_recv_trailing_metadata_ready", + calld, state, false, "recv_trailing_metadata_ready", &batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready); } if (batch->cancel_stream) { diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 3d69db4f83c..eb7e67233b7 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -1425,7 +1425,7 @@ static void receiving_stream_ready_in_call_combiner(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; - GRPC_CALL_COMBINER_STOP(&call->call_combiner, "call_recv_message_ready"); + GRPC_CALL_COMBINER_STOP(&call->call_combiner, "recv_message_ready"); receiving_stream_ready(bctlp, error); } @@ -1510,8 +1510,7 @@ static void receiving_initial_metadata_ready(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; - GRPC_CALL_COMBINER_STOP(&call->call_combiner, - "call_recv_initial_metadata_ready"); + GRPC_CALL_COMBINER_STOP(&call->call_combiner, "recv_initial_metadata_ready"); add_batch_error(bctl, GRPC_ERROR_REF(error), false); if (error == GRPC_ERROR_NONE) { @@ -1562,8 +1561,7 @@ static void receiving_initial_metadata_ready(void* bctlp, grpc_error* error) { static void receiving_trailing_metadata_ready(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; - GRPC_CALL_COMBINER_STOP(&call->call_combiner, - "call_recv_trailing_metadata_ready"); + GRPC_CALL_COMBINER_STOP(&call->call_combiner, "recv_trailing_metadata_ready"); add_batch_error(bctl, GRPC_ERROR_REF(error), false); grpc_metadata_batch* md = &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index e33277753b5..d594445bfb9 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -44,8 +44,8 @@ namespace testing { // testing peer to access channel internals class ChannelNodePeer { public: - ChannelNodePeer(ChannelNode* node) : node_(node) {} - ChannelTrace* trace() { return &node_->trace_; } + explicit ChannelNodePeer(ChannelNode* node) : node_(node) {} + ChannelTrace* trace() const { return &node_->trace_; } private: ChannelNode* node_; diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index 8fa46a18dae..09189fa36df 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -46,8 +46,8 @@ namespace testing { // testing peer to access channel internals class CallCountingHelperPeer { public: - CallCountingHelperPeer(CallCountingHelper* node) : node_(node) {} - grpc_millis last_call_started_millis() { + explicit CallCountingHelperPeer(CallCountingHelper* node) : node_(node) {} + grpc_millis last_call_started_millis() const { return (grpc_millis)gpr_atm_no_barrier_load( &node_->last_call_started_millis_); } From fe1f7f58139a3ccafb7b8e8ca92d5d209880a3e5 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 7 Sep 2018 15:58:22 -0700 Subject: [PATCH 320/546] reviewer feedback --- src/core/lib/channel/channelz.cc | 3 --- src/core/lib/channel/channelz.h | 2 -- src/core/lib/surface/call.cc | 11 +++++------ src/core/lib/surface/channel.cc | 4 ++-- test/core/channel/channelz_test.cc | 17 +++++++++-------- test/core/end2end/tests/channelz.cc | 4 ++-- 6 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index bb790056544..375cf25cc66 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -181,9 +181,6 @@ grpc_json* ServerNode::RenderJson() { // ask CallCountingHelper to populate trace and call count data. call_counter_.PopulateCallCounts(json); json = top_level_json; - // template method. Child classes may override this to add their specific - // functionality. - PopulateSockets(json); return top_level_json; } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 9a448d3b389..603ec0b4732 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -174,8 +174,6 @@ class ServerNode : public BaseNode { grpc_json* RenderJson() override; - void PopulateSockets(grpc_json* json) {} - // proxy methods to composed classes. void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { trace_.AddTraceEvent(severity, data); diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 826c0fb8348..bff3ec379f8 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -167,8 +167,6 @@ struct grpc_call { grpc_completion_queue* cq; grpc_polling_entity pollent; grpc_channel* channel; - // backpointer to owning server if this is a server side call. - grpc_server* server; gpr_timespec start_time; /* parent_call* */ gpr_atm parent_call_atm; child_call* child; @@ -250,6 +248,8 @@ struct grpc_call { } client; struct { int* cancelled; + // backpointer to owning server if this is a server side call. + grpc_server* server; } server; } final_op; @@ -369,7 +369,6 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, grpc_slice path = grpc_empty_slice(); if (call->is_client) { GRPC_STATS_INC_CLIENT_CALLS_CREATED(); - call->server = nullptr; GPR_ASSERT(args->add_initial_metadata_count < MAX_SEND_EXTRA_METADATA_COUNT); for (i = 0; i < args->add_initial_metadata_count; i++) { @@ -384,7 +383,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, static_cast(args->add_initial_metadata_count); } else { GRPC_STATS_INC_SERVER_CALLS_CREATED(); - call->server = args->server; + call->final_op.server.server = args->server; GPR_ASSERT(args->add_initial_metadata_count == 0); call->send_extra_metadata_count = 0; } @@ -496,7 +495,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, } } else { grpc_core::channelz::ServerNode* channelz_server = - grpc_server_get_channelz_node(call->server); + grpc_server_get_channelz_node(call->final_op.server.server); if (channelz_server != nullptr) { channelz_server->RecordCallStarted(); } @@ -1286,7 +1285,7 @@ static void post_batch_completion(batch_control* bctl) { get_final_status(call, set_cancelled_value, call->final_op.server.cancelled, nullptr, nullptr); grpc_core::channelz::ServerNode* channelz_server = - grpc_server_get_channelz_node(call->server); + grpc_server_get_channelz_node(call->final_op.server.server); if (channelz_server != nullptr) { if (*call->final_op.server.cancelled) { channelz_server->RecordCallFailed(); diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index 815d302577a..52056b86711 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -166,8 +166,8 @@ grpc_channel* grpc_channel_create_with_builder( } grpc_channel_args_destroy(args); - // only track client channels since server channels are held in the - // grpc_server channel. + // we only need to do the channelz bookkeeping for clients here. The channelz + // bookkeeping for server channels occurs in src/core/lib/surface/server.cc if (channelz_enabled && channel->is_client) { channel->channelz_channel = channel_node_create_func( channel, channel_tracer_max_nodes, !internal_channel); diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index f947617d0fd..4bfab4e2eec 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -146,20 +146,21 @@ class ChannelFixture { class ServerFixture { public: - ServerFixture(int max_trace_nodes = 0) { - grpc_arg server_a[2]; - server_a[0] = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE), - max_trace_nodes); - server_a[1] = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ENABLE_CHANNELZ), true); + explicit ServerFixture(int max_trace_nodes = 0) { + grpc_arg server_a[] = { + grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE), + max_trace_nodes), + grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ENABLE_CHANNELZ), true), + }; grpc_channel_args server_args = {GPR_ARRAY_SIZE(server_a), server_a}; server_ = grpc_server_create(&server_args, nullptr); } ~ServerFixture() { grpc_server_destroy(server_); } - grpc_server* server() { return server_; } + grpc_server* server() const { return server_; } private: grpc_server* server_; diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index f96c430b69f..40a0370f0ea 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -240,7 +240,7 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"2\"")); GPR_ASSERT(nullptr != strstr(json, "\"callsFailed\":\"1\"")); GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"1\"")); - // channel tracing is not enables, so these should not be preset. + // channel tracing is not enabled, so these should not be preset. GPR_ASSERT(nullptr == strstr(json, "\"trace\"")); GPR_ASSERT(nullptr == strstr(json, "\"description\":\"Channel created\"")); GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); @@ -252,7 +252,7 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"2\"")); GPR_ASSERT(nullptr != strstr(json, "\"callsFailed\":\"1\"")); GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"1\"")); - // channel tracing is not enables, so these should not be preset. + // channel tracing is not enabled, so these should not be preset. GPR_ASSERT(nullptr == strstr(json, "\"trace\"")); GPR_ASSERT(nullptr == strstr(json, "\"description\":\"Channel created\"")); GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); From 4205b97dd9e4f9e03ca4ce5f2d5bcfa6984a55eb Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 7 Sep 2018 16:02:08 -0700 Subject: [PATCH 321/546] reviewer feedback --- src/cpp/server/channelz/channelz_service.cc | 3 --- test/cpp/end2end/channelz_service_test.cc | 9 +-------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc index f6f6e47917b..e0ef4acd58f 100644 --- a/src/cpp/server/channelz/channelz_service.cc +++ b/src/cpp/server/channelz/channelz_service.cc @@ -32,7 +32,6 @@ Status ChannelzService::GetTopChannels( ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request, channelz::v1::GetTopChannelsResponse* response) { char* json_str = grpc_channelz_get_top_channels(request->start_channel_id()); - // gpr_log(GPR_ERROR, "%s", json_str); google::protobuf::util::Status s = google::protobuf::util::JsonStringToMessage(json_str, response); gpr_free(json_str); @@ -46,7 +45,6 @@ Status ChannelzService::GetChannel( ServerContext* unused, const channelz::v1::GetChannelRequest* request, channelz::v1::GetChannelResponse* response) { char* json_str = grpc_channelz_get_channel(request->channel_id()); - // gpr_log(GPR_ERROR, "%s", json_str); google::protobuf::util::Status s = google::protobuf::util::JsonStringToMessage(json_str, response); gpr_free(json_str); @@ -60,7 +58,6 @@ Status ChannelzService::GetSubchannel( ServerContext* unused, const channelz::v1::GetSubchannelRequest* request, channelz::v1::GetSubchannelResponse* response) { char* json_str = grpc_channelz_get_subchannel(request->subchannel_id()); - // gpr_log(GPR_ERROR, "%s", json_str); google::protobuf::util::Status s = google::protobuf::util::JsonStringToMessage(json_str, response); gpr_free(json_str); diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index 504eb8441ee..7fe80832515 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -360,7 +360,6 @@ TEST_F(ChannelzServerTest, ManySubchannels) { SendFailedEcho(1); SendFailedEcho(2); } - GetTopChannelsRequest gtc_request; GetTopChannelsResponse gtc_response; gtc_request.set_start_channel_id(0); @@ -369,11 +368,6 @@ TEST_F(ChannelzServerTest, ManySubchannels) { channelz_stub_->GetTopChannels(&context, gtc_request, >c_response); EXPECT_TRUE(s.ok()) << s.error_message(); EXPECT_EQ(gtc_response.channel_size(), kNumChannels); - - // std::string gtc_str; - // google::protobuf::TextFormat::PrintToString(gtc_response, >c_str); - // std::cout << "GetTopChannels:\n" << gtc_str << "\n"; - for (int i = 0; i < gtc_response.channel_size(); ++i) { // if the channel sent no RPCs, then expect no subchannels to have been // created. @@ -381,8 +375,7 @@ TEST_F(ChannelzServerTest, ManySubchannels) { EXPECT_EQ(gtc_response.channel(i).subchannel_ref_size(), 0); continue; } - // Since this is pick first, we know that there was only one subchannel - // used. We request it here. + // The resolver must return at least one address. ASSERT_GT(gtc_response.channel(i).subchannel_ref_size(), 0); GetSubchannelRequest gsc_request; GetSubchannelResponse gsc_response; From 86f1c7a5df2eb71e653ab8f227582e40c73a4c5c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 7 Sep 2018 16:54:31 -0700 Subject: [PATCH 322/546] Be cautious and wait for possible error causing callbacks before we treat trailing metadata --- .../filters/http/client/http_client_filter.cc | 18 ++++++++++++- .../filters/http/server/http_server_filter.cc | 20 +++++++++++++- .../message_size/message_size_filter.cc | 18 ++++++++++++- .../security/transport/server_auth_filter.cc | 27 ++++++++++++++++--- 4 files changed, 77 insertions(+), 6 deletions(-) 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 91fa163fecb..c7d7f333a5b 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -67,6 +67,8 @@ struct call_data { grpc_closure on_send_message_next_done; grpc_closure* original_send_message_on_complete; grpc_closure send_message_on_complete; + grpc_error* recv_trailing_metadata_err; + bool seen_recv_trailing_metadata_ready; }; struct channel_data { @@ -157,12 +159,25 @@ static void recv_initial_metadata_ready(void* user_data, grpc_error* error) { } else { GRPC_ERROR_REF(error); } - GRPC_CLOSURE_RUN(calld->original_recv_initial_metadata_ready, error); + grpc_closure* closure = calld->original_recv_initial_metadata_ready; + calld->original_recv_initial_metadata_ready = nullptr; + if (calld->seen_recv_trailing_metadata_ready) { + GRPC_CALL_COMBINER_START( + calld->call_combiner, &calld->recv_trailing_metadata_ready, + calld->recv_trailing_metadata_err, "continue recv trailing metadata"); + } + GRPC_CLOSURE_RUN(closure, error); } static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); + if (calld->original_recv_initial_metadata_ready != nullptr) { + calld->recv_trailing_metadata_err = GRPC_ERROR_REF(error); + calld->seen_recv_trailing_metadata_ready = true; + GRPC_CALL_COMBINER_STOP(calld->call_combiner, "wait for initial metadata"); + return; + } if (error == GRPC_ERROR_NONE) { error = client_filter_incoming_metadata(elem, calld->recv_trailing_metadata); @@ -427,6 +442,7 @@ static grpc_error* init_call_elem(grpc_call_element* elem, const grpc_call_element_args* args) { call_data* calld = static_cast(elem->call_data); calld->call_combiner = args->call_combiner; + calld->seen_recv_trailing_metadata_ready = false; GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready, recv_initial_metadata_ready, elem, grpc_schedule_on_exec_ctx); 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 926afeec84f..484ce9c22f3 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -64,6 +64,9 @@ struct call_data { grpc_closure recv_trailing_metadata_ready; grpc_closure* original_recv_trailing_metadata_ready; + + grpc_error* recv_trailing_metadata_ready_error; + bool seen_recv_trailing_metadata_ready; }; } // namespace @@ -291,7 +294,15 @@ static void hs_recv_initial_metadata_ready(void* user_data, grpc_error* err) { } else { GRPC_ERROR_REF(err); } - GRPC_CLOSURE_RUN(calld->original_recv_initial_metadata_ready, err); + grpc_closure* closure = calld->original_recv_initial_metadata_ready; + calld->original_recv_initial_metadata_ready = nullptr; + if (calld->seen_recv_trailing_metadata_ready) { + GRPC_CALL_COMBINER_START(calld->call_combiner, + &calld->recv_trailing_metadata_ready, + calld->recv_trailing_metadata_ready_error, + "continue recv trailing metadata"); + } + GRPC_CLOSURE_RUN(closure, err); } static void hs_recv_message_ready(void* user_data, grpc_error* err) { @@ -321,6 +332,12 @@ static void hs_recv_message_ready(void* user_data, grpc_error* err) { static void hs_recv_trailing_metadata_ready(void* user_data, grpc_error* err) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); + if (calld->original_recv_initial_metadata_ready) { + calld->recv_trailing_metadata_ready_error = GRPC_ERROR_REF(err); + calld->seen_recv_trailing_metadata_ready = true; + GRPC_CALL_COMBINER_STOP(calld->call_combiner, "wait for initial metadata"); + return; + } err = grpc_error_add_child( GRPC_ERROR_REF(err), GRPC_ERROR_REF(calld->recv_initial_metadata_ready_error)); @@ -405,6 +422,7 @@ static grpc_error* hs_init_call_elem(grpc_call_element* elem, const grpc_call_element_args* args) { call_data* calld = static_cast(elem->call_data); calld->call_combiner = args->call_combiner; + calld->seen_recv_trailing_metadata_ready = false; GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready, hs_recv_initial_metadata_ready, elem, grpc_schedule_on_exec_ctx); 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 c17df86f3da..01d483f45e7 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -108,6 +108,8 @@ struct call_data { grpc_closure* next_recv_message_ready; // Original recv_trailing_metadata callback, invoked after our own. grpc_closure* original_recv_trailing_metadata_ready; + bool seen_recv_trailing_metadata; + grpc_error* recv_trailing_metadata_error; }; struct channel_data { @@ -147,7 +149,14 @@ static void recv_message_ready(void* user_data, grpc_error* error) { GRPC_ERROR_REF(error); } // Invoke the next callback. - GRPC_CLOSURE_RUN(calld->next_recv_message_ready, error); + grpc_closure* closure = calld->next_recv_message_ready; + calld->next_recv_message_ready = nullptr; + if (calld->seen_recv_trailing_metadata) { + GRPC_CALL_COMBINER_START( + calld->call_combiner, &calld->recv_trailing_metadata_ready, + calld->recv_trailing_metadata_error, "continue recv trailing metadata"); + } + GRPC_CLOSURE_RUN(closure, error); } // Callback invoked on completion of recv_trailing_metadata @@ -155,6 +164,12 @@ static void recv_message_ready(void* user_data, grpc_error* error) { static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); + if (calld->next_recv_message_ready) { + calld->seen_recv_trailing_metadata = true; + calld->recv_trailing_metadata_error = GRPC_ERROR_REF(error); + GRPC_CALL_COMBINER_STOP(calld->call_combiner, "wait for recv message"); + return; + } error = grpc_error_add_child(GRPC_ERROR_REF(error), GRPC_ERROR_REF(calld->error)); // Invoke the next callback. @@ -209,6 +224,7 @@ static grpc_error* init_call_elem(grpc_call_element* elem, calld->next_recv_message_ready = nullptr; calld->original_recv_trailing_metadata_ready = nullptr; calld->error = GRPC_ERROR_NONE; + calld->seen_recv_trailing_metadata = false; GRPC_CLOSURE_INIT(&calld->recv_message_ready, recv_message_ready, elem, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc index 552e70130ad..05dfd09ffb7 100644 --- a/src/core/lib/security/transport/server_auth_filter.cc +++ b/src/core/lib/security/transport/server_auth_filter.cc @@ -49,6 +49,8 @@ struct call_data { size_t num_consumed_md; grpc_closure cancel_closure; gpr_atm state; // async_state + grpc_error* recv_trailing_metadata_error; + bool seen_recv_trailing_ready; }; struct channel_data { @@ -115,7 +117,14 @@ static void on_md_processing_done_inner(grpc_call_element* elem, remove_consumed_md, elem, "Response metadata filtering error"); } calld->error = GRPC_ERROR_REF(error); - GRPC_CLOSURE_SCHED(calld->original_recv_initial_metadata_ready, error); + grpc_closure* closure = calld->original_recv_initial_metadata_ready; + calld->original_recv_initial_metadata_ready = nullptr; + if (calld->seen_recv_trailing_ready) { + GRPC_CALL_COMBINER_START( + calld->call_combiner, &calld->recv_trailing_metadata_ready, + calld->recv_trailing_metadata_error, "continue recv trailing metadata"); + } + GRPC_CLOSURE_SCHED(closure, error); } // Called from application code. @@ -184,13 +193,24 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { return; } } - GRPC_CLOSURE_RUN(calld->original_recv_initial_metadata_ready, - GRPC_ERROR_REF(error)); + grpc_closure* closure = calld->original_recv_initial_metadata_ready; + calld->original_recv_initial_metadata_ready = nullptr; + if (calld->seen_recv_trailing_ready) { + GRPC_CALL_COMBINER_START( + calld->call_combiner, &calld->recv_trailing_metadata_ready, + calld->recv_trailing_metadata_error, "continue recv trailing metadata"); + } + GRPC_CLOSURE_RUN(closure, GRPC_ERROR_REF(error)); } static void recv_trailing_metadata_ready(void* user_data, grpc_error* err) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); + if (calld->original_recv_initial_metadata_ready) { + calld->recv_trailing_metadata_error = GRPC_ERROR_REF(err); + calld->seen_recv_trailing_ready = true; + GRPC_CALL_COMBINER_STOP(calld->call_combiner, "wait for initial metadata"); + } err = grpc_error_add_child(GRPC_ERROR_REF(err), GRPC_ERROR_REF(calld->error)); GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); } @@ -228,6 +248,7 @@ static grpc_error* init_call_elem(grpc_call_element* elem, GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, recv_trailing_metadata_ready, elem, grpc_schedule_on_exec_ctx); + calld->seen_recv_trailing_ready = false; // Create server security context. Set its auth context from channel // data and save it in the call context. grpc_server_security_context* server_ctx = From 30e7b02b5c8bc55c109ed84dfa30663ce90e134b Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 7 Sep 2018 17:02:57 -0700 Subject: [PATCH 323/546] Also initialize closures again --- src/core/ext/filters/http/client/http_client_filter.cc | 3 +++ src/core/ext/filters/http/server/http_server_filter.cc | 3 +++ src/core/ext/filters/message_size/message_size_filter.cc | 3 +++ src/core/lib/security/transport/server_auth_filter.cc | 3 +++ 4 files changed, 12 insertions(+) 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 c7d7f333a5b..e4030afcb45 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -175,6 +175,9 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { if (calld->original_recv_initial_metadata_ready != nullptr) { calld->recv_trailing_metadata_err = GRPC_ERROR_REF(error); calld->seen_recv_trailing_metadata_ready = true; + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, + recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); GRPC_CALL_COMBINER_STOP(calld->call_combiner, "wait for initial metadata"); return; } 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 484ce9c22f3..90336103cfa 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -335,6 +335,9 @@ static void hs_recv_trailing_metadata_ready(void* user_data, grpc_error* err) { if (calld->original_recv_initial_metadata_ready) { calld->recv_trailing_metadata_ready_error = GRPC_ERROR_REF(err); calld->seen_recv_trailing_metadata_ready = true; + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, + hs_recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); GRPC_CALL_COMBINER_STOP(calld->call_combiner, "wait for initial metadata"); return; } 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 01d483f45e7..d85c299abe8 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -167,6 +167,9 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { if (calld->next_recv_message_ready) { calld->seen_recv_trailing_metadata = true; calld->recv_trailing_metadata_error = GRPC_ERROR_REF(error); + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, + recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); GRPC_CALL_COMBINER_STOP(calld->call_combiner, "wait for recv message"); return; } diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc index 05dfd09ffb7..882f9859599 100644 --- a/src/core/lib/security/transport/server_auth_filter.cc +++ b/src/core/lib/security/transport/server_auth_filter.cc @@ -209,6 +209,9 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* err) { if (calld->original_recv_initial_metadata_ready) { calld->recv_trailing_metadata_error = GRPC_ERROR_REF(err); calld->seen_recv_trailing_ready = true; + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, + recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); GRPC_CALL_COMBINER_STOP(calld->call_combiner, "wait for initial metadata"); } err = grpc_error_add_child(GRPC_ERROR_REF(err), GRPC_ERROR_REF(calld->error)); From 97cbec1c98b8660e6fd7ba2c1a2d23dff8e9030d Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Sat, 8 Sep 2018 17:48:42 -0700 Subject: [PATCH 324/546] WIP. Setting md_index to 0 on grpc_linked_mdelem creation --- src/core/lib/surface/call.cc | 1 + src/core/lib/transport/metadata_batch.cc | 24 +++++++++++++------ .../transport/chttp2/hpack_encoder_test.cc | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index def99f5a222..a72a3ce57cf 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -374,6 +374,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, MAX_SEND_EXTRA_METADATA_COUNT); for (i = 0; i < args->add_initial_metadata_count; i++) { call->send_extra_metadata[i].md = args->add_initial_metadata[i]; + call->send_extra_metadata[i].md_index = 0; if (grpc_slice_eq(GRPC_MDKEY(args->add_initial_metadata[i]), GRPC_MDSTR_PATH)) { path = grpc_slice_ref_internal( diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index 788681f006c..2e19071fb25 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -264,6 +264,7 @@ grpc_error* grpc_metadata_batch_add_head(grpc_metadata_batch* batch, grpc_linked_mdelem* storage, grpc_mdelem elem_to_add) { GPR_ASSERT(!GRPC_MDISNULL(elem_to_add)); + storage->md_index = 0; storage->md = elem_to_add; return grpc_metadata_batch_link_head(batch, storage); } @@ -310,6 +311,7 @@ grpc_error* grpc_metadata_batch_add_tail(grpc_metadata_batch* batch, grpc_mdelem elem_to_add) { GPR_ASSERT(!GRPC_MDISNULL(elem_to_add)); storage->md = elem_to_add; + storage->md_index = 0; return grpc_metadata_batch_link_tail(batch, storage); } @@ -459,12 +461,15 @@ grpc_error* grpc_metadata_batch_filter(grpc_metadata_batch* batch, grpc_error* error = GRPC_ERROR_NONE; while (l) { grpc_linked_mdelem* next = l->next; - grpc_filtered_mdelem new_mdelem = func(user_data, l->md); - add_error(&error, new_mdelem.error, composite_error_string); - if (GRPC_MDISNULL(new_mdelem.md)) { - grpc_metadata_batch_remove(batch, l); - } else if (new_mdelem.md.payload != l->md.payload) { - grpc_metadata_batch_substitute(batch, l, new_mdelem.md); + //TODO(hcaseyal): provide a mechanism to filter mdelems with indices + if (!is_mdelem_index_used(l->md_index)) { + grpc_filtered_mdelem new_mdelem = func(user_data, l->md); + add_error(&error, new_mdelem.error, composite_error_string); + if (GRPC_MDISNULL(new_mdelem.md)) { + grpc_metadata_batch_remove(batch, l); + } else if (new_mdelem.md.payload != l->md.payload) { + grpc_metadata_batch_substitute(batch, l, new_mdelem.md); + } } l = next; } @@ -479,8 +484,13 @@ void grpc_metadata_batch_copy(grpc_metadata_batch* src, 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_error* error = nullptr; + if (is_mdelem_index_used(elem->md_index)) { + error = grpc_metadata_batch_add_tail_index(dst, &storage[i++], elem->md_index); + } else { + 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 diff --git a/test/core/transport/chttp2/hpack_encoder_test.cc b/test/core/transport/chttp2/hpack_encoder_test.cc index 39a7973da9e..ab59ee9c5b1 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.cc +++ b/test/core/transport/chttp2/hpack_encoder_test.cc @@ -205,7 +205,7 @@ static void verify_table_size_change_match_elem_size(const char* key, size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem, use_true_binary); size_t initial_table_size = g_compressor.table_size; grpc_linked_mdelem* e = - static_cast(gpr_malloc(sizeof(*e))); + static_cast(gpr_zalloc(sizeof(*e))); grpc_metadata_batch b; grpc_metadata_batch_init(&b); e[0].md = elem; From 7c368ce71b69f829e9b1d362d107d04f029a125f Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Sat, 8 Sep 2018 18:56:57 -0700 Subject: [PATCH 325/546] Clang tidy --- src/core/lib/transport/metadata_batch.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index 2e19071fb25..e2918fa08ab 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -461,7 +461,7 @@ grpc_error* grpc_metadata_batch_filter(grpc_metadata_batch* batch, grpc_error* error = GRPC_ERROR_NONE; while (l) { grpc_linked_mdelem* next = l->next; - //TODO(hcaseyal): provide a mechanism to filter mdelems with indices + // TODO(hcaseyal): provide a mechanism to filter mdelems with indices if (!is_mdelem_index_used(l->md_index)) { grpc_filtered_mdelem new_mdelem = func(user_data, l->md); add_error(&error, new_mdelem.error, composite_error_string); @@ -486,10 +486,11 @@ void grpc_metadata_batch_copy(grpc_metadata_batch* src, elem = elem->next) { grpc_error* error = nullptr; if (is_mdelem_index_used(elem->md_index)) { - error = grpc_metadata_batch_add_tail_index(dst, &storage[i++], elem->md_index); + error = grpc_metadata_batch_add_tail_index(dst, &storage[i++], + elem->md_index); } else { error = grpc_metadata_batch_add_tail(dst, &storage[i++], - GRPC_MDELEM_REF(elem->md)); + 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 From 5e2f7c472a6f1ed4b174eb8591b4924093d43607 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Sat, 8 Sep 2018 21:33:40 -0700 Subject: [PATCH 326/546] Fix objective c unit test and debugging functions --- src/core/lib/transport/transport_op_string.cc | 8 +++++++- src/objective-c/tests/CronetUnitTests/CronetUnitTests.m | 8 ++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/core/lib/transport/transport_op_string.cc b/src/core/lib/transport/transport_op_string.cc index 8c7db642a54..736c2b17778 100644 --- a/src/core/lib/transport/transport_op_string.cc +++ b/src/core/lib/transport/transport_op_string.cc @@ -48,7 +48,13 @@ static void put_metadata_list(gpr_strvec* b, grpc_metadata_batch md) { grpc_linked_mdelem* m; for (m = md.list.head; m != nullptr; m = m->next) { if (m != md.list.head) gpr_strvec_add(b, gpr_strdup(", ")); - put_metadata(b, m->md); + if (is_valid_mdelem_index(m->md_index)) { + char* tmp; + gpr_asprintf(&tmp, "index=%d" , m->md_index); + gpr_strvec_add(b, gpr_strdup("index=")); + } else { + put_metadata(b, m->md); + } } if (md.deadline != GRPC_MILLIS_INF_FUTURE) { char* tmp; diff --git a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m index 75a669da4d4..79cc8071e74 100644 --- a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m +++ b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m @@ -140,11 +140,11 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), grpc_slice_from_static_string("val1"), 0, - {{NULL, NULL, NULL, NULL}}}, + {0, {NULL, NULL, NULL, NULL}}}, {grpc_slice_from_static_string("key2"), grpc_slice_from_static_string("val2"), 0, - {{NULL, NULL, NULL, NULL}}}}; + {0, {NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); char *addr; @@ -274,11 +274,11 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), grpc_slice_from_static_string("val1"), 0, - {{NULL, NULL, NULL, NULL}}}, + {0, {NULL, NULL, NULL, NULL}}}, {grpc_slice_from_static_string("key2"), grpc_slice_from_static_string("val2"), 0, - {{NULL, NULL, NULL, NULL}}}}; + {0, {NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); char *addr; From 1a92eb46d4e804cf1379f186ff5cc4a8b61130d6 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Sat, 8 Sep 2018 21:41:49 -0700 Subject: [PATCH 327/546] Clang tidy --- src/core/lib/transport/transport_op_string.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/transport/transport_op_string.cc b/src/core/lib/transport/transport_op_string.cc index 736c2b17778..9c362f669cc 100644 --- a/src/core/lib/transport/transport_op_string.cc +++ b/src/core/lib/transport/transport_op_string.cc @@ -50,7 +50,7 @@ static void put_metadata_list(gpr_strvec* b, grpc_metadata_batch md) { if (m != md.list.head) gpr_strvec_add(b, gpr_strdup(", ")); if (is_valid_mdelem_index(m->md_index)) { char* tmp; - gpr_asprintf(&tmp, "index=%d" , m->md_index); + gpr_asprintf(&tmp, "index=%d", m->md_index); gpr_strvec_add(b, gpr_strdup("index=")); } else { put_metadata(b, m->md); From 9e086516398e05952c9c1e86a09dc0feee036ed3 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Sat, 8 Sep 2018 23:13:39 -0700 Subject: [PATCH 328/546] Fix mdelem tracing --- .../chttp2/transport/chttp2_transport.cc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 027a57d606d..b544b9eff45 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1332,12 +1332,17 @@ static void log_metadata(const grpc_metadata_batch* md_batch, uint32_t id, bool is_client, bool is_initial) { for (grpc_linked_mdelem* md = md_batch->list.head; md != nullptr; md = md->next) { - char* key = grpc_slice_to_c_string(GRPC_MDKEY(md->md)); - char* value = grpc_slice_to_c_string(GRPC_MDVALUE(md->md)); - gpr_log(GPR_INFO, "HTTP:%d:%s:%s: %s: %s", id, is_initial ? "HDR" : "TRL", - is_client ? "CLI" : "SVR", key, value); - gpr_free(key); - gpr_free(value); + if (is_valid_mdelem_index(md->md_index)) { + gpr_log(GPR_INFO, "HTTP:%d:%s:%s: hpack table index: %d", id, is_initial ? "HDR" : "TRL", + is_client ? "CLI" : "SVR", md->md_index); + } else { + char* key = grpc_slice_to_c_string(GRPC_MDKEY(md->md)); + char* value = grpc_slice_to_c_string(GRPC_MDVALUE(md->md)); + gpr_log(GPR_INFO, "HTTP:%d:%s:%s: %s: %s", id, is_initial ? "HDR" : "TRL", + is_client ? "CLI" : "SVR", key, value); + gpr_free(key); + gpr_free(value); + } } } From f2b34aabc2353d4089a32fd7b64a7a967245cabd Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Sat, 8 Sep 2018 23:14:48 -0700 Subject: [PATCH 329/546] Clang tidy --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index b544b9eff45..f510a3f52ca 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1333,8 +1333,9 @@ static void log_metadata(const grpc_metadata_batch* md_batch, uint32_t id, for (grpc_linked_mdelem* md = md_batch->list.head; md != nullptr; md = md->next) { if (is_valid_mdelem_index(md->md_index)) { - gpr_log(GPR_INFO, "HTTP:%d:%s:%s: hpack table index: %d", id, is_initial ? "HDR" : "TRL", - is_client ? "CLI" : "SVR", md->md_index); + gpr_log(GPR_INFO, "HTTP:%d:%s:%s: hpack table index: %d", id, + is_initial ? "HDR" : "TRL", is_client ? "CLI" : "SVR", + md->md_index); } else { char* key = grpc_slice_to_c_string(GRPC_MDKEY(md->md)); char* value = grpc_slice_to_c_string(GRPC_MDVALUE(md->md)); From 898009822789f1932e81714b9c7f76f1cb48d037 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Sun, 9 Sep 2018 11:16:33 -0700 Subject: [PATCH 330/546] Fix memory leak in debugging function --- src/core/lib/transport/transport_op_string.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/transport/transport_op_string.cc b/src/core/lib/transport/transport_op_string.cc index 9c362f669cc..976e2b8f7dd 100644 --- a/src/core/lib/transport/transport_op_string.cc +++ b/src/core/lib/transport/transport_op_string.cc @@ -51,7 +51,7 @@ static void put_metadata_list(gpr_strvec* b, grpc_metadata_batch md) { if (is_valid_mdelem_index(m->md_index)) { char* tmp; gpr_asprintf(&tmp, "index=%d", m->md_index); - gpr_strvec_add(b, gpr_strdup("index=")); + gpr_strvec_add(b, tmp); } else { put_metadata(b, m->md); } From 8cf33aa8fabfd9eeeb9e89f0796121d94cde7e34 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Sun, 9 Sep 2018 13:33:39 -0700 Subject: [PATCH 331/546] Fix asan bug --- test/core/client_channel/parse_address_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/core/client_channel/parse_address_test.cc b/test/core/client_channel/parse_address_test.cc index d51c6178f88..004549fa621 100644 --- a/test/core/client_channel/parse_address_test.cc +++ b/test/core/client_channel/parse_address_test.cc @@ -97,6 +97,7 @@ static void test_grpc_parse_ipv6_invalid(const char* uri_text) { grpc_uri* uri = grpc_uri_parse(uri_text, 0); grpc_resolved_address addr; GPR_ASSERT(!grpc_parse_ipv6(uri, &addr)); + grpc_uri_destroy(uri); } int main(int argc, char** argv) { From 23f0ab38fb6f09dcbf9371e6d681515e36df85a1 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Sun, 9 Sep 2018 14:06:04 -0700 Subject: [PATCH 332/546] Temporary workaround for memory leak in debugging function --- src/core/lib/transport/transport_op_string.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/lib/transport/transport_op_string.cc b/src/core/lib/transport/transport_op_string.cc index 976e2b8f7dd..7771b4d220e 100644 --- a/src/core/lib/transport/transport_op_string.cc +++ b/src/core/lib/transport/transport_op_string.cc @@ -49,9 +49,8 @@ static void put_metadata_list(gpr_strvec* b, grpc_metadata_batch md) { for (m = md.list.head; m != nullptr; m = m->next) { if (m != md.list.head) gpr_strvec_add(b, gpr_strdup(", ")); if (is_valid_mdelem_index(m->md_index)) { - char* tmp; - gpr_asprintf(&tmp, "index=%d", m->md_index); - gpr_strvec_add(b, tmp); + // TODO(hcaseyal): print out the mdelem index + gpr_strvec_add(b, gpr_strdup("indexed mdelem")); } else { put_metadata(b, m->md); } From 2ff5be8c08c75a2c2c0152694788aa1e5ed3d50d Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 10 Sep 2018 10:14:05 -0700 Subject: [PATCH 333/546] reveiwer comments --- .../filters/client_channel/client_channel.cc | 128 +++++++++--------- src/core/lib/channel/connected_channel.cc | 6 +- 2 files changed, 68 insertions(+), 66 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 4691aa1c971..388736b60a3 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -936,7 +936,7 @@ typedef struct client_channel_call_data { // state needed to support channelz interception of recv trailing metadata. grpc_closure recv_trailing_metadata_ready_channelz; grpc_closure* original_recv_trailing_metadata; - grpc_metadata_batch* recv_trailing_metadata_batch; + grpc_metadata_batch* recv_trailing_metadata; grpc_polling_entity* pollent; bool pollent_added_to_interested_parties; @@ -999,7 +999,7 @@ 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 start_pick_locked(void* arg, grpc_error* ignored); -static void maybe_intercept_metadata_for_channelz( +static void maybe_intercept_recv_trailing_metadata_for_channelz( grpc_call_element* elem, grpc_transport_stream_op_batch* batch); // @@ -1299,7 +1299,7 @@ static void pending_batches_resume(grpc_call_element* elem) { pending_batch* pending = &calld->pending_batches[i]; grpc_transport_stream_op_batch* batch = pending->batch; if (batch != nullptr) { - maybe_intercept_metadata_for_channelz(elem, batch); + maybe_intercept_recv_trailing_metadata_for_channelz(elem, batch); batch->handler_private.extra_arg = calld->subchannel_call; GRPC_CLOSURE_INIT(&batch->handler_private.closure, resume_pending_batch_in_call_combiner, batch, @@ -2589,6 +2589,69 @@ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) { closures.RunClosures(calld->call_combiner); } +// +// Channelz +// + +static void recv_trailing_metadata_ready_channelz(void* arg, + grpc_error* error) { + grpc_call_element* elem = static_cast(arg); + channel_data* chand = static_cast(elem->channel_data); + call_data* calld = static_cast(elem->call_data); + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, + "chand=%p calld=%p: got recv_trailing_metadata_ready_channelz, " + "error=%s", + chand, calld, grpc_error_string(error)); + } + GPR_ASSERT(calld->recv_trailing_metadata != nullptr); + grpc_status_code status = GRPC_STATUS_OK; + grpc_metadata_batch* md_batch = calld->recv_trailing_metadata; + get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, nullptr); + grpc_core::channelz::SubchannelNode* channelz_subchannel = + calld->pick.connected_subchannel->channelz_subchannel(); + GPR_ASSERT(channelz_subchannel != nullptr); + if (status == GRPC_STATUS_OK) { + channelz_subchannel->RecordCallSucceeded(); + } else { + channelz_subchannel->RecordCallFailed(); + } + calld->recv_trailing_metadata = nullptr; + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata, error); +} + +// If channelz is enabled, intercept recv_trailing so that we may check the +// status and associate it to a subchannel. +// Returns true if callback was intercepted, false otherwise. +static void maybe_intercept_recv_trailing_metadata_for_channelz( + grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { + call_data* calld = static_cast(elem->call_data); + // only intercept payloads with recv trailing. + if (!batch->recv_trailing_metadata) { + return; + } + // only add interceptor is channelz is enabled. + if (calld->pick.connected_subchannel->channelz_subchannel() == nullptr) { + return; + } + if (grpc_client_channel_trace.enabled()) { + gpr_log(GPR_INFO, + "calld=%p batch=%p: intercepting recv trailing for channelz", calld, + batch); + } + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_channelz, + recv_trailing_metadata_ready_channelz, elem, + grpc_schedule_on_exec_ctx); + // save some state needed for the interception callback. + GPR_ASSERT(calld->recv_trailing_metadata == nullptr); + calld->recv_trailing_metadata = + batch->payload->recv_trailing_metadata.recv_trailing_metadata; + calld->original_recv_trailing_metadata = + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; + batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = + &calld->recv_trailing_metadata_ready_channelz; +} + // // LB pick // @@ -2669,65 +2732,6 @@ static void pick_done(void* arg, grpc_error* error) { } } -static void recv_trailing_metadata_ready_channelz(void* arg, - grpc_error* error) { - grpc_call_element* elem = static_cast(arg); - channel_data* chand = static_cast(elem->channel_data); - call_data* calld = static_cast(elem->call_data); - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "chand=%p calld=%p: got recv_trailing_metadata_ready_channelz, " - "error=%s", - chand, calld, grpc_error_string(error)); - } - GPR_ASSERT(calld->recv_trailing_metadata_batch != nullptr); - grpc_status_code status = GRPC_STATUS_OK; - grpc_metadata_batch* md_batch = calld->recv_trailing_metadata_batch; - get_call_status(elem, md_batch, GRPC_ERROR_REF(error), &status, nullptr); - grpc_core::channelz::SubchannelNode* channelz_subchannel = - calld->pick.connected_subchannel->channelz_subchannel(); - GPR_ASSERT(channelz_subchannel != nullptr); - if (status == GRPC_STATUS_OK) { - channelz_subchannel->RecordCallSucceeded(); - } else { - channelz_subchannel->RecordCallFailed(); - } - calld->recv_trailing_metadata_batch = nullptr; - GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata, error); -} - -// If channelz is enabled, intercept recv_trailing so that we may check the -// status and associate it to a subchannel. -// Returns true if callback was intercepted, false otherwise. -static void maybe_intercept_metadata_for_channelz( - grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { - call_data* calld = static_cast(elem->call_data); - // only intercept payloads with recv trailing. - if (!batch->recv_trailing_metadata) { - return; - } - // only add interceptor is channelz is enabled. - if (calld->pick.connected_subchannel->channelz_subchannel() == nullptr) { - return; - } - if (grpc_client_channel_trace.enabled()) { - gpr_log(GPR_INFO, - "calld=%p batch=%p: intercepting recv trailing for channelz", calld, - batch); - } - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_channelz, - recv_trailing_metadata_ready_channelz, elem, - grpc_schedule_on_exec_ctx); - // save some state needed for the interception callback. - GPR_ASSERT(calld->recv_trailing_metadata_batch == nullptr); - calld->recv_trailing_metadata_batch = - batch->payload->recv_trailing_metadata.recv_trailing_metadata; - calld->original_recv_trailing_metadata = - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready; - batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready = - &calld->recv_trailing_metadata_ready_channelz; -} - static void maybe_add_call_to_channel_interested_parties_locked( grpc_call_element* elem) { channel_data* chand = static_cast(elem->channel_data); diff --git a/src/core/lib/channel/connected_channel.cc b/src/core/lib/channel/connected_channel.cc index 4a4f0e49d00..e2ea334dedf 100644 --- a/src/core/lib/channel/connected_channel.cc +++ b/src/core/lib/channel/connected_channel.cc @@ -126,13 +126,11 @@ static void con_start_transport_stream_op_batch( // closure for each one. callback_state* state = static_cast(gpr_malloc(sizeof(*state))); - intercept_callback(calld, state, true, - "connected_on_complete (cancel_stream)", + intercept_callback(calld, state, true, "on_complete (cancel_stream)", &batch->on_complete); } else if (batch->on_complete != nullptr) { callback_state* state = get_state_for_batch(calld, batch); - intercept_callback(calld, state, false, "connected_on_complete", - &batch->on_complete); + intercept_callback(calld, state, false, "on_complete", &batch->on_complete); } grpc_transport_perform_stream_op( chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld), batch); From 11d3309130c7ed657fecf77b981a57cc48173753 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 10 Sep 2018 11:53:18 -0700 Subject: [PATCH 334/546] Make batch_error an atomic to avoid data races --- src/core/lib/surface/call.cc | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index b07c4d6c10b..90d812dad66 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -95,7 +95,7 @@ typedef struct batch_control { grpc_closure start_batch; grpc_closure finish_batch; gpr_refcount steps_to_complete; - grpc_error* batch_error; + gpr_atm batch_error; grpc_transport_stream_op_batch op; } batch_control; @@ -1106,14 +1106,16 @@ static void finish_batch_completion(void* user_data, } static void reset_batch_errors(batch_control* bctl) { - GRPC_ERROR_UNREF(bctl->batch_error); - bctl->batch_error = GRPC_ERROR_NONE; + GRPC_ERROR_UNREF( + reinterpret_cast(gpr_atm_acq_load(&bctl->batch_error))); + gpr_atm_rel_store(&bctl->batch_error, GRPC_ERROR_NONE); } static void post_batch_completion(batch_control* bctl) { grpc_call* next_child_call; grpc_call* call = bctl->call; - grpc_error* error = GRPC_ERROR_REF(bctl->batch_error); + grpc_error* error = GRPC_ERROR_REF( + reinterpret_cast(gpr_atm_acq_load(&bctl->batch_error))); if (bctl->op.send_initial_metadata) { grpc_metadata_batch_destroy( @@ -1277,8 +1279,9 @@ static void receiving_stream_ready(void* bctlp, grpc_error* error) { grpc_call* call = bctl->call; if (error != GRPC_ERROR_NONE) { call->receiving_stream.reset(); - if (bctl->batch_error == GRPC_ERROR_NONE) { - bctl->batch_error = GRPC_ERROR_REF(error); + if (reinterpret_cast(gpr_atm_acq_load(&bctl->batch_error)) == + GRPC_ERROR_NONE) { + gpr_atm_rel_store(&bctl->batch_error, GRPC_ERROR_REF(error)); } cancel_with_error(call, GRPC_ERROR_REF(error)); } @@ -1384,8 +1387,9 @@ static void receiving_initial_metadata_ready(void* bctlp, grpc_error* error) { call->send_deadline = md->deadline; } } else { - if (bctl->batch_error == GRPC_ERROR_NONE) { - bctl->batch_error = GRPC_ERROR_REF(error); + if (reinterpret_cast gpr_atm_acq_load(&bctl->batch_error) == + GRPC_ERROR_NONE) { + gpr_atm_rel_store(&bctl->batch_error, GRPC_ERROR_REF(error)); } cancel_with_error(call, GRPC_ERROR_REF(error)); } @@ -1435,8 +1439,9 @@ static void finish_batch(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; GRPC_CALL_COMBINER_STOP(&call->call_combiner, "on_complete"); - if (bctl->batch_error == GRPC_ERROR_NONE) { - bctl->batch_error = GRPC_ERROR_REF(error); + if (reinterpret_cast gpr_atm_acq_load(&bctl->batch_error) == + GRPC_ERROR_NONE) { + gpr_atm_rel_store(&bctl->batch_error, GRPC_ERROR_REF(error)); } if (error != GRPC_ERROR_NONE) { cancel_with_error(call, GRPC_ERROR_REF(error)); From 796509b66d8245b2051f3c5dde642ff177f7b155 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 10 Sep 2018 13:11:34 -0700 Subject: [PATCH 335/546] Fix ubsan error in subchannel_list code. --- .../lb_policy/pick_first/pick_first.cc | 11 +++++---- .../lb_policy/round_robin/round_robin.cc | 11 +++++---- .../lb_policy/subchannel_list.h | 24 ++++++++++++------- 3 files changed, 27 insertions(+), 19 deletions(-) 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 602d6e92f98..ed8cc60ea1c 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 @@ -71,11 +71,12 @@ class PickFirst : public LoadBalancingPolicy { : public SubchannelData { public: - PickFirstSubchannelData(PickFirstSubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, - grpc_subchannel* subchannel, - grpc_combiner* combiner) + PickFirstSubchannelData( + SubchannelList* + subchannel_list, + const grpc_lb_user_data_vtable* user_data_vtable, + const grpc_lb_address& address, grpc_subchannel* subchannel, + grpc_combiner* combiner) : SubchannelData(subchannel_list, user_data_vtable, address, subchannel, combiner) {} 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 4195c1e9d1a..8dd5820bae8 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 @@ -89,11 +89,12 @@ class RoundRobin : public LoadBalancingPolicy { : public SubchannelData { public: - RoundRobinSubchannelData(RoundRobinSubchannelList* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, - grpc_subchannel* subchannel, - grpc_combiner* combiner) + RoundRobinSubchannelData( + SubchannelList* + subchannel_list, + const grpc_lb_user_data_vtable* user_data_vtable, + const grpc_lb_address& address, grpc_subchannel* subchannel, + grpc_combiner* combiner) : SubchannelData(subchannel_list, user_data_vtable, address, subchannel, combiner), user_data_vtable_(user_data_vtable), 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 d87de510829..5e8682e056a 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 @@ -65,6 +65,10 @@ class MySubchannelList namespace grpc_core { +// Forward declaration. +template +class SubchannelList; + // Stores data for a particular subchannel in a subchannel list. // Callers must create a subclass that implements the // ProcessConnectivityChangeLocked() method. @@ -72,7 +76,9 @@ template class SubchannelData { public: // Returns a pointer to the subchannel list containing this object. - SubchannelListType* subchannel_list() const { return subchannel_list_; } + SubchannelListType* subchannel_list() const { + return static_cast(subchannel_list_); + } // Returns the index into the subchannel list of this object. size_t Index() const { @@ -133,10 +139,11 @@ class SubchannelData { GRPC_ABSTRACT_BASE_CLASS protected: - SubchannelData(SubchannelListType* subchannel_list, - const grpc_lb_user_data_vtable* user_data_vtable, - const grpc_lb_address& address, grpc_subchannel* subchannel, - grpc_combiner* combiner); + SubchannelData( + SubchannelList* subchannel_list, + const grpc_lb_user_data_vtable* user_data_vtable, + const grpc_lb_address& address, grpc_subchannel* subchannel, + grpc_combiner* combiner); virtual ~SubchannelData(); @@ -161,7 +168,7 @@ class SubchannelData { static void OnConnectivityChangedLocked(void* arg, grpc_error* error); // Backpointer to owning subchannel list. Not owned. - SubchannelListType* subchannel_list_; + SubchannelList* subchannel_list_; // The subchannel and connected subchannel. grpc_subchannel* subchannel_; @@ -268,7 +275,7 @@ class SubchannelList template SubchannelData::SubchannelData( - SubchannelListType* subchannel_list, + SubchannelList* subchannel_list, const grpc_lb_user_data_vtable* user_data_vtable, const grpc_lb_address& address, grpc_subchannel* subchannel, grpc_combiner* combiner) @@ -532,8 +539,7 @@ SubchannelList::SubchannelList( address_uri); gpr_free(address_uri); } - subchannels_.emplace_back(static_cast(this), - addresses->user_data_vtable, + subchannels_.emplace_back(this, addresses->user_data_vtable, addresses->addresses[i], subchannel, combiner); } } From 42d9becd91bf1fa51a9775e8141ddece74ea82a6 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 10 Sep 2018 14:06:52 -0700 Subject: [PATCH 336/546] Revert "Second attempt: Implement Watch method in health check service." --- .../grpcpp/impl/codegen/completion_queue.h | 1 - .../health/default_health_check_service.cc | 484 +++--------------- .../health/default_health_check_service.h | 242 +-------- src/cpp/server/health/health.pb.c | 1 + src/cpp/server/health/health.pb.h | 7 +- src/cpp/server/server_cc.cc | 27 +- src/proto/grpc/health/v1/health.proto | 20 - .../end2end/health_service_end2end_test.cc | 76 +-- tools/distrib/check_nanopb_output.sh | 18 - 9 files changed, 105 insertions(+), 771 deletions(-) diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 6c8428ebde6..3f7d4fb765f 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -384,7 +384,6 @@ class ServerCompletionQueue : public CompletionQueue { grpc_cq_polling_type polling_type_; friend class ServerBuilder; - friend class Server; }; } // namespace grpc diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index fc3db1bba73..bfda67d0864 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -30,162 +30,29 @@ #include "src/cpp/server/health/health.pb.h" namespace grpc { - -// -// DefaultHealthCheckService -// - -DefaultHealthCheckService::DefaultHealthCheckService() { - services_map_[""].SetServingStatus(SERVING); -} - -void DefaultHealthCheckService::SetServingStatus( - const grpc::string& service_name, bool serving) { - std::unique_lock lock(mu_); - services_map_[service_name].SetServingStatus(serving ? SERVING : NOT_SERVING); -} - -void DefaultHealthCheckService::SetServingStatus(bool serving) { - const ServingStatus status = serving ? SERVING : NOT_SERVING; - std::unique_lock lock(mu_); - for (auto& p : services_map_) { - ServiceData& service_data = p.second; - service_data.SetServingStatus(status); - } -} - -DefaultHealthCheckService::ServingStatus -DefaultHealthCheckService::GetServingStatus( - const grpc::string& service_name) const { - std::lock_guard lock(mu_); - auto it = services_map_.find(service_name); - if (it == services_map_.end()) { - return NOT_FOUND; - } - const ServiceData& service_data = it->second; - return service_data.GetServingStatus(); -} - -void DefaultHealthCheckService::RegisterCallHandler( - const grpc::string& service_name, - std::shared_ptr handler) { - std::unique_lock lock(mu_); - ServiceData& service_data = services_map_[service_name]; - service_data.AddCallHandler(handler /* copies ref */); - handler->SendHealth(std::move(handler), service_data.GetServingStatus()); -} - -void DefaultHealthCheckService::UnregisterCallHandler( - const grpc::string& service_name, - std::shared_ptr handler) { - std::unique_lock lock(mu_); - auto it = services_map_.find(service_name); - if (it == services_map_.end()) return; - ServiceData& service_data = it->second; - service_data.RemoveCallHandler(std::move(handler)); - if (service_data.Unused()) { - services_map_.erase(it); - } -} - -DefaultHealthCheckService::HealthCheckServiceImpl* -DefaultHealthCheckService::GetHealthCheckService( - std::unique_ptr cq) { - GPR_ASSERT(impl_ == nullptr); - impl_.reset(new HealthCheckServiceImpl(this, std::move(cq))); - return impl_.get(); -} - -// -// DefaultHealthCheckService::ServiceData -// - -void DefaultHealthCheckService::ServiceData::SetServingStatus( - ServingStatus status) { - status_ = status; - for (auto& call_handler : call_handlers_) { - call_handler->SendHealth(call_handler /* copies ref */, status); - } -} - -void DefaultHealthCheckService::ServiceData::AddCallHandler( - std::shared_ptr handler) { - call_handlers_.insert(std::move(handler)); -} - -void DefaultHealthCheckService::ServiceData::RemoveCallHandler( - std::shared_ptr handler) { - call_handlers_.erase(std::move(handler)); -} - -// -// DefaultHealthCheckService::HealthCheckServiceImpl -// - namespace { const char kHealthCheckMethodName[] = "/grpc.health.v1.Health/Check"; -const char kHealthWatchMethodName[] = "/grpc.health.v1.Health/Watch"; } // namespace DefaultHealthCheckService::HealthCheckServiceImpl::HealthCheckServiceImpl( - DefaultHealthCheckService* database, - std::unique_ptr cq) - : database_(database), cq_(std::move(cq)) { - // Add Check() method. - check_method_ = new internal::RpcServiceMethod( - kHealthCheckMethodName, internal::RpcMethod::NORMAL_RPC, nullptr); - AddMethod(check_method_); - // Add Watch() method. - watch_method_ = new internal::RpcServiceMethod( - kHealthWatchMethodName, internal::RpcMethod::SERVER_STREAMING, nullptr); - AddMethod(watch_method_); - // Create serving thread. - thread_ = std::unique_ptr<::grpc_core::Thread>( - new ::grpc_core::Thread("grpc_health_check_service", Serve, this)); -} - -DefaultHealthCheckService::HealthCheckServiceImpl::~HealthCheckServiceImpl() { - // We will reach here after the server starts shutting down. - shutdown_ = true; - { - std::unique_lock lock(cq_shutdown_mu_); - cq_->Shutdown(); - } - thread_->Join(); -} - -void DefaultHealthCheckService::HealthCheckServiceImpl::StartServingThread() { - thread_->Start(); -} - -void DefaultHealthCheckService::HealthCheckServiceImpl::Serve(void* arg) { - HealthCheckServiceImpl* service = - reinterpret_cast(arg); - // TODO(juanlishen): This is a workaround to wait for the cq to be ready. - // Need to figure out why cq is not ready after service starts. - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(1, GPR_TIMESPAN))); - CheckCallHandler::CreateAndStart(service->cq_.get(), service->database_, - service); - WatchCallHandler::CreateAndStart(service->cq_.get(), service->database_, - service); - void* tag; - bool ok; - while (true) { - if (!service->cq_->Next(&tag, &ok)) { - // The completion queue is shutting down. - GPR_ASSERT(service->shutdown_); - break; - } - auto* next_step = static_cast(tag); - next_step->Run(ok); - } -} - -bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest( - const ByteBuffer& request, grpc::string* service_name) { + DefaultHealthCheckService* service) + : service_(service), method_(nullptr) { + internal::MethodHandler* handler = + new internal::RpcMethodHandler( + std::mem_fn(&HealthCheckServiceImpl::Check), this); + method_ = new internal::RpcServiceMethod( + kHealthCheckMethodName, internal::RpcMethod::NORMAL_RPC, handler); + AddMethod(method_); +} + +Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( + ServerContext* context, const ByteBuffer* request, ByteBuffer* response) { + // Decode request. std::vector slices; - if (!request.Dump(&slices).ok()) return false; + if (!request->Dump(&slices).ok()) { + return Status(StatusCode::INVALID_ARGUMENT, ""); + } uint8_t* request_bytes = nullptr; bool request_bytes_owned = false; size_t request_size = 0; @@ -197,13 +64,14 @@ bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest( request_size = slices[0].size(); } else { request_bytes_owned = true; - request_bytes = static_cast(gpr_malloc(request.Length())); + request_bytes = static_cast(gpr_malloc(request->Length())); uint8_t* copy_to = request_bytes; for (size_t i = 0; i < slices.size(); i++) { memcpy(copy_to, slices[i].begin(), slices[i].size()); copy_to += slices[i].size(); } } + if (request_bytes != nullptr) { pb_istream_t istream = pb_istream_from_buffer(request_bytes, request_size); bool decode_status = pb_decode( @@ -211,22 +79,26 @@ bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest( if (request_bytes_owned) { gpr_free(request_bytes); } - if (!decode_status) return false; + if (!decode_status) { + return Status(StatusCode::INVALID_ARGUMENT, ""); + } } - *service_name = request_struct.has_service ? request_struct.service : ""; - return true; -} -bool DefaultHealthCheckService::HealthCheckServiceImpl::EncodeResponse( - ServingStatus status, ByteBuffer* response) { + // Check status from the associated default health checking service. + DefaultHealthCheckService::ServingStatus serving_status = + service_->GetServingStatus( + request_struct.has_service ? request_struct.service : ""); + if (serving_status == DefaultHealthCheckService::NOT_FOUND) { + return Status(StatusCode::NOT_FOUND, ""); + } + + // Encode response grpc_health_v1_HealthCheckResponse response_struct; response_struct.has_status = true; response_struct.status = - status == NOT_FOUND - ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN - : status == SERVING - ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING - : grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING; + serving_status == DefaultHealthCheckService::SERVING + ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING + : grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING; pb_ostream_t ostream; memset(&ostream, 0, sizeof(ostream)); pb_encode(&ostream, grpc_health_v1_HealthCheckResponse_fields, @@ -236,282 +108,48 @@ bool DefaultHealthCheckService::HealthCheckServiceImpl::EncodeResponse( GRPC_SLICE_LENGTH(response_slice)); bool encode_status = pb_encode( &ostream, grpc_health_v1_HealthCheckResponse_fields, &response_struct); - if (!encode_status) return false; + if (!encode_status) { + return Status(StatusCode::INTERNAL, "Failed to encode response."); + } Slice encoded_response(response_slice, Slice::STEAL_REF); ByteBuffer response_buffer(&encoded_response, 1); response->Swap(&response_buffer); - return true; -} - -// -// DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler -// - -void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: - CreateAndStart(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service) { - std::shared_ptr self = - std::make_shared(cq, database, service); - CheckCallHandler* handler = static_cast(self.get()); - { - std::unique_lock lock(service->cq_shutdown_mu_); - if (service->shutdown_) return; - // Request a Check() call. - handler->next_ = - CallableTag(std::bind(&CheckCallHandler::OnCallReceived, handler, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - service->RequestAsyncUnary(0, &handler->ctx_, &handler->request_, - &handler->writer_, cq, cq, &handler->next_); - } -} - -DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: - CheckCallHandler(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service) - : cq_(cq), database_(database), service_(service), writer_(&ctx_) {} - -void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: - OnCallReceived(std::shared_ptr self, bool ok) { - if (!ok) { - // The value of ok being false means that the server is shutting down. - return; - } - // Spawn a new handler instance to serve the next new client. Every handler - // instance will deallocate itself when it's done. - CreateAndStart(cq_, database_, service_); - // Process request. - gpr_log(GPR_DEBUG, "[HCS %p] Health check started for handler %p", service_, - this); - grpc::string service_name; - grpc::Status status = Status::OK; - ByteBuffer response; - if (!service_->DecodeRequest(request_, &service_name)) { - status = Status(StatusCode::INVALID_ARGUMENT, ""); - } else { - ServingStatus serving_status = database_->GetServingStatus(service_name); - if (serving_status == NOT_FOUND) { - status = Status(StatusCode::NOT_FOUND, "service name unknown"); - } else if (!service_->EncodeResponse(serving_status, &response)) { - status = Status(StatusCode::INTERNAL, ""); - } - } - // Send response. - { - std::unique_lock lock(service_->cq_shutdown_mu_); - if (!service_->shutdown_) { - next_ = - CallableTag(std::bind(&CheckCallHandler::OnFinishDone, this, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - if (status.ok()) { - writer_.Finish(response, status, &next_); - } else { - writer_.FinishWithError(status, &next_); - } - } - } -} - -void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: - OnFinishDone(std::shared_ptr self, bool ok) { - if (ok) { - gpr_log(GPR_DEBUG, "[HCS %p] Health check call finished for handler %p", - service_, this); - } -} - -// -// DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler -// - -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - CreateAndStart(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service) { - std::shared_ptr self = - std::make_shared(cq, database, service); - WatchCallHandler* handler = static_cast(self.get()); - { - std::unique_lock lock(service->cq_shutdown_mu_); - if (service->shutdown_) return; - // Request AsyncNotifyWhenDone(). - handler->on_done_notified_ = - CallableTag(std::bind(&WatchCallHandler::OnDoneNotified, handler, - std::placeholders::_1, std::placeholders::_2), - self /* copies ref */); - handler->ctx_.AsyncNotifyWhenDone(&handler->on_done_notified_); - // Request a Watch() call. - handler->next_ = - CallableTag(std::bind(&WatchCallHandler::OnCallReceived, handler, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - service->RequestAsyncServerStreaming(1, &handler->ctx_, &handler->request_, - &handler->stream_, cq, cq, - &handler->next_); - } + return Status::OK; } -DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - WatchCallHandler(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service) - : cq_(cq), - database_(database), - service_(service), - stream_(&ctx_), - call_state_(WAITING_FOR_CALL) {} - -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - OnCallReceived(std::shared_ptr self, bool ok) { - if (ok) { - call_state_ = CALL_RECEIVED; - } else { - // AsyncNotifyWhenDone() needs to be called before the call starts, but the - // tag will not pop out if the call never starts ( - // https://github.com/grpc/grpc/issues/10136). So we need to manually - // release the ownership of the handler in this case. - GPR_ASSERT(on_done_notified_.ReleaseHandler() != nullptr); - } - if (!ok || shutdown_) { - // The value of ok being false means that the server is shutting down. - Shutdown(std::move(self), "OnCallReceived"); - return; - } - // Spawn a new handler instance to serve the next new client. Every handler - // instance will deallocate itself when it's done. - CreateAndStart(cq_, database_, service_); - // Parse request. - if (!service_->DecodeRequest(request_, &service_name_)) { - on_finish_done_ = - CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - stream_.Finish(Status(StatusCode::INVALID_ARGUMENT, ""), &on_finish_done_); - call_state_ = FINISH_CALLED; - return; - } - // Register the call for updates to the service. - gpr_log(GPR_DEBUG, - "[HCS %p] Health check watch started for service \"%s\" " - "(handler: %p)", - service_, service_name_.c_str(), this); - database_->RegisterCallHandler(service_name_, std::move(self)); -} - -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - SendHealth(std::shared_ptr self, ServingStatus status) { - std::unique_lock lock(mu_); - // If there's already a send in flight, cache the new status, and - // we'll start a new send for it when the one in flight completes. - if (send_in_flight_) { - pending_status_ = status; - return; - } - // Start a send. - SendHealthLocked(std::move(self), status); -} - -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - SendHealthLocked(std::shared_ptr self, ServingStatus status) { - std::unique_lock cq_lock(service_->cq_shutdown_mu_); - if (service_->shutdown_) { - cq_lock.release()->unlock(); - Shutdown(std::move(self), "SendHealthLocked"); - return; - } - send_in_flight_ = true; - call_state_ = SEND_MESSAGE_PENDING; - // Construct response. - ByteBuffer response; - if (!service_->EncodeResponse(status, &response)) { - on_finish_done_ = - CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - stream_.Finish(Status(StatusCode::INTERNAL, ""), &on_finish_done_); - return; - } - next_ = CallableTag(std::bind(&WatchCallHandler::OnSendHealthDone, this, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - stream_.Write(response, &next_); +DefaultHealthCheckService::DefaultHealthCheckService() { + services_map_.emplace("", true); } -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - OnSendHealthDone(std::shared_ptr self, bool ok) { - if (!ok || shutdown_) { - Shutdown(std::move(self), "OnSendHealthDone"); - return; - } - call_state_ = CALL_RECEIVED; - { - std::unique_lock lock(mu_); - send_in_flight_ = false; - // If we got a new status since we started the last send, start a - // new send for it. - if (pending_status_ != NOT_FOUND) { - auto status = pending_status_; - pending_status_ = NOT_FOUND; - SendHealthLocked(std::move(self), status); - } - } +void DefaultHealthCheckService::SetServingStatus( + const grpc::string& service_name, bool serving) { + std::lock_guard lock(mu_); + services_map_[service_name] = serving; } -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - OnDoneNotified(std::shared_ptr self, bool ok) { - GPR_ASSERT(ok); - done_notified_ = true; - if (ctx_.IsCancelled()) { - is_cancelled_ = true; +void DefaultHealthCheckService::SetServingStatus(bool serving) { + std::lock_guard lock(mu_); + for (auto iter = services_map_.begin(); iter != services_map_.end(); ++iter) { + iter->second = serving; } - gpr_log(GPR_DEBUG, - "[HCS %p] Healt check call is notified done (handler: %p, " - "is_cancelled: %d).", - service_, this, static_cast(is_cancelled_)); - Shutdown(std::move(self), "OnDoneNotified"); } -// TODO(roth): This method currently assumes that there will be only one -// thread polling the cq and invoking the corresponding callbacks. If -// that changes, we will need to add synchronization here. -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - Shutdown(std::shared_ptr self, const char* reason) { - if (!shutdown_) { - gpr_log(GPR_DEBUG, - "[HCS %p] Shutting down the handler (service_name: \"%s\", " - "handler: %p, reason: %s).", - service_, service_name_.c_str(), this, reason); - shutdown_ = true; - } - // OnCallReceived() may be called after OnDoneNotified(), so we need to - // try to Finish() every time we are in Shutdown(). - if (call_state_ >= CALL_RECEIVED && call_state_ < FINISH_CALLED) { - std::unique_lock lock(service_->cq_shutdown_mu_); - if (!service_->shutdown_) { - on_finish_done_ = - CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, - std::placeholders::_1, std::placeholders::_2), - std::move(self)); - // TODO(juanlishen): Maybe add a message proto for the client to - // explicitly cancel the stream so that we can return OK status in such - // cases. - stream_.Finish(Status::CANCELLED, &on_finish_done_); - call_state_ = FINISH_CALLED; - } +DefaultHealthCheckService::ServingStatus +DefaultHealthCheckService::GetServingStatus( + const grpc::string& service_name) const { + std::lock_guard lock(mu_); + const auto& iter = services_map_.find(service_name); + if (iter == services_map_.end()) { + return NOT_FOUND; } + return iter->second ? SERVING : NOT_SERVING; } -void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: - OnFinishDone(std::shared_ptr self, bool ok) { - if (ok) { - gpr_log(GPR_DEBUG, - "[HCS %p] Health check call finished (service_name: \"%s\", " - "handler: %p).", - service_, service_name_.c_str(), this); - } +DefaultHealthCheckService::HealthCheckServiceImpl* +DefaultHealthCheckService::GetHealthCheckService() { + GPR_ASSERT(impl_ == nullptr); + impl_.reset(new HealthCheckServiceImpl(this)); + return impl_.get(); } } // namespace grpc diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index edad5949362..a1ce5aa64ec 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -19,268 +19,42 @@ #ifndef GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H #define GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H -#include #include -#include -#include -#include #include -#include -#include #include #include -#include "src/core/lib/gprpp/thd.h" - namespace grpc { // Default implementation of HealthCheckServiceInterface. Server will create and // own it. class DefaultHealthCheckService final : public HealthCheckServiceInterface { public: - enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; - // The service impl to register with the server. class HealthCheckServiceImpl : public Service { public: - // Base class for call handlers. - class CallHandler { - public: - virtual ~CallHandler() = default; - virtual void SendHealth(std::shared_ptr self, - ServingStatus status) = 0; - }; + explicit HealthCheckServiceImpl(DefaultHealthCheckService* service); - HealthCheckServiceImpl(DefaultHealthCheckService* database, - std::unique_ptr cq); - - ~HealthCheckServiceImpl(); - - void StartServingThread(); + Status Check(ServerContext* context, const ByteBuffer* request, + ByteBuffer* response); private: - // A tag that can be called with a bool argument. It's tailored for - // CallHandler's use. Before being used, it should be constructed with a - // method of CallHandler and a shared pointer to the handler. The - // shared pointer will be moved to the invoked function and the function - // can only be invoked once. That makes ref counting of the handler easier, - // because the shared pointer is not bound to the function and can be gone - // once the invoked function returns (if not used any more). - class CallableTag { - public: - using HandlerFunction = - std::function, bool)>; - - CallableTag() {} - - CallableTag(HandlerFunction func, std::shared_ptr handler) - : handler_function_(std::move(func)), handler_(std::move(handler)) { - GPR_ASSERT(handler_function_ != nullptr); - GPR_ASSERT(handler_ != nullptr); - } - - // Runs the tag. This should be called only once. The handler is no - // longer owned by this tag after this method is invoked. - void Run(bool ok) { - GPR_ASSERT(handler_function_ != nullptr); - GPR_ASSERT(handler_ != nullptr); - handler_function_(std::move(handler_), ok); - } - - // Releases and returns the shared pointer to the handler. - std::shared_ptr ReleaseHandler() { - return std::move(handler_); - } - - private: - HandlerFunction handler_function_ = nullptr; - std::shared_ptr handler_; - }; - - // Call handler for Check method. - // Each handler takes care of one call. It contains per-call data and it - // will access the members of the parent class (i.e., - // DefaultHealthCheckService) for per-service health data. - class CheckCallHandler : public CallHandler { - public: - // Instantiates a CheckCallHandler and requests the next health check - // call. The handler object will manage its own lifetime, so no action is - // needed from the caller any more regarding that object. - static void CreateAndStart(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service); - - // This ctor is public because we want to use std::make_shared<> in - // CreateAndStart(). This ctor shouldn't be used elsewhere. - CheckCallHandler(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service); - - // Not used for Check. - void SendHealth(std::shared_ptr self, - ServingStatus status) override {} - - private: - // Called when we receive a call. - // Spawns a new handler so that we can keep servicing future calls. - void OnCallReceived(std::shared_ptr self, bool ok); - - // Called when Finish() is done. - void OnFinishDone(std::shared_ptr self, bool ok); - - // The members passed down from HealthCheckServiceImpl. - ServerCompletionQueue* cq_; - DefaultHealthCheckService* database_; - HealthCheckServiceImpl* service_; - - ByteBuffer request_; - GenericServerAsyncResponseWriter writer_; - ServerContext ctx_; - - CallableTag next_; - }; - - // Call handler for Watch method. - // Each handler takes care of one call. It contains per-call data and it - // will access the members of the parent class (i.e., - // DefaultHealthCheckService) for per-service health data. - class WatchCallHandler : public CallHandler { - public: - // Instantiates a WatchCallHandler and requests the next health check - // call. The handler object will manage its own lifetime, so no action is - // needed from the caller any more regarding that object. - static void CreateAndStart(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service); - - // This ctor is public because we want to use std::make_shared<> in - // CreateAndStart(). This ctor shouldn't be used elsewhere. - WatchCallHandler(ServerCompletionQueue* cq, - DefaultHealthCheckService* database, - HealthCheckServiceImpl* service); - - void SendHealth(std::shared_ptr self, - ServingStatus status) override; - - private: - // Called when we receive a call. - // Spawns a new handler so that we can keep servicing future calls. - void OnCallReceived(std::shared_ptr self, bool ok); - - // Requires holding mu_. - void SendHealthLocked(std::shared_ptr self, - ServingStatus status); - - // When sending a health result finishes. - void OnSendHealthDone(std::shared_ptr self, bool ok); - - // Called when Finish() is done. - void OnFinishDone(std::shared_ptr self, bool ok); - - // Called when AsyncNotifyWhenDone() notifies us. - void OnDoneNotified(std::shared_ptr self, bool ok); - - void Shutdown(std::shared_ptr self, const char* reason); - - // The members passed down from HealthCheckServiceImpl. - ServerCompletionQueue* cq_; - DefaultHealthCheckService* database_; - HealthCheckServiceImpl* service_; - - ByteBuffer request_; - grpc::string service_name_; - GenericServerAsyncWriter stream_; - ServerContext ctx_; - - std::mutex mu_; - bool send_in_flight_ = false; // Guarded by mu_. - ServingStatus pending_status_ = NOT_FOUND; // Guarded by mu_. - - // The state of the RPC progress. - enum CallState { - WAITING_FOR_CALL, - CALL_RECEIVED, - SEND_MESSAGE_PENDING, - FINISH_CALLED - } call_state_; - - bool shutdown_ = false; - bool done_notified_ = false; - bool is_cancelled_ = false; - CallableTag next_; - CallableTag on_done_notified_; - CallableTag on_finish_done_; - }; - - // Handles the incoming requests and drives the completion queue in a loop. - static void Serve(void* arg); - - // Returns true on success. - static bool DecodeRequest(const ByteBuffer& request, - grpc::string* service_name); - static bool EncodeResponse(ServingStatus status, ByteBuffer* response); - - // Needed to appease Windows compilers, which don't seem to allow - // nested classes to access protected members in the parent's - // superclass. - using Service::RequestAsyncServerStreaming; - using Service::RequestAsyncUnary; - - DefaultHealthCheckService* database_; - std::unique_ptr cq_; - internal::RpcServiceMethod* check_method_; - internal::RpcServiceMethod* watch_method_; - - // To synchronize the operations related to shutdown state of cq_, so that - // we don't enqueue new tags into cq_ after it is already shut down. - std::mutex cq_shutdown_mu_; - std::atomic_bool shutdown_{false}; - std::unique_ptr<::grpc_core::Thread> thread_; + const DefaultHealthCheckService* const service_; + internal::RpcServiceMethod* method_; }; DefaultHealthCheckService(); - void SetServingStatus(const grpc::string& service_name, bool serving) override; void SetServingStatus(bool serving) override; - + enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; ServingStatus GetServingStatus(const grpc::string& service_name) const; - - HealthCheckServiceImpl* GetHealthCheckService( - std::unique_ptr cq); + HealthCheckServiceImpl* GetHealthCheckService(); private: - // Stores the current serving status of a service and any call - // handlers registered for updates when the service's status changes. - class ServiceData { - public: - void SetServingStatus(ServingStatus status); - ServingStatus GetServingStatus() const { return status_; } - void AddCallHandler( - std::shared_ptr handler); - void RemoveCallHandler( - std::shared_ptr handler); - bool Unused() const { - return call_handlers_.empty() && status_ == NOT_FOUND; - } - - private: - ServingStatus status_ = NOT_FOUND; - std::set> - call_handlers_; - }; - - void RegisterCallHandler( - const grpc::string& service_name, - std::shared_ptr handler); - - void UnregisterCallHandler( - const grpc::string& service_name, - std::shared_ptr handler); - mutable std::mutex mu_; - std::map services_map_; // Guarded by mu_. + std::map services_map_; std::unique_ptr impl_; }; diff --git a/src/cpp/server/health/health.pb.c b/src/cpp/server/health/health.pb.c index 5c214c7160f..09bd98a3d97 100644 --- a/src/cpp/server/health/health.pb.c +++ b/src/cpp/server/health/health.pb.c @@ -2,6 +2,7 @@ /* Generated by nanopb-0.3.7-dev */ #include "src/cpp/server/health/health.pb.h" + /* @@protoc_insertion_point(includes) */ #if PB_PROTO_HEADER_VERSION != 30 #error Regenerate this file with the current version of nanopb generator. diff --git a/src/cpp/server/health/health.pb.h b/src/cpp/server/health/health.pb.h index 9d54ccd6182..29e1f3bacb1 100644 --- a/src/cpp/server/health/health.pb.h +++ b/src/cpp/server/health/health.pb.h @@ -17,12 +17,11 @@ extern "C" { typedef enum _grpc_health_v1_HealthCheckResponse_ServingStatus { grpc_health_v1_HealthCheckResponse_ServingStatus_UNKNOWN = 0, grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING = 1, - grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING = 2, - grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN = 3 + grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING = 2 } grpc_health_v1_HealthCheckResponse_ServingStatus; #define _grpc_health_v1_HealthCheckResponse_ServingStatus_MIN grpc_health_v1_HealthCheckResponse_ServingStatus_UNKNOWN -#define _grpc_health_v1_HealthCheckResponse_ServingStatus_MAX grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN -#define _grpc_health_v1_HealthCheckResponse_ServingStatus_ARRAYSIZE ((grpc_health_v1_HealthCheckResponse_ServingStatus)(grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN+1)) +#define _grpc_health_v1_HealthCheckResponse_ServingStatus_MAX grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING +#define _grpc_health_v1_HealthCheckResponse_ServingStatus_ARRAYSIZE ((grpc_health_v1_HealthCheckResponse_ServingStatus)(grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING+1)) /* Struct definitions */ typedef struct _grpc_health_v1_HealthCheckRequest { diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 48f0f110a6c..b8ba7042d90 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -559,20 +559,16 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { // Only create default health check service when user did not provide an // explicit one. - ServerCompletionQueue* health_check_cq = nullptr; - DefaultHealthCheckService::HealthCheckServiceImpl* - default_health_check_service_impl = nullptr; if (health_check_service_ == nullptr && !health_check_service_disabled_ && DefaultHealthCheckServiceEnabled()) { - auto* default_hc_service = new DefaultHealthCheckService; - health_check_service_.reset(default_hc_service); - health_check_cq = new ServerCompletionQueue(GRPC_CQ_DEFAULT_POLLING); - grpc_server_register_completion_queue(server_, health_check_cq->cq(), - nullptr); - default_health_check_service_impl = - default_hc_service->GetHealthCheckService( - std::unique_ptr(health_check_cq)); - RegisterService(nullptr, default_health_check_service_impl); + if (sync_server_cqs_ == nullptr || sync_server_cqs_->empty()) { + gpr_log(GPR_INFO, + "Default health check service disabled at async-only server."); + } else { + auto* default_hc_service = new DefaultHealthCheckService; + health_check_service_.reset(default_hc_service); + RegisterService(nullptr, default_hc_service->GetHealthCheckService()); + } } grpc_server_start(server_); @@ -587,9 +583,6 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { new UnimplementedAsyncRequest(this, cqs[i]); } } - if (health_check_cq != nullptr) { - new UnimplementedAsyncRequest(this, health_check_cq); - } } // If this server has any support for synchronous methods (has any sync @@ -602,10 +595,6 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { (*it)->Start(); } - - if (default_health_check_service_impl != nullptr) { - default_health_check_service_impl->StartServingThread(); - } } void Server::ShutdownInternal(gpr_timespec deadline) { diff --git a/src/proto/grpc/health/v1/health.proto b/src/proto/grpc/health/v1/health.proto index 38843ff1e73..4b4677b8a4d 100644 --- a/src/proto/grpc/health/v1/health.proto +++ b/src/proto/grpc/health/v1/health.proto @@ -34,30 +34,10 @@ message HealthCheckResponse { UNKNOWN = 0; SERVING = 1; NOT_SERVING = 2; - SERVICE_UNKNOWN = 3; // Used only by the Watch method. } ServingStatus status = 1; } service Health { - // If the requested service is unknown, the call will fail with status - // NOT_FOUND. rpc Check(HealthCheckRequest) returns (HealthCheckResponse); - - // Performs a watch for the serving status of the requested service. - // The server will immediately send back a message indicating the current - // serving status. It will then subsequently send a new message whenever - // the service's serving status changes. - // - // If the requested service is unknown when the call is received, the - // server will send a message setting the serving status to - // SERVICE_UNKNOWN but will *not* terminate the call. If at some - // future point, the serving status of the service becomes known, the - // server will send a new message with the service's serving status. - // - // If the call terminates with status UNIMPLEMENTED, then clients - // should assume this method is not supported and should not retry the - // call. If the call terminates with any other status (including OK), - // clients should retry the call with appropriate exponential backoff. - rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); } diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index fca65dfc13b..1c48b9d151a 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -64,29 +64,6 @@ class HealthCheckServiceImpl : public ::grpc::health::v1::Health::Service { return Status::OK; } - Status Watch(ServerContext* context, const HealthCheckRequest* request, - ::grpc::ServerWriter* writer) override { - auto last_state = HealthCheckResponse::UNKNOWN; - while (!context->IsCancelled()) { - { - std::lock_guard lock(mu_); - HealthCheckResponse response; - auto iter = status_map_.find(request->service()); - if (iter == status_map_.end()) { - response.set_status(response.SERVICE_UNKNOWN); - } else { - response.set_status(iter->second); - } - if (response.status() != last_state) { - writer->Write(response, ::grpc::WriteOptions()); - } - } - gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_millis(1000, GPR_TIMESPAN))); - } - return Status::OK; - } - void SetStatus(const grpc::string& service_name, HealthCheckResponse::ServingStatus status) { std::lock_guard lock(mu_); @@ -129,6 +106,14 @@ class CustomHealthCheckService : public HealthCheckServiceInterface { HealthCheckServiceImpl* impl_; // not owned }; +void LoopCompletionQueue(ServerCompletionQueue* cq) { + void* tag; + bool ok; + while (cq->Next(&tag, &ok)) { + abort(); // Nothing should come out of the cq. + } +} + class HealthServiceEnd2endTest : public ::testing::Test { protected: HealthServiceEnd2endTest() {} @@ -233,33 +218,6 @@ class HealthServiceEnd2endTest : public ::testing::Test { Status(StatusCode::NOT_FOUND, "")); } - void VerifyHealthCheckServiceStreaming() { - const grpc::string kServiceName("service_name"); - HealthCheckServiceInterface* service = server_->GetHealthCheckService(); - // Start Watch for service. - ClientContext context; - HealthCheckRequest request; - request.set_service(kServiceName); - std::unique_ptr<::grpc::ClientReaderInterface> reader = - hc_stub_->Watch(&context, request); - // Initial response will be SERVICE_UNKNOWN. - HealthCheckResponse response; - EXPECT_TRUE(reader->Read(&response)); - EXPECT_EQ(response.SERVICE_UNKNOWN, response.status()); - response.Clear(); - // Now set service to NOT_SERVING and make sure we get an update. - service->SetServingStatus(kServiceName, false); - EXPECT_TRUE(reader->Read(&response)); - EXPECT_EQ(response.NOT_SERVING, response.status()); - response.Clear(); - // Now set service to SERVING and make sure we get another update. - service->SetServingStatus(kServiceName, true); - EXPECT_TRUE(reader->Read(&response)); - EXPECT_EQ(response.SERVING, response.status()); - // Finish call. - context.TryCancel(); - } - TestServiceImpl echo_test_service_; HealthCheckServiceImpl health_check_service_impl_; std::unique_ptr hc_stub_; @@ -287,7 +245,6 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); SetUpServer(true, false, false, nullptr); VerifyHealthCheckService(); - VerifyHealthCheckServiceStreaming(); // The default service has a size limit of the service name. const grpc::string kTooLongServiceName(201, 'x'); @@ -295,6 +252,22 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { Status(StatusCode::INVALID_ARGUMENT, "")); } +// The server has no sync service. +TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceAsyncOnly) { + EnableDefaultHealthCheckService(true); + EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); + SetUpServer(false, true, false, nullptr); + cq_thread_ = std::thread(LoopCompletionQueue, cq_.get()); + + HealthCheckServiceInterface* default_service = + server_->GetHealthCheckService(); + EXPECT_TRUE(default_service == nullptr); + + ResetStubs(); + + SendHealthCheckRpc("", Status(StatusCode::UNIMPLEMENTED, "")); +} + // Provide an empty service to disable the default service. TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) { EnableDefaultHealthCheckService(true); @@ -323,7 +296,6 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) { ResetStubs(); VerifyHealthCheckService(); - VerifyHealthCheckServiceStreaming(); } } // namespace diff --git a/tools/distrib/check_nanopb_output.sh b/tools/distrib/check_nanopb_output.sh index 1c2ef9b7686..6b98619c320 100755 --- a/tools/distrib/check_nanopb_output.sh +++ b/tools/distrib/check_nanopb_output.sh @@ -16,7 +16,6 @@ set -ex readonly NANOPB_ALTS_TMP_OUTPUT="$(mktemp -d)" -readonly NANOPB_HEALTH_TMP_OUTPUT="$(mktemp -d)" readonly NANOPB_TMP_OUTPUT="$(mktemp -d)" readonly PROTOBUF_INSTALL_PREFIX="$(mktemp -d)" @@ -68,23 +67,6 @@ if ! diff -r "$NANOPB_TMP_OUTPUT" src/core/ext/filters/client_channel/lb_policy/ exit 2 fi -# -# checks for health.proto -# -readonly HEALTH_GRPC_OUTPUT_PATH='src/cpp/server/health' -# nanopb-compile the proto to a temp location -./tools/codegen/core/gen_nano_proto.sh \ - src/proto/grpc/health/v1/health.proto \ - "$NANOPB_HEALTH_TMP_OUTPUT" \ - "$HEALTH_GRPC_OUTPUT_PATH" -# compare outputs to checked compiled code -for NANOPB_OUTPUT_FILE in $NANOPB_HEALTH_TMP_OUTPUT/*.pb.*; do - if ! diff "$NANOPB_OUTPUT_FILE" "src/cpp/server/health/$(basename $NANOPB_OUTPUT_FILE)"; then - echo "Outputs differ: $NANOPB_HEALTH_TMP_OUTPUT vs $HEALTH_GRPC_OUTPUT_PATH" - exit 2 - fi -done - # # Checks for handshaker.proto and transport_security_common.proto # From b6bb49dbf73805e4998ad6f4ac7adc94550e8d97 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 10 Sep 2018 14:20:01 -0700 Subject: [PATCH 337/546] reinterpret casts for compiler checks --- src/core/lib/surface/call.cc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 90d812dad66..ee7c15381a1 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -1108,7 +1108,8 @@ static void finish_batch_completion(void* user_data, static void reset_batch_errors(batch_control* bctl) { GRPC_ERROR_UNREF( reinterpret_cast(gpr_atm_acq_load(&bctl->batch_error))); - gpr_atm_rel_store(&bctl->batch_error, GRPC_ERROR_NONE); + gpr_atm_rel_store(&bctl->batch_error, + reinterpret_cast(GRPC_ERROR_NONE)); } static void post_batch_completion(batch_control* bctl) { @@ -1281,7 +1282,8 @@ static void receiving_stream_ready(void* bctlp, grpc_error* error) { call->receiving_stream.reset(); if (reinterpret_cast(gpr_atm_acq_load(&bctl->batch_error)) == GRPC_ERROR_NONE) { - gpr_atm_rel_store(&bctl->batch_error, GRPC_ERROR_REF(error)); + gpr_atm_rel_store(&bctl->batch_error, + reinterpret_cast(GRPC_ERROR_REF(error))); } cancel_with_error(call, GRPC_ERROR_REF(error)); } @@ -1387,9 +1389,10 @@ static void receiving_initial_metadata_ready(void* bctlp, grpc_error* error) { call->send_deadline = md->deadline; } } else { - if (reinterpret_cast gpr_atm_acq_load(&bctl->batch_error) == + if (reinterpret_cast(gpr_atm_acq_load(&bctl->batch_error)) == GRPC_ERROR_NONE) { - gpr_atm_rel_store(&bctl->batch_error, GRPC_ERROR_REF(error)); + gpr_atm_rel_store(&bctl->batch_error, + reinterpret_cast(GRPC_ERROR_REF(error))); } cancel_with_error(call, GRPC_ERROR_REF(error)); } @@ -1439,9 +1442,10 @@ static void finish_batch(void* bctlp, grpc_error* error) { batch_control* bctl = static_cast(bctlp); grpc_call* call = bctl->call; GRPC_CALL_COMBINER_STOP(&call->call_combiner, "on_complete"); - if (reinterpret_cast gpr_atm_acq_load(&bctl->batch_error) == + if (reinterpret_cast(gpr_atm_acq_load(&bctl->batch_error)) == GRPC_ERROR_NONE) { - gpr_atm_rel_store(&bctl->batch_error, GRPC_ERROR_REF(error)); + gpr_atm_rel_store(&bctl->batch_error, + reinterpret_cast(GRPC_ERROR_REF(error))); } if (error != GRPC_ERROR_NONE) { cancel_with_error(call, GRPC_ERROR_REF(error)); From 71e0ca94e96cf01d43da994a1044290fa90a85bd Mon Sep 17 00:00:00 2001 From: Kun Zhang Date: Mon, 10 Sep 2018 15:22:11 -0700 Subject: [PATCH 338/546] Add v1.15.0 release of grpc-java --- tools/interop_matrix/client_matrix.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index bb9222d953f..c55789f27ee 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -184,6 +184,9 @@ LANG_RELEASE_MATRIX = { { 'v1.14.0': None }, + { + 'v1.15.0': None + }, ], 'python': [ { From c004a8e2593bfd4f493d35bfc995b895b51c261b Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Mon, 10 Sep 2018 15:31:14 -0700 Subject: [PATCH 339/546] Responding to code review comments --- .../filters/http/server/http_server_filter.cc | 2 +- .../chttp2/transport/chttp2_transport.cc | 2 +- .../chttp2/transport/hpack_encoder.cc | 4 +-- src/core/lib/transport/metadata.h | 2 -- src/core/lib/transport/metadata_batch.cc | 25 ++++++++-------- src/core/lib/transport/metadata_batch.h | 30 ++++++++++++------- src/core/lib/transport/transport_op_string.cc | 2 +- 7 files changed, 37 insertions(+), 30 deletions(-) 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 8e9db0a5e77..1880dbb38d9 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -322,7 +322,7 @@ static grpc_error* hs_mutate_op(grpc_call_element* elem, grpc_error* error = GRPC_ERROR_NONE; static const char* error_name = "Failed sending initial metadata"; hs_add_error(error_name, &error, - grpc_metadata_batch_add_head_index( + grpc_metadata_batch_add_head_static( op->payload->send_initial_metadata.send_initial_metadata, &calld->status, GRPC_MDELEM_STATUS_200_INDEX)); hs_add_error(error_name, &error, diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index f510a3f52ca..3d6f150ea1e 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1332,7 +1332,7 @@ static void log_metadata(const grpc_metadata_batch* md_batch, uint32_t id, bool is_client, bool is_initial) { for (grpc_linked_mdelem* md = md_batch->list.head; md != nullptr; md = md->next) { - if (is_valid_mdelem_index(md->md_index)) { + if (grpc_metadata_batch_is_valid_mdelem_index(md->md_index)) { gpr_log(GPR_INFO, "HTTP:%d:%s:%s: hpack table index: %d", id, is_initial ? "HDR" : "TRL", is_client ? "CLI" : "SVR", md->md_index); diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index c9ba74bf642..9e63144c945 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -689,7 +689,7 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, } for (size_t i = 0; i < extra_headers_size; ++i) { grpc_linked_mdelem* linked_md = extra_headers[i]; - if (is_valid_mdelem_index(linked_md->md_index)) { + if (grpc_metadata_batch_is_valid_mdelem_index(linked_md->md_index)) { emit_indexed(c, linked_md->md_index, &st); } else { hpack_enc(c, linked_md->md, &st); @@ -697,7 +697,7 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, } grpc_metadata_batch_assert_ok(metadata); for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) { - if (is_valid_mdelem_index(l->md_index)) { + if (grpc_metadata_batch_is_valid_mdelem_index(l->md_index)) { emit_indexed(c, l->md_index, &st); } else { hpack_enc(c, l->md, &st); diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 74c6672fd20..4fde0130c0f 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -348,6 +348,4 @@ void grpc_mdctx_global_shutdown(); /* {"www-authenticate", ""} */ #define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY_INDEX 61 -/* Forward declarations */ -typedef struct grpc_mdelem grpc_mdelem; #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */ diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index e2918fa08ab..05f7a29e8ac 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -114,7 +114,7 @@ static_hpack_table_metadata_info static_hpack_table_metadata[] = { }; /* This is a faster check for seeing if a mdelem index is used or not. To verify - that the index value is valid, use 'is_valid_mdelem_index' */ + that the index value is valid, use 'grpc_metadata_batch_is_valid_mdelem_index' */ static bool is_mdelem_index_used(uint8_t index); static void set_mdelem_index_unused(uint8_t* index); @@ -150,7 +150,7 @@ static void assert_valid_callouts(grpc_metadata_batch* batch) { for (grpc_linked_mdelem* l = batch->list.head; l != nullptr; l = l->next) { grpc_metadata_batch_callouts_index callout_idx; if (is_mdelem_index_used(l->md_index)) { - GPR_ASSERT(is_valid_mdelem_index(l->md_index)); + GPR_ASSERT(grpc_metadata_batch_is_valid_mdelem_index(l->md_index)); callout_idx = get_callouts_index(l); if (callout_idx != GRPC_BATCH_CALLOUTS_COUNT) { GPR_ASSERT(batch->idx.array[callout_idx] == l); @@ -219,7 +219,6 @@ static grpc_error* maybe_link_callout(grpc_metadata_batch* batch, batch->idx.array[idx] = storage; return GRPC_ERROR_NONE; } - grpc_error* err; if (is_mdelem_index_used(storage->md_index)) { char* message; @@ -248,14 +247,14 @@ static void maybe_unlink_callout(grpc_metadata_batch* batch, batch->idx.array[idx] = nullptr; } -bool is_valid_mdelem_index(uint8_t index) { +bool grpc_metadata_batch_is_valid_mdelem_index(uint8_t index) { return index >= MIN_STATIC_HPACK_TABLE_IDX && index <= MAX_STATIC_HPACK_TABLE_IDX; } -bool is_mdelem_index_used(uint8_t index) { return index != 0; } +static bool is_mdelem_index_used(uint8_t index) { return index != 0; } -void set_mdelem_index_unused(uint8_t* index) { +static void set_mdelem_index_unused(uint8_t* index) { GPR_ASSERT(index != nullptr); *index = 0; } @@ -269,17 +268,17 @@ grpc_error* grpc_metadata_batch_add_head(grpc_metadata_batch* batch, return grpc_metadata_batch_link_head(batch, storage); } -grpc_error* grpc_metadata_batch_add_head_index(grpc_metadata_batch* batch, +grpc_error* grpc_metadata_batch_add_head_static(grpc_metadata_batch* batch, grpc_linked_mdelem* storage, uint8_t index_to_add) { - GPR_ASSERT(is_valid_mdelem_index(index_to_add)); + GPR_ASSERT(grpc_metadata_batch_is_valid_mdelem_index(index_to_add)); storage->md_index = index_to_add; return grpc_metadata_batch_link_head(batch, storage); } static void link_head(grpc_mdelem_list* list, grpc_linked_mdelem* storage) { assert_valid_list(list); - GPR_ASSERT(is_valid_mdelem_index(storage->md_index) || + GPR_ASSERT(grpc_metadata_batch_is_valid_mdelem_index(storage->md_index) || !GRPC_MDISNULL(storage->md)); storage->prev = nullptr; storage->next = list->head; @@ -315,17 +314,17 @@ grpc_error* grpc_metadata_batch_add_tail(grpc_metadata_batch* batch, return grpc_metadata_batch_link_tail(batch, storage); } -grpc_error* grpc_metadata_batch_add_tail_index(grpc_metadata_batch* batch, +grpc_error* grpc_metadata_batch_add_tail_static(grpc_metadata_batch* batch, grpc_linked_mdelem* storage, uint8_t index_to_add) { - GPR_ASSERT(is_valid_mdelem_index(index_to_add)); + GPR_ASSERT(grpc_metadata_batch_is_valid_mdelem_index(index_to_add)); storage->md_index = index_to_add; return grpc_metadata_batch_link_tail(batch, storage); } static void link_tail(grpc_mdelem_list* list, grpc_linked_mdelem* storage) { assert_valid_list(list); - GPR_ASSERT(is_valid_mdelem_index(storage->md_index) || + GPR_ASSERT(grpc_metadata_batch_is_valid_mdelem_index(storage->md_index) || !GRPC_MDISNULL(storage->md)); storage->prev = list->tail; storage->next = nullptr; @@ -486,7 +485,7 @@ void grpc_metadata_batch_copy(grpc_metadata_batch* src, elem = elem->next) { grpc_error* error = nullptr; if (is_mdelem_index_used(elem->md_index)) { - error = grpc_metadata_batch_add_tail_index(dst, &storage[i++], + error = grpc_metadata_batch_add_tail_static(dst, &storage[i++], elem->md_index); } else { error = grpc_metadata_batch_add_tail(dst, &storage[i++], diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index 25f9d0c14c1..c0450684bb9 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -110,12 +110,17 @@ grpc_error* grpc_metadata_batch_add_head( grpc_metadata_batch* batch, grpc_linked_mdelem* storage, grpc_mdelem elem_to_add) GRPC_MUST_USE_RESULT; -/** Identical to grpc_metadata_batch_add_head, except takes the index of the - metadata element to add instead of a grpc_mdelem object. The index must - be a valid static hpack table index */ -grpc_error* grpc_metadata_batch_add_head_index( +/** Add the static metadata element associated with \a elem_to_add_index + as the first element in \a batch, using \a storage as backing storage for + the linked list element. \a storage is owned by the caller and must survive + for the lifetime of batch. This usually means it should be around + for the lifetime of the call. + Valid indices are in metadata.h (e.g., GRPC_MDELEM_STATUS_200_INDEX). + This is an optimization in the case where chttp2 is used as the underlying + transport. */ +grpc_error* grpc_metadata_batch_add_head_static( grpc_metadata_batch* batch, grpc_linked_mdelem* storage, - uint8_t index_to_add) GRPC_MUST_USE_RESULT; + uint8_t elem_to_add_index) GRPC_MUST_USE_RESULT; /** Add \a elem_to_add as the last element in \a batch, using \a storage as backing storage for the linked list element. @@ -127,10 +132,15 @@ grpc_error* grpc_metadata_batch_add_tail( grpc_metadata_batch* batch, grpc_linked_mdelem* storage, grpc_mdelem elem_to_add) GRPC_MUST_USE_RESULT; -/** Identical to grpc_metadata_batch_add_tail, except takes the index of the - metadata element to add instead of a grpc_mdelem object. The index must - be a valid static hpack table index */ -grpc_error* grpc_metadata_batch_add_head_index( +/** Add the static metadata element associated with \a elem_to_add_index + as the last element in \a batch, using \a storage as backing storage for + the linked list element. \a storage is owned by the caller and must survive + for the lifetime of batch. This usually means it should be around + for the lifetime of the call. + Valid indices are in metadata.h (e.g., GRPC_MDELEM_STATUS_200_INDEX). + This is an optimization in the case where chttp2 is used as the underlying + transport. */ +grpc_error* grpc_metadata_batch_add_tail_static( grpc_metadata_batch* batch, grpc_linked_mdelem* storage, uint8_t index_to_add) GRPC_MUST_USE_RESULT; @@ -138,7 +148,7 @@ grpc_error* grpc_attach_md_to_error(grpc_error* src, grpc_mdelem md); /** Returns if the index is a valid static hpack table index, and thus if the grpc_linked_mdelem stores the index rather than the actual grpc_mdelem **/ -bool is_valid_mdelem_index(uint8_t index); +bool grpc_metadata_batch_is_valid_mdelem_index(uint8_t index); /* Static hpack table metadata info */ typedef struct static_hpack_table_metadata_info { diff --git a/src/core/lib/transport/transport_op_string.cc b/src/core/lib/transport/transport_op_string.cc index 7771b4d220e..9f5dafa4afd 100644 --- a/src/core/lib/transport/transport_op_string.cc +++ b/src/core/lib/transport/transport_op_string.cc @@ -48,7 +48,7 @@ static void put_metadata_list(gpr_strvec* b, grpc_metadata_batch md) { grpc_linked_mdelem* m; for (m = md.list.head; m != nullptr; m = m->next) { if (m != md.list.head) gpr_strvec_add(b, gpr_strdup(", ")); - if (is_valid_mdelem_index(m->md_index)) { + if (grpc_metadata_batch_is_valid_mdelem_index(m->md_index)) { // TODO(hcaseyal): print out the mdelem index gpr_strvec_add(b, gpr_strdup("indexed mdelem")); } else { From 009d828341a272e05401daf32907d8f400b19a90 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Mon, 10 Sep 2018 19:23:05 -0700 Subject: [PATCH 340/546] WIP. Modifying grpc_mdelem to store the static hpack table idnex --- .../chttp2/transport/chttp2_transport.cc | 19 +- .../chttp2/transport/hpack_encoder.cc | 4 +- src/core/lib/transport/metadata.h | 11 +- src/core/lib/transport/static_metadata.cc | 888 +++++++----------- src/core/lib/transport/static_metadata.h | 531 +++++------ tools/codegen/core/gen_static_metadata.py | 168 ++-- 6 files changed, 658 insertions(+), 963 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 3d6f150ea1e..9bdad94e824 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1332,18 +1332,13 @@ static void log_metadata(const grpc_metadata_batch* md_batch, uint32_t id, bool is_client, bool is_initial) { for (grpc_linked_mdelem* md = md_batch->list.head; md != nullptr; md = md->next) { - if (grpc_metadata_batch_is_valid_mdelem_index(md->md_index)) { - gpr_log(GPR_INFO, "HTTP:%d:%s:%s: hpack table index: %d", id, - is_initial ? "HDR" : "TRL", is_client ? "CLI" : "SVR", - md->md_index); - } else { - char* key = grpc_slice_to_c_string(GRPC_MDKEY(md->md)); - char* value = grpc_slice_to_c_string(GRPC_MDVALUE(md->md)); - gpr_log(GPR_INFO, "HTTP:%d:%s:%s: %s: %s", id, is_initial ? "HDR" : "TRL", - is_client ? "CLI" : "SVR", key, value); - gpr_free(key); - gpr_free(value); - } + grpc_mdelem mdelem = grpc_get_md_from_linked_mdelem(md); + char* key = grpc_slice_to_c_string(GRPC_MDKEY(mdelem)); + char* value = grpc_slice_to_c_string(GRPC_MDVALUE(mdelem)); + gpr_log(GPR_INFO, "HTTP:%d:%s:%s: %s: %s", id, is_initial ? "HDR" : "TRL", + is_client ? "CLI" : "SVR", key, value); + gpr_free(key); + gpr_free(value); } } diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 9e63144c945..6674b701523 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -689,7 +689,7 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, } for (size_t i = 0; i < extra_headers_size; ++i) { grpc_linked_mdelem* linked_md = extra_headers[i]; - if (grpc_metadata_batch_is_valid_mdelem_index(linked_md->md_index)) { + if (grpc_is_mdelem_index_used(linked_md)) { emit_indexed(c, linked_md->md_index, &st); } else { hpack_enc(c, linked_md->md, &st); @@ -697,7 +697,7 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, } grpc_metadata_batch_assert_ok(metadata); for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) { - if (grpc_metadata_batch_is_valid_mdelem_index(l->md_index)) { + if (grpc_is_mdelem_index_used(l)) { emit_indexed(c, l->md_index, &st); } else { hpack_enc(c, l->md, &st); diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 4fde0130c0f..5c34f7323be 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -92,17 +92,20 @@ struct grpc_mdelem { /* a grpc_mdelem_data* generally, with the two lower bits signalling memory ownership as per grpc_mdelem_data_storage */ uintptr_t payload; + /* The static index of this mdelem. This is equivalent to the + mdelem's index into the hpack static table. 0 if unused. */ + uint8_t static_index; }; #define GRPC_MDELEM_DATA(md) ((grpc_mdelem_data*)((md).payload & ~(uintptr_t)3)) #define GRPC_MDELEM_STORAGE(md) \ ((grpc_mdelem_data_storage)((md).payload & (uintptr_t)3)) #ifdef __cplusplus -#define GRPC_MAKE_MDELEM(data, storage) \ - (grpc_mdelem{((uintptr_t)(data)) | ((uintptr_t)storage)}) +#define GRPC_MAKE_MDELEM(data, storage, index) \ + (grpc_mdelem{((uintptr_t)(data)) | ((uintptr_t)storage), index}) #else -#define GRPC_MAKE_MDELEM(data, storage) \ - ((grpc_mdelem){((uintptr_t)(data)) | ((uintptr_t)storage)}) +#define GRPC_MAKE_MDELEM(data, storage, index) \ + ((grpc_mdelem){((uintptr_t)(data)) | ((uintptr_t)storage), index}) #endif #define GRPC_MDELEM_IS_INTERNED(md) \ ((grpc_mdelem_data_storage)((md).payload & \ diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 6a5144f21a2..b4f8fac3d65 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -1,12 +1,12 @@ /* * 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. @@ -16,337 +16,247 @@ /* * WARNING: Auto-generated code. - * + * * To make changes to this file, change * tools/codegen/core/gen_static_metadata.py, and then re-run it. - * + * * See metadata.h for an explanation of the interface here, and metadata.cc for * an explanation of what's going on. */ -#include - #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/slice/slice_internal.h" -static uint8_t g_bytes[] = { - 58, 112, 97, 116, 104, 58, 109, 101, 116, 104, 111, 100, 58, 115, 116, - 97, 116, 117, 115, 58, 97, 117, 116, 104, 111, 114, 105, 116, 121, 58, - 115, 99, 104, 101, 109, 101, 116, 101, 103, 114, 112, 99, 45, 109, 101, - 115, 115, 97, 103, 101, 103, 114, 112, 99, 45, 115, 116, 97, 116, 117, - 115, 103, 114, 112, 99, 45, 112, 97, 121, 108, 111, 97, 100, 45, 98, - 105, 110, 103, 114, 112, 99, 45, 101, 110, 99, 111, 100, 105, 110, 103, - 103, 114, 112, 99, 45, 97, 99, 99, 101, 112, 116, 45, 101, 110, 99, - 111, 100, 105, 110, 103, 103, 114, 112, 99, 45, 115, 101, 114, 118, 101, - 114, 45, 115, 116, 97, 116, 115, 45, 98, 105, 110, 103, 114, 112, 99, - 45, 116, 97, 103, 115, 45, 98, 105, 110, 103, 114, 112, 99, 45, 116, - 114, 97, 99, 101, 45, 98, 105, 110, 99, 111, 110, 116, 101, 110, 116, - 45, 116, 121, 112, 101, 99, 111, 110, 116, 101, 110, 116, 45, 101, 110, - 99, 111, 100, 105, 110, 103, 97, 99, 99, 101, 112, 116, 45, 101, 110, - 99, 111, 100, 105, 110, 103, 103, 114, 112, 99, 45, 105, 110, 116, 101, - 114, 110, 97, 108, 45, 101, 110, 99, 111, 100, 105, 110, 103, 45, 114, - 101, 113, 117, 101, 115, 116, 103, 114, 112, 99, 45, 105, 110, 116, 101, - 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, 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 uint8_t g_bytes[] = {58,112,97,116,104,58,109,101,116,104,111,100,58,115,116,97,116,117,115,58,97,117,116,104,111,114,105,116,121,58,115,99,104,101,109,101,116,101,103,114,112,99,45,109,101,115,115,97,103,101,103,114,112,99,45,115,116,97,116,117,115,103,114,112,99,45,112,97,121,108,111,97,100,45,98,105,110,103,114,112,99,45,101,110,99,111,100,105,110,103,103,114,112,99,45,97,99,99,101,112,116,45,101,110,99,111,100,105,110,103,103,114,112,99,45,115,101,114,118,101,114,45,115,116,97,116,115,45,98,105,110,103,114,112,99,45,116,97,103,115,45,98,105,110,103,114,112,99,45,116,114,97,99,101,45,98,105,110,99,111,110,116,101,110,116,45,116,121,112,101,99,111,110,116,101,110,116,45,101,110,99,111,100,105,110,103,97,99,99,101,112,116,45,101,110,99,111,100,105,110,103,103,114,112,99,45,105,110,116,101,114,110,97,108,45,101,110,99,111,100,105,110,103,45,114,101,113,117,101,115,116,103,114,112,99,45,105,110,116,101,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,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) {} -static const grpc_slice_refcount_vtable static_sub_vtable = { - static_ref, static_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; -const grpc_slice_refcount_vtable grpc_static_metadata_vtable = { - static_ref, static_unref, grpc_static_slice_eq, grpc_static_slice_hash}; -static grpc_slice_refcount static_sub_refcnt = {&static_sub_vtable, - &static_sub_refcnt}; +static void static_ref(void *unused) {} +static void static_unref(void *unused) {} +static const grpc_slice_refcount_vtable static_sub_vtable = {static_ref, static_unref, grpc_slice_default_eq_impl, grpc_slice_default_hash_impl}; +const grpc_slice_refcount_vtable grpc_static_metadata_vtable = {static_ref, static_unref, grpc_static_slice_eq, grpc_static_slice_hash}; +static grpc_slice_refcount static_sub_refcnt = {&static_sub_vtable, &static_sub_refcnt}; 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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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] = { - {&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, - {&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[6], {{g_bytes + 38, 12}}}, - {&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[8], {{g_bytes + 61, 16}}}, - {&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[11], {{g_bytes + 110, 21}}}, - {&grpc_static_metadata_refcounts[12], {{g_bytes + 131, 13}}}, - {&grpc_static_metadata_refcounts[13], {{g_bytes + 144, 14}}}, - {&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[17], {{g_bytes + 201, 30}}}, - {&grpc_static_metadata_refcounts[18], {{g_bytes + 231, 37}}}, - {&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, 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}}}, +{&grpc_static_metadata_refcounts[0], {{g_bytes+0, 5}}}, +{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}}, +{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}}, +{&grpc_static_metadata_refcounts[3], {{g_bytes+19, 10}}}, +{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}}, +{&grpc_static_metadata_refcounts[5], {{g_bytes+36, 2}}}, +{&grpc_static_metadata_refcounts[6], {{g_bytes+38, 12}}}, +{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}}, +{&grpc_static_metadata_refcounts[8], {{g_bytes+61, 16}}}, +{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}}, +{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}}, +{&grpc_static_metadata_refcounts[11], {{g_bytes+110, 21}}}, +{&grpc_static_metadata_refcounts[12], {{g_bytes+131, 13}}}, +{&grpc_static_metadata_refcounts[13], {{g_bytes+144, 14}}}, +{&grpc_static_metadata_refcounts[14], {{g_bytes+158, 12}}}, +{&grpc_static_metadata_refcounts[15], {{g_bytes+170, 16}}}, +{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}}, +{&grpc_static_metadata_refcounts[17], {{g_bytes+201, 30}}}, +{&grpc_static_metadata_refcounts[18], {{g_bytes+231, 37}}}, +{&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, 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] = { - 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, 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, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4}; + 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,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,0,0,0,0,0,0,2,4,4,6,6,8,8,2,4,4 +}; + -static const int8_t elems_r[] = { - 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 const int8_t elems_r[] = {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 -= 50; uint32_t x = i % 103; @@ -358,244 +268,136 @@ static uint32_t elems_phash(uint32_t i) { } return h; } - -static const uint16_t elem_keys[] = { - 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, 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}; + +static const uint16_t elem_keys[] = {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,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 = (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 - ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], - GRPC_MDELEM_STORAGE_STATIC) - : GRPC_MDNULL; + return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC, 0) : GRPC_MDNULL; } grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 1}}}}, - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}}, - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, - {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 513, 8}}}}, - {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 521, 16}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 537, 4}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 541, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 544, 3}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 547, 4}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 551, 5}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 556, 4}}}}, - {{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 560, 3}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 563, 3}}}}, - {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 566, 1}}}}, - {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 567, 11}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 578, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[53], {{g_bytes + 581, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[54], {{g_bytes + 584, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[55], {{g_bytes + 587, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&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[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&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[39], {{g_bytes + 505, 8}}}}, - {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, - {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&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[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[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[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[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[39], {{g_bytes + 505, 8}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, +{{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}},{&grpc_static_metadata_refcounts[38], {{g_bytes+504, 1}}}}, +{{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}},{&grpc_static_metadata_refcounts[25], {{g_bytes+350, 1}}}}, +{{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}},{&grpc_static_metadata_refcounts[26], {{g_bytes+351, 1}}}}, +{{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}},{&grpc_static_metadata_refcounts[39], {{g_bytes+505, 8}}}}, +{{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, +{{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}},{&grpc_static_metadata_refcounts[35], {{g_bytes+482, 7}}}}, +{{&grpc_static_metadata_refcounts[5], {{g_bytes+36, 2}}},{&grpc_static_metadata_refcounts[40], {{g_bytes+513, 8}}}}, +{{&grpc_static_metadata_refcounts[14], {{g_bytes+158, 12}}},{&grpc_static_metadata_refcounts[41], {{g_bytes+521, 16}}}}, +{{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}},{&grpc_static_metadata_refcounts[42], {{g_bytes+537, 4}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[43], {{g_bytes+541, 3}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[44], {{g_bytes+544, 3}}}}, +{{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}},{&grpc_static_metadata_refcounts[45], {{g_bytes+547, 4}}}}, +{{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}},{&grpc_static_metadata_refcounts[46], {{g_bytes+551, 5}}}}, +{{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}},{&grpc_static_metadata_refcounts[47], {{g_bytes+556, 4}}}}, +{{&grpc_static_metadata_refcounts[3], {{g_bytes+19, 10}}},{&grpc_static_metadata_refcounts[29], {{g_bytes+354, 0}}}}, +{{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}},{&grpc_static_metadata_refcounts[48], {{g_bytes+560, 3}}}}, +{{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}},{&grpc_static_metadata_refcounts[49], {{g_bytes+563, 3}}}}, +{{&grpc_static_metadata_refcounts[0], {{g_bytes+0, 5}}},{&grpc_static_metadata_refcounts[50], {{g_bytes+566, 1}}}}, +{{&grpc_static_metadata_refcounts[0], {{g_bytes+0, 5}}},{&grpc_static_metadata_refcounts[51], {{g_bytes+567, 11}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[52], {{g_bytes+578, 3}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[53], {{g_bytes+581, 3}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[54], {{g_bytes+584, 3}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[55], {{g_bytes+587, 3}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&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[29], {{g_bytes+354, 0}}}}, +{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&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[39], {{g_bytes+505, 8}}}}, +{{&grpc_static_metadata_refcounts[15], {{g_bytes+170, 16}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, +{{&grpc_static_metadata_refcounts[15], {{g_bytes+170, 16}}},{&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[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[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[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[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[39], {{g_bytes+505, 8}}}}, +{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[35], {{g_bytes+482, 7}}}}, +{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[101], {{g_bytes+1085, 16}}}}, +{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, +{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[102], {{g_bytes+1101, 13}}}}, +{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[103], {{g_bytes+1114, 12}}}}, +{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[104], {{g_bytes+1126, 21}}}}, +{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&grpc_static_metadata_refcounts[39], {{g_bytes+505, 8}}}}, +{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, +{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&grpc_static_metadata_refcounts[102], {{g_bytes+1101, 13}}}}, }; bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = { - true, // :path - true, // :method - true, // :status - true, // :authority - true, // :scheme - true, // te - true, // grpc-message - true, // grpc-status - true, // grpc-payload-bin - true, // grpc-encoding - true, // grpc-accept-encoding - true, // grpc-server-stats-bin - true, // grpc-tags-bin - true, // grpc-trace-bin - true, // content-type - true, // content-encoding - true, // accept-encoding - true, // grpc-internal-encoding-request - true, // grpc-internal-stream-encoding-request - true, // user-agent - true, // host - true, // lb-token - true, // grpc-previous-rpc-attempts - true, // grpc-retry-pushback-ms + true, // :path + true, // :method + true, // :status + true, // :authority + true, // :scheme + true, // te + true, // grpc-message + true, // grpc-status + true, // grpc-payload-bin + true, // grpc-encoding + true, // grpc-accept-encoding + true, // grpc-server-stats-bin + true, // grpc-tags-bin + true, // grpc-trace-bin + true, // content-type + true, // content-encoding + true, // accept-encoding + true, // grpc-internal-encoding-request + true, // grpc-internal-stream-encoding-request + 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, - 79, 80, 81, 82}; +const uint8_t grpc_static_accept_encoding_metadata[8] = { +0,76,77,78,79,80,81,82 +}; -const uint8_t grpc_static_accept_stream_encoding_metadata[4] = {0, 83, 84, 85}; +const uint8_t grpc_static_accept_stream_encoding_metadata[4] = { +0,83,84,85 +}; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index b3a10f58730..333bc789d68 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -1,12 +1,12 @@ /* * 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. @@ -16,10 +16,10 @@ /* * WARNING: Auto-generated code. - * + * * To make changes to this file, change * tools/codegen/core/gen_static_metadata.py, and then re-run it. - * + * * See metadata.h for an explanation of the interface here, and metadata.cc for * an explanation of what's going on. */ @@ -27,8 +27,6 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H #define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H -#include - #include "src/core/lib/transport/metadata.h" #define GRPC_STATIC_MDSTR_COUNT 105 @@ -70,8 +68,7 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "grpc-internal-encoding-request" */ #define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (grpc_static_slice_table[17]) /* "grpc-internal-stream-encoding-request" */ -#define GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST \ - (grpc_static_slice_table[18]) +#define GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST (grpc_static_slice_table[18]) /* "user-agent" */ #define GRPC_MDSTR_USER_AGENT (grpc_static_slice_table[19]) /* "host" */ @@ -99,14 +96,11 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "grpc.timeout" */ #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[32]) +#define GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES (grpc_static_slice_table[32]) /* "grpc.max_response_message_bytes" */ -#define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES \ - (grpc_static_slice_table[33]) +#define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES (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[34]) +#define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD (grpc_static_slice_table[34]) /* "deflate" */ #define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[35]) /* "gzip" */ @@ -246,15 +240,12 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "deflate,gzip" */ #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[104]) +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP (grpc_static_slice_table[104]) extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable; -extern grpc_slice_refcount - grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT]; +extern grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT]; #define GRPC_IS_STATIC_METADATA_STRING(slice) \ - ((slice).refcount != NULL && \ - (slice).refcount->vtable == &grpc_static_metadata_vtable) + ((slice).refcount != NULL && (slice).refcount->vtable == &grpc_static_metadata_vtable) #define GRPC_STATIC_METADATA_INDEX(static_slice) \ ((int)((static_slice).refcount - grpc_static_metadata_refcounts)) @@ -262,264 +253,178 @@ extern grpc_slice_refcount #define GRPC_STATIC_MDELEM_COUNT 86 extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; -/* "grpc-status": "0" */ -#define GRPC_MDELEM_GRPC_STATUS_0 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-status": "1" */ -#define GRPC_MDELEM_GRPC_STATUS_1 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-status": "2" */ -#define GRPC_MDELEM_GRPC_STATUS_2 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-encoding": "identity" */ -#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-encoding": "gzip" */ -#define GRPC_MDELEM_GRPC_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-encoding": "deflate" */ -#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC)) -/* "te": "trailers" */ -#define GRPC_MDELEM_TE_TRAILERS \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-type": "application/grpc" */ -#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC)) -/* ":method": "POST" */ -#define GRPC_MDELEM_METHOD_POST \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC)) -/* ":status": "200" */ -#define GRPC_MDELEM_STATUS_200 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC)) -/* ":status": "404" */ -#define GRPC_MDELEM_STATUS_404 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC)) -/* ":scheme": "http" */ -#define GRPC_MDELEM_SCHEME_HTTP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC)) -/* ":scheme": "https" */ -#define GRPC_MDELEM_SCHEME_HTTPS \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC)) -/* ":scheme": "grpc" */ -#define GRPC_MDELEM_SCHEME_GRPC \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC)) -/* ":authority": "" */ -#define GRPC_MDELEM_AUTHORITY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC)) -/* ":method": "GET" */ -#define GRPC_MDELEM_METHOD_GET \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC)) -/* ":method": "PUT" */ -#define GRPC_MDELEM_METHOD_PUT \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC)) -/* ":path": "/" */ -#define GRPC_MDELEM_PATH_SLASH \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC)) -/* ":path": "/index.html" */ -#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC)) -/* ":status": "204" */ -#define GRPC_MDELEM_STATUS_204 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC)) -/* ":status": "206" */ -#define GRPC_MDELEM_STATUS_206 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC)) -/* ":status": "304" */ -#define GRPC_MDELEM_STATUS_304 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC)) -/* ":status": "400" */ -#define GRPC_MDELEM_STATUS_400 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC)) -/* ":status": "500" */ -#define GRPC_MDELEM_STATUS_500 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC)) -/* "accept-charset": "" */ -#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC)) -/* "accept-encoding": "" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC)) -/* "accept-encoding": "gzip, deflate" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC)) -/* "accept-language": "" */ -#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC)) -/* "accept-ranges": "" */ -#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC)) -/* "accept": "" */ -#define GRPC_MDELEM_ACCEPT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC)) -/* "access-control-allow-origin": "" */ -#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC)) -/* "age": "" */ -#define GRPC_MDELEM_AGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC)) -/* "allow": "" */ -#define GRPC_MDELEM_ALLOW_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC)) -/* "authorization": "" */ -#define GRPC_MDELEM_AUTHORIZATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC)) -/* "cache-control": "" */ -#define GRPC_MDELEM_CACHE_CONTROL_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-disposition": "" */ -#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-encoding": "identity" */ -#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-encoding": "gzip" */ -#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-encoding": "" */ -#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-language": "" */ -#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-length": "" */ -#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-location": "" */ -#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-range": "" */ -#define GRPC_MDELEM_CONTENT_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-type": "" */ -#define GRPC_MDELEM_CONTENT_TYPE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC)) -/* "cookie": "" */ -#define GRPC_MDELEM_COOKIE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC)) -/* "date": "" */ -#define GRPC_MDELEM_DATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC)) -/* "etag": "" */ -#define GRPC_MDELEM_ETAG_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC)) -/* "expect": "" */ -#define GRPC_MDELEM_EXPECT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC)) -/* "expires": "" */ -#define GRPC_MDELEM_EXPIRES_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC)) -/* "from": "" */ -#define GRPC_MDELEM_FROM_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC)) -/* "host": "" */ -#define GRPC_MDELEM_HOST_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC)) -/* "if-match": "" */ -#define GRPC_MDELEM_IF_MATCH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC)) -/* "if-modified-since": "" */ -#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC)) -/* "if-none-match": "" */ -#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC)) -/* "if-range": "" */ -#define GRPC_MDELEM_IF_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC)) -/* "if-unmodified-since": "" */ -#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC)) -/* "last-modified": "" */ -#define GRPC_MDELEM_LAST_MODIFIED_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC)) -/* "lb-token": "" */ -#define GRPC_MDELEM_LB_TOKEN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC)) -/* "lb-cost-bin": "" */ -#define GRPC_MDELEM_LB_COST_BIN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC)) -/* "link": "" */ -#define GRPC_MDELEM_LINK_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC)) -/* "location": "" */ -#define GRPC_MDELEM_LOCATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC)) -/* "max-forwards": "" */ -#define GRPC_MDELEM_MAX_FORWARDS_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC)) -/* "proxy-authenticate": "" */ -#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC)) -/* "proxy-authorization": "" */ -#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC)) -/* "range": "" */ -#define GRPC_MDELEM_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC)) -/* "referer": "" */ -#define GRPC_MDELEM_REFERER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC)) -/* "refresh": "" */ -#define GRPC_MDELEM_REFRESH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC)) -/* "retry-after": "" */ -#define GRPC_MDELEM_RETRY_AFTER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC)) -/* "server": "" */ -#define GRPC_MDELEM_SERVER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC)) -/* "set-cookie": "" */ -#define GRPC_MDELEM_SET_COOKIE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC)) -/* "strict-transport-security": "" */ -#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC)) -/* "transfer-encoding": "" */ -#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC)) -/* "user-agent": "" */ -#define GRPC_MDELEM_USER_AGENT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC)) -/* "vary": "" */ -#define GRPC_MDELEM_VARY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC)) -/* "via": "" */ -#define GRPC_MDELEM_VIA_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC)) -/* "www-authenticate": "" */ -#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-accept-encoding": "identity" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-accept-encoding": "deflate" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-accept-encoding": "identity,deflate" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-accept-encoding": "gzip" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-accept-encoding": "identity,gzip" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-accept-encoding": "deflate,gzip" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-accept-encoding": "identity,deflate,gzip" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82], GRPC_MDELEM_STORAGE_STATIC)) -/* "accept-encoding": "identity" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83], GRPC_MDELEM_STORAGE_STATIC)) -/* "accept-encoding": "gzip" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84], GRPC_MDELEM_STORAGE_STATIC)) -/* "accept-encoding": "identity,gzip" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-status": "0" Index="0" */ +#define GRPC_MDELEM_GRPC_STATUS_0 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "grpc-status": "1" Index="0" */ +#define GRPC_MDELEM_GRPC_STATUS_1 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "grpc-status": "2" Index="0" */ +#define GRPC_MDELEM_GRPC_STATUS_2 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "grpc-encoding": "identity" Index="0" */ +#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "grpc-encoding": "gzip" Index="0" */ +#define GRPC_MDELEM_GRPC_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "grpc-encoding": "deflate" Index="0" */ +#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "te": "trailers" Index="0" */ +#define GRPC_MDELEM_TE_TRAILERS (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "content-type": "application/grpc" Index="0" */ +#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC), 0) +/* ":method": "POST" Index="3" */ +#define GRPC_MDELEM_METHOD_POST (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC), 3) +/* ":status": "200" Index="8" */ +#define GRPC_MDELEM_STATUS_200 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC), 8) +/* ":status": "404" Index="13" */ +#define GRPC_MDELEM_STATUS_404 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC), 13) +/* ":scheme": "http" Index="6" */ +#define GRPC_MDELEM_SCHEME_HTTP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC), 6) +/* ":scheme": "https" Index="7" */ +#define GRPC_MDELEM_SCHEME_HTTPS (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC), 7) +/* ":scheme": "grpc" Index="0" */ +#define GRPC_MDELEM_SCHEME_GRPC (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC), 0) +/* ":authority": "" Index="1" */ +#define GRPC_MDELEM_AUTHORITY_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC), 1) +/* ":method": "GET" Index="2" */ +#define GRPC_MDELEM_METHOD_GET (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC), 2) +/* ":method": "PUT" Index="0" */ +#define GRPC_MDELEM_METHOD_PUT (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC), 0) +/* ":path": "/" Index="4" */ +#define GRPC_MDELEM_PATH_SLASH (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC), 4) +/* ":path": "/index.html" Index="5" */ +#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC), 5) +/* ":status": "204" Index="9" */ +#define GRPC_MDELEM_STATUS_204 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC), 9) +/* ":status": "206" Index="10" */ +#define GRPC_MDELEM_STATUS_206 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC), 10) +/* ":status": "304" Index="11" */ +#define GRPC_MDELEM_STATUS_304 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC), 11) +/* ":status": "400" Index="12" */ +#define GRPC_MDELEM_STATUS_400 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC), 12) +/* ":status": "500" Index="14" */ +#define GRPC_MDELEM_STATUS_500 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC), 14) +/* "accept-charset": "" Index="15" */ +#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC), 15) +/* "accept-encoding": "" Index="0" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "accept-encoding": "gzip, deflate" Index="16" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC), 16) +/* "accept-language": "" Index="17" */ +#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC), 17) +/* "accept-ranges": "" Index="18" */ +#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC), 18) +/* "accept": "" Index="19" */ +#define GRPC_MDELEM_ACCEPT_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC), 19) +/* "access-control-allow-origin": "" Index="20" */ +#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC), 20) +/* "age": "" Index="21" */ +#define GRPC_MDELEM_AGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC), 21) +/* "allow": "" Index="22" */ +#define GRPC_MDELEM_ALLOW_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC), 22) +/* "authorization": "" Index="23" */ +#define GRPC_MDELEM_AUTHORIZATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC), 23) +/* "cache-control": "" Index="24" */ +#define GRPC_MDELEM_CACHE_CONTROL_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC), 24) +/* "content-disposition": "" Index="25" */ +#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC), 25) +/* "content-encoding": "identity" Index="0" */ +#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "content-encoding": "gzip" Index="0" */ +#define GRPC_MDELEM_CONTENT_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "content-encoding": "" Index="26" */ +#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC), 26) +/* "content-language": "" Index="27" */ +#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC), 27) +/* "content-length": "" Index="28" */ +#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC), 28) +/* "content-location": "" Index="29" */ +#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC), 29) +/* "content-range": "" Index="30" */ +#define GRPC_MDELEM_CONTENT_RANGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC), 30) +/* "content-type": "" Index="31" */ +#define GRPC_MDELEM_CONTENT_TYPE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC), 31) +/* "cookie": "" Index="32" */ +#define GRPC_MDELEM_COOKIE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC), 32) +/* "date": "" Index="33" */ +#define GRPC_MDELEM_DATE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC), 33) +/* "etag": "" Index="34" */ +#define GRPC_MDELEM_ETAG_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC), 34) +/* "expect": "" Index="35" */ +#define GRPC_MDELEM_EXPECT_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC), 35) +/* "expires": "" Index="36" */ +#define GRPC_MDELEM_EXPIRES_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC), 36) +/* "from": "" Index="37" */ +#define GRPC_MDELEM_FROM_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC), 37) +/* "host": "" Index="38" */ +#define GRPC_MDELEM_HOST_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC), 38) +/* "if-match": "" Index="39" */ +#define GRPC_MDELEM_IF_MATCH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC), 39) +/* "if-modified-since": "" Index="40" */ +#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC), 40) +/* "if-none-match": "" Index="41" */ +#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC), 41) +/* "if-range": "" Index="42" */ +#define GRPC_MDELEM_IF_RANGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC), 42) +/* "if-unmodified-since": "" Index="43" */ +#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC), 43) +/* "last-modified": "" Index="44" */ +#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC), 44) +/* "lb-token": "" Index="0" */ +#define GRPC_MDELEM_LB_TOKEN_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "lb-cost-bin": "" Index="0" */ +#define GRPC_MDELEM_LB_COST_BIN_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "link": "" Index="45" */ +#define GRPC_MDELEM_LINK_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC), 45) +/* "location": "" Index="46" */ +#define GRPC_MDELEM_LOCATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC), 46) +/* "max-forwards": "" Index="47" */ +#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC), 47) +/* "proxy-authenticate": "" Index="48" */ +#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC), 48) +/* "proxy-authorization": "" Index="49" */ +#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC), 49) +/* "range": "" Index="50" */ +#define GRPC_MDELEM_RANGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC), 50) +/* "referer": "" Index="51" */ +#define GRPC_MDELEM_REFERER_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC), 51) +/* "refresh": "" Index="52" */ +#define GRPC_MDELEM_REFRESH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC), 52) +/* "retry-after": "" Index="53" */ +#define GRPC_MDELEM_RETRY_AFTER_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC), 53) +/* "server": "" Index="54" */ +#define GRPC_MDELEM_SERVER_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC), 54) +/* "set-cookie": "" Index="55" */ +#define GRPC_MDELEM_SET_COOKIE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC), 55) +/* "strict-transport-security": "" Index="56" */ +#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC), 56) +/* "transfer-encoding": "" Index="57" */ +#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC), 57) +/* "user-agent": "" Index="58" */ +#define GRPC_MDELEM_USER_AGENT_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC), 58) +/* "vary": "" Index="59" */ +#define GRPC_MDELEM_VARY_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC), 59) +/* "via": "" Index="60" */ +#define GRPC_MDELEM_VIA_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC), 60) +/* "www-authenticate": "" Index="61" */ +#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC), 61) +/* "grpc-accept-encoding": "identity" Index="0" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "grpc-accept-encoding": "deflate" Index="0" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "grpc-accept-encoding": "identity,deflate" Index="0" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "grpc-accept-encoding": "gzip" Index="0" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "grpc-accept-encoding": "identity,gzip" Index="0" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "grpc-accept-encoding": "deflate,gzip" Index="0" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "grpc-accept-encoding": "identity,deflate,gzip" Index="0" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "accept-encoding": "identity" Index="0" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "accept-encoding": "gzip" Index="0" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84], GRPC_MDELEM_STORAGE_STATIC), 0) +/* "accept-encoding": "identity,gzip" Index="0" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC), 0) grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b); typedef enum { @@ -551,53 +456,43 @@ typedef enum { } grpc_metadata_batch_callouts_index; typedef union { - struct grpc_linked_mdelem* array[GRPC_BATCH_CALLOUTS_COUNT]; + struct grpc_linked_mdelem *array[GRPC_BATCH_CALLOUTS_COUNT]; struct { - struct grpc_linked_mdelem* path; - struct grpc_linked_mdelem* method; - struct grpc_linked_mdelem* status; - struct grpc_linked_mdelem* authority; - struct grpc_linked_mdelem* scheme; - struct grpc_linked_mdelem* te; - struct grpc_linked_mdelem* grpc_message; - struct grpc_linked_mdelem* grpc_status; - struct grpc_linked_mdelem* grpc_payload_bin; - struct grpc_linked_mdelem* grpc_encoding; - struct grpc_linked_mdelem* grpc_accept_encoding; - struct grpc_linked_mdelem* grpc_server_stats_bin; - struct grpc_linked_mdelem* grpc_tags_bin; - struct grpc_linked_mdelem* grpc_trace_bin; - struct grpc_linked_mdelem* content_type; - struct grpc_linked_mdelem* content_encoding; - struct grpc_linked_mdelem* accept_encoding; - struct grpc_linked_mdelem* grpc_internal_encoding_request; - struct grpc_linked_mdelem* grpc_internal_stream_encoding_request; - 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; + struct grpc_linked_mdelem *path; + struct grpc_linked_mdelem *method; + struct grpc_linked_mdelem *status; + struct grpc_linked_mdelem *authority; + struct grpc_linked_mdelem *scheme; + struct grpc_linked_mdelem *te; + struct grpc_linked_mdelem *grpc_message; + struct grpc_linked_mdelem *grpc_status; + struct grpc_linked_mdelem *grpc_payload_bin; + struct grpc_linked_mdelem *grpc_encoding; + struct grpc_linked_mdelem *grpc_accept_encoding; + struct grpc_linked_mdelem *grpc_server_stats_bin; + struct grpc_linked_mdelem *grpc_tags_bin; + struct grpc_linked_mdelem *grpc_trace_bin; + struct grpc_linked_mdelem *content_type; + struct grpc_linked_mdelem *content_encoding; + struct grpc_linked_mdelem *accept_encoding; + struct grpc_linked_mdelem *grpc_internal_encoding_request; + struct grpc_linked_mdelem *grpc_internal_stream_encoding_request; + 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; -#define GRPC_BATCH_INDEX_OF(slice) \ - (GRPC_IS_STATIC_METADATA_STRING((slice)) \ - ? (grpc_metadata_batch_callouts_index)GPR_CLAMP( \ - GRPC_STATIC_METADATA_INDEX((slice)), 0, \ - GRPC_BATCH_CALLOUTS_COUNT) \ - : GRPC_BATCH_CALLOUTS_COUNT) +#define GRPC_BATCH_INDEX_OF(slice) \ + (GRPC_IS_STATIC_METADATA_STRING((slice)) ? (grpc_metadata_batch_callouts_index)GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, GRPC_BATCH_CALLOUTS_COUNT) : GRPC_BATCH_CALLOUTS_COUNT) extern bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT]; extern const uint8_t grpc_static_accept_encoding_metadata[8]; -#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \ - (GRPC_MAKE_MDELEM( \ - &grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC), 0) extern const uint8_t grpc_static_accept_stream_encoding_metadata[4]; -#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table \ - [grpc_static_accept_stream_encoding_metadata[(algs)]], \ - GRPC_MDELEM_STORAGE_STATIC)) +#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_stream_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC), 0) #endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */ diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index 25da3fdd5f2..621ee9991d2 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -64,82 +64,82 @@ CONFIG = [ 'gzip', 'stream/gzip', # metadata elements - ('grpc-status', '0'), - ('grpc-status', '1'), - ('grpc-status', '2'), - ('grpc-encoding', 'identity'), - ('grpc-encoding', 'gzip'), - ('grpc-encoding', 'deflate'), - ('te', 'trailers'), - ('content-type', 'application/grpc'), - (':method', 'POST'), - (':status', '200'), - (':status', '404'), - (':scheme', 'http'), - (':scheme', 'https'), - (':scheme', 'grpc'), - (':authority', ''), - (':method', 'GET'), - (':method', 'PUT'), - (':path', '/'), - (':path', '/index.html'), - (':status', '204'), - (':status', '206'), - (':status', '304'), - (':status', '400'), - (':status', '500'), - ('accept-charset', ''), - ('accept-encoding', ''), - ('accept-encoding', 'gzip, deflate'), - ('accept-language', ''), - ('accept-ranges', ''), - ('accept', ''), - ('access-control-allow-origin', ''), - ('age', ''), - ('allow', ''), - ('authorization', ''), - ('cache-control', ''), - ('content-disposition', ''), - ('content-encoding', 'identity'), - ('content-encoding', 'gzip'), - ('content-encoding', ''), - ('content-language', ''), - ('content-length', ''), - ('content-location', ''), - ('content-range', ''), - ('content-type', ''), - ('cookie', ''), - ('date', ''), - ('etag', ''), - ('expect', ''), - ('expires', ''), - ('from', ''), - ('host', ''), - ('if-match', ''), - ('if-modified-since', ''), - ('if-none-match', ''), - ('if-range', ''), - ('if-unmodified-since', ''), - ('last-modified', ''), - ('lb-token', ''), - ('lb-cost-bin', ''), - ('link', ''), - ('location', ''), - ('max-forwards', ''), - ('proxy-authenticate', ''), - ('proxy-authorization', ''), - ('range', ''), - ('referer', ''), - ('refresh', ''), - ('retry-after', ''), - ('server', ''), - ('set-cookie', ''), - ('strict-transport-security', ''), - ('transfer-encoding', ''), - ('user-agent', ''), - ('vary', ''), - ('via', ''), - ('www-authenticate', ''), + ('grpc-status', '0', 0), + ('grpc-status', '1', 0), + ('grpc-status', '2', 0), + ('grpc-encoding', 'identity', 0), + ('grpc-encoding', 'gzip', 0), + ('grpc-encoding', 'deflate', 0), + ('te', 'trailers', 0), + ('content-type', 'application/grpc', 0), + (':method', 'POST', 3), + (':status', '200', 8), + (':status', '404', 13), + (':scheme', 'http', 6), + (':scheme', 'https', 7), + (':scheme', 'grpc', 0), + (':authority', '', 1), + (':method', 'GET', 2), + (':method', 'PUT', 0), + (':path', '/', 4), + (':path', '/index.html', 5), + (':status', '204', 9), + (':status', '206', 10), + (':status', '304', 11), + (':status', '400', 12), + (':status', '500', 14), + ('accept-charset', '', 15), + ('accept-encoding', '', 0), + ('accept-encoding', 'gzip, deflate', 16), + ('accept-language', '', 17), + ('accept-ranges', '', 18), + ('accept', '', 19), + ('access-control-allow-origin', '', 20), + ('age', '', 21), + ('allow', '', 22), + ('authorization', '', 23), + ('cache-control', '', 24), + ('content-disposition', '', 25), + ('content-encoding', 'identity', 0), + ('content-encoding', 'gzip', 0), + ('content-encoding', '', 26), + ('content-language', '', 27), + ('content-length', '', 28), + ('content-location', '', 29), + ('content-range', '', 30), + ('content-type', '', 31), + ('cookie', '', 32), + ('date', '', 33), + ('etag', '', 34), + ('expect', '', 35), + ('expires', '', 36), + ('from', '', 37), + ('host', '', 38), + ('if-match', '', 39), + ('if-modified-since', '', 40), + ('if-none-match', '', 41), + ('if-range', '', 42), + ('if-unmodified-since', '', 43), + ('last-modified', '', 44), + ('lb-token', '', 0), + ('lb-cost-bin', '', 0), + ('link', '', 45), + ('location', '', 46), + ('max-forwards', '', 47), + ('proxy-authenticate', '', 48), + ('proxy-authorization', '', 49), + ('range', '', 50), + ('referer', '', 51), + ('refresh', '', 52), + ('retry-after', '', 53), + ('server', '', 54), + ('set-cookie', '', 55), + ('strict-transport-security', '', 56), + ('transfer-encoding', '', 57), + ('user-agent', '', 58), + ('vary', '', 59), + ('via', '', 60), + ('www-authenticate', '', 61), ] # Entries marked with is_default=True are ignored when counting @@ -271,7 +271,7 @@ for mask in range(1, 1 << len(COMPRESSION_ALGORITHMS)): val = ','.join(COMPRESSION_ALGORITHMS[alg] for alg in range(0, len(COMPRESSION_ALGORITHMS)) if (1 << alg) & mask) - elem = ('grpc-accept-encoding', val) + elem = ('grpc-accept-encoding', val, 0) if val not in all_strs: all_strs.append(val) if elem not in all_elems: @@ -283,7 +283,7 @@ for mask in range(1, 1 << len(STREAM_COMPRESSION_ALGORITHMS)): val = ','.join(STREAM_COMPRESSION_ALGORITHMS[alg] for alg in range(0, len(STREAM_COMPRESSION_ALGORITHMS)) if (1 << alg) & mask) - elem = ('accept-encoding', val) + elem = ('accept-encoding', val, 0) if val not in all_strs: all_strs.append(val) if elem not in all_elems: @@ -450,9 +450,9 @@ print >> H, ('extern grpc_mdelem_data ' print >> H, ('extern uintptr_t ' 'grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];') for i, elem in enumerate(all_elems): - print >> H, '/* "%s": "%s" */' % elem + print >> H, '/* "%s": "%s" Index="%d" */' % elem print >> H, ('#define %s (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[%d], ' - 'GRPC_MDELEM_STORAGE_STATIC))') % (mangle(elem).upper(), i) + 'GRPC_MDELEM_STORAGE_STATIC), %d)') % (mangle(elem).upper(), i, elem[2]) print >> H print >> C, ('uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] ' '= {') @@ -541,12 +541,12 @@ print >> C, 'grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {' print >> C, ' if (a == -1 || b == -1) return GRPC_MDNULL;' print >> C, ' uint32_t k = (uint32_t)(a * %d + b);' % len(all_strs) print >> C, ' uint32_t h = elems_phash(k);' -print >> C, ' return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC) : GRPC_MDNULL;' +print >> C, ' return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC, 0) : GRPC_MDNULL;' print >> C, '}' print >> C print >> C, 'grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {' -for a, b in all_elems: +for a, b, c in all_elems: print >> C, '{%s,%s},' % (slice_def(str_idx(a)), slice_def(str_idx(b))) print >> C, '};' @@ -584,7 +584,7 @@ print >> C, '0,%s' % ','.join('%d' % md_idx(elem) for elem in compression_elems) print >> C, '};' print >> C -print >> H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC))' +print >> H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC), 0)' print >> H print >> H, 'extern const uint8_t grpc_static_accept_stream_encoding_metadata[%d];' % ( @@ -595,7 +595,7 @@ print >> C, '0,%s' % ','.join( '%d' % md_idx(elem) for elem in stream_compression_elems) print >> C, '};' -print >> H, '#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_stream_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC))' +print >> H, '#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_stream_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC), 0)' print >> H, '#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */' From fbe594beeb0e065bc357674bd99c3a3161795341 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Mon, 10 Sep 2018 20:34:49 -0700 Subject: [PATCH 341/546] Much cleaner approach that should address code review comments as well --- .../client_channel/lb_policy/grpclb/grpclb.cc | 6 +- .../filters/http/server/http_server_filter.cc | 4 +- .../chttp2/transport/chttp2_transport.cc | 5 +- .../chttp2/transport/hpack_encoder.cc | 18 +- .../chttp2/transport/hpack_encoder.h | 2 +- .../ext/transport/chttp2/transport/writing.cc | 6 +- src/core/lib/surface/call.cc | 2 - src/core/lib/transport/metadata.cc | 12 +- src/core/lib/transport/metadata.h | 196 +--- src/core/lib/transport/metadata_batch.cc | 238 +---- src/core/lib/transport/metadata_batch.h | 53 +- src/core/lib/transport/static_metadata.cc | 886 +++++++++++------- src/core/lib/transport/static_metadata.h | 443 ++++++--- src/core/lib/transport/transport_op_string.cc | 7 +- .../transport/chttp2/hpack_encoder_test.cc | 4 +- test/core/transport/metadata_test.cc | 5 +- tools/codegen/core/gen_static_metadata.py | 7 +- 17 files changed, 936 insertions(+), 958 deletions(-) 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 25b0149393e..b20d8d8c694 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 @@ -352,11 +352,13 @@ class GrpcLb : public LoadBalancingPolicy { void* lb_token_copy(void* token) { return token == nullptr ? nullptr - : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload; + : (void*)GRPC_MDELEM_REF( + (grpc_mdelem{(uintptr_t)token, GRPC_MDINDEX_UNUSED})) + .payload; } void lb_token_destroy(void* token) { if (token != nullptr) { - GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token}); + GRPC_MDELEM_UNREF((grpc_mdelem{(uintptr_t)token, GRPC_MDINDEX_UNUSED})); } } int lb_token_cmp(void* token1, void* token2) { 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 1880dbb38d9..3919447f264 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -322,9 +322,9 @@ static grpc_error* hs_mutate_op(grpc_call_element* elem, grpc_error* error = GRPC_ERROR_NONE; static const char* error_name = "Failed sending initial metadata"; hs_add_error(error_name, &error, - grpc_metadata_batch_add_head_static( + grpc_metadata_batch_add_head( op->payload->send_initial_metadata.send_initial_metadata, - &calld->status, GRPC_MDELEM_STATUS_200_INDEX)); + &calld->status, GRPC_MDELEM_STATUS_200)); hs_add_error(error_name, &error, grpc_metadata_batch_add_tail( op->payload->send_initial_metadata.send_initial_metadata, diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 9bdad94e824..027a57d606d 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1332,9 +1332,8 @@ static void log_metadata(const grpc_metadata_batch* md_batch, uint32_t id, bool is_client, bool is_initial) { for (grpc_linked_mdelem* md = md_batch->list.head; md != nullptr; md = md->next) { - grpc_mdelem mdelem = grpc_get_md_from_linked_mdelem(md); - char* key = grpc_slice_to_c_string(GRPC_MDKEY(mdelem)); - char* value = grpc_slice_to_c_string(GRPC_MDVALUE(mdelem)); + char* key = grpc_slice_to_c_string(GRPC_MDKEY(md->md)); + char* value = grpc_slice_to_c_string(GRPC_MDVALUE(md->md)); gpr_log(GPR_INFO, "HTTP:%d:%s:%s: %s: %s", id, is_initial ? "HDR" : "TRL", is_client ? "CLI" : "SVR", key, value); gpr_free(key); diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 6674b701523..d0e65ddebd9 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -37,7 +37,7 @@ #include "src/core/lib/debug/stats.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" -#include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/timeout_encoding.h" @@ -663,7 +663,7 @@ void grpc_chttp2_hpack_compressor_set_max_table_size( } void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, - grpc_linked_mdelem** extra_headers, + grpc_mdelem** extra_headers, size_t extra_headers_size, grpc_metadata_batch* metadata, const grpc_encode_header_options* options, @@ -688,17 +688,19 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, emit_advertise_table_size_change(c, &st); } for (size_t i = 0; i < extra_headers_size; ++i) { - grpc_linked_mdelem* linked_md = extra_headers[i]; - if (grpc_is_mdelem_index_used(linked_md)) { - emit_indexed(c, linked_md->md_index, &st); + grpc_mdelem md = *extra_headers[i]; + uint8_t static_index = GRPC_MDINDEX(md); + if (static_index > 0) { + emit_indexed(c, static_index, &st); } else { - hpack_enc(c, linked_md->md, &st); + hpack_enc(c, md, &st); } } grpc_metadata_batch_assert_ok(metadata); for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) { - if (grpc_is_mdelem_index_used(l)) { - emit_indexed(c, l->md_index, &st); + uint8_t static_index = GRPC_MDINDEX(l->md); + if (static_index > 0) { + emit_indexed(c, static_index, &st); } else { hpack_enc(c, l->md, &st); } diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h index 0994eeb45f4..e31a7399d78 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h @@ -87,7 +87,7 @@ typedef struct { } grpc_encode_header_options; void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, - grpc_linked_mdelem** extra_headers, + grpc_mdelem** extra_headers, size_t extra_headers_size, grpc_metadata_batch* metadata, const grpc_encode_header_options* options, diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 9eabdb4da48..8b73b01dea2 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -557,12 +557,12 @@ class StreamWriteContext { if (s_->send_initial_metadata->idx.named.status != nullptr) { extra_headers_for_trailing_metadata_ [num_extra_headers_for_trailing_metadata_++] = - s_->send_initial_metadata->idx.named.status; + &s_->send_initial_metadata->idx.named.status->md; } if (s_->send_initial_metadata->idx.named.content_type != nullptr) { extra_headers_for_trailing_metadata_ [num_extra_headers_for_trailing_metadata_++] = - s_->send_initial_metadata->idx.named.content_type; + &s_->send_initial_metadata->idx.named.content_type->md; } } @@ -583,7 +583,7 @@ class StreamWriteContext { grpc_chttp2_transport* const t_; grpc_chttp2_stream* const s_; bool stream_became_writable_ = false; - grpc_linked_mdelem* extra_headers_for_trailing_metadata_[2]; + grpc_mdelem* extra_headers_for_trailing_metadata_[2]; size_t num_extra_headers_for_trailing_metadata_ = 0; }; } // namespace diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index a72a3ce57cf..2923a86646a 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -374,7 +374,6 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, MAX_SEND_EXTRA_METADATA_COUNT); for (i = 0; i < args->add_initial_metadata_count; i++) { call->send_extra_metadata[i].md = args->add_initial_metadata[i]; - call->send_extra_metadata[i].md_index = 0; if (grpc_slice_eq(GRPC_MDKEY(args->add_initial_metadata[i]), GRPC_MDSTR_PATH)) { path = grpc_slice_ref_internal( @@ -955,7 +954,6 @@ static int prepare_application_metadata(grpc_call* call, int count, const grpc_metadata* md = get_md_elem(metadata, additional_metadata, i, count); grpc_linked_mdelem* l = linked_from_md(md); - l->md_index = 0; GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data)); if (!GRPC_LOG_IF_ERROR("validate_metadata", grpc_validate_header_key_is_legal(md->key))) { diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index d10194a2fe7..c5458d1d56a 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -242,7 +242,8 @@ grpc_mdelem grpc_mdelem_create( if (!grpc_slice_is_interned(key) || !grpc_slice_is_interned(value)) { if (compatible_external_backing_store != nullptr) { return GRPC_MAKE_MDELEM(compatible_external_backing_store, - GRPC_MDELEM_STORAGE_EXTERNAL); + GRPC_MDELEM_STORAGE_EXTERNAL, + GRPC_MDINDEX_UNUSED); } allocated_metadata* allocated = @@ -261,7 +262,8 @@ grpc_mdelem grpc_mdelem_create( gpr_free(value_str); } #endif - return GRPC_MAKE_MDELEM(allocated, GRPC_MDELEM_STORAGE_ALLOCATED); + return GRPC_MAKE_MDELEM(allocated, GRPC_MDELEM_STORAGE_ALLOCATED, + GRPC_MDINDEX_UNUSED); } if (GRPC_IS_STATIC_METADATA_STRING(key) && @@ -289,7 +291,8 @@ grpc_mdelem grpc_mdelem_create( if (grpc_slice_eq(key, md->key) && grpc_slice_eq(value, md->value)) { REF_MD_LOCKED(shard, md); gpr_mu_unlock(&shard->mu); - return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED); + return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED, + GRPC_MDINDEX_UNUSED); } } @@ -321,7 +324,8 @@ grpc_mdelem grpc_mdelem_create( gpr_mu_unlock(&shard->mu); - return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED); + return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED, + GRPC_MDINDEX_UNUSED); } grpc_mdelem grpc_mdelem_from_slices(grpc_slice key, grpc_slice value) { diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 5c34f7323be..513ac826ea1 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -92,9 +92,9 @@ struct grpc_mdelem { /* a grpc_mdelem_data* generally, with the two lower bits signalling memory ownership as per grpc_mdelem_data_storage */ uintptr_t payload; - /* The static index of this mdelem. This is equivalent to the - mdelem's index into the hpack static table. 0 if unused. */ - uint8_t static_index; + /* The static index of this mdelem. This is equivalent to the + mdelem's index into the hpack static table. 0 if unused. */ + uint8_t static_index; }; #define GRPC_MDELEM_DATA(md) ((grpc_mdelem_data*)((md).payload & ~(uintptr_t)3)) @@ -151,8 +151,10 @@ void grpc_mdelem_unref(grpc_mdelem md); #define GRPC_MDKEY(md) (GRPC_MDELEM_DATA(md)->key) #define GRPC_MDVALUE(md) (GRPC_MDELEM_DATA(md)->value) +#define GRPC_MDINDEX(md) (md.static_index) +#define GRPC_MDINDEX_UNUSED 0 -#define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL) +#define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL, 0) #define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL) /* We add 32 bytes of padding as per RFC-7540 section 6.5.2. */ @@ -165,190 +167,4 @@ void grpc_mdelem_unref(grpc_mdelem md); void grpc_mdctx_global_init(void); void grpc_mdctx_global_shutdown(); -#define MIN_STATIC_HPACK_TABLE_IDX 1 -#define MAX_STATIC_HPACK_TABLE_IDX 61 - -/* {:authority, ""} */ -#define GRPC_MDELEM_AUTHORITY_EMPTY_INDEX 1 - -/* {":method", "GET"} */ -#define GRPC_MDELEM_METHOD_GET_INDEX 2 - -/* {":method", "POST"} */ -#define GRPC_MDELEM_METHOD_POST_INDEX 3 - -/* {":path", "/"} */ -#define GRPC_MDELEM_PATH_SLASH_INDEX 4 - -/* {":path", "/index.html"} */ -#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML_INDEX 5 - -/* {":scheme", "http"} */ -#define GRPC_MDELEM_SCHEME_HTTP_INDEX 6 - -/* {":scheme", "https"} */ -#define GRPC_MDELEM_SCHEME_HTTPS_INDEX 7 - -/* {":status", "200"} */ -#define GRPC_MDELEM_STATUS_200_INDEX 8 - -/* {":status", "204"} */ -#define GRPC_MDELEM_STATUS_204_INDEX 9 - -/* {":status", "206"} */ -#define GRPC_MDELEM_STATUS_206_INDEX 10 - -/* {":status", "304"} */ -#define GRPC_MDELEM_STATUS_304_INDEX 11 - -/* {":status", "400"} */ -#define GRPC_MDELEM_STATUS_400_INDEX 12 - -/* {":status", "404"} */ -#define GRPC_MDELEM_STATUS_404_INDEX 13 - -/* {":status", "500"} */ -#define GRPC_MDELEM_STATUS_500_INDEX 14 - -/* {"accept-charset", ""} */ -#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY_INDEX 15 - -/* {"accept-encoding", "gzip, deflate"} */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_DEFLATE_INDEX 16 - -/* {"accept-language", ""} */ -#define GRPC_MDELEM_MDELEM_ACCEPT_LANGUAGE_EMPTY_INDEX 17 - -/* {"accept-ranges", ""} */ -#define GRPC_MDELEM_MDELEM_ACCEPT_RANGES_EMPTY_INDEX 18 - -/* {"accept", ""} */ -#define GRPC_MDELEM_ACCEPT_EMPTY_INDEX 19 - -/* {"access-control-allow-origin", ""} */ -#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY_INDEX 20 - -/* {"age", ""} */ -#define GRPC_MDELEM_AGE_EMPTY_INDEX 21 - -/* {"allow", ""} */ -#define GRPC_MDELEM_ALLOW_EMPTY_INDEX 22 - -/* {"authorization", ""} */ -#define GRPC_MDELEM_AUTHORIZATION_EMPTY_INDEX 23 - -/* {"cache-control", ""} */ -#define GRPC_MDELEM_CACHE_CONTROL_EMPTY_INDEX 24 - -/* {"content-disposition", ""} */ -#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY_INDEX 25 - -/* {"content-encoding", ""} */ -#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY_INDEX 26 - -/* {"content-language", ""} */ -#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY_INDEX 27 - -/* {"content-length", ""} */ -#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY_INDEX 28 - -/* {"content-location", ""} */ -#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY_INDEX 29 - -/* {"content-range", ""} */ -#define GRPC_MDELEM_CONTENT_RANGE_EMPTY_INDEX 30 - -/* {"content-type", ""} */ -#define GRPC_MDELEM_CONTENT_TYPE_EMPTY_INDEX 31 - -/* {"cookie", ""} */ -#define GRPC_MDELEM_COOKIE_EMPTY_INDEX 32 - -/* {"date", ""} */ -#define GRPC_MDELEM_DATE_EMPTY_INDEX 33 - -/* {"etag", ""} */ -#define GRPC_MDELEM_ETAG_EMPTY_INDEX 34 - -/* {"expect", ""} */ -#define GRPC_MDELEM_EXPECT_EMPTY_INDEX 35 - -/* {"expires", ""} */ -#define GRPC_MDELEM_EXPIRES_EMPTY_INDEX 36 - -/* {"from", ""} */ -#define GRPC_MDELEM_FROM_EMPTY_INDEX 37 - -/* {"host", ""} */ -#define GRPC_MDELEM_HOST_EMPTY_INDEX 38 - -/* {"if-match", ""} */ -#define GRPC_MDELEM_IF_MATCH_EMPTY_INDEX 39 - -/* {"if-modified-since", ""} */ -#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY_INDEX 40 - -/* {"if-none-match", ""} */ -#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY_INDEX 41 - -/* {"if-range", ""} */ -#define GRPC_MDELEM_IF_RANGE_EMPTY_INDEX 42 - -/* {"if-unmodified-since", ""} */ -#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY_INDEX 43 - -/* {"last-modified", ""} */ -#define GRPC_MDELEM_LAST_MODIFIED_EMPTY_INDEX 44 - -/* {"link", ""} */ -#define GRPC_MDELEM_LINK_EMPTY_INDEX 45 - -/* {"location", ""} */ -#define GRPC_MDELEM_LOCATION_EMPTY_INDEX 46 - -/* {"max-forwards", ""} */ -#define GRPC_MDELEM_MAX_FORWARDS_EMPTY_INDEX 47 - -/* {"proxy-authenticate", ""} */ -#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY_INDEX 48 - -/* {"proxy-authorization", ""} */ -#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY_INDEX 49 - -/* {"range", ""} */ -#define GRPC_MDELEM_RANGE_EMPTY_INDEX 50 - -/* {"referer", ""} */ -#define GRPC_MDELEM_REFERER_EMPTY_INDEX 51 - -/* {"refresh", ""} */ -#define GRPC_MDELEM_REFRESH_EMPTY_INDEX 52 - -/* {"retry-after", ""} */ -#define GRPC_MDELEM_RETRY_AFTER_EMPTY_INDEX 53 - -/* {"server", ""} */ -#define GRPC_MDELEM_SERVER_EMPTY_INDEX 54 - -/* {"set-cookie", ""} */ -#define GRPC_MDELEM_SET_COOKIE_EMPTY_INDEX 55 * / - -/* {"strict-transport-security", ""} */ -#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY_INDEX 56 - -/* {"transfer-encoding", ""} */ -#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY_INDEX 57 - -/* {"user-agent", ""} */ -#define GRPC_MDELEM_USER_AGENT_EMPTY_INDEX 58 - -/* {"vary", ""} */ -#define GRPC_MDELEM_VARY_EMPTY_INDEX 59 - -/* {"via", ""} */ -#define GRPC_MDELEM_VIA_EMPTY_INDEX 60 - -/* {"www-authenticate", ""} */ -#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY_INDEX 61 - #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */ diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index 05f7a29e8ac..b7ab4cc7b94 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -25,103 +25,11 @@ #include #include -#include #include "src/core/lib/profiling/timers.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" -static_hpack_table_metadata_info static_hpack_table_metadata[] = { - {0, 0, GRPC_BATCH_CALLOUTS_COUNT}, // NOT USED - {GRPC_MDELEM_AUTHORITY_EMPTY_INDEX, 10 + 32, GRPC_BATCH_AUTHORITY}, - {GRPC_MDELEM_METHOD_GET_INDEX, 10 + 32, GRPC_BATCH_METHOD}, - {GRPC_MDELEM_METHOD_POST_INDEX, 11 + 32, GRPC_BATCH_METHOD}, - {GRPC_MDELEM_PATH_SLASH_INDEX, 6 + 32, GRPC_BATCH_PATH}, - {GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML_INDEX, 16 + 32, GRPC_BATCH_PATH}, - {GRPC_MDELEM_SCHEME_HTTP_INDEX, 11 + 32, GRPC_BATCH_SCHEME}, - {GRPC_MDELEM_SCHEME_HTTPS_INDEX, 12 + 32, GRPC_BATCH_SCHEME}, - {GRPC_MDELEM_STATUS_200_INDEX, 10 + 32, GRPC_BATCH_STATUS}, - {GRPC_MDELEM_STATUS_204_INDEX, 10 + 32, GRPC_BATCH_STATUS}, - {GRPC_MDELEM_STATUS_206_INDEX, 10 + 32, GRPC_BATCH_STATUS}, - {GRPC_MDELEM_STATUS_304_INDEX, 10 + 32, GRPC_BATCH_STATUS}, - {GRPC_MDELEM_STATUS_400_INDEX, 10 + 32, GRPC_BATCH_STATUS}, - {GRPC_MDELEM_STATUS_404_INDEX, 10 + 32, GRPC_BATCH_STATUS}, - {GRPC_MDELEM_STATUS_500_INDEX, 10 + 32, GRPC_BATCH_STATUS}, - {GRPC_MDELEM_ACCEPT_CHARSET_EMPTY_INDEX, 14 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_ACCEPT_ENCODING_GZIP_DEFLATE_INDEX, 28 + 32, - GRPC_BATCH_ACCEPT_ENCODING}, - {GRPC_MDELEM_MDELEM_ACCEPT_LANGUAGE_EMPTY_INDEX, 15 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_MDELEM_ACCEPT_RANGES_EMPTY_INDEX, 13 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_ACCEPT_EMPTY_INDEX, 6 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY_INDEX, 27 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_AGE_EMPTY_INDEX, 3 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_ALLOW_EMPTY_INDEX, 5 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_AUTHORIZATION_EMPTY_INDEX, 13 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_CACHE_CONTROL_EMPTY_INDEX, 13 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY_INDEX, 19 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_CONTENT_ENCODING_EMPTY_INDEX, 16 + 32, - GRPC_BATCH_CONTENT_ENCODING}, - {GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY_INDEX, 16 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_CONTENT_LENGTH_EMPTY_INDEX, 14 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_CONTENT_LOCATION_EMPTY_INDEX, 16 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_CONTENT_RANGE_EMPTY_INDEX, 13 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_CONTENT_TYPE_EMPTY_INDEX, 12 + 32, GRPC_BATCH_CONTENT_TYPE}, - {GRPC_MDELEM_COOKIE_EMPTY_INDEX, 6 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_DATE_EMPTY_INDEX, 4 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_ETAG_EMPTY_INDEX, 4 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_EXPECT_EMPTY_INDEX, 6 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_EXPIRES_EMPTY_INDEX, 7 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_FROM_EMPTY_INDEX, 4 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_HOST_EMPTY_INDEX, 4 + 32, GRPC_BATCH_HOST}, - {GRPC_MDELEM_IF_MATCH_EMPTY_INDEX, 8 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY_INDEX, 17 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_IF_NONE_MATCH_EMPTY_INDEX, 13 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_IF_RANGE_EMPTY_INDEX, 8 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY_INDEX, 19 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_LAST_MODIFIED_EMPTY_INDEX, 13 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_LINK_EMPTY_INDEX, 4 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_LOCATION_EMPTY_INDEX, 8 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_MAX_FORWARDS_EMPTY_INDEX, 12 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY_INDEX, 18 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY_INDEX, 19 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_RANGE_EMPTY_INDEX, 5 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_REFERER_EMPTY_INDEX, 7 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_REFRESH_EMPTY_INDEX, 7 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_RETRY_AFTER_EMPTY_INDEX, 11 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_SERVER_EMPTY_INDEX, 6 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_COOKIE_EMPTY_INDEX, 10 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY_INDEX, 25 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_TRANSFER_ENCODING_EMPTY_INDEX, 17 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_USER_AGENT_EMPTY_INDEX, 10 + 32, GRPC_BATCH_USER_AGENT}, - {GRPC_MDELEM_VARY_EMPTY_INDEX, 4 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_VIA_EMPTY_INDEX, 3 + 32, GRPC_BATCH_CALLOUTS_COUNT}, - {GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY_INDEX, 16 + 32, - GRPC_BATCH_CALLOUTS_COUNT}, -}; - -/* This is a faster check for seeing if a mdelem index is used or not. To verify - that the index value is valid, use 'grpc_metadata_batch_is_valid_mdelem_index' */ -static bool is_mdelem_index_used(uint8_t index); - -static void set_mdelem_index_unused(uint8_t* index); - -static grpc_metadata_batch_callouts_index get_callouts_index( - grpc_linked_mdelem* storage); - static void assert_valid_list(grpc_mdelem_list* list) { #ifndef NDEBUG grpc_linked_mdelem* l; @@ -134,7 +42,7 @@ static void assert_valid_list(grpc_mdelem_list* list) { size_t verified_count = 0; for (l = list->head; l; l = l->next) { - GPR_ASSERT(is_mdelem_index_used(l->md_index) || !GRPC_MDISNULL(l->md)); + GPR_ASSERT(!GRPC_MDISNULL(l->md)); GPR_ASSERT((l->prev == nullptr) == (l == list->head)); GPR_ASSERT((l->next == nullptr) == (l == list->tail)); if (l->next) GPR_ASSERT(l->next->prev == l); @@ -148,21 +56,13 @@ static void assert_valid_list(grpc_mdelem_list* list) { static void assert_valid_callouts(grpc_metadata_batch* batch) { #ifndef NDEBUG for (grpc_linked_mdelem* l = batch->list.head; l != nullptr; l = l->next) { - grpc_metadata_batch_callouts_index callout_idx; - if (is_mdelem_index_used(l->md_index)) { - GPR_ASSERT(grpc_metadata_batch_is_valid_mdelem_index(l->md_index)); - callout_idx = get_callouts_index(l); - if (callout_idx != GRPC_BATCH_CALLOUTS_COUNT) { - GPR_ASSERT(batch->idx.array[callout_idx] == l); - } - } else { - grpc_slice key_interned = grpc_slice_intern(GRPC_MDKEY(l->md)); - callout_idx = GRPC_BATCH_INDEX_OF(key_interned); - if (callout_idx != GRPC_BATCH_CALLOUTS_COUNT) { - GPR_ASSERT(batch->idx.array[callout_idx] == l); - } - grpc_slice_unref_internal(key_interned); + grpc_slice key_interned = grpc_slice_intern(GRPC_MDKEY(l->md)); + grpc_metadata_batch_callouts_index callout_idx = + GRPC_BATCH_INDEX_OF(key_interned); + if (callout_idx != GRPC_BATCH_CALLOUTS_COUNT) { + GPR_ASSERT(batch->idx.array[callout_idx] == l); } + grpc_slice_unref_internal(key_interned); } #endif } @@ -181,9 +81,7 @@ void grpc_metadata_batch_init(grpc_metadata_batch* batch) { void grpc_metadata_batch_destroy(grpc_metadata_batch* batch) { grpc_linked_mdelem* l; for (l = batch->list.head; l; l = l->next) { - if (!is_mdelem_index_used(l->md_index)) { - GRPC_MDELEM_UNREF(l->md); - } + GRPC_MDELEM_UNREF(l->md); } } @@ -195,22 +93,14 @@ grpc_error* grpc_attach_md_to_error(grpc_error* src, grpc_mdelem md) { return out; } -static grpc_metadata_batch_callouts_index get_callouts_index( - grpc_linked_mdelem* storage) { - if (is_mdelem_index_used(storage->md_index)) { - return static_hpack_table_metadata[storage->md_index].callouts_index; - } else { - return GRPC_BATCH_INDEX_OF(GRPC_MDKEY(storage->md)); - } -} - static grpc_error* maybe_link_callout(grpc_metadata_batch* batch, grpc_linked_mdelem* storage) GRPC_MUST_USE_RESULT; static grpc_error* maybe_link_callout(grpc_metadata_batch* batch, grpc_linked_mdelem* storage) { - grpc_metadata_batch_callouts_index idx = get_callouts_index(storage); + grpc_metadata_batch_callouts_index idx = + GRPC_BATCH_INDEX_OF(GRPC_MDKEY(storage->md)); if (idx == GRPC_BATCH_CALLOUTS_COUNT) { return GRPC_ERROR_NONE; } @@ -219,26 +109,16 @@ static grpc_error* maybe_link_callout(grpc_metadata_batch* batch, batch->idx.array[idx] = storage; return GRPC_ERROR_NONE; } - grpc_error* err; - if (is_mdelem_index_used(storage->md_index)) { - char* message; - gpr_asprintf(&message, - "Unallowed duplicate metadata with static hpack table index " - "%d and callouts index %d", - storage->md_index, idx); - err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(message); - gpr_free(message); - } else { - err = grpc_attach_md_to_error( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("Unallowed duplicate metadata"), - storage->md); - } - return err; + + return grpc_attach_md_to_error( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("Unallowed duplicate metadata"), + storage->md); } static void maybe_unlink_callout(grpc_metadata_batch* batch, grpc_linked_mdelem* storage) { - grpc_metadata_batch_callouts_index idx = get_callouts_index(storage); + grpc_metadata_batch_callouts_index idx = + GRPC_BATCH_INDEX_OF(GRPC_MDKEY(storage->md)); if (idx == GRPC_BATCH_CALLOUTS_COUNT) { return; } @@ -247,39 +127,17 @@ static void maybe_unlink_callout(grpc_metadata_batch* batch, batch->idx.array[idx] = nullptr; } -bool grpc_metadata_batch_is_valid_mdelem_index(uint8_t index) { - return index >= MIN_STATIC_HPACK_TABLE_IDX && - index <= MAX_STATIC_HPACK_TABLE_IDX; -} - -static bool is_mdelem_index_used(uint8_t index) { return index != 0; } - -static void set_mdelem_index_unused(uint8_t* index) { - GPR_ASSERT(index != nullptr); - *index = 0; -} - grpc_error* grpc_metadata_batch_add_head(grpc_metadata_batch* batch, grpc_linked_mdelem* storage, grpc_mdelem elem_to_add) { GPR_ASSERT(!GRPC_MDISNULL(elem_to_add)); - storage->md_index = 0; storage->md = elem_to_add; return grpc_metadata_batch_link_head(batch, storage); } -grpc_error* grpc_metadata_batch_add_head_static(grpc_metadata_batch* batch, - grpc_linked_mdelem* storage, - uint8_t index_to_add) { - GPR_ASSERT(grpc_metadata_batch_is_valid_mdelem_index(index_to_add)); - storage->md_index = index_to_add; - return grpc_metadata_batch_link_head(batch, storage); -} - static void link_head(grpc_mdelem_list* list, grpc_linked_mdelem* storage) { assert_valid_list(list); - GPR_ASSERT(grpc_metadata_batch_is_valid_mdelem_index(storage->md_index) || - !GRPC_MDISNULL(storage->md)); + GPR_ASSERT(!GRPC_MDISNULL(storage->md)); storage->prev = nullptr; storage->next = list->head; if (list->head != nullptr) { @@ -310,22 +168,12 @@ grpc_error* grpc_metadata_batch_add_tail(grpc_metadata_batch* batch, grpc_mdelem elem_to_add) { GPR_ASSERT(!GRPC_MDISNULL(elem_to_add)); storage->md = elem_to_add; - storage->md_index = 0; - return grpc_metadata_batch_link_tail(batch, storage); -} - -grpc_error* grpc_metadata_batch_add_tail_static(grpc_metadata_batch* batch, - grpc_linked_mdelem* storage, - uint8_t index_to_add) { - GPR_ASSERT(grpc_metadata_batch_is_valid_mdelem_index(index_to_add)); - storage->md_index = index_to_add; return grpc_metadata_batch_link_tail(batch, storage); } static void link_tail(grpc_mdelem_list* list, grpc_linked_mdelem* storage) { assert_valid_list(list); - GPR_ASSERT(grpc_metadata_batch_is_valid_mdelem_index(storage->md_index) || - !GRPC_MDISNULL(storage->md)); + GPR_ASSERT(!GRPC_MDISNULL(storage->md)); storage->prev = list->tail; storage->next = nullptr; storage->reserved = nullptr; @@ -374,15 +222,12 @@ void grpc_metadata_batch_remove(grpc_metadata_batch* batch, assert_valid_callouts(batch); maybe_unlink_callout(batch, storage); unlink_storage(&batch->list, storage); - if (!is_mdelem_index_used(storage->md_index)) { - GRPC_MDELEM_UNREF(storage->md); - } + GRPC_MDELEM_UNREF(storage->md); assert_valid_callouts(batch); } void grpc_metadata_batch_set_value(grpc_linked_mdelem* storage, grpc_slice value) { - set_mdelem_index_unused(&storage->md_index); grpc_mdelem old_mdelem = storage->md; grpc_mdelem new_mdelem = grpc_mdelem_from_slices( grpc_slice_ref_internal(GRPC_MDKEY(old_mdelem)), value); @@ -396,26 +241,18 @@ grpc_error* grpc_metadata_batch_substitute(grpc_metadata_batch* batch, assert_valid_callouts(batch); grpc_error* error = GRPC_ERROR_NONE; grpc_mdelem old_mdelem = storage->md; - bool is_index_used = is_mdelem_index_used(storage->md_index); - if (is_index_used || - !grpc_slice_eq(GRPC_MDKEY(new_mdelem), GRPC_MDKEY(old_mdelem))) { + if (!grpc_slice_eq(GRPC_MDKEY(new_mdelem), GRPC_MDKEY(old_mdelem))) { maybe_unlink_callout(batch, storage); storage->md = new_mdelem; - set_mdelem_index_unused(&storage->md_index); error = maybe_link_callout(batch, storage); if (error != GRPC_ERROR_NONE) { unlink_storage(&batch->list, storage); - if (!is_index_used) { - GRPC_MDELEM_UNREF(storage->md); - } + GRPC_MDELEM_UNREF(storage->md); } } else { storage->md = new_mdelem; } - - if (!is_index_used) { - GRPC_MDELEM_UNREF(old_mdelem); - } + GRPC_MDELEM_UNREF(old_mdelem); assert_valid_callouts(batch); return error; } @@ -434,11 +271,7 @@ size_t grpc_metadata_batch_size(grpc_metadata_batch* batch) { size_t size = 0; for (grpc_linked_mdelem* elem = batch->list.head; elem != nullptr; elem = elem->next) { - if (!is_mdelem_index_used(elem->md_index)) { - size += GRPC_MDELEM_LENGTH(elem->md); - } else { // Mdelem is represented by static hpack table index - size += static_hpack_table_metadata[elem->md_index].size; - } + size += GRPC_MDELEM_LENGTH(elem->md); } return size; } @@ -460,15 +293,12 @@ grpc_error* grpc_metadata_batch_filter(grpc_metadata_batch* batch, grpc_error* error = GRPC_ERROR_NONE; while (l) { grpc_linked_mdelem* next = l->next; - // TODO(hcaseyal): provide a mechanism to filter mdelems with indices - if (!is_mdelem_index_used(l->md_index)) { - grpc_filtered_mdelem new_mdelem = func(user_data, l->md); - add_error(&error, new_mdelem.error, composite_error_string); - if (GRPC_MDISNULL(new_mdelem.md)) { - grpc_metadata_batch_remove(batch, l); - } else if (new_mdelem.md.payload != l->md.payload) { - grpc_metadata_batch_substitute(batch, l, new_mdelem.md); - } + grpc_filtered_mdelem new_mdelem = func(user_data, l->md); + add_error(&error, new_mdelem.error, composite_error_string); + if (GRPC_MDISNULL(new_mdelem.md)) { + grpc_metadata_batch_remove(batch, l); + } else if (new_mdelem.md.payload != l->md.payload) { + grpc_metadata_batch_substitute(batch, l, new_mdelem.md); } l = next; } @@ -483,14 +313,8 @@ void grpc_metadata_batch_copy(grpc_metadata_batch* src, size_t i = 0; for (grpc_linked_mdelem* elem = src->list.head; elem != nullptr; elem = elem->next) { - grpc_error* error = nullptr; - if (is_mdelem_index_used(elem->md_index)) { - error = grpc_metadata_batch_add_tail_static(dst, &storage[i++], - elem->md_index); - } else { - error = grpc_metadata_batch_add_tail(dst, &storage[i++], - GRPC_MDELEM_REF(elem->md)); - } + 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 diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index c0450684bb9..0bcbb32d1fe 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -30,16 +30,8 @@ #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/static_metadata.h" -/** Each grpc_linked_mdelem refers to a particular metadata element by either: - 1) grpc_mdelem md - 2) uint8_t md_index - md_index is an optional optimization. It can only be used for metadata in - the hpack static table and is equivalent to the metadata's index in the - table. If a metadata elem is not contained in the hpack static table, then - md must be used instead. */ typedef struct grpc_linked_mdelem { - uint8_t md_index; // If 0, not used. Else, use this field instead of md. - grpc_mdelem md; // If md_index is 0, use this field instead of md_index. + grpc_mdelem md; struct grpc_linked_mdelem* next; struct grpc_linked_mdelem* prev; void* reserved; @@ -58,7 +50,7 @@ typedef struct grpc_metadata_batch { grpc_metadata_batch_callouts idx; /** Used to calculate grpc-timeout at the point of sending, or GRPC_MILLIS_INF_FUTURE if this batch does not need to send a - grpc-timeout. */ + grpc-timeout */ grpc_millis deadline; } grpc_metadata_batch; @@ -110,18 +102,6 @@ grpc_error* grpc_metadata_batch_add_head( grpc_metadata_batch* batch, grpc_linked_mdelem* storage, grpc_mdelem elem_to_add) GRPC_MUST_USE_RESULT; -/** Add the static metadata element associated with \a elem_to_add_index - as the first element in \a batch, using \a storage as backing storage for - the linked list element. \a storage is owned by the caller and must survive - for the lifetime of batch. This usually means it should be around - for the lifetime of the call. - Valid indices are in metadata.h (e.g., GRPC_MDELEM_STATUS_200_INDEX). - This is an optimization in the case where chttp2 is used as the underlying - transport. */ -grpc_error* grpc_metadata_batch_add_head_static( - grpc_metadata_batch* batch, grpc_linked_mdelem* storage, - uint8_t elem_to_add_index) GRPC_MUST_USE_RESULT; - /** Add \a elem_to_add as the last element in \a batch, using \a storage as backing storage for the linked list element. \a storage is owned by the caller and must survive for the @@ -132,37 +112,8 @@ grpc_error* grpc_metadata_batch_add_tail( grpc_metadata_batch* batch, grpc_linked_mdelem* storage, grpc_mdelem elem_to_add) GRPC_MUST_USE_RESULT; -/** Add the static metadata element associated with \a elem_to_add_index - as the last element in \a batch, using \a storage as backing storage for - the linked list element. \a storage is owned by the caller and must survive - for the lifetime of batch. This usually means it should be around - for the lifetime of the call. - Valid indices are in metadata.h (e.g., GRPC_MDELEM_STATUS_200_INDEX). - This is an optimization in the case where chttp2 is used as the underlying - transport. */ -grpc_error* grpc_metadata_batch_add_tail_static( - grpc_metadata_batch* batch, grpc_linked_mdelem* storage, - uint8_t index_to_add) GRPC_MUST_USE_RESULT; - grpc_error* grpc_attach_md_to_error(grpc_error* src, grpc_mdelem md); -/** Returns if the index is a valid static hpack table index, and thus if the - grpc_linked_mdelem stores the index rather than the actual grpc_mdelem **/ -bool grpc_metadata_batch_is_valid_mdelem_index(uint8_t index); - -/* Static hpack table metadata info */ -typedef struct static_hpack_table_metadata_info { - uint8_t index; // Index in the static hpack table - uint8_t size; // Size of the metadata per RFC-7540 section 6.5.2., including - // 32 bytes of padding - grpc_metadata_batch_callouts_index - callouts_index; // For duplicate metadata detection. If - // GRPC_BATCH_CALLOUTS_COUNT, then the metadata is not - // one of the callouts. -} static_hpack_table_metadata_info; - -extern static_hpack_table_metadata_info static_hpack_table_metadata[]; - typedef struct { grpc_error* error; grpc_mdelem md; diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index b4f8fac3d65..259aa187f70 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -1,12 +1,12 @@ /* * 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. @@ -16,10 +16,10 @@ /* * WARNING: Auto-generated code. - * + * * To make changes to this file, change * tools/codegen/core/gen_static_metadata.py, and then re-run it. - * + * * See metadata.h for an explanation of the interface here, and metadata.cc for * an explanation of what's going on. */ @@ -28,235 +28,323 @@ #include "src/core/lib/slice/slice_internal.h" -static uint8_t g_bytes[] = {58,112,97,116,104,58,109,101,116,104,111,100,58,115,116,97,116,117,115,58,97,117,116,104,111,114,105,116,121,58,115,99,104,101,109,101,116,101,103,114,112,99,45,109,101,115,115,97,103,101,103,114,112,99,45,115,116,97,116,117,115,103,114,112,99,45,112,97,121,108,111,97,100,45,98,105,110,103,114,112,99,45,101,110,99,111,100,105,110,103,103,114,112,99,45,97,99,99,101,112,116,45,101,110,99,111,100,105,110,103,103,114,112,99,45,115,101,114,118,101,114,45,115,116,97,116,115,45,98,105,110,103,114,112,99,45,116,97,103,115,45,98,105,110,103,114,112,99,45,116,114,97,99,101,45,98,105,110,99,111,110,116,101,110,116,45,116,121,112,101,99,111,110,116,101,110,116,45,101,110,99,111,100,105,110,103,97,99,99,101,112,116,45,101,110,99,111,100,105,110,103,103,114,112,99,45,105,110,116,101,114,110,97,108,45,101,110,99,111,100,105,110,103,45,114,101,113,117,101,115,116,103,114,112,99,45,105,110,116,101,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,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 uint8_t g_bytes[] = { + 58, 112, 97, 116, 104, 58, 109, 101, 116, 104, 111, 100, 58, 115, 116, + 97, 116, 117, 115, 58, 97, 117, 116, 104, 111, 114, 105, 116, 121, 58, + 115, 99, 104, 101, 109, 101, 116, 101, 103, 114, 112, 99, 45, 109, 101, + 115, 115, 97, 103, 101, 103, 114, 112, 99, 45, 115, 116, 97, 116, 117, + 115, 103, 114, 112, 99, 45, 112, 97, 121, 108, 111, 97, 100, 45, 98, + 105, 110, 103, 114, 112, 99, 45, 101, 110, 99, 111, 100, 105, 110, 103, + 103, 114, 112, 99, 45, 97, 99, 99, 101, 112, 116, 45, 101, 110, 99, + 111, 100, 105, 110, 103, 103, 114, 112, 99, 45, 115, 101, 114, 118, 101, + 114, 45, 115, 116, 97, 116, 115, 45, 98, 105, 110, 103, 114, 112, 99, + 45, 116, 97, 103, 115, 45, 98, 105, 110, 103, 114, 112, 99, 45, 116, + 114, 97, 99, 101, 45, 98, 105, 110, 99, 111, 110, 116, 101, 110, 116, + 45, 116, 121, 112, 101, 99, 111, 110, 116, 101, 110, 116, 45, 101, 110, + 99, 111, 100, 105, 110, 103, 97, 99, 99, 101, 112, 116, 45, 101, 110, + 99, 111, 100, 105, 110, 103, 103, 114, 112, 99, 45, 105, 110, 116, 101, + 114, 110, 97, 108, 45, 101, 110, 99, 111, 100, 105, 110, 103, 45, 114, + 101, 113, 117, 101, 115, 116, 103, 114, 112, 99, 45, 105, 110, 116, 101, + 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, 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) {} -static const grpc_slice_refcount_vtable static_sub_vtable = {static_ref, static_unref, grpc_slice_default_eq_impl, grpc_slice_default_hash_impl}; -const grpc_slice_refcount_vtable grpc_static_metadata_vtable = {static_ref, static_unref, grpc_static_slice_eq, grpc_static_slice_hash}; -static grpc_slice_refcount static_sub_refcnt = {&static_sub_vtable, &static_sub_refcnt}; +static void static_ref(void* unused) {} +static void static_unref(void* unused) {} +static const grpc_slice_refcount_vtable static_sub_vtable = { + static_ref, static_unref, grpc_slice_default_eq_impl, + grpc_slice_default_hash_impl}; +const grpc_slice_refcount_vtable grpc_static_metadata_vtable = { + static_ref, static_unref, grpc_static_slice_eq, grpc_static_slice_hash}; +static grpc_slice_refcount static_sub_refcnt = {&static_sub_vtable, + &static_sub_refcnt}; 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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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] = { -{&grpc_static_metadata_refcounts[0], {{g_bytes+0, 5}}}, -{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}}, -{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}}, -{&grpc_static_metadata_refcounts[3], {{g_bytes+19, 10}}}, -{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}}, -{&grpc_static_metadata_refcounts[5], {{g_bytes+36, 2}}}, -{&grpc_static_metadata_refcounts[6], {{g_bytes+38, 12}}}, -{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}}, -{&grpc_static_metadata_refcounts[8], {{g_bytes+61, 16}}}, -{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}}, -{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}}, -{&grpc_static_metadata_refcounts[11], {{g_bytes+110, 21}}}, -{&grpc_static_metadata_refcounts[12], {{g_bytes+131, 13}}}, -{&grpc_static_metadata_refcounts[13], {{g_bytes+144, 14}}}, -{&grpc_static_metadata_refcounts[14], {{g_bytes+158, 12}}}, -{&grpc_static_metadata_refcounts[15], {{g_bytes+170, 16}}}, -{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}}, -{&grpc_static_metadata_refcounts[17], {{g_bytes+201, 30}}}, -{&grpc_static_metadata_refcounts[18], {{g_bytes+231, 37}}}, -{&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, 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}}}, + {&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, + {&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, + {&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, + {&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, + {&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, + {&grpc_static_metadata_refcounts[6], {{g_bytes + 38, 12}}}, + {&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, + {&grpc_static_metadata_refcounts[8], {{g_bytes + 61, 16}}}, + {&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, + {&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[11], {{g_bytes + 110, 21}}}, + {&grpc_static_metadata_refcounts[12], {{g_bytes + 131, 13}}}, + {&grpc_static_metadata_refcounts[13], {{g_bytes + 144, 14}}}, + {&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, + {&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, + {&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, + {&grpc_static_metadata_refcounts[17], {{g_bytes + 201, 30}}}, + {&grpc_static_metadata_refcounts[18], {{g_bytes + 231, 37}}}, + {&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, 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] = { - 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,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,0,0,0,0,0,0,2,4,4,6,6,8,8,2,4,4 -}; - + 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, 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, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4}; -static const int8_t elems_r[] = {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 const int8_t elems_r[] = { + 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 -= 50; uint32_t x = i % 103; @@ -268,136 +356,244 @@ static uint32_t elems_phash(uint32_t i) { } return h; } - -static const uint16_t elem_keys[] = {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,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}; + +static const uint16_t elem_keys[] = { + 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, 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 = (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 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC, 0) : GRPC_MDNULL; + return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && + elem_idxs[h] != 255 + ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], + GRPC_MDELEM_STORAGE_STATIC, 0) + : GRPC_MDNULL; } grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { -{{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}},{&grpc_static_metadata_refcounts[38], {{g_bytes+504, 1}}}}, -{{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}},{&grpc_static_metadata_refcounts[25], {{g_bytes+350, 1}}}}, -{{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}},{&grpc_static_metadata_refcounts[26], {{g_bytes+351, 1}}}}, -{{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}},{&grpc_static_metadata_refcounts[39], {{g_bytes+505, 8}}}}, -{{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, -{{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}},{&grpc_static_metadata_refcounts[35], {{g_bytes+482, 7}}}}, -{{&grpc_static_metadata_refcounts[5], {{g_bytes+36, 2}}},{&grpc_static_metadata_refcounts[40], {{g_bytes+513, 8}}}}, -{{&grpc_static_metadata_refcounts[14], {{g_bytes+158, 12}}},{&grpc_static_metadata_refcounts[41], {{g_bytes+521, 16}}}}, -{{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}},{&grpc_static_metadata_refcounts[42], {{g_bytes+537, 4}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[43], {{g_bytes+541, 3}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[44], {{g_bytes+544, 3}}}}, -{{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}},{&grpc_static_metadata_refcounts[45], {{g_bytes+547, 4}}}}, -{{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}},{&grpc_static_metadata_refcounts[46], {{g_bytes+551, 5}}}}, -{{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}},{&grpc_static_metadata_refcounts[47], {{g_bytes+556, 4}}}}, -{{&grpc_static_metadata_refcounts[3], {{g_bytes+19, 10}}},{&grpc_static_metadata_refcounts[29], {{g_bytes+354, 0}}}}, -{{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}},{&grpc_static_metadata_refcounts[48], {{g_bytes+560, 3}}}}, -{{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}},{&grpc_static_metadata_refcounts[49], {{g_bytes+563, 3}}}}, -{{&grpc_static_metadata_refcounts[0], {{g_bytes+0, 5}}},{&grpc_static_metadata_refcounts[50], {{g_bytes+566, 1}}}}, -{{&grpc_static_metadata_refcounts[0], {{g_bytes+0, 5}}},{&grpc_static_metadata_refcounts[51], {{g_bytes+567, 11}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[52], {{g_bytes+578, 3}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[53], {{g_bytes+581, 3}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[54], {{g_bytes+584, 3}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[55], {{g_bytes+587, 3}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&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[29], {{g_bytes+354, 0}}}}, -{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&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[39], {{g_bytes+505, 8}}}}, -{{&grpc_static_metadata_refcounts[15], {{g_bytes+170, 16}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, -{{&grpc_static_metadata_refcounts[15], {{g_bytes+170, 16}}},{&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[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[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[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[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[39], {{g_bytes+505, 8}}}}, -{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[35], {{g_bytes+482, 7}}}}, -{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[101], {{g_bytes+1085, 16}}}}, -{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, -{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[102], {{g_bytes+1101, 13}}}}, -{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[103], {{g_bytes+1114, 12}}}}, -{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[104], {{g_bytes+1126, 21}}}}, -{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&grpc_static_metadata_refcounts[39], {{g_bytes+505, 8}}}}, -{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, -{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&grpc_static_metadata_refcounts[102], {{g_bytes+1101, 13}}}}, + {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, + {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 1}}}}, + {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, + {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}}, + {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, + {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}}, + {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, + {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, + {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, + {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, + {&grpc_static_metadata_refcounts[40], {{g_bytes + 513, 8}}}}, + {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, + {&grpc_static_metadata_refcounts[41], {{g_bytes + 521, 16}}}}, + {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, + {&grpc_static_metadata_refcounts[42], {{g_bytes + 537, 4}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[43], {{g_bytes + 541, 3}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[44], {{g_bytes + 544, 3}}}}, + {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, + {&grpc_static_metadata_refcounts[45], {{g_bytes + 547, 4}}}}, + {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, + {&grpc_static_metadata_refcounts[46], {{g_bytes + 551, 5}}}}, + {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, + {&grpc_static_metadata_refcounts[47], {{g_bytes + 556, 4}}}}, + {{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, + {&grpc_static_metadata_refcounts[48], {{g_bytes + 560, 3}}}}, + {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, + {&grpc_static_metadata_refcounts[49], {{g_bytes + 563, 3}}}}, + {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, + {&grpc_static_metadata_refcounts[50], {{g_bytes + 566, 1}}}}, + {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, + {&grpc_static_metadata_refcounts[51], {{g_bytes + 567, 11}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[52], {{g_bytes + 578, 3}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[53], {{g_bytes + 581, 3}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[54], {{g_bytes + 584, 3}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[55], {{g_bytes + 587, 3}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&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[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, + {&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[39], {{g_bytes + 505, 8}}}}, + {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, + {&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[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[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[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[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[39], {{g_bytes + 505, 8}}}}, + {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, + {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}}}, + {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, + {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}}}, + {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}}, + {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, + {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, + {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, }; bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = { - true, // :path - true, // :method - true, // :status - true, // :authority - true, // :scheme - true, // te - true, // grpc-message - true, // grpc-status - true, // grpc-payload-bin - true, // grpc-encoding - true, // grpc-accept-encoding - true, // grpc-server-stats-bin - true, // grpc-tags-bin - true, // grpc-trace-bin - true, // content-type - true, // content-encoding - true, // accept-encoding - true, // grpc-internal-encoding-request - true, // grpc-internal-stream-encoding-request - true, // user-agent - true, // host - true, // lb-token - true, // grpc-previous-rpc-attempts - true, // grpc-retry-pushback-ms + true, // :path + true, // :method + true, // :status + true, // :authority + true, // :scheme + true, // te + true, // grpc-message + true, // grpc-status + true, // grpc-payload-bin + true, // grpc-encoding + true, // grpc-accept-encoding + true, // grpc-server-stats-bin + true, // grpc-tags-bin + true, // grpc-trace-bin + true, // content-type + true, // content-encoding + true, // accept-encoding + true, // grpc-internal-encoding-request + true, // grpc-internal-stream-encoding-request + 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,79,80,81,82 -}; +const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78, + 79, 80, 81, 82}; -const uint8_t grpc_static_accept_stream_encoding_metadata[4] = { -0,83,84,85 -}; +const uint8_t grpc_static_accept_stream_encoding_metadata[4] = {0, 83, 84, 85}; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 333bc789d68..0fc154d1a14 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -1,12 +1,12 @@ /* * 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. @@ -16,10 +16,10 @@ /* * WARNING: Auto-generated code. - * + * * To make changes to this file, change * tools/codegen/core/gen_static_metadata.py, and then re-run it. - * + * * See metadata.h for an explanation of the interface here, and metadata.cc for * an explanation of what's going on. */ @@ -68,7 +68,8 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "grpc-internal-encoding-request" */ #define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (grpc_static_slice_table[17]) /* "grpc-internal-stream-encoding-request" */ -#define GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST (grpc_static_slice_table[18]) +#define GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST \ + (grpc_static_slice_table[18]) /* "user-agent" */ #define GRPC_MDSTR_USER_AGENT (grpc_static_slice_table[19]) /* "host" */ @@ -96,11 +97,14 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "grpc.timeout" */ #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[32]) +#define GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES \ + (grpc_static_slice_table[32]) /* "grpc.max_response_message_bytes" */ -#define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES (grpc_static_slice_table[33]) +#define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES \ + (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[34]) +#define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \ + (grpc_static_slice_table[34]) /* "deflate" */ #define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[35]) /* "gzip" */ @@ -240,12 +244,15 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "deflate,gzip" */ #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[104]) +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ + (grpc_static_slice_table[104]) extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable; -extern grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT]; +extern grpc_slice_refcount + grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT]; #define GRPC_IS_STATIC_METADATA_STRING(slice) \ - ((slice).refcount != NULL && (slice).refcount->vtable == &grpc_static_metadata_vtable) + ((slice).refcount != NULL && \ + (slice).refcount->vtable == &grpc_static_metadata_vtable) #define GRPC_STATIC_METADATA_INDEX(static_slice) \ ((int)((static_slice).refcount - grpc_static_metadata_refcounts)) @@ -254,177 +261,349 @@ extern grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUN extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; /* "grpc-status": "0" Index="0" */ -#define GRPC_MDELEM_GRPC_STATUS_0 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_STATUS_0 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-status": "1" Index="0" */ -#define GRPC_MDELEM_GRPC_STATUS_1 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_STATUS_1 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-status": "2" Index="0" */ -#define GRPC_MDELEM_GRPC_STATUS_2 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_STATUS_2 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-encoding": "deflate" Index="0" */ -#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "te": "trailers" Index="0" */ -#define GRPC_MDELEM_TE_TRAILERS (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_TE_TRAILERS \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "content-type": "application/grpc" Index="0" */ -#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* ":method": "POST" Index="3" */ -#define GRPC_MDELEM_METHOD_POST (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC), 3) +#define GRPC_MDELEM_METHOD_POST \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC, \ + 3)) /* ":status": "200" Index="8" */ -#define GRPC_MDELEM_STATUS_200 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC), 8) +#define GRPC_MDELEM_STATUS_200 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC, \ + 8)) /* ":status": "404" Index="13" */ -#define GRPC_MDELEM_STATUS_404 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC), 13) +#define GRPC_MDELEM_STATUS_404 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC, \ + 13)) /* ":scheme": "http" Index="6" */ -#define GRPC_MDELEM_SCHEME_HTTP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC), 6) +#define GRPC_MDELEM_SCHEME_HTTP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC, \ + 6)) /* ":scheme": "https" Index="7" */ -#define GRPC_MDELEM_SCHEME_HTTPS (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC), 7) +#define GRPC_MDELEM_SCHEME_HTTPS \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC, \ + 7)) /* ":scheme": "grpc" Index="0" */ -#define GRPC_MDELEM_SCHEME_GRPC (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_SCHEME_GRPC \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* ":authority": "" Index="1" */ -#define GRPC_MDELEM_AUTHORITY_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC), 1) +#define GRPC_MDELEM_AUTHORITY_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC, \ + 1)) /* ":method": "GET" Index="2" */ -#define GRPC_MDELEM_METHOD_GET (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC), 2) +#define GRPC_MDELEM_METHOD_GET \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC, \ + 2)) /* ":method": "PUT" Index="0" */ -#define GRPC_MDELEM_METHOD_PUT (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_METHOD_PUT \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* ":path": "/" Index="4" */ -#define GRPC_MDELEM_PATH_SLASH (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC), 4) +#define GRPC_MDELEM_PATH_SLASH \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC, \ + 4)) /* ":path": "/index.html" Index="5" */ -#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC), 5) +#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC, \ + 5)) /* ":status": "204" Index="9" */ -#define GRPC_MDELEM_STATUS_204 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC), 9) +#define GRPC_MDELEM_STATUS_204 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC, \ + 9)) /* ":status": "206" Index="10" */ -#define GRPC_MDELEM_STATUS_206 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC), 10) +#define GRPC_MDELEM_STATUS_206 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC, \ + 10)) /* ":status": "304" Index="11" */ -#define GRPC_MDELEM_STATUS_304 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC), 11) +#define GRPC_MDELEM_STATUS_304 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC, \ + 11)) /* ":status": "400" Index="12" */ -#define GRPC_MDELEM_STATUS_400 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC), 12) +#define GRPC_MDELEM_STATUS_400 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC, \ + 12)) /* ":status": "500" Index="14" */ -#define GRPC_MDELEM_STATUS_500 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC), 14) +#define GRPC_MDELEM_STATUS_500 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC, \ + 14)) /* "accept-charset": "" Index="15" */ -#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC), 15) +#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC, \ + 15)) /* "accept-encoding": "" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "accept-encoding": "gzip, deflate" Index="16" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC), 16) +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC, \ + 16)) /* "accept-language": "" Index="17" */ -#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC), 17) +#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC, \ + 17)) /* "accept-ranges": "" Index="18" */ -#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC), 18) +#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC, \ + 18)) /* "accept": "" Index="19" */ -#define GRPC_MDELEM_ACCEPT_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC), 19) +#define GRPC_MDELEM_ACCEPT_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC, \ + 19)) /* "access-control-allow-origin": "" Index="20" */ -#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC), 20) +#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC, \ + 20)) /* "age": "" Index="21" */ -#define GRPC_MDELEM_AGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC), 21) +#define GRPC_MDELEM_AGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC, \ + 21)) /* "allow": "" Index="22" */ -#define GRPC_MDELEM_ALLOW_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC), 22) +#define GRPC_MDELEM_ALLOW_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC, \ + 22)) /* "authorization": "" Index="23" */ -#define GRPC_MDELEM_AUTHORIZATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC), 23) +#define GRPC_MDELEM_AUTHORIZATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC, \ + 23)) /* "cache-control": "" Index="24" */ -#define GRPC_MDELEM_CACHE_CONTROL_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC), 24) +#define GRPC_MDELEM_CACHE_CONTROL_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC, \ + 24)) /* "content-disposition": "" Index="25" */ -#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC), 25) +#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC, \ + 25)) /* "content-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "content-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_CONTENT_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "content-encoding": "" Index="26" */ -#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC), 26) +#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC, \ + 26)) /* "content-language": "" Index="27" */ -#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC), 27) +#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC, \ + 27)) /* "content-length": "" Index="28" */ -#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC), 28) +#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC, \ + 28)) /* "content-location": "" Index="29" */ -#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC), 29) +#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC, \ + 29)) /* "content-range": "" Index="30" */ -#define GRPC_MDELEM_CONTENT_RANGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC), 30) +#define GRPC_MDELEM_CONTENT_RANGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC, \ + 30)) /* "content-type": "" Index="31" */ -#define GRPC_MDELEM_CONTENT_TYPE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC), 31) +#define GRPC_MDELEM_CONTENT_TYPE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC, \ + 31)) /* "cookie": "" Index="32" */ -#define GRPC_MDELEM_COOKIE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC), 32) +#define GRPC_MDELEM_COOKIE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC, \ + 32)) /* "date": "" Index="33" */ -#define GRPC_MDELEM_DATE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC), 33) +#define GRPC_MDELEM_DATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC, \ + 33)) /* "etag": "" Index="34" */ -#define GRPC_MDELEM_ETAG_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC), 34) +#define GRPC_MDELEM_ETAG_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC, \ + 34)) /* "expect": "" Index="35" */ -#define GRPC_MDELEM_EXPECT_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC), 35) +#define GRPC_MDELEM_EXPECT_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC, \ + 35)) /* "expires": "" Index="36" */ -#define GRPC_MDELEM_EXPIRES_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC), 36) +#define GRPC_MDELEM_EXPIRES_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC, \ + 36)) /* "from": "" Index="37" */ -#define GRPC_MDELEM_FROM_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC), 37) +#define GRPC_MDELEM_FROM_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC, \ + 37)) /* "host": "" Index="38" */ -#define GRPC_MDELEM_HOST_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC), 38) +#define GRPC_MDELEM_HOST_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC, \ + 38)) /* "if-match": "" Index="39" */ -#define GRPC_MDELEM_IF_MATCH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC), 39) +#define GRPC_MDELEM_IF_MATCH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC, \ + 39)) /* "if-modified-since": "" Index="40" */ -#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC), 40) +#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC, \ + 40)) /* "if-none-match": "" Index="41" */ -#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC), 41) +#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC, \ + 41)) /* "if-range": "" Index="42" */ -#define GRPC_MDELEM_IF_RANGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC), 42) +#define GRPC_MDELEM_IF_RANGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC, \ + 42)) /* "if-unmodified-since": "" Index="43" */ -#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC), 43) +#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC, \ + 43)) /* "last-modified": "" Index="44" */ -#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC), 44) +#define GRPC_MDELEM_LAST_MODIFIED_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC, \ + 44)) /* "lb-token": "" Index="0" */ -#define GRPC_MDELEM_LB_TOKEN_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_LB_TOKEN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "lb-cost-bin": "" Index="0" */ -#define GRPC_MDELEM_LB_COST_BIN_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_LB_COST_BIN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "link": "" Index="45" */ -#define GRPC_MDELEM_LINK_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC), 45) +#define GRPC_MDELEM_LINK_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC, \ + 45)) /* "location": "" Index="46" */ -#define GRPC_MDELEM_LOCATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC), 46) +#define GRPC_MDELEM_LOCATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC, \ + 46)) /* "max-forwards": "" Index="47" */ -#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC), 47) +#define GRPC_MDELEM_MAX_FORWARDS_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC, \ + 47)) /* "proxy-authenticate": "" Index="48" */ -#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC), 48) +#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC, \ + 48)) /* "proxy-authorization": "" Index="49" */ -#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC), 49) +#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC, \ + 49)) /* "range": "" Index="50" */ -#define GRPC_MDELEM_RANGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC), 50) +#define GRPC_MDELEM_RANGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC, \ + 50)) /* "referer": "" Index="51" */ -#define GRPC_MDELEM_REFERER_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC), 51) +#define GRPC_MDELEM_REFERER_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC, \ + 51)) /* "refresh": "" Index="52" */ -#define GRPC_MDELEM_REFRESH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC), 52) +#define GRPC_MDELEM_REFRESH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC, \ + 52)) /* "retry-after": "" Index="53" */ -#define GRPC_MDELEM_RETRY_AFTER_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC), 53) +#define GRPC_MDELEM_RETRY_AFTER_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC, \ + 53)) /* "server": "" Index="54" */ -#define GRPC_MDELEM_SERVER_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC), 54) +#define GRPC_MDELEM_SERVER_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC, \ + 54)) /* "set-cookie": "" Index="55" */ -#define GRPC_MDELEM_SET_COOKIE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC), 55) +#define GRPC_MDELEM_SET_COOKIE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC, \ + 55)) /* "strict-transport-security": "" Index="56" */ -#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC), 56) +#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC, \ + 56)) /* "transfer-encoding": "" Index="57" */ -#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC), 57) +#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC, \ + 57)) /* "user-agent": "" Index="58" */ -#define GRPC_MDELEM_USER_AGENT_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC), 58) +#define GRPC_MDELEM_USER_AGENT_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC, \ + 58)) /* "vary": "" Index="59" */ -#define GRPC_MDELEM_VARY_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC), 59) +#define GRPC_MDELEM_VARY_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC, \ + 59)) /* "via": "" Index="60" */ -#define GRPC_MDELEM_VIA_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC), 60) +#define GRPC_MDELEM_VIA_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC, \ + 60)) /* "www-authenticate": "" Index="61" */ -#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC), 61) +#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC, \ + 61)) /* "grpc-accept-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-accept-encoding": "deflate" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-accept-encoding": "identity,deflate" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-accept-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-accept-encoding": "identity,gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-accept-encoding": "deflate,gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-accept-encoding": "identity,deflate,gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "accept-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "accept-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "accept-encoding": "identity,gzip" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b); typedef enum { @@ -456,43 +635,53 @@ typedef enum { } grpc_metadata_batch_callouts_index; typedef union { - struct grpc_linked_mdelem *array[GRPC_BATCH_CALLOUTS_COUNT]; + struct grpc_linked_mdelem* array[GRPC_BATCH_CALLOUTS_COUNT]; struct { - struct grpc_linked_mdelem *path; - struct grpc_linked_mdelem *method; - struct grpc_linked_mdelem *status; - struct grpc_linked_mdelem *authority; - struct grpc_linked_mdelem *scheme; - struct grpc_linked_mdelem *te; - struct grpc_linked_mdelem *grpc_message; - struct grpc_linked_mdelem *grpc_status; - struct grpc_linked_mdelem *grpc_payload_bin; - struct grpc_linked_mdelem *grpc_encoding; - struct grpc_linked_mdelem *grpc_accept_encoding; - struct grpc_linked_mdelem *grpc_server_stats_bin; - struct grpc_linked_mdelem *grpc_tags_bin; - struct grpc_linked_mdelem *grpc_trace_bin; - struct grpc_linked_mdelem *content_type; - struct grpc_linked_mdelem *content_encoding; - struct grpc_linked_mdelem *accept_encoding; - struct grpc_linked_mdelem *grpc_internal_encoding_request; - struct grpc_linked_mdelem *grpc_internal_stream_encoding_request; - 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; + struct grpc_linked_mdelem* path; + struct grpc_linked_mdelem* method; + struct grpc_linked_mdelem* status; + struct grpc_linked_mdelem* authority; + struct grpc_linked_mdelem* scheme; + struct grpc_linked_mdelem* te; + struct grpc_linked_mdelem* grpc_message; + struct grpc_linked_mdelem* grpc_status; + struct grpc_linked_mdelem* grpc_payload_bin; + struct grpc_linked_mdelem* grpc_encoding; + struct grpc_linked_mdelem* grpc_accept_encoding; + struct grpc_linked_mdelem* grpc_server_stats_bin; + struct grpc_linked_mdelem* grpc_tags_bin; + struct grpc_linked_mdelem* grpc_trace_bin; + struct grpc_linked_mdelem* content_type; + struct grpc_linked_mdelem* content_encoding; + struct grpc_linked_mdelem* accept_encoding; + struct grpc_linked_mdelem* grpc_internal_encoding_request; + struct grpc_linked_mdelem* grpc_internal_stream_encoding_request; + 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; -#define GRPC_BATCH_INDEX_OF(slice) \ - (GRPC_IS_STATIC_METADATA_STRING((slice)) ? (grpc_metadata_batch_callouts_index)GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, GRPC_BATCH_CALLOUTS_COUNT) : GRPC_BATCH_CALLOUTS_COUNT) +#define GRPC_BATCH_INDEX_OF(slice) \ + (GRPC_IS_STATIC_METADATA_STRING((slice)) \ + ? (grpc_metadata_batch_callouts_index)GPR_CLAMP( \ + GRPC_STATIC_METADATA_INDEX((slice)), 0, \ + GRPC_BATCH_CALLOUTS_COUNT) \ + : GRPC_BATCH_CALLOUTS_COUNT) extern bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT]; extern const uint8_t grpc_static_accept_encoding_metadata[8]; -#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \ + (GRPC_MAKE_MDELEM( \ + &grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], \ + GRPC_MDELEM_STORAGE_STATIC, 0)) extern const uint8_t grpc_static_accept_stream_encoding_metadata[4]; -#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_stream_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC), 0) +#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table \ + [grpc_static_accept_stream_encoding_metadata[(algs)]], \ + GRPC_MDELEM_STORAGE_STATIC, 0)) #endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */ diff --git a/src/core/lib/transport/transport_op_string.cc b/src/core/lib/transport/transport_op_string.cc index 9f5dafa4afd..8c7db642a54 100644 --- a/src/core/lib/transport/transport_op_string.cc +++ b/src/core/lib/transport/transport_op_string.cc @@ -48,12 +48,7 @@ static void put_metadata_list(gpr_strvec* b, grpc_metadata_batch md) { grpc_linked_mdelem* m; for (m = md.list.head; m != nullptr; m = m->next) { if (m != md.list.head) gpr_strvec_add(b, gpr_strdup(", ")); - if (grpc_metadata_batch_is_valid_mdelem_index(m->md_index)) { - // TODO(hcaseyal): print out the mdelem index - gpr_strvec_add(b, gpr_strdup("indexed mdelem")); - } else { - put_metadata(b, m->md); - } + put_metadata(b, m->md); } if (md.deadline != GRPC_MILLIS_INF_FUTURE) { char* tmp; diff --git a/test/core/transport/chttp2/hpack_encoder_test.cc b/test/core/transport/chttp2/hpack_encoder_test.cc index ab59ee9c5b1..2a57198ab64 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.cc +++ b/test/core/transport/chttp2/hpack_encoder_test.cc @@ -59,7 +59,7 @@ static void verify(const verify_params params, const char* expected, size_t i; va_list l; grpc_linked_mdelem* e = - static_cast(gpr_zalloc(sizeof(*e) * nheaders)); + static_cast(gpr_malloc(sizeof(*e) * nheaders)); grpc_metadata_batch b; grpc_metadata_batch_init(&b); @@ -205,7 +205,7 @@ static void verify_table_size_change_match_elem_size(const char* key, size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem, use_true_binary); size_t initial_table_size = g_compressor.table_size; grpc_linked_mdelem* e = - static_cast(gpr_zalloc(sizeof(*e))); + static_cast(gpr_malloc(sizeof(*e))); grpc_metadata_batch b; grpc_metadata_batch_init(&b); e[0].md = elem; diff --git a/test/core/transport/metadata_test.cc b/test/core/transport/metadata_test.cc index 4be34f72d9b..7b064c4f2a2 100644 --- a/test/core/transport/metadata_test.cc +++ b/test/core/transport/metadata_test.cc @@ -350,8 +350,9 @@ static void test_copied_static_metadata(bool dup_key, bool dup_value) { grpc_core::ExecCtx exec_ctx; for (size_t i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) { - grpc_mdelem p = GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[i], - GRPC_MDELEM_STORAGE_STATIC); + grpc_mdelem p = + GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[i], + GRPC_MDELEM_STORAGE_STATIC, GRPC_MDINDEX_UNUSED); grpc_mdelem q = grpc_mdelem_from_slices(maybe_dup(GRPC_MDKEY(p), dup_key), maybe_dup(GRPC_MDVALUE(p), dup_value)); diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index 621ee9991d2..36c76fada9a 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -452,7 +452,8 @@ print >> H, ('extern uintptr_t ' for i, elem in enumerate(all_elems): print >> H, '/* "%s": "%s" Index="%d" */' % elem print >> H, ('#define %s (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[%d], ' - 'GRPC_MDELEM_STORAGE_STATIC), %d)') % (mangle(elem).upper(), i, elem[2]) + 'GRPC_MDELEM_STORAGE_STATIC, %d))') % (mangle(elem).upper(), i, + elem[2]) print >> H print >> C, ('uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] ' '= {') @@ -584,7 +585,7 @@ print >> C, '0,%s' % ','.join('%d' % md_idx(elem) for elem in compression_elems) print >> C, '};' print >> C -print >> H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC), 0)' +print >> H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC, 0))' print >> H print >> H, 'extern const uint8_t grpc_static_accept_stream_encoding_metadata[%d];' % ( @@ -595,7 +596,7 @@ print >> C, '0,%s' % ','.join( '%d' % md_idx(elem) for elem in stream_compression_elems) print >> C, '};' -print >> H, '#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_stream_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC), 0)' +print >> H, '#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_stream_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC, 0))' print >> H, '#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */' From b731178a7ccc1c6a0da26a410b71840d08ab37af Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Mon, 10 Sep 2018 22:29:03 -0700 Subject: [PATCH 342/546] Fix codegen script to include port_platform --- src/core/lib/transport/static_metadata.cc | 888 +++++++++------------- src/core/lib/transport/static_metadata.h | 445 ++++------- tools/codegen/core/gen_static_metadata.py | 4 + 3 files changed, 480 insertions(+), 857 deletions(-) diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 259aa187f70..7e6e5191b57 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -1,12 +1,12 @@ /* * 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. @@ -16,335 +16,249 @@ /* * WARNING: Auto-generated code. - * + * * To make changes to this file, change * tools/codegen/core/gen_static_metadata.py, and then re-run it. - * + * * See metadata.h for an explanation of the interface here, and metadata.cc for * an explanation of what's going on. */ +#include + #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/slice/slice_internal.h" -static uint8_t g_bytes[] = { - 58, 112, 97, 116, 104, 58, 109, 101, 116, 104, 111, 100, 58, 115, 116, - 97, 116, 117, 115, 58, 97, 117, 116, 104, 111, 114, 105, 116, 121, 58, - 115, 99, 104, 101, 109, 101, 116, 101, 103, 114, 112, 99, 45, 109, 101, - 115, 115, 97, 103, 101, 103, 114, 112, 99, 45, 115, 116, 97, 116, 117, - 115, 103, 114, 112, 99, 45, 112, 97, 121, 108, 111, 97, 100, 45, 98, - 105, 110, 103, 114, 112, 99, 45, 101, 110, 99, 111, 100, 105, 110, 103, - 103, 114, 112, 99, 45, 97, 99, 99, 101, 112, 116, 45, 101, 110, 99, - 111, 100, 105, 110, 103, 103, 114, 112, 99, 45, 115, 101, 114, 118, 101, - 114, 45, 115, 116, 97, 116, 115, 45, 98, 105, 110, 103, 114, 112, 99, - 45, 116, 97, 103, 115, 45, 98, 105, 110, 103, 114, 112, 99, 45, 116, - 114, 97, 99, 101, 45, 98, 105, 110, 99, 111, 110, 116, 101, 110, 116, - 45, 116, 121, 112, 101, 99, 111, 110, 116, 101, 110, 116, 45, 101, 110, - 99, 111, 100, 105, 110, 103, 97, 99, 99, 101, 112, 116, 45, 101, 110, - 99, 111, 100, 105, 110, 103, 103, 114, 112, 99, 45, 105, 110, 116, 101, - 114, 110, 97, 108, 45, 101, 110, 99, 111, 100, 105, 110, 103, 45, 114, - 101, 113, 117, 101, 115, 116, 103, 114, 112, 99, 45, 105, 110, 116, 101, - 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, 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 uint8_t g_bytes[] = {58,112,97,116,104,58,109,101,116,104,111,100,58,115,116,97,116,117,115,58,97,117,116,104,111,114,105,116,121,58,115,99,104,101,109,101,116,101,103,114,112,99,45,109,101,115,115,97,103,101,103,114,112,99,45,115,116,97,116,117,115,103,114,112,99,45,112,97,121,108,111,97,100,45,98,105,110,103,114,112,99,45,101,110,99,111,100,105,110,103,103,114,112,99,45,97,99,99,101,112,116,45,101,110,99,111,100,105,110,103,103,114,112,99,45,115,101,114,118,101,114,45,115,116,97,116,115,45,98,105,110,103,114,112,99,45,116,97,103,115,45,98,105,110,103,114,112,99,45,116,114,97,99,101,45,98,105,110,99,111,110,116,101,110,116,45,116,121,112,101,99,111,110,116,101,110,116,45,101,110,99,111,100,105,110,103,97,99,99,101,112,116,45,101,110,99,111,100,105,110,103,103,114,112,99,45,105,110,116,101,114,110,97,108,45,101,110,99,111,100,105,110,103,45,114,101,113,117,101,115,116,103,114,112,99,45,105,110,116,101,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,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) {} -static const grpc_slice_refcount_vtable static_sub_vtable = { - static_ref, static_unref, grpc_slice_default_eq_impl, - grpc_slice_default_hash_impl}; -const grpc_slice_refcount_vtable grpc_static_metadata_vtable = { - static_ref, static_unref, grpc_static_slice_eq, grpc_static_slice_hash}; -static grpc_slice_refcount static_sub_refcnt = {&static_sub_vtable, - &static_sub_refcnt}; +static void static_ref(void *unused) {} +static void static_unref(void *unused) {} +static const grpc_slice_refcount_vtable static_sub_vtable = {static_ref, static_unref, grpc_slice_default_eq_impl, grpc_slice_default_hash_impl}; +const grpc_slice_refcount_vtable grpc_static_metadata_vtable = {static_ref, static_unref, grpc_static_slice_eq, grpc_static_slice_hash}; +static grpc_slice_refcount static_sub_refcnt = {&static_sub_vtable, &static_sub_refcnt}; 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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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] = { - {&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, - {&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[6], {{g_bytes + 38, 12}}}, - {&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[8], {{g_bytes + 61, 16}}}, - {&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[11], {{g_bytes + 110, 21}}}, - {&grpc_static_metadata_refcounts[12], {{g_bytes + 131, 13}}}, - {&grpc_static_metadata_refcounts[13], {{g_bytes + 144, 14}}}, - {&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[17], {{g_bytes + 201, 30}}}, - {&grpc_static_metadata_refcounts[18], {{g_bytes + 231, 37}}}, - {&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, 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}}}, +{&grpc_static_metadata_refcounts[0], {{g_bytes+0, 5}}}, +{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}}, +{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}}, +{&grpc_static_metadata_refcounts[3], {{g_bytes+19, 10}}}, +{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}}, +{&grpc_static_metadata_refcounts[5], {{g_bytes+36, 2}}}, +{&grpc_static_metadata_refcounts[6], {{g_bytes+38, 12}}}, +{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}}, +{&grpc_static_metadata_refcounts[8], {{g_bytes+61, 16}}}, +{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}}, +{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}}, +{&grpc_static_metadata_refcounts[11], {{g_bytes+110, 21}}}, +{&grpc_static_metadata_refcounts[12], {{g_bytes+131, 13}}}, +{&grpc_static_metadata_refcounts[13], {{g_bytes+144, 14}}}, +{&grpc_static_metadata_refcounts[14], {{g_bytes+158, 12}}}, +{&grpc_static_metadata_refcounts[15], {{g_bytes+170, 16}}}, +{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}}, +{&grpc_static_metadata_refcounts[17], {{g_bytes+201, 30}}}, +{&grpc_static_metadata_refcounts[18], {{g_bytes+231, 37}}}, +{&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, 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] = { - 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, 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, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4}; + 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,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,0,0,0,0,0,0,2,4,4,6,6,8,8,2,4,4 +}; + -static const int8_t elems_r[] = { - 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 const int8_t elems_r[] = {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 -= 50; uint32_t x = i % 103; @@ -356,244 +270,136 @@ static uint32_t elems_phash(uint32_t i) { } return h; } - -static const uint16_t elem_keys[] = { - 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, 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}; + +static const uint16_t elem_keys[] = {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,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 = (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 - ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], - GRPC_MDELEM_STORAGE_STATIC, 0) - : GRPC_MDNULL; + return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC, 0) : GRPC_MDNULL; } grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 1}}}}, - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}}, - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, - {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 513, 8}}}}, - {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 521, 16}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 537, 4}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 541, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 544, 3}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 547, 4}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 551, 5}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 556, 4}}}}, - {{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, - {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 560, 3}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 563, 3}}}}, - {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 566, 1}}}}, - {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 567, 11}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 578, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[53], {{g_bytes + 581, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[54], {{g_bytes + 584, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[55], {{g_bytes + 587, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&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[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&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[39], {{g_bytes + 505, 8}}}}, - {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, - {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&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[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[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[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[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[39], {{g_bytes + 505, 8}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}}}, - {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, - {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, +{{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}},{&grpc_static_metadata_refcounts[38], {{g_bytes+504, 1}}}}, +{{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}},{&grpc_static_metadata_refcounts[25], {{g_bytes+350, 1}}}}, +{{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}},{&grpc_static_metadata_refcounts[26], {{g_bytes+351, 1}}}}, +{{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}},{&grpc_static_metadata_refcounts[39], {{g_bytes+505, 8}}}}, +{{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, +{{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}},{&grpc_static_metadata_refcounts[35], {{g_bytes+482, 7}}}}, +{{&grpc_static_metadata_refcounts[5], {{g_bytes+36, 2}}},{&grpc_static_metadata_refcounts[40], {{g_bytes+513, 8}}}}, +{{&grpc_static_metadata_refcounts[14], {{g_bytes+158, 12}}},{&grpc_static_metadata_refcounts[41], {{g_bytes+521, 16}}}}, +{{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}},{&grpc_static_metadata_refcounts[42], {{g_bytes+537, 4}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[43], {{g_bytes+541, 3}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[44], {{g_bytes+544, 3}}}}, +{{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}},{&grpc_static_metadata_refcounts[45], {{g_bytes+547, 4}}}}, +{{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}},{&grpc_static_metadata_refcounts[46], {{g_bytes+551, 5}}}}, +{{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}},{&grpc_static_metadata_refcounts[47], {{g_bytes+556, 4}}}}, +{{&grpc_static_metadata_refcounts[3], {{g_bytes+19, 10}}},{&grpc_static_metadata_refcounts[29], {{g_bytes+354, 0}}}}, +{{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}},{&grpc_static_metadata_refcounts[48], {{g_bytes+560, 3}}}}, +{{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}},{&grpc_static_metadata_refcounts[49], {{g_bytes+563, 3}}}}, +{{&grpc_static_metadata_refcounts[0], {{g_bytes+0, 5}}},{&grpc_static_metadata_refcounts[50], {{g_bytes+566, 1}}}}, +{{&grpc_static_metadata_refcounts[0], {{g_bytes+0, 5}}},{&grpc_static_metadata_refcounts[51], {{g_bytes+567, 11}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[52], {{g_bytes+578, 3}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[53], {{g_bytes+581, 3}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[54], {{g_bytes+584, 3}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[55], {{g_bytes+587, 3}}}}, +{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&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[29], {{g_bytes+354, 0}}}}, +{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&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[39], {{g_bytes+505, 8}}}}, +{{&grpc_static_metadata_refcounts[15], {{g_bytes+170, 16}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, +{{&grpc_static_metadata_refcounts[15], {{g_bytes+170, 16}}},{&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[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[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[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[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[39], {{g_bytes+505, 8}}}}, +{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[35], {{g_bytes+482, 7}}}}, +{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[101], {{g_bytes+1085, 16}}}}, +{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, +{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[102], {{g_bytes+1101, 13}}}}, +{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[103], {{g_bytes+1114, 12}}}}, +{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[104], {{g_bytes+1126, 21}}}}, +{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&grpc_static_metadata_refcounts[39], {{g_bytes+505, 8}}}}, +{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, +{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&grpc_static_metadata_refcounts[102], {{g_bytes+1101, 13}}}}, }; bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = { - true, // :path - true, // :method - true, // :status - true, // :authority - true, // :scheme - true, // te - true, // grpc-message - true, // grpc-status - true, // grpc-payload-bin - true, // grpc-encoding - true, // grpc-accept-encoding - true, // grpc-server-stats-bin - true, // grpc-tags-bin - true, // grpc-trace-bin - true, // content-type - true, // content-encoding - true, // accept-encoding - true, // grpc-internal-encoding-request - true, // grpc-internal-stream-encoding-request - true, // user-agent - true, // host - true, // lb-token - true, // grpc-previous-rpc-attempts - true, // grpc-retry-pushback-ms + true, // :path + true, // :method + true, // :status + true, // :authority + true, // :scheme + true, // te + true, // grpc-message + true, // grpc-status + true, // grpc-payload-bin + true, // grpc-encoding + true, // grpc-accept-encoding + true, // grpc-server-stats-bin + true, // grpc-tags-bin + true, // grpc-trace-bin + true, // content-type + true, // content-encoding + true, // accept-encoding + true, // grpc-internal-encoding-request + true, // grpc-internal-stream-encoding-request + 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, - 79, 80, 81, 82}; +const uint8_t grpc_static_accept_encoding_metadata[8] = { +0,76,77,78,79,80,81,82 +}; -const uint8_t grpc_static_accept_stream_encoding_metadata[4] = {0, 83, 84, 85}; +const uint8_t grpc_static_accept_stream_encoding_metadata[4] = { +0,83,84,85 +}; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 0fc154d1a14..a2735767eff 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -1,12 +1,12 @@ /* * 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. @@ -16,10 +16,10 @@ /* * WARNING: Auto-generated code. - * + * * To make changes to this file, change * tools/codegen/core/gen_static_metadata.py, and then re-run it. - * + * * See metadata.h for an explanation of the interface here, and metadata.cc for * an explanation of what's going on. */ @@ -27,6 +27,8 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H #define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H +#include + #include "src/core/lib/transport/metadata.h" #define GRPC_STATIC_MDSTR_COUNT 105 @@ -68,8 +70,7 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "grpc-internal-encoding-request" */ #define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (grpc_static_slice_table[17]) /* "grpc-internal-stream-encoding-request" */ -#define GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST \ - (grpc_static_slice_table[18]) +#define GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST (grpc_static_slice_table[18]) /* "user-agent" */ #define GRPC_MDSTR_USER_AGENT (grpc_static_slice_table[19]) /* "host" */ @@ -97,14 +98,11 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "grpc.timeout" */ #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[32]) +#define GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES (grpc_static_slice_table[32]) /* "grpc.max_response_message_bytes" */ -#define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES \ - (grpc_static_slice_table[33]) +#define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES (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[34]) +#define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD (grpc_static_slice_table[34]) /* "deflate" */ #define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[35]) /* "gzip" */ @@ -244,15 +242,12 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "deflate,gzip" */ #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[104]) +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP (grpc_static_slice_table[104]) extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable; -extern grpc_slice_refcount - grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT]; +extern grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT]; #define GRPC_IS_STATIC_METADATA_STRING(slice) \ - ((slice).refcount != NULL && \ - (slice).refcount->vtable == &grpc_static_metadata_vtable) + ((slice).refcount != NULL && (slice).refcount->vtable == &grpc_static_metadata_vtable) #define GRPC_STATIC_METADATA_INDEX(static_slice) \ ((int)((static_slice).refcount - grpc_static_metadata_refcounts)) @@ -261,349 +256,177 @@ extern grpc_slice_refcount extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; /* "grpc-status": "0" Index="0" */ -#define GRPC_MDELEM_GRPC_STATUS_0 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_STATUS_0 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "grpc-status": "1" Index="0" */ -#define GRPC_MDELEM_GRPC_STATUS_1 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_STATUS_1 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "grpc-status": "2" Index="0" */ -#define GRPC_MDELEM_GRPC_STATUS_2 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_STATUS_2 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "grpc-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "grpc-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "grpc-encoding": "deflate" Index="0" */ -#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "te": "trailers" Index="0" */ -#define GRPC_MDELEM_TE_TRAILERS \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_TE_TRAILERS (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "content-type": "application/grpc" Index="0" */ -#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC, 0)) /* ":method": "POST" Index="3" */ -#define GRPC_MDELEM_METHOD_POST \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC, \ - 3)) +#define GRPC_MDELEM_METHOD_POST (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC, 3)) /* ":status": "200" Index="8" */ -#define GRPC_MDELEM_STATUS_200 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC, \ - 8)) +#define GRPC_MDELEM_STATUS_200 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC, 8)) /* ":status": "404" Index="13" */ -#define GRPC_MDELEM_STATUS_404 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC, \ - 13)) +#define GRPC_MDELEM_STATUS_404 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC, 13)) /* ":scheme": "http" Index="6" */ -#define GRPC_MDELEM_SCHEME_HTTP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC, \ - 6)) +#define GRPC_MDELEM_SCHEME_HTTP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC, 6)) /* ":scheme": "https" Index="7" */ -#define GRPC_MDELEM_SCHEME_HTTPS \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC, \ - 7)) +#define GRPC_MDELEM_SCHEME_HTTPS (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC, 7)) /* ":scheme": "grpc" Index="0" */ -#define GRPC_MDELEM_SCHEME_GRPC \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_SCHEME_GRPC (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC, 0)) /* ":authority": "" Index="1" */ -#define GRPC_MDELEM_AUTHORITY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC, \ - 1)) +#define GRPC_MDELEM_AUTHORITY_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC, 1)) /* ":method": "GET" Index="2" */ -#define GRPC_MDELEM_METHOD_GET \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC, \ - 2)) +#define GRPC_MDELEM_METHOD_GET (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC, 2)) /* ":method": "PUT" Index="0" */ -#define GRPC_MDELEM_METHOD_PUT \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_METHOD_PUT (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC, 0)) /* ":path": "/" Index="4" */ -#define GRPC_MDELEM_PATH_SLASH \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC, \ - 4)) +#define GRPC_MDELEM_PATH_SLASH (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC, 4)) /* ":path": "/index.html" Index="5" */ -#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC, \ - 5)) +#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC, 5)) /* ":status": "204" Index="9" */ -#define GRPC_MDELEM_STATUS_204 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC, \ - 9)) +#define GRPC_MDELEM_STATUS_204 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC, 9)) /* ":status": "206" Index="10" */ -#define GRPC_MDELEM_STATUS_206 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC, \ - 10)) +#define GRPC_MDELEM_STATUS_206 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC, 10)) /* ":status": "304" Index="11" */ -#define GRPC_MDELEM_STATUS_304 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC, \ - 11)) +#define GRPC_MDELEM_STATUS_304 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC, 11)) /* ":status": "400" Index="12" */ -#define GRPC_MDELEM_STATUS_400 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC, \ - 12)) +#define GRPC_MDELEM_STATUS_400 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC, 12)) /* ":status": "500" Index="14" */ -#define GRPC_MDELEM_STATUS_500 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC, \ - 14)) +#define GRPC_MDELEM_STATUS_500 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC, 14)) /* "accept-charset": "" Index="15" */ -#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC, \ - 15)) +#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC, 15)) /* "accept-encoding": "" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "accept-encoding": "gzip, deflate" Index="16" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC, \ - 16)) +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC, 16)) /* "accept-language": "" Index="17" */ -#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC, \ - 17)) +#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC, 17)) /* "accept-ranges": "" Index="18" */ -#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC, \ - 18)) +#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC, 18)) /* "accept": "" Index="19" */ -#define GRPC_MDELEM_ACCEPT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC, \ - 19)) +#define GRPC_MDELEM_ACCEPT_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC, 19)) /* "access-control-allow-origin": "" Index="20" */ -#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC, \ - 20)) +#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC, 20)) /* "age": "" Index="21" */ -#define GRPC_MDELEM_AGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC, \ - 21)) +#define GRPC_MDELEM_AGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC, 21)) /* "allow": "" Index="22" */ -#define GRPC_MDELEM_ALLOW_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC, \ - 22)) +#define GRPC_MDELEM_ALLOW_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC, 22)) /* "authorization": "" Index="23" */ -#define GRPC_MDELEM_AUTHORIZATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC, \ - 23)) +#define GRPC_MDELEM_AUTHORIZATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC, 23)) /* "cache-control": "" Index="24" */ -#define GRPC_MDELEM_CACHE_CONTROL_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC, \ - 24)) +#define GRPC_MDELEM_CACHE_CONTROL_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC, 24)) /* "content-disposition": "" Index="25" */ -#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC, \ - 25)) +#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC, 25)) /* "content-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "content-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_CONTENT_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "content-encoding": "" Index="26" */ -#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC, \ - 26)) +#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC, 26)) /* "content-language": "" Index="27" */ -#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC, \ - 27)) +#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC, 27)) /* "content-length": "" Index="28" */ -#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC, \ - 28)) +#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC, 28)) /* "content-location": "" Index="29" */ -#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC, \ - 29)) +#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC, 29)) /* "content-range": "" Index="30" */ -#define GRPC_MDELEM_CONTENT_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC, \ - 30)) +#define GRPC_MDELEM_CONTENT_RANGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC, 30)) /* "content-type": "" Index="31" */ -#define GRPC_MDELEM_CONTENT_TYPE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC, \ - 31)) +#define GRPC_MDELEM_CONTENT_TYPE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC, 31)) /* "cookie": "" Index="32" */ -#define GRPC_MDELEM_COOKIE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC, \ - 32)) +#define GRPC_MDELEM_COOKIE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC, 32)) /* "date": "" Index="33" */ -#define GRPC_MDELEM_DATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC, \ - 33)) +#define GRPC_MDELEM_DATE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC, 33)) /* "etag": "" Index="34" */ -#define GRPC_MDELEM_ETAG_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC, \ - 34)) +#define GRPC_MDELEM_ETAG_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC, 34)) /* "expect": "" Index="35" */ -#define GRPC_MDELEM_EXPECT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC, \ - 35)) +#define GRPC_MDELEM_EXPECT_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC, 35)) /* "expires": "" Index="36" */ -#define GRPC_MDELEM_EXPIRES_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC, \ - 36)) +#define GRPC_MDELEM_EXPIRES_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC, 36)) /* "from": "" Index="37" */ -#define GRPC_MDELEM_FROM_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC, \ - 37)) +#define GRPC_MDELEM_FROM_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC, 37)) /* "host": "" Index="38" */ -#define GRPC_MDELEM_HOST_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC, \ - 38)) +#define GRPC_MDELEM_HOST_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC, 38)) /* "if-match": "" Index="39" */ -#define GRPC_MDELEM_IF_MATCH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC, \ - 39)) +#define GRPC_MDELEM_IF_MATCH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC, 39)) /* "if-modified-since": "" Index="40" */ -#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC, \ - 40)) +#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC, 40)) /* "if-none-match": "" Index="41" */ -#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC, \ - 41)) +#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC, 41)) /* "if-range": "" Index="42" */ -#define GRPC_MDELEM_IF_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC, \ - 42)) +#define GRPC_MDELEM_IF_RANGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC, 42)) /* "if-unmodified-since": "" Index="43" */ -#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC, \ - 43)) +#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC, 43)) /* "last-modified": "" Index="44" */ -#define GRPC_MDELEM_LAST_MODIFIED_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC, \ - 44)) +#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC, 44)) /* "lb-token": "" Index="0" */ -#define GRPC_MDELEM_LB_TOKEN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_LB_TOKEN_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "lb-cost-bin": "" Index="0" */ -#define GRPC_MDELEM_LB_COST_BIN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_LB_COST_BIN_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "link": "" Index="45" */ -#define GRPC_MDELEM_LINK_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC, \ - 45)) +#define GRPC_MDELEM_LINK_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC, 45)) /* "location": "" Index="46" */ -#define GRPC_MDELEM_LOCATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC, \ - 46)) +#define GRPC_MDELEM_LOCATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC, 46)) /* "max-forwards": "" Index="47" */ -#define GRPC_MDELEM_MAX_FORWARDS_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC, \ - 47)) +#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC, 47)) /* "proxy-authenticate": "" Index="48" */ -#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC, \ - 48)) +#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC, 48)) /* "proxy-authorization": "" Index="49" */ -#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC, \ - 49)) +#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC, 49)) /* "range": "" Index="50" */ -#define GRPC_MDELEM_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC, \ - 50)) +#define GRPC_MDELEM_RANGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC, 50)) /* "referer": "" Index="51" */ -#define GRPC_MDELEM_REFERER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC, \ - 51)) +#define GRPC_MDELEM_REFERER_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC, 51)) /* "refresh": "" Index="52" */ -#define GRPC_MDELEM_REFRESH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC, \ - 52)) +#define GRPC_MDELEM_REFRESH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC, 52)) /* "retry-after": "" Index="53" */ -#define GRPC_MDELEM_RETRY_AFTER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC, \ - 53)) +#define GRPC_MDELEM_RETRY_AFTER_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC, 53)) /* "server": "" Index="54" */ -#define GRPC_MDELEM_SERVER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC, \ - 54)) +#define GRPC_MDELEM_SERVER_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC, 54)) /* "set-cookie": "" Index="55" */ -#define GRPC_MDELEM_SET_COOKIE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC, \ - 55)) +#define GRPC_MDELEM_SET_COOKIE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC, 55)) /* "strict-transport-security": "" Index="56" */ -#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC, \ - 56)) +#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC, 56)) /* "transfer-encoding": "" Index="57" */ -#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC, \ - 57)) +#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC, 57)) /* "user-agent": "" Index="58" */ -#define GRPC_MDELEM_USER_AGENT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC, \ - 58)) +#define GRPC_MDELEM_USER_AGENT_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC, 58)) /* "vary": "" Index="59" */ -#define GRPC_MDELEM_VARY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC, \ - 59)) +#define GRPC_MDELEM_VARY_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC, 59)) /* "via": "" Index="60" */ -#define GRPC_MDELEM_VIA_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC, \ - 60)) +#define GRPC_MDELEM_VIA_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC, 60)) /* "www-authenticate": "" Index="61" */ -#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC, \ - 61)) +#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC, 61)) /* "grpc-accept-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "grpc-accept-encoding": "deflate" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "grpc-accept-encoding": "identity,deflate" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "grpc-accept-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "grpc-accept-encoding": "identity,gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "grpc-accept-encoding": "deflate,gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "grpc-accept-encoding": "identity,deflate,gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "accept-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "accept-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84], GRPC_MDELEM_STORAGE_STATIC, 0)) /* "accept-encoding": "identity,gzip" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC, 0)) grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b); typedef enum { @@ -635,53 +458,43 @@ typedef enum { } grpc_metadata_batch_callouts_index; typedef union { - struct grpc_linked_mdelem* array[GRPC_BATCH_CALLOUTS_COUNT]; + struct grpc_linked_mdelem *array[GRPC_BATCH_CALLOUTS_COUNT]; struct { - struct grpc_linked_mdelem* path; - struct grpc_linked_mdelem* method; - struct grpc_linked_mdelem* status; - struct grpc_linked_mdelem* authority; - struct grpc_linked_mdelem* scheme; - struct grpc_linked_mdelem* te; - struct grpc_linked_mdelem* grpc_message; - struct grpc_linked_mdelem* grpc_status; - struct grpc_linked_mdelem* grpc_payload_bin; - struct grpc_linked_mdelem* grpc_encoding; - struct grpc_linked_mdelem* grpc_accept_encoding; - struct grpc_linked_mdelem* grpc_server_stats_bin; - struct grpc_linked_mdelem* grpc_tags_bin; - struct grpc_linked_mdelem* grpc_trace_bin; - struct grpc_linked_mdelem* content_type; - struct grpc_linked_mdelem* content_encoding; - struct grpc_linked_mdelem* accept_encoding; - struct grpc_linked_mdelem* grpc_internal_encoding_request; - struct grpc_linked_mdelem* grpc_internal_stream_encoding_request; - 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; + struct grpc_linked_mdelem *path; + struct grpc_linked_mdelem *method; + struct grpc_linked_mdelem *status; + struct grpc_linked_mdelem *authority; + struct grpc_linked_mdelem *scheme; + struct grpc_linked_mdelem *te; + struct grpc_linked_mdelem *grpc_message; + struct grpc_linked_mdelem *grpc_status; + struct grpc_linked_mdelem *grpc_payload_bin; + struct grpc_linked_mdelem *grpc_encoding; + struct grpc_linked_mdelem *grpc_accept_encoding; + struct grpc_linked_mdelem *grpc_server_stats_bin; + struct grpc_linked_mdelem *grpc_tags_bin; + struct grpc_linked_mdelem *grpc_trace_bin; + struct grpc_linked_mdelem *content_type; + struct grpc_linked_mdelem *content_encoding; + struct grpc_linked_mdelem *accept_encoding; + struct grpc_linked_mdelem *grpc_internal_encoding_request; + struct grpc_linked_mdelem *grpc_internal_stream_encoding_request; + 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; -#define GRPC_BATCH_INDEX_OF(slice) \ - (GRPC_IS_STATIC_METADATA_STRING((slice)) \ - ? (grpc_metadata_batch_callouts_index)GPR_CLAMP( \ - GRPC_STATIC_METADATA_INDEX((slice)), 0, \ - GRPC_BATCH_CALLOUTS_COUNT) \ - : GRPC_BATCH_CALLOUTS_COUNT) +#define GRPC_BATCH_INDEX_OF(slice) \ + (GRPC_IS_STATIC_METADATA_STRING((slice)) ? (grpc_metadata_batch_callouts_index)GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, GRPC_BATCH_CALLOUTS_COUNT) : GRPC_BATCH_CALLOUTS_COUNT) extern bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT]; extern const uint8_t grpc_static_accept_encoding_metadata[8]; -#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \ - (GRPC_MAKE_MDELEM( \ - &grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], \ - GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC, 0)) extern const uint8_t grpc_static_accept_stream_encoding_metadata[4]; -#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table \ - [grpc_static_accept_stream_encoding_metadata[(algs)]], \ - GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_stream_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC, 0)) #endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */ diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index 36c76fada9a..98e375127ea 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -367,9 +367,13 @@ an explanation of what's going on. print >> H, '#ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H' print >> H, '#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H' print >> H +print >> H, '#include ' +print >> H print >> H, '#include "src/core/lib/transport/metadata.h"' print >> H +print >> C, '#include ' +print >> C print >> C, '#include "src/core/lib/transport/static_metadata.h"' print >> C print >> C, '#include "src/core/lib/slice/slice_internal.h"' From 4a9cd9c38b18a613f82a19062f15e7f4e8179fc0 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Mon, 10 Sep 2018 22:29:03 -0700 Subject: [PATCH 343/546] Fix codegen script to include port_platform --- src/core/lib/transport/static_metadata.cc | 2 ++ src/core/lib/transport/static_metadata.h | 2 ++ tools/codegen/core/gen_static_metadata.py | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 259aa187f70..5a953fc37ef 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 + #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/slice/slice_internal.h" diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 0fc154d1a14..a2aca6ca681 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -27,6 +27,8 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H #define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H +#include + #include "src/core/lib/transport/metadata.h" #define GRPC_STATIC_MDSTR_COUNT 105 diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index 36c76fada9a..98e375127ea 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -367,9 +367,13 @@ an explanation of what's going on. print >> H, '#ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H' print >> H, '#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H' print >> H +print >> H, '#include ' +print >> H print >> H, '#include "src/core/lib/transport/metadata.h"' print >> H +print >> C, '#include ' +print >> C print >> C, '#include "src/core/lib/transport/static_metadata.h"' print >> C print >> C, '#include "src/core/lib/slice/slice_internal.h"' From 2d8c682cac54ff2f6024a4b629b1f12be41fca9e Mon Sep 17 00:00:00 2001 From: Nathan Herring Date: Tue, 11 Sep 2018 09:31:39 +0200 Subject: [PATCH 344/546] Revert "Missing #include" This reverts commit 234fdc6fbf68aa6c29990db7c7ddcface3355cb5. --- test/cpp/util/cli_credentials.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/test/cpp/util/cli_credentials.cc b/test/cpp/util/cli_credentials.cc index 3defd82443a..d48b94ad85b 100644 --- a/test/cpp/util/cli_credentials.cc +++ b/test/cpp/util/cli_credentials.cc @@ -24,7 +24,6 @@ #include #include "src/core/lib/iomgr/load_file.h" -#include "src/core/lib/slice/slice_internal.h" DEFINE_bool( enable_ssl, false, From 916a686ef3b69a9036ed0423c62a2ce1c53ef062 Mon Sep 17 00:00:00 2001 From: Nathan Herring Date: Tue, 11 Sep 2018 09:32:06 +0200 Subject: [PATCH 345/546] Revert "Use grpc_slice_unref_internal" This reverts commit 147826a909cc60d963c34b919417ce7a888e29ce. --- test/cpp/util/cli_credentials.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/util/cli_credentials.cc b/test/cpp/util/cli_credentials.cc index d48b94ad85b..1125b2d945e 100644 --- a/test/cpp/util/cli_credentials.cc +++ b/test/cpp/util/cli_credentials.cc @@ -121,7 +121,7 @@ CliCredentials::GetChannelCredentials() const { grpc_load_file(FLAGS_ssl_client_cert.c_str(), 1, &cert_slice)); ssl_creds_options.pem_cert_chain = grpc::StringFromCopiedSlice(cert_slice); - grpc_slice_unref_internal(cert_slice); + grpc_slice_unref(cert_slice); } if (!FLAGS_ssl_client_key.empty()) { grpc_slice key_slice = grpc_empty_slice(); @@ -130,7 +130,7 @@ CliCredentials::GetChannelCredentials() const { grpc_load_file(FLAGS_ssl_client_key.c_str(), 1, &key_slice)); ssl_creds_options.pem_private_key = grpc::StringFromCopiedSlice(key_slice); - grpc_slice_unref_internal(key_slice); + grpc_slice_unref(key_slice); } return grpc::SslCredentials(ssl_creds_options); } else if (FLAGS_channel_creds_type.compare("gdc") == 0) { From 0b4e263fdf5d4be817f1ad7b93a0b7328aff97f1 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 11 Sep 2018 08:52:59 -0700 Subject: [PATCH 346/546] Small formatting and style changes --- src/core/ext/transport/chttp2/transport/hpack_encoder.cc | 4 ++-- src/core/lib/transport/metadata_batch.cc | 1 - src/core/lib/transport/static_metadata.cc | 2 +- src/core/lib/transport/static_metadata.h | 2 +- tools/codegen/core/gen_static_metadata.py | 4 ++-- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index d0e65ddebd9..9a5af3712d8 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -690,7 +690,7 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, for (size_t i = 0; i < extra_headers_size; ++i) { grpc_mdelem md = *extra_headers[i]; uint8_t static_index = GRPC_MDINDEX(md); - if (static_index > 0) { + if (static_index != GRPC_MDINDEX_UNUSED) { emit_indexed(c, static_index, &st); } else { hpack_enc(c, md, &st); @@ -699,7 +699,7 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, grpc_metadata_batch_assert_ok(metadata); for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) { uint8_t static_index = GRPC_MDINDEX(l->md); - if (static_index > 0) { + if (static_index != GRPC_MDINDEX_UNUSED) { emit_indexed(c, static_index, &st); } else { hpack_enc(c, l->md, &st); diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index b7ab4cc7b94..49740fcd1e3 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -109,7 +109,6 @@ static grpc_error* maybe_link_callout(grpc_metadata_batch* batch, batch->idx.array[idx] = storage; return GRPC_ERROR_NONE; } - return grpc_attach_md_to_error( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Unallowed duplicate metadata"), storage->md); diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 7e6e5191b57..7e750ff3d24 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -24,7 +24,7 @@ * an explanation of what's going on. */ -#include +#include #include "src/core/lib/transport/static_metadata.h" diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index a2735767eff..44a0c5d8d43 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -27,7 +27,7 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H #define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H -#include +#include #include "src/core/lib/transport/metadata.h" diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index 98e375127ea..583384cb8ce 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -367,12 +367,12 @@ an explanation of what's going on. print >> H, '#ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H' print >> H, '#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H' print >> H -print >> H, '#include ' +print >> H, '#include ' print >> H print >> H, '#include "src/core/lib/transport/metadata.h"' print >> H -print >> C, '#include ' +print >> C, '#include ' print >> C print >> C, '#include "src/core/lib/transport/static_metadata.h"' print >> C From 713f9bc93a94ee7859314725f6c6fd6836d2fce0 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 11 Sep 2018 09:07:12 -0700 Subject: [PATCH 347/546] Clang tidy --- src/core/lib/transport/static_metadata.cc | 886 +++++++++++++--------- src/core/lib/transport/static_metadata.h | 443 +++++++---- 2 files changed, 857 insertions(+), 472 deletions(-) diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 7e750ff3d24..240a55e0abc 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -1,12 +1,12 @@ /* * 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. @@ -16,10 +16,10 @@ /* * WARNING: Auto-generated code. - * + * * To make changes to this file, change * tools/codegen/core/gen_static_metadata.py, and then re-run it. - * + * * See metadata.h for an explanation of the interface here, and metadata.cc for * an explanation of what's going on. */ @@ -30,235 +30,323 @@ #include "src/core/lib/slice/slice_internal.h" -static uint8_t g_bytes[] = {58,112,97,116,104,58,109,101,116,104,111,100,58,115,116,97,116,117,115,58,97,117,116,104,111,114,105,116,121,58,115,99,104,101,109,101,116,101,103,114,112,99,45,109,101,115,115,97,103,101,103,114,112,99,45,115,116,97,116,117,115,103,114,112,99,45,112,97,121,108,111,97,100,45,98,105,110,103,114,112,99,45,101,110,99,111,100,105,110,103,103,114,112,99,45,97,99,99,101,112,116,45,101,110,99,111,100,105,110,103,103,114,112,99,45,115,101,114,118,101,114,45,115,116,97,116,115,45,98,105,110,103,114,112,99,45,116,97,103,115,45,98,105,110,103,114,112,99,45,116,114,97,99,101,45,98,105,110,99,111,110,116,101,110,116,45,116,121,112,101,99,111,110,116,101,110,116,45,101,110,99,111,100,105,110,103,97,99,99,101,112,116,45,101,110,99,111,100,105,110,103,103,114,112,99,45,105,110,116,101,114,110,97,108,45,101,110,99,111,100,105,110,103,45,114,101,113,117,101,115,116,103,114,112,99,45,105,110,116,101,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,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 uint8_t g_bytes[] = { + 58, 112, 97, 116, 104, 58, 109, 101, 116, 104, 111, 100, 58, 115, 116, + 97, 116, 117, 115, 58, 97, 117, 116, 104, 111, 114, 105, 116, 121, 58, + 115, 99, 104, 101, 109, 101, 116, 101, 103, 114, 112, 99, 45, 109, 101, + 115, 115, 97, 103, 101, 103, 114, 112, 99, 45, 115, 116, 97, 116, 117, + 115, 103, 114, 112, 99, 45, 112, 97, 121, 108, 111, 97, 100, 45, 98, + 105, 110, 103, 114, 112, 99, 45, 101, 110, 99, 111, 100, 105, 110, 103, + 103, 114, 112, 99, 45, 97, 99, 99, 101, 112, 116, 45, 101, 110, 99, + 111, 100, 105, 110, 103, 103, 114, 112, 99, 45, 115, 101, 114, 118, 101, + 114, 45, 115, 116, 97, 116, 115, 45, 98, 105, 110, 103, 114, 112, 99, + 45, 116, 97, 103, 115, 45, 98, 105, 110, 103, 114, 112, 99, 45, 116, + 114, 97, 99, 101, 45, 98, 105, 110, 99, 111, 110, 116, 101, 110, 116, + 45, 116, 121, 112, 101, 99, 111, 110, 116, 101, 110, 116, 45, 101, 110, + 99, 111, 100, 105, 110, 103, 97, 99, 99, 101, 112, 116, 45, 101, 110, + 99, 111, 100, 105, 110, 103, 103, 114, 112, 99, 45, 105, 110, 116, 101, + 114, 110, 97, 108, 45, 101, 110, 99, 111, 100, 105, 110, 103, 45, 114, + 101, 113, 117, 101, 115, 116, 103, 114, 112, 99, 45, 105, 110, 116, 101, + 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, 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) {} -static const grpc_slice_refcount_vtable static_sub_vtable = {static_ref, static_unref, grpc_slice_default_eq_impl, grpc_slice_default_hash_impl}; -const grpc_slice_refcount_vtable grpc_static_metadata_vtable = {static_ref, static_unref, grpc_static_slice_eq, grpc_static_slice_hash}; -static grpc_slice_refcount static_sub_refcnt = {&static_sub_vtable, &static_sub_refcnt}; +static void static_ref(void* unused) {} +static void static_unref(void* unused) {} +static const grpc_slice_refcount_vtable static_sub_vtable = { + static_ref, static_unref, grpc_slice_default_eq_impl, + grpc_slice_default_hash_impl}; +const grpc_slice_refcount_vtable grpc_static_metadata_vtable = { + static_ref, static_unref, grpc_static_slice_eq, grpc_static_slice_hash}; +static grpc_slice_refcount static_sub_refcnt = {&static_sub_vtable, + &static_sub_refcnt}; 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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, - {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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}, + {&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] = { -{&grpc_static_metadata_refcounts[0], {{g_bytes+0, 5}}}, -{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}}, -{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}}, -{&grpc_static_metadata_refcounts[3], {{g_bytes+19, 10}}}, -{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}}, -{&grpc_static_metadata_refcounts[5], {{g_bytes+36, 2}}}, -{&grpc_static_metadata_refcounts[6], {{g_bytes+38, 12}}}, -{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}}, -{&grpc_static_metadata_refcounts[8], {{g_bytes+61, 16}}}, -{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}}, -{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}}, -{&grpc_static_metadata_refcounts[11], {{g_bytes+110, 21}}}, -{&grpc_static_metadata_refcounts[12], {{g_bytes+131, 13}}}, -{&grpc_static_metadata_refcounts[13], {{g_bytes+144, 14}}}, -{&grpc_static_metadata_refcounts[14], {{g_bytes+158, 12}}}, -{&grpc_static_metadata_refcounts[15], {{g_bytes+170, 16}}}, -{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}}, -{&grpc_static_metadata_refcounts[17], {{g_bytes+201, 30}}}, -{&grpc_static_metadata_refcounts[18], {{g_bytes+231, 37}}}, -{&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, 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}}}, + {&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, + {&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, + {&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, + {&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, + {&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, + {&grpc_static_metadata_refcounts[6], {{g_bytes + 38, 12}}}, + {&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, + {&grpc_static_metadata_refcounts[8], {{g_bytes + 61, 16}}}, + {&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, + {&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[11], {{g_bytes + 110, 21}}}, + {&grpc_static_metadata_refcounts[12], {{g_bytes + 131, 13}}}, + {&grpc_static_metadata_refcounts[13], {{g_bytes + 144, 14}}}, + {&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, + {&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, + {&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, + {&grpc_static_metadata_refcounts[17], {{g_bytes + 201, 30}}}, + {&grpc_static_metadata_refcounts[18], {{g_bytes + 231, 37}}}, + {&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, 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] = { - 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,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,0,0,0,0,0,0,2,4,4,6,6,8,8,2,4,4 -}; - + 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, 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, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4}; -static const int8_t elems_r[] = {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 const int8_t elems_r[] = { + 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 -= 50; uint32_t x = i % 103; @@ -270,136 +358,244 @@ static uint32_t elems_phash(uint32_t i) { } return h; } - -static const uint16_t elem_keys[] = {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,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}; + +static const uint16_t elem_keys[] = { + 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, 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 = (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 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC, 0) : GRPC_MDNULL; + return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && + elem_idxs[h] != 255 + ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], + GRPC_MDELEM_STORAGE_STATIC, 0) + : GRPC_MDNULL; } grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { -{{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}},{&grpc_static_metadata_refcounts[38], {{g_bytes+504, 1}}}}, -{{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}},{&grpc_static_metadata_refcounts[25], {{g_bytes+350, 1}}}}, -{{&grpc_static_metadata_refcounts[7], {{g_bytes+50, 11}}},{&grpc_static_metadata_refcounts[26], {{g_bytes+351, 1}}}}, -{{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}},{&grpc_static_metadata_refcounts[39], {{g_bytes+505, 8}}}}, -{{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, -{{&grpc_static_metadata_refcounts[9], {{g_bytes+77, 13}}},{&grpc_static_metadata_refcounts[35], {{g_bytes+482, 7}}}}, -{{&grpc_static_metadata_refcounts[5], {{g_bytes+36, 2}}},{&grpc_static_metadata_refcounts[40], {{g_bytes+513, 8}}}}, -{{&grpc_static_metadata_refcounts[14], {{g_bytes+158, 12}}},{&grpc_static_metadata_refcounts[41], {{g_bytes+521, 16}}}}, -{{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}},{&grpc_static_metadata_refcounts[42], {{g_bytes+537, 4}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[43], {{g_bytes+541, 3}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[44], {{g_bytes+544, 3}}}}, -{{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}},{&grpc_static_metadata_refcounts[45], {{g_bytes+547, 4}}}}, -{{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}},{&grpc_static_metadata_refcounts[46], {{g_bytes+551, 5}}}}, -{{&grpc_static_metadata_refcounts[4], {{g_bytes+29, 7}}},{&grpc_static_metadata_refcounts[47], {{g_bytes+556, 4}}}}, -{{&grpc_static_metadata_refcounts[3], {{g_bytes+19, 10}}},{&grpc_static_metadata_refcounts[29], {{g_bytes+354, 0}}}}, -{{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}},{&grpc_static_metadata_refcounts[48], {{g_bytes+560, 3}}}}, -{{&grpc_static_metadata_refcounts[1], {{g_bytes+5, 7}}},{&grpc_static_metadata_refcounts[49], {{g_bytes+563, 3}}}}, -{{&grpc_static_metadata_refcounts[0], {{g_bytes+0, 5}}},{&grpc_static_metadata_refcounts[50], {{g_bytes+566, 1}}}}, -{{&grpc_static_metadata_refcounts[0], {{g_bytes+0, 5}}},{&grpc_static_metadata_refcounts[51], {{g_bytes+567, 11}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[52], {{g_bytes+578, 3}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[53], {{g_bytes+581, 3}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[54], {{g_bytes+584, 3}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&grpc_static_metadata_refcounts[55], {{g_bytes+587, 3}}}}, -{{&grpc_static_metadata_refcounts[2], {{g_bytes+12, 7}}},{&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[29], {{g_bytes+354, 0}}}}, -{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&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[39], {{g_bytes+505, 8}}}}, -{{&grpc_static_metadata_refcounts[15], {{g_bytes+170, 16}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, -{{&grpc_static_metadata_refcounts[15], {{g_bytes+170, 16}}},{&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[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[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[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[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[39], {{g_bytes+505, 8}}}}, -{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[35], {{g_bytes+482, 7}}}}, -{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[101], {{g_bytes+1085, 16}}}}, -{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, -{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[102], {{g_bytes+1101, 13}}}}, -{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[103], {{g_bytes+1114, 12}}}}, -{{&grpc_static_metadata_refcounts[10], {{g_bytes+90, 20}}},{&grpc_static_metadata_refcounts[104], {{g_bytes+1126, 21}}}}, -{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&grpc_static_metadata_refcounts[39], {{g_bytes+505, 8}}}}, -{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&grpc_static_metadata_refcounts[36], {{g_bytes+489, 4}}}}, -{{&grpc_static_metadata_refcounts[16], {{g_bytes+186, 15}}},{&grpc_static_metadata_refcounts[102], {{g_bytes+1101, 13}}}}, + {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, + {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 1}}}}, + {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, + {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}}, + {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, + {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}}, + {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, + {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, + {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, + {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, + {&grpc_static_metadata_refcounts[40], {{g_bytes + 513, 8}}}}, + {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, + {&grpc_static_metadata_refcounts[41], {{g_bytes + 521, 16}}}}, + {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, + {&grpc_static_metadata_refcounts[42], {{g_bytes + 537, 4}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[43], {{g_bytes + 541, 3}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[44], {{g_bytes + 544, 3}}}}, + {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, + {&grpc_static_metadata_refcounts[45], {{g_bytes + 547, 4}}}}, + {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, + {&grpc_static_metadata_refcounts[46], {{g_bytes + 551, 5}}}}, + {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, + {&grpc_static_metadata_refcounts[47], {{g_bytes + 556, 4}}}}, + {{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, + {&grpc_static_metadata_refcounts[48], {{g_bytes + 560, 3}}}}, + {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, + {&grpc_static_metadata_refcounts[49], {{g_bytes + 563, 3}}}}, + {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, + {&grpc_static_metadata_refcounts[50], {{g_bytes + 566, 1}}}}, + {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, + {&grpc_static_metadata_refcounts[51], {{g_bytes + 567, 11}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[52], {{g_bytes + 578, 3}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[53], {{g_bytes + 581, 3}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[54], {{g_bytes + 584, 3}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[55], {{g_bytes + 587, 3}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&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[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, + {&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[39], {{g_bytes + 505, 8}}}}, + {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, + {&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[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[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[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[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[39], {{g_bytes + 505, 8}}}}, + {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, + {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}}}, + {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, + {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}}}, + {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, + {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}}, + {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, + {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, + {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, }; bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = { - true, // :path - true, // :method - true, // :status - true, // :authority - true, // :scheme - true, // te - true, // grpc-message - true, // grpc-status - true, // grpc-payload-bin - true, // grpc-encoding - true, // grpc-accept-encoding - true, // grpc-server-stats-bin - true, // grpc-tags-bin - true, // grpc-trace-bin - true, // content-type - true, // content-encoding - true, // accept-encoding - true, // grpc-internal-encoding-request - true, // grpc-internal-stream-encoding-request - true, // user-agent - true, // host - true, // lb-token - true, // grpc-previous-rpc-attempts - true, // grpc-retry-pushback-ms + true, // :path + true, // :method + true, // :status + true, // :authority + true, // :scheme + true, // te + true, // grpc-message + true, // grpc-status + true, // grpc-payload-bin + true, // grpc-encoding + true, // grpc-accept-encoding + true, // grpc-server-stats-bin + true, // grpc-tags-bin + true, // grpc-trace-bin + true, // content-type + true, // content-encoding + true, // accept-encoding + true, // grpc-internal-encoding-request + true, // grpc-internal-stream-encoding-request + 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,79,80,81,82 -}; +const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78, + 79, 80, 81, 82}; -const uint8_t grpc_static_accept_stream_encoding_metadata[4] = { -0,83,84,85 -}; +const uint8_t grpc_static_accept_stream_encoding_metadata[4] = {0, 83, 84, 85}; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 44a0c5d8d43..e4a9e2a4141 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -1,12 +1,12 @@ /* * 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. @@ -16,10 +16,10 @@ /* * WARNING: Auto-generated code. - * + * * To make changes to this file, change * tools/codegen/core/gen_static_metadata.py, and then re-run it. - * + * * See metadata.h for an explanation of the interface here, and metadata.cc for * an explanation of what's going on. */ @@ -70,7 +70,8 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "grpc-internal-encoding-request" */ #define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (grpc_static_slice_table[17]) /* "grpc-internal-stream-encoding-request" */ -#define GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST (grpc_static_slice_table[18]) +#define GRPC_MDSTR_GRPC_INTERNAL_STREAM_ENCODING_REQUEST \ + (grpc_static_slice_table[18]) /* "user-agent" */ #define GRPC_MDSTR_USER_AGENT (grpc_static_slice_table[19]) /* "host" */ @@ -98,11 +99,14 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "grpc.timeout" */ #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[32]) +#define GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES \ + (grpc_static_slice_table[32]) /* "grpc.max_response_message_bytes" */ -#define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES (grpc_static_slice_table[33]) +#define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES \ + (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[34]) +#define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \ + (grpc_static_slice_table[34]) /* "deflate" */ #define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[35]) /* "gzip" */ @@ -242,12 +246,15 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "deflate,gzip" */ #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[104]) +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ + (grpc_static_slice_table[104]) extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable; -extern grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT]; +extern grpc_slice_refcount + grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT]; #define GRPC_IS_STATIC_METADATA_STRING(slice) \ - ((slice).refcount != NULL && (slice).refcount->vtable == &grpc_static_metadata_vtable) + ((slice).refcount != NULL && \ + (slice).refcount->vtable == &grpc_static_metadata_vtable) #define GRPC_STATIC_METADATA_INDEX(static_slice) \ ((int)((static_slice).refcount - grpc_static_metadata_refcounts)) @@ -256,177 +263,349 @@ extern grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUN extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; /* "grpc-status": "0" Index="0" */ -#define GRPC_MDELEM_GRPC_STATUS_0 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_STATUS_0 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-status": "1" Index="0" */ -#define GRPC_MDELEM_GRPC_STATUS_1 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_STATUS_1 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-status": "2" Index="0" */ -#define GRPC_MDELEM_GRPC_STATUS_2 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_STATUS_2 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-encoding": "deflate" Index="0" */ -#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "te": "trailers" Index="0" */ -#define GRPC_MDELEM_TE_TRAILERS (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_TE_TRAILERS \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "content-type": "application/grpc" Index="0" */ -#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* ":method": "POST" Index="3" */ -#define GRPC_MDELEM_METHOD_POST (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC, 3)) +#define GRPC_MDELEM_METHOD_POST \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC, \ + 3)) /* ":status": "200" Index="8" */ -#define GRPC_MDELEM_STATUS_200 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC, 8)) +#define GRPC_MDELEM_STATUS_200 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC, \ + 8)) /* ":status": "404" Index="13" */ -#define GRPC_MDELEM_STATUS_404 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC, 13)) +#define GRPC_MDELEM_STATUS_404 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC, \ + 13)) /* ":scheme": "http" Index="6" */ -#define GRPC_MDELEM_SCHEME_HTTP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC, 6)) +#define GRPC_MDELEM_SCHEME_HTTP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC, \ + 6)) /* ":scheme": "https" Index="7" */ -#define GRPC_MDELEM_SCHEME_HTTPS (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC, 7)) +#define GRPC_MDELEM_SCHEME_HTTPS \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC, \ + 7)) /* ":scheme": "grpc" Index="0" */ -#define GRPC_MDELEM_SCHEME_GRPC (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_SCHEME_GRPC \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* ":authority": "" Index="1" */ -#define GRPC_MDELEM_AUTHORITY_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC, 1)) +#define GRPC_MDELEM_AUTHORITY_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC, \ + 1)) /* ":method": "GET" Index="2" */ -#define GRPC_MDELEM_METHOD_GET (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC, 2)) +#define GRPC_MDELEM_METHOD_GET \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC, \ + 2)) /* ":method": "PUT" Index="0" */ -#define GRPC_MDELEM_METHOD_PUT (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_METHOD_PUT \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* ":path": "/" Index="4" */ -#define GRPC_MDELEM_PATH_SLASH (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC, 4)) +#define GRPC_MDELEM_PATH_SLASH \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC, \ + 4)) /* ":path": "/index.html" Index="5" */ -#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC, 5)) +#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC, \ + 5)) /* ":status": "204" Index="9" */ -#define GRPC_MDELEM_STATUS_204 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC, 9)) +#define GRPC_MDELEM_STATUS_204 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC, \ + 9)) /* ":status": "206" Index="10" */ -#define GRPC_MDELEM_STATUS_206 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC, 10)) +#define GRPC_MDELEM_STATUS_206 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC, \ + 10)) /* ":status": "304" Index="11" */ -#define GRPC_MDELEM_STATUS_304 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC, 11)) +#define GRPC_MDELEM_STATUS_304 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC, \ + 11)) /* ":status": "400" Index="12" */ -#define GRPC_MDELEM_STATUS_400 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC, 12)) +#define GRPC_MDELEM_STATUS_400 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC, \ + 12)) /* ":status": "500" Index="14" */ -#define GRPC_MDELEM_STATUS_500 (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC, 14)) +#define GRPC_MDELEM_STATUS_500 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC, \ + 14)) /* "accept-charset": "" Index="15" */ -#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC, 15)) +#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC, \ + 15)) /* "accept-encoding": "" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "accept-encoding": "gzip, deflate" Index="16" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC, 16)) +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC, \ + 16)) /* "accept-language": "" Index="17" */ -#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC, 17)) +#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC, \ + 17)) /* "accept-ranges": "" Index="18" */ -#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC, 18)) +#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC, \ + 18)) /* "accept": "" Index="19" */ -#define GRPC_MDELEM_ACCEPT_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC, 19)) +#define GRPC_MDELEM_ACCEPT_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC, \ + 19)) /* "access-control-allow-origin": "" Index="20" */ -#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC, 20)) +#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC, \ + 20)) /* "age": "" Index="21" */ -#define GRPC_MDELEM_AGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC, 21)) +#define GRPC_MDELEM_AGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC, \ + 21)) /* "allow": "" Index="22" */ -#define GRPC_MDELEM_ALLOW_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC, 22)) +#define GRPC_MDELEM_ALLOW_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC, \ + 22)) /* "authorization": "" Index="23" */ -#define GRPC_MDELEM_AUTHORIZATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC, 23)) +#define GRPC_MDELEM_AUTHORIZATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC, \ + 23)) /* "cache-control": "" Index="24" */ -#define GRPC_MDELEM_CACHE_CONTROL_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC, 24)) +#define GRPC_MDELEM_CACHE_CONTROL_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC, \ + 24)) /* "content-disposition": "" Index="25" */ -#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC, 25)) +#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC, \ + 25)) /* "content-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "content-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_CONTENT_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "content-encoding": "" Index="26" */ -#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC, 26)) +#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC, \ + 26)) /* "content-language": "" Index="27" */ -#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC, 27)) +#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC, \ + 27)) /* "content-length": "" Index="28" */ -#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC, 28)) +#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC, \ + 28)) /* "content-location": "" Index="29" */ -#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC, 29)) +#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC, \ + 29)) /* "content-range": "" Index="30" */ -#define GRPC_MDELEM_CONTENT_RANGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC, 30)) +#define GRPC_MDELEM_CONTENT_RANGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC, \ + 30)) /* "content-type": "" Index="31" */ -#define GRPC_MDELEM_CONTENT_TYPE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC, 31)) +#define GRPC_MDELEM_CONTENT_TYPE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC, \ + 31)) /* "cookie": "" Index="32" */ -#define GRPC_MDELEM_COOKIE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC, 32)) +#define GRPC_MDELEM_COOKIE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC, \ + 32)) /* "date": "" Index="33" */ -#define GRPC_MDELEM_DATE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC, 33)) +#define GRPC_MDELEM_DATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC, \ + 33)) /* "etag": "" Index="34" */ -#define GRPC_MDELEM_ETAG_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC, 34)) +#define GRPC_MDELEM_ETAG_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC, \ + 34)) /* "expect": "" Index="35" */ -#define GRPC_MDELEM_EXPECT_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC, 35)) +#define GRPC_MDELEM_EXPECT_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC, \ + 35)) /* "expires": "" Index="36" */ -#define GRPC_MDELEM_EXPIRES_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC, 36)) +#define GRPC_MDELEM_EXPIRES_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC, \ + 36)) /* "from": "" Index="37" */ -#define GRPC_MDELEM_FROM_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC, 37)) +#define GRPC_MDELEM_FROM_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC, \ + 37)) /* "host": "" Index="38" */ -#define GRPC_MDELEM_HOST_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC, 38)) +#define GRPC_MDELEM_HOST_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC, \ + 38)) /* "if-match": "" Index="39" */ -#define GRPC_MDELEM_IF_MATCH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC, 39)) +#define GRPC_MDELEM_IF_MATCH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC, \ + 39)) /* "if-modified-since": "" Index="40" */ -#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC, 40)) +#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC, \ + 40)) /* "if-none-match": "" Index="41" */ -#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC, 41)) +#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC, \ + 41)) /* "if-range": "" Index="42" */ -#define GRPC_MDELEM_IF_RANGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC, 42)) +#define GRPC_MDELEM_IF_RANGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC, \ + 42)) /* "if-unmodified-since": "" Index="43" */ -#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC, 43)) +#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC, \ + 43)) /* "last-modified": "" Index="44" */ -#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC, 44)) +#define GRPC_MDELEM_LAST_MODIFIED_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC, \ + 44)) /* "lb-token": "" Index="0" */ -#define GRPC_MDELEM_LB_TOKEN_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_LB_TOKEN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "lb-cost-bin": "" Index="0" */ -#define GRPC_MDELEM_LB_COST_BIN_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_LB_COST_BIN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "link": "" Index="45" */ -#define GRPC_MDELEM_LINK_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC, 45)) +#define GRPC_MDELEM_LINK_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC, \ + 45)) /* "location": "" Index="46" */ -#define GRPC_MDELEM_LOCATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC, 46)) +#define GRPC_MDELEM_LOCATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC, \ + 46)) /* "max-forwards": "" Index="47" */ -#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC, 47)) +#define GRPC_MDELEM_MAX_FORWARDS_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC, \ + 47)) /* "proxy-authenticate": "" Index="48" */ -#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC, 48)) +#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC, \ + 48)) /* "proxy-authorization": "" Index="49" */ -#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC, 49)) +#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC, \ + 49)) /* "range": "" Index="50" */ -#define GRPC_MDELEM_RANGE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC, 50)) +#define GRPC_MDELEM_RANGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC, \ + 50)) /* "referer": "" Index="51" */ -#define GRPC_MDELEM_REFERER_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC, 51)) +#define GRPC_MDELEM_REFERER_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC, \ + 51)) /* "refresh": "" Index="52" */ -#define GRPC_MDELEM_REFRESH_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC, 52)) +#define GRPC_MDELEM_REFRESH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC, \ + 52)) /* "retry-after": "" Index="53" */ -#define GRPC_MDELEM_RETRY_AFTER_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC, 53)) +#define GRPC_MDELEM_RETRY_AFTER_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC, \ + 53)) /* "server": "" Index="54" */ -#define GRPC_MDELEM_SERVER_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC, 54)) +#define GRPC_MDELEM_SERVER_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC, \ + 54)) /* "set-cookie": "" Index="55" */ -#define GRPC_MDELEM_SET_COOKIE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC, 55)) +#define GRPC_MDELEM_SET_COOKIE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC, \ + 55)) /* "strict-transport-security": "" Index="56" */ -#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC, 56)) +#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC, \ + 56)) /* "transfer-encoding": "" Index="57" */ -#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC, 57)) +#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC, \ + 57)) /* "user-agent": "" Index="58" */ -#define GRPC_MDELEM_USER_AGENT_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC, 58)) +#define GRPC_MDELEM_USER_AGENT_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC, \ + 58)) /* "vary": "" Index="59" */ -#define GRPC_MDELEM_VARY_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC, 59)) +#define GRPC_MDELEM_VARY_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC, \ + 59)) /* "via": "" Index="60" */ -#define GRPC_MDELEM_VIA_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC, 60)) +#define GRPC_MDELEM_VIA_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC, \ + 60)) /* "www-authenticate": "" Index="61" */ -#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC, 61)) +#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC, \ + 61)) /* "grpc-accept-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-accept-encoding": "deflate" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-accept-encoding": "identity,deflate" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-accept-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-accept-encoding": "identity,gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-accept-encoding": "deflate,gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "grpc-accept-encoding": "identity,deflate,gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "accept-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "accept-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) /* "accept-encoding": "identity,gzip" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC, \ + 0)) grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b); typedef enum { @@ -458,43 +637,53 @@ typedef enum { } grpc_metadata_batch_callouts_index; typedef union { - struct grpc_linked_mdelem *array[GRPC_BATCH_CALLOUTS_COUNT]; + struct grpc_linked_mdelem* array[GRPC_BATCH_CALLOUTS_COUNT]; struct { - struct grpc_linked_mdelem *path; - struct grpc_linked_mdelem *method; - struct grpc_linked_mdelem *status; - struct grpc_linked_mdelem *authority; - struct grpc_linked_mdelem *scheme; - struct grpc_linked_mdelem *te; - struct grpc_linked_mdelem *grpc_message; - struct grpc_linked_mdelem *grpc_status; - struct grpc_linked_mdelem *grpc_payload_bin; - struct grpc_linked_mdelem *grpc_encoding; - struct grpc_linked_mdelem *grpc_accept_encoding; - struct grpc_linked_mdelem *grpc_server_stats_bin; - struct grpc_linked_mdelem *grpc_tags_bin; - struct grpc_linked_mdelem *grpc_trace_bin; - struct grpc_linked_mdelem *content_type; - struct grpc_linked_mdelem *content_encoding; - struct grpc_linked_mdelem *accept_encoding; - struct grpc_linked_mdelem *grpc_internal_encoding_request; - struct grpc_linked_mdelem *grpc_internal_stream_encoding_request; - 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; + struct grpc_linked_mdelem* path; + struct grpc_linked_mdelem* method; + struct grpc_linked_mdelem* status; + struct grpc_linked_mdelem* authority; + struct grpc_linked_mdelem* scheme; + struct grpc_linked_mdelem* te; + struct grpc_linked_mdelem* grpc_message; + struct grpc_linked_mdelem* grpc_status; + struct grpc_linked_mdelem* grpc_payload_bin; + struct grpc_linked_mdelem* grpc_encoding; + struct grpc_linked_mdelem* grpc_accept_encoding; + struct grpc_linked_mdelem* grpc_server_stats_bin; + struct grpc_linked_mdelem* grpc_tags_bin; + struct grpc_linked_mdelem* grpc_trace_bin; + struct grpc_linked_mdelem* content_type; + struct grpc_linked_mdelem* content_encoding; + struct grpc_linked_mdelem* accept_encoding; + struct grpc_linked_mdelem* grpc_internal_encoding_request; + struct grpc_linked_mdelem* grpc_internal_stream_encoding_request; + 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; -#define GRPC_BATCH_INDEX_OF(slice) \ - (GRPC_IS_STATIC_METADATA_STRING((slice)) ? (grpc_metadata_batch_callouts_index)GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, GRPC_BATCH_CALLOUTS_COUNT) : GRPC_BATCH_CALLOUTS_COUNT) +#define GRPC_BATCH_INDEX_OF(slice) \ + (GRPC_IS_STATIC_METADATA_STRING((slice)) \ + ? (grpc_metadata_batch_callouts_index)GPR_CLAMP( \ + GRPC_STATIC_METADATA_INDEX((slice)), 0, \ + GRPC_BATCH_CALLOUTS_COUNT) \ + : GRPC_BATCH_CALLOUTS_COUNT) extern bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT]; extern const uint8_t grpc_static_accept_encoding_metadata[8]; -#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \ + (GRPC_MAKE_MDELEM( \ + &grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], \ + GRPC_MDELEM_STORAGE_STATIC, 0)) extern const uint8_t grpc_static_accept_stream_encoding_metadata[4]; -#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_stream_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC, 0)) +#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table \ + [grpc_static_accept_stream_encoding_metadata[(algs)]], \ + GRPC_MDELEM_STORAGE_STATIC, 0)) #endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */ From 20778b0c468db746088793da13699dd22c8993e0 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 11 Sep 2018 09:14:57 -0700 Subject: [PATCH 348/546] Address reviewer comments --- include/grpcpp/channel.h | 8 ++++++- include/grpcpp/impl/codegen/call.h | 8 ++++++- include/grpcpp/impl/codegen/callback_common.h | 22 ++++++++++++++++-- .../impl/codegen/completion_queue_tag.h | 23 +++++++++++++++---- src/cpp/common/callback_common.cc | 14 +++++++++++ 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h index 58a6f516648..f1dba5b8ad1 100644 --- a/include/grpcpp/channel.h +++ b/include/grpcpp/channel.h @@ -83,8 +83,14 @@ class Channel final : public ChannelInterface, const grpc::string host_; grpc_channel* const c_channel_; // owned - CompletionQueue* callback_cq_ = nullptr; + // mu_ protects callback_cq_ (the per-channel callbackable completion queue) std::mutex mu_; + + // callback_cq_ references the callbackable completion queue associated + // with this channel (if any). It is set on the first call to CallbackCQ(). + // It is _not owned_ by the channel; ownership belongs with its internal + // shutdown callback tag (invoked when the CQ is fully shutdown). + CompletionQueue* callback_cq_ = nullptr; }; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/call.h b/include/grpcpp/impl/codegen/call.h index 7bd03b6b1bd..9e4163ec95c 100644 --- a/include/grpcpp/impl/codegen/call.h +++ b/include/grpcpp/impl/codegen/call.h @@ -609,7 +609,9 @@ class CallOpSetInterface : public CompletionQueueTag { /// upwards. virtual void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) = 0; - /// Get the tag to be used at the CQ + /// Get the tag to be used at the core completion queue. Generally, the + /// value of cq_tag will be "this". However, it can be overridden if we + /// want core to process the tag differently (e.g., as a core callback) virtual void* cq_tag() = 0; }; @@ -659,6 +661,10 @@ class CallOpSet : public CallOpSetInterface, void* cq_tag() override { return cq_tag_; } + /// set_cq_tag is used to provide a different core CQ tag than "this". + /// This is used for callback-based tags, where the core tag is the core + /// callback function. It does not change the use or behavior of any other + /// function (such as FinalizeResult) void set_cq_tag(void* cq_tag) { cq_tag_ = cq_tag; } private: diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index 3481460c767..68c318d2b44 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -42,6 +42,13 @@ class CallbackWithStatusTag { assert(size == sizeof(CallbackWithStatusTag)); } + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + CallbackWithStatusTag(grpc_call* call, std::function f, CompletionQueueTag* ops); ~CallbackWithStatusTag() {} @@ -49,7 +56,9 @@ class CallbackWithStatusTag { Status* status_ptr() { return status_; } CompletionQueueTag* ops() { return ops_; } - // force_run can only be performed on a tag before it can ever be active + // force_run can not be performed on a tag if operations using this tag + // have been sent to PerformOpsOnCall. It is intended for error conditions + // that are detected before the operations are internally processed. void force_run(Status s); private: @@ -65,13 +74,22 @@ class CallbackWithSuccessTag { assert(size == sizeof(CallbackWithSuccessTag)); } + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + CallbackWithSuccessTag(grpc_call* call, std::function f, CompletionQueueTag* ops); void* tag() { return static_cast(impl_); } CompletionQueueTag* ops() { return ops_; } - // force_run can only be performed on a tag before it can ever be active + // force_run can not be performed on a tag if operations using this tag + // have been sent to PerformOpsOnCall. It is intended for error conditions + // that are detected before the operations are internally processed. void force_run(bool ok); private: diff --git a/include/grpcpp/impl/codegen/completion_queue_tag.h b/include/grpcpp/impl/codegen/completion_queue_tag.h index ffb642c56b5..304386a9ecc 100644 --- a/include/grpcpp/impl/codegen/completion_queue_tag.h +++ b/include/grpcpp/impl/codegen/completion_queue_tag.h @@ -26,10 +26,25 @@ namespace internal { class CompletionQueueTag { public: virtual ~CompletionQueueTag() {} - /// Called prior to returning from Next(), return value is the status of the - /// operation (return status is the default thing to do). If this function - /// returns false, the tag is dropped and not returned from the completion - /// queue + + /// FinalizeResult must be called before informing user code that the + /// operation bound to the underlying core completion queue tag has + /// completed. In practice, this means: + /// + /// 1. For the sync API - before returning from Pluck + /// 2. For the CQ-based async API - before returning from Next + /// 3. For the callback-based API - before invoking the user callback + /// + /// This is the method that translates from core-side tag/status to + /// C++ API-observable tag/status. + /// + /// The return value is the status of the operation (returning status is the + /// general behavior of this function). If this function returns false, the + /// tag is dropped and not returned from the completion queue: this concept is + /// for events that are observed at core but not requested by the user + /// application (e.g., server shutdown, for server unimplemented method + /// responses, or for cases where a server-side RPC doesn't have a completion + /// notification registered using AsyncNotifyWhenDone) virtual bool FinalizeResult(void** tag, bool* status) = 0; }; } // namespace internal diff --git a/src/cpp/common/callback_common.cc b/src/cpp/common/callback_common.cc index 68df1166ba9..ae47901f1be 100644 --- a/src/cpp/common/callback_common.cc +++ b/src/cpp/common/callback_common.cc @@ -34,6 +34,13 @@ class CallbackWithSuccessImpl : public grpc_core::CQCallbackInterface { assert(size == sizeof(CallbackWithSuccessImpl)); } + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + CallbackWithSuccessImpl(grpc_call* call, CallbackWithSuccessTag* parent, std::function f) : call_(call), parent_(parent), func_(std::move(f)) { @@ -62,6 +69,13 @@ class CallbackWithStatusImpl : public grpc_core::CQCallbackInterface { assert(size == sizeof(CallbackWithStatusImpl)); } + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + CallbackWithStatusImpl(grpc_call* call, CallbackWithStatusTag* parent, std::function f) : call_(call), parent_(parent), func_(std::move(f)), status_() { From b9a174ab1507306fed5fa4ee70416e2489ef8fcb Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 11 Sep 2018 12:42:01 -0700 Subject: [PATCH 349/546] Add check on server for channelz accessor --- src/core/lib/surface/server.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index c0fae0f140d..5fa58ffdec2 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -1500,5 +1500,8 @@ int grpc_server_has_open_connections(grpc_server* server) { grpc_core::channelz::ServerNode* grpc_server_get_channelz_node( grpc_server* server) { + if (server == nullptr) { + return nullptr; + } return server->channelz_server.get(); } From 964d679edc32b0f7316cacdb0652477d607f6de5 Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Tue, 21 Aug 2018 08:00:49 -0700 Subject: [PATCH 350/546] Resolve ip literals and Windows localhost manually when using c-ares --- CMakeLists.txt | 38 ++++++- Makefile | 58 ++++++++--- build.yaml | 16 ++- .../filters/client_channel/parse_address.cc | 9 ++ .../filters/client_channel/parse_address.h | 3 + .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 99 +++++++++++++++---- .../resolver/dns/c_ares/grpc_ares_wrapper.h | 12 ++- .../dns/c_ares/grpc_ares_wrapper_posix.cc | 5 + .../dns/c_ares/grpc_ares_wrapper_windows.cc | 70 +++++++++++++ test/core/iomgr/BUILD | 20 +++- test/core/iomgr/resolve_address_test.cc | 40 +++++++- test/cpp/naming/address_sorting_test.cc | 52 +++++----- .../generated/sources_and_headers.json | 19 +++- tools/run_tests/generated/tests.json | 32 +++++- 14 files changed, 403 insertions(+), 70 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a21bb8b5fae..4cbc7597ab1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -361,7 +361,8 @@ endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c resolve_address_posix_test) endif() -add_dependencies(buildtests_c resolve_address_test) +add_dependencies(buildtests_c resolve_address_using_ares_resolver_test) +add_dependencies(buildtests_c resolve_address_using_native_resolver_test) add_dependencies(buildtests_c resource_quota_test) add_dependencies(buildtests_c secure_channel_create_test) add_dependencies(buildtests_c secure_endpoint_test) @@ -8553,12 +8554,12 @@ endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) -add_executable(resolve_address_test +add_executable(resolve_address_using_ares_resolver_test test/core/iomgr/resolve_address_test.cc ) -target_include_directories(resolve_address_test +target_include_directories(resolve_address_using_ares_resolver_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${_gRPC_SSL_INCLUDE_DIR} @@ -8571,7 +8572,36 @@ target_include_directories(resolve_address_test PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) -target_link_libraries(resolve_address_test +target_link_libraries(resolve_address_using_ares_resolver_test + ${_gRPC_ALLTARGETS_LIBRARIES} + grpc_test_util + grpc + gpr_test_util + gpr +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(resolve_address_using_native_resolver_test + test/core/iomgr/resolve_address_test.cc +) + + +target_include_directories(resolve_address_using_native_resolver_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 ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} +) + +target_link_libraries(resolve_address_using_native_resolver_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc diff --git a/Makefile b/Makefile index 96ea890bcb8..85de7b67c5e 100644 --- a/Makefile +++ b/Makefile @@ -1081,7 +1081,8 @@ percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer percent_encoding_test: $(BINDIR)/$(CONFIG)/percent_encoding_test pollset_set_test: $(BINDIR)/$(CONFIG)/pollset_set_test resolve_address_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_posix_test -resolve_address_test: $(BINDIR)/$(CONFIG)/resolve_address_test +resolve_address_using_ares_resolver_test: $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test +resolve_address_using_native_resolver_test: $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test resource_quota_test: $(BINDIR)/$(CONFIG)/resource_quota_test secure_channel_create_test: $(BINDIR)/$(CONFIG)/secure_channel_create_test secure_endpoint_test: $(BINDIR)/$(CONFIG)/secure_endpoint_test @@ -1524,7 +1525,8 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/percent_encoding_test \ $(BINDIR)/$(CONFIG)/pollset_set_test \ $(BINDIR)/$(CONFIG)/resolve_address_posix_test \ - $(BINDIR)/$(CONFIG)/resolve_address_test \ + $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test \ + $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test \ $(BINDIR)/$(CONFIG)/resource_quota_test \ $(BINDIR)/$(CONFIG)/secure_channel_create_test \ $(BINDIR)/$(CONFIG)/secure_endpoint_test \ @@ -2118,8 +2120,10 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/pollset_set_test || ( echo test pollset_set_test failed ; exit 1 ) $(E) "[RUN] Testing resolve_address_posix_test" $(Q) $(BINDIR)/$(CONFIG)/resolve_address_posix_test || ( echo test resolve_address_posix_test failed ; exit 1 ) - $(E) "[RUN] Testing resolve_address_test" - $(Q) $(BINDIR)/$(CONFIG)/resolve_address_test || ( echo test resolve_address_test failed ; exit 1 ) + $(E) "[RUN] Testing resolve_address_using_ares_resolver_test" + $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test || ( echo test resolve_address_using_ares_resolver_test failed ; exit 1 ) + $(E) "[RUN] Testing resolve_address_using_native_resolver_test" + $(Q) $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test || ( echo test resolve_address_using_native_resolver_test failed ; exit 1 ) $(E) "[RUN] Testing resource_quota_test" $(Q) $(BINDIR)/$(CONFIG)/resource_quota_test || ( echo test resource_quota_test failed ; exit 1 ) $(E) "[RUN] Testing secure_channel_create_test" @@ -14031,34 +14035,66 @@ endif endif -RESOLVE_ADDRESS_TEST_SRC = \ +RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_SRC = \ test/core/iomgr/resolve_address_test.cc \ -RESOLVE_ADDRESS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RESOLVE_ADDRESS_TEST_SRC)))) +RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/resolve_address_test: openssl_dep_error +$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/resolve_address_test: $(RESOLVE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_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) $(RESOLVE_ADDRESS_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)/resolve_address_test + $(Q) $(LD) $(LDFLAGS) $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_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)/resolve_address_using_ares_resolver_test endif $(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_resolve_address_test: $(RESOLVE_ADDRESS_TEST_OBJS:.o=.dep) +deps_resolve_address_using_ares_resolver_test: $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(RESOLVE_ADDRESS_TEST_OBJS:.o=.dep) +-include $(RESOLVE_ADDRESS_USING_ARES_RESOLVER_TEST_OBJS:.o=.dep) +endif +endif + + +RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_SRC = \ + test/core/iomgr/resolve_address_test.cc \ + +RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_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) $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_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)/resolve_address_using_native_resolver_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/iomgr/resolve_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_resolve_address_using_native_resolver_test: $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(RESOLVE_ADDRESS_USING_NATIVE_RESOLVER_TEST_OBJS:.o=.dep) endif endif diff --git a/build.yaml b/build.yaml index a50a0a4ab65..b354826128d 100644 --- a/build.yaml +++ b/build.yaml @@ -3363,7 +3363,7 @@ targets: - mac - linux - posix -- name: resolve_address_test +- name: resolve_address_using_ares_resolver_test build: test language: c src: @@ -3373,6 +3373,20 @@ targets: - grpc - gpr_test_util - gpr + args: + - --resolver=ares +- name: resolve_address_using_native_resolver_test + build: test + language: c + src: + - test/core/iomgr/resolve_address_test.cc + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr + args: + - --resolver=native - name: resource_quota_test cpu_cost: 30 build: test diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc index 7e726dd5624..b94429e207e 100644 --- a/src/core/ext/filters/client_channel/parse_address.cc +++ b/src/core/ext/filters/client_channel/parse_address.cc @@ -197,3 +197,12 @@ bool grpc_parse_uri(const grpc_uri* uri, grpc_resolved_address* resolved_addr) { gpr_log(GPR_ERROR, "Can't parse scheme '%s'", uri->scheme); return false; } + +uint16_t grpc_strhtons(const char* port) { + if (strcmp(port, "http") == 0) { + return htons(80); + } else if (strcmp(port, "https") == 0) { + return htons(443); + } + return htons(static_cast(atoi(port))); +} diff --git a/src/core/ext/filters/client_channel/parse_address.h b/src/core/ext/filters/client_channel/parse_address.h index 9a88b66edcf..c2af0e6c498 100644 --- a/src/core/ext/filters/client_channel/parse_address.h +++ b/src/core/ext/filters/client_channel/parse_address.h @@ -47,4 +47,7 @@ bool grpc_parse_ipv4_hostport(const char* hostport, grpc_resolved_address* addr, bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, bool log_errors); +/* Converts named or numeric port to a uint16 suitable for use in a sockaddr. */ +uint16_t grpc_strhtons(const char* port); + #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PARSE_ADDRESS_H */ 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 485998f5e44..4c795c34c8e 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 @@ -87,15 +87,6 @@ typedef struct grpc_ares_hostbyname_request { static void do_basic_init(void) { gpr_mu_init(&g_init_mu); } -static uint16_t strhtons(const char* port) { - if (strcmp(port, "http") == 0) { - return htons(80); - } else if (strcmp(port, "https") == 0) { - return htons(443); - } - return htons(static_cast(atoi(port))); -} - static void log_address_sorting_list(grpc_lb_addresses* lb_addrs, const char* input_output_str) { for (size_t i = 0; i < lb_addrs->num_addresses; i++) { @@ -139,12 +130,6 @@ void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs) { } } -/* Allow tests to access grpc_ares_wrapper_address_sorting_sort */ -void grpc_cares_wrapper_test_only_address_sorting_sort( - grpc_lb_addresses* lb_addrs) { - grpc_cares_wrapper_address_sorting_sort(lb_addrs); -} - static void grpc_ares_request_ref_locked(grpc_ares_request* r) { r->pending_queries++; } @@ -371,7 +356,8 @@ done: grpc_ares_request_unref_locked(r); } -static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( +static grpc_ares_request* +grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, @@ -454,12 +440,12 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( } r->pending_queries = 1; if (grpc_ares_query_ipv6()) { - hr = create_hostbyname_request_locked(r, host, strhtons(port), + hr = create_hostbyname_request_locked(r, host, grpc_strhtons(port), false /* is_balancer */); ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_locked, hr); } - hr = create_hostbyname_request_locked(r, host, strhtons(port), + hr = create_hostbyname_request_locked(r, host, grpc_strhtons(port), false /* is_balancer */); ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_locked, hr); @@ -494,6 +480,79 @@ error_cleanup: return nullptr; } +static bool inner_resolve_as_ip_literal_locked(const char* name, + const char* default_port, + grpc_lb_addresses** addrs, + char** host, char** port, + char** hostport) { + gpr_split_host_port(name, host, port); + if (*host == nullptr) { + gpr_log(GPR_ERROR, + "Failed to parse %s to host:port while attempting to resolve as ip " + "literal.", + name); + return false; + } + if (*port == nullptr) { + if (default_port == nullptr) { + gpr_log(GPR_ERROR, + "No port or default port for %s while attempting to resolve as " + "ip literal.", + name); + return false; + } + *port = gpr_strdup(default_port); + } + grpc_resolved_address addr; + GPR_ASSERT(gpr_join_host_port(hostport, *host, atoi(*port))); + if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) || + grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) { + GPR_ASSERT(*addrs == nullptr); + *addrs = grpc_lb_addresses_create(1, nullptr); + grpc_lb_addresses_set_address( + *addrs, 0, addr.addr, addr.len, false /* is_balancer */, + nullptr /* balancer_name */, nullptr /* user_data */); + return true; + } + return false; +} + +static bool resolve_as_ip_literal_locked(const char* name, + const char* default_port, + grpc_lb_addresses** addrs) { + char* host = nullptr; + char* port = nullptr; + char* hostport = nullptr; + bool out = inner_resolve_as_ip_literal_locked(name, default_port, addrs, + &host, &port, &hostport); + gpr_free(host); + gpr_free(port); + gpr_free(hostport); + return out; +} + +static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( + const char* dns_server, const char* name, const char* default_port, + grpc_pollset_set* interested_parties, grpc_closure* on_done, + grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, + grpc_combiner* combiner) { + // Early out if the target is an ipv4 or ipv6 literal. + if (resolve_as_ip_literal_locked(name, default_port, addrs)) { + GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + return nullptr; + } + // Early out if the target is localhost and we're on Windows. + if (grpc_ares_maybe_resolve_localhost_manually_locked(name, default_port, + addrs)) { + GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); + return nullptr; + } + // Look up name using c-ares lib. + return grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( + dns_server, name, default_port, interested_parties, on_done, addrs, + check_grpclb, service_config_json, combiner); +} + grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, @@ -502,7 +561,9 @@ grpc_ares_request* (*grpc_dns_lookup_ares_locked)( void grpc_cancel_ares_request(grpc_ares_request* r) { if (grpc_dns_lookup_ares_locked == grpc_dns_lookup_ares_locked_impl) { - grpc_ares_ev_driver_shutdown_locked(r->ev_driver); + if (r != nullptr) { + grpc_ares_ev_driver_shutdown_locked(r->ev_driver); + } } } 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 ca5779e1d79..1bc457d4cfe 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 @@ -81,9 +81,15 @@ void grpc_ares_complete_request_locked(grpc_ares_request* request); /* E.g., return false if ipv6 is known to not be available. */ bool grpc_ares_query_ipv6(); -/* Exposed only for testing */ -void grpc_cares_wrapper_test_only_address_sorting_sort( - grpc_lb_addresses* lb_addrs); +/* Maybe (depending on the current platform) checks if "name" matches + * "localhost" and if so fills in addrs with the correct sockaddr structures. + * Returns a bool indicating whether or not such an action was performed. + * See https://github.com/grpc/grpc/issues/15158. */ +bool grpc_ares_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, grpc_lb_addresses** addrs); + +/* Sorts destinations in lb_addrs according to RFC 6724. */ +void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs); #endif /* GRPC_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_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc index 23c0fec74f3..639eec2323f 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc @@ -26,4 +26,9 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } +bool grpc_ares_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, grpc_lb_addresses** addrs) { + return false; +} + #endif /* GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER) */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index ee827e284e2..7e34784691f 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -21,9 +21,79 @@ #include "src/core/lib/iomgr/port.h" #if GRPC_ARES == 1 && defined(GPR_WINDOWS) +#include + +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" +#include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/socket_windows.h" bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } +static bool inner_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, grpc_lb_addresses** addrs, + char** host, char** port) { + gpr_split_host_port(name, host, port); + if (*host == nullptr) { + gpr_log(GPR_ERROR, + "Failed to parse %s into host:port during Windows localhost " + "resolution check.", + name); + return false; + } + if (*port == nullptr) { + if (default_port == nullptr) { + gpr_log(GPR_ERROR, + "No port or default port for %s during Windows localhost " + "resolution check.", + name); + return false; + } + *port = gpr_strdup(default_port); + } + if (gpr_stricmp(*host, "localhost") == 0) { + GPR_ASSERT(*addrs == nullptr); + *addrs = grpc_lb_addresses_create(2, nullptr); + uint16_t numeric_port = grpc_strhtons(*port); + // Append the ipv6 loopback address. + struct sockaddr_in6 ipv6_loopback_addr; + memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); + ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; + ipv6_loopback_addr.sin6_family = AF_INET6; + ipv6_loopback_addr.sin6_port = numeric_port; + grpc_lb_addresses_set_address( + *addrs, 0, &ipv6_loopback_addr, sizeof(ipv6_loopback_addr), + false /* is_balancer */, nullptr /* balancer_name */, + nullptr /* user_data */); + // Append the ipv4 loopback address. + struct sockaddr_in ipv4_loopback_addr; + memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); + ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; + ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; + ipv4_loopback_addr.sin_family = AF_INET; + ipv4_loopback_addr.sin_port = numeric_port; + grpc_lb_addresses_set_address( + *addrs, 1, &ipv4_loopback_addr, sizeof(ipv4_loopback_addr), + false /* is_balancer */, nullptr /* balancer_name */, + nullptr /* user_data */); + // Let the address sorter figure out which one should be tried first. + grpc_cares_wrapper_address_sorting_sort(*addrs); + return true; + } + return false; +} + +bool grpc_ares_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, grpc_lb_addresses** addrs) { + char* host = nullptr; + char* port = nullptr; + bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, + addrs, &host, &port); + gpr_free(host); + gpr_free(port); + return out; +} + #endif /* GRPC_ARES == 1 && defined(GPR_WINDOWS) */ diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 675d9e6278c..7754bc49708 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -174,9 +174,27 @@ grpc_cc_test( ) grpc_cc_test( - name = "resolve_address_test", + name = "resolve_address_using_ares_resolver_test", srcs = ["resolve_address_test.cc"], language = "C++", + args = [ + "--resolver=ares", + ], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "resolve_address_using_native_resolver_test", + srcs = ["resolve_address_test.cc"], + language = "C++", + args = [ + "--resolver=native", + ], deps = [ "//:gpr", "//:grpc", diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index 2fb831a6a46..52e4840c7c6 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -22,8 +22,14 @@ #include #include #include + +#include + +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/executor.h" #include "src/core/lib/iomgr/iomgr.h" +#include "test/core/util/cmdline.h" #include "test/core/util/test_config.h" static gpr_timespec test_deadline(void) { @@ -240,6 +246,28 @@ static void test_unparseable_hostports(void) { } int main(int argc, char** argv) { + // First set the resolver type based off of --resolver + const char* resolver_type = nullptr; + gpr_cmdline* cl = gpr_cmdline_create("resolve address test"); + gpr_cmdline_add_string(cl, "resolver", "Resolver type (ares or native)", + &resolver_type); + gpr_cmdline_parse(cl, argc, argv); + const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER"); + if (cur_resolver != nullptr && strlen(cur_resolver) != 0) { + gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s", + cur_resolver); + } + if (gpr_stricmp(resolver_type, "native") == 0) { + gpr_setenv("GRPC_DNS_RESOLVER", "native"); + } else if (gpr_stricmp(resolver_type, "ares") == 0) { +#ifndef GRPC_UV + gpr_setenv("GRPC_DNS_RESOLVER", "ares"); +#endif + } else { + gpr_log(GPR_ERROR, "--resolver_type was not set to ares or native"); + abort(); + } + // Run the test. grpc_test_init(argc, argv); grpc_init(); { @@ -250,10 +278,18 @@ int main(int argc, char** argv) { test_missing_default_port(); test_ipv6_with_port(); test_ipv6_without_port(); - test_invalid_ip_addresses(); - test_unparseable_hostports(); + if (gpr_stricmp(resolver_type, "ares") != 0) { + // These tests can trigger DNS queries to the nearby nameserver + // that need to come back in order for the test to succeed. + // c-ares is prone to not using the local system caches that the + // native getaddrinfo implementations take advantage of, so running + // these unit tests under c-ares risks flakiness. + test_invalid_ip_addresses(); + test_unparseable_hostports(); + } grpc_executor_shutdown(); } + gpr_cmdline_destroy(cl); grpc_shutdown(); return 0; diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc index 04c300876cc..fc6721d0ba8 100644 --- a/test/cpp/naming/address_sorting_test.cc +++ b/test/cpp/naming/address_sorting_test.cc @@ -216,7 +216,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) { {"1.2.3.4:443", AF_INET}, {"5.6.7.8:443", AF_INET}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "1.2.3.4:443", "5.6.7.8:443", @@ -235,7 +235,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) { {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "1.2.3.4:443", "[2607:f8b0:400a:801::1002]:443", @@ -255,7 +255,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) { {"[2607:f8b0:400a:801::1002]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2607:f8b0:400a:801::1002]:443", "1.2.3.4:443", @@ -279,7 +279,7 @@ TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) { {"[2000:f8b0:400a:801::1002]:443", AF_INET6}, {"[fec0::5000]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fec0::5000]:443", "[2000:f8b0:400a:801::1002]:443", @@ -302,7 +302,7 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) { {"[2002::5001]:443", AF_INET6}, {"[2001::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2001::5001]:443", "[2002::5001]:443", @@ -325,7 +325,7 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) { {"[2001::5001]:443", AF_INET6}, {"[2002::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2001::5001]:443", "[2002::5001]:443", @@ -348,7 +348,7 @@ TEST_F(AddressSortingTest, {"[3ffe::5001]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs( lb_addrs, { // The AF_INET address should be IPv4-mapped by the sort, @@ -381,7 +381,7 @@ TEST_F(AddressSortingTest, {v4_compat_dest, AF_INET6}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", v4_compat_dest, @@ -404,7 +404,7 @@ TEST_F(AddressSortingTest, {"[1234::2]:443", AF_INET6}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs( lb_addrs, { @@ -428,7 +428,7 @@ TEST_F(AddressSortingTest, {"[2001::1234]:443", AF_INET6}, {"[2000::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs( lb_addrs, { // The 2000::/16 address should match the ::/0 prefix rule @@ -452,7 +452,7 @@ TEST_F( {"[2001::1231]:443", AF_INET6}, {"[2000::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[2000::5001]:443", "[2001::1231]:443", @@ -473,7 +473,7 @@ TEST_F(AddressSortingTest, {"[fec0::1234]:443", AF_INET6}, {"[fc00::5001]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fc00::5001]:443", "[fec0::1234]:443", @@ -498,7 +498,7 @@ TEST_F( {"[::ffff:1.1.1.2]:443", AF_INET6}, {"[1234::2]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { // ::ffff:0:2 should match the v4-mapped // precedence entry and be deprioritized. @@ -525,7 +525,7 @@ TEST_F(AddressSortingTest, TestPrefersSmallerScope) { {"[3ffe::5001]:443", AF_INET6}, {"[fec0::1234]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[fec0::1234]:443", "[3ffe::5001]:443", @@ -550,7 +550,7 @@ TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) { {"[3ffe:5001::]:443", AF_INET6}, {"[3ffe:1234::]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:1234::]:443", "[3ffe:5001::]:443", @@ -571,7 +571,7 @@ TEST_F(AddressSortingTest, {"[3ffe::5001]:443", AF_INET6}, {"[3ffe::1234]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1234]:443", "[3ffe::5001]:443", @@ -591,7 +591,7 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) { {"[3ffe:8000::]:443", AF_INET6}, {"[3ffe:2000::]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:2000::]:443", "[3ffe:8000::]:443", @@ -611,7 +611,7 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) { {"[3ffe:6::]:443", AF_INET6}, {"[3ffe:c::]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:c::]:443", "[3ffe:6::]:443", @@ -633,7 +633,7 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) { {"[3ffe:1111:1111:1110::]:443", AF_INET6}, {"[3ffe:1111:1111:1111::]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe:1111:1111:1111::]:443", "[3ffe:1111:1111:1110::]:443", @@ -655,7 +655,7 @@ TEST_F(AddressSortingTest, TestStableSort) { {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1234]:443", "[3ffe::1235]:443", @@ -681,7 +681,7 @@ TEST_F(AddressSortingTest, TestStableSortFiveElements) { {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1231]:443", "[3ffe::1232]:443", @@ -702,7 +702,7 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) { {"[3ffe::1234]:443", AF_INET6}, {"[3ffe::1235]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[3ffe::1231]:443", "[3ffe::1232]:443", @@ -720,7 +720,7 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) { {"[::ffff:5.6.7.8]:443", AF_INET6}, {"1.2.3.4:443", AF_INET}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::ffff:5.6.7.8]:443", "1.2.3.4:443", @@ -748,7 +748,7 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) { {"[fec0::2000]:443", AF_INET6}, {v4_compat_dest, AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { // The sort should be stable since @@ -769,7 +769,7 @@ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) { {"[::1]:443", AF_INET6}, {"127.0.0.1:443", AF_INET}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", "127.0.0.1:443", @@ -783,7 +783,7 @@ TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) { {"127.0.0.1:443", AF_INET}, {"[::1]:443", AF_INET6}, }); - grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs); + grpc_cares_wrapper_address_sorting_sort(lb_addrs); VerifyLbAddrOutputs(lb_addrs, { "[::1]:443", "127.0.0.1:443", diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8ea5126fdef..5d6113bc18f 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -1897,7 +1897,24 @@ "headers": [], "is_filegroup": false, "language": "c", - "name": "resolve_address_test", + "name": "resolve_address_using_ares_resolver_test", + "src": [ + "test/core/iomgr/resolve_address_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "resolve_address_using_native_resolver_test", "src": [ "test/core/iomgr/resolve_address_test.cc" ], diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index fba76d69d1e..0ecc8a120a3 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -2146,7 +2146,35 @@ "uses_polling": true }, { - "args": [], + "args": [ + "--resolver=ares" + ], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "resolve_address_using_ares_resolver_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, + { + "args": [ + "--resolver=native" + ], "benchmark": false, "ci_platforms": [ "linux", @@ -2160,7 +2188,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "resolve_address_test", + "name": "resolve_address_using_native_resolver_test", "platforms": [ "linux", "mac", From 157e7fa03e600a4156a2913f8f645c5af4270408 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 11 Sep 2018 14:33:40 -0700 Subject: [PATCH 351/546] fix clang tidy --- include/grpc/grpc.h | 2 +- src/core/lib/channel/channel_trace.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index ce421e93bd8..3ef95ff4626 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -500,7 +500,7 @@ GRPCAPI const grpc_arg_pointer_vtable* grpc_resource_quota_arg_vtable(void); GRPCAPI char* grpc_channelz_get_top_channels(intptr_t start_channel_id); /* Gets all servers that exist in the process. */ -GRPCAPI char* grpc_channelz_get_servers(intptr_t start_channel_id); +GRPCAPI char* grpc_channelz_get_servers(intptr_t start_server_id); /* Returns a single Channel, or else a NOT_FOUND code. The returned string is allocated and must be freed by the application. */ diff --git a/src/core/lib/channel/channel_trace.h b/src/core/lib/channel/channel_trace.h index 230faa483e4..94fea20b451 100644 --- a/src/core/lib/channel/channel_trace.h +++ b/src/core/lib/channel/channel_trace.h @@ -63,7 +63,7 @@ class ChannelTrace { // stack, determine if it makes more sense to accept a char* instead of a // slice. void AddTraceEventWithReference(Severity severity, grpc_slice data, - RefCountedPtr referenced_channel); + RefCountedPtr referenced_entity); // Creates and returns the raw grpc_json object, so a parent channelz // object may incorporate the json before rendering. From 6656bc7398431d27e778e740d67a534f286deb12 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 11 Sep 2018 14:58:13 -0700 Subject: [PATCH 352/546] regenerate projects --- src/ruby/ext/grpc/rb_grpc_imports.generated.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 6adddb536c9..d00e75c3260 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -266,7 +266,7 @@ extern grpc_resource_quota_arg_vtable_type grpc_resource_quota_arg_vtable_import typedef char*(*grpc_channelz_get_top_channels_type)(intptr_t start_channel_id); extern grpc_channelz_get_top_channels_type grpc_channelz_get_top_channels_import; #define grpc_channelz_get_top_channels grpc_channelz_get_top_channels_import -typedef char*(*grpc_channelz_get_servers_type)(intptr_t start_channel_id); +typedef char*(*grpc_channelz_get_servers_type)(intptr_t start_server_id); extern grpc_channelz_get_servers_type grpc_channelz_get_servers_import; #define grpc_channelz_get_servers grpc_channelz_get_servers_import typedef char*(*grpc_channelz_get_channel_type)(intptr_t channel_id); From 0382d062486b5ba384d1288008147b6d36868485 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 11 Sep 2018 23:32:53 -0700 Subject: [PATCH 353/546] Don't use cq_tag on Server CallOpSet's yet --- src/cpp/server/server_cc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index f271825cbab..4970d9d68b9 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -657,8 +657,8 @@ void Server::PerformOpsOnCall(internal::CallOpSetInterface* ops, size_t nops = 0; grpc_op cops[MAX_OPS]; ops->FillOps(call->call(), cops, &nops); - auto result = - grpc_call_start_batch(call->call(), cops, nops, ops->cq_tag(), nullptr); + // TODO(vjpai): Use ops->cq_tag once this case supports callbacks + auto result = grpc_call_start_batch(call->call(), cops, nops, ops, nullptr); if (result != GRPC_CALL_OK) { gpr_log(GPR_ERROR, "Fatal: grpc_call_start_batch returned %d", result); grpc_call_log_batch(__FILE__, __LINE__, GPR_LOG_SEVERITY_ERROR, From d1263c8c90c78b823037541edcce85c39b0a2c6b Mon Sep 17 00:00:00 2001 From: jiangtaoli2016 Date: Wed, 12 Sep 2018 09:24:05 -0700 Subject: [PATCH 354/546] Update TLS root perm (monthly, if needed). --- etc/roots.pem | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/etc/roots.pem b/etc/roots.pem index c22dfe69f87..3e6bbcd76ea 100644 --- a/etc/roots.pem +++ b/etc/roots.pem @@ -4317,3 +4317,26 @@ JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R 8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= -----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GC CA" +# Serial: 44084345621038548146064804565436152554 +# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 +# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 +# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- From 1e69a21beb223617f797a2a323e2cb842861acf0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 11 Sep 2018 23:15:03 +0200 Subject: [PATCH 355/546] upload test duration for foundry tests --- .../python_utils/upload_rbe_results.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index d29ebc6219a..74f329048fc 100644 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -40,13 +40,14 @@ _RESULTS_SCHEMA = [ ('test_case', 'STRING', 'Name of test case'), ('result', 'STRING', 'Test or build result'), ('timestamp', 'TIMESTAMP', 'Timestamp of test run'), + ('duration', 'FLOAT', 'Duration of the test run'), ] _TABLE_ID = 'rbe_test_results' def _get_api_key(): """Returns string with API key to access ResultStore. - Intended to be used in Kokoro envrionment.""" + Intended to be used in Kokoro environment.""" api_key_directory = os.getenv('KOKORO_GFILE_DIR') api_key_file = os.path.join(api_key_directory, 'resultstore_api_key') assert os.path.isfile(api_key_file), 'Must add --api_key arg if not on ' \ @@ -57,7 +58,7 @@ def _get_api_key(): def _get_invocation_id(): """Returns String of Bazel invocation ID. Intended to be used in - Kokoro envirionment.""" + Kokoro environment.""" bazel_id_directory = os.getenv('KOKORO_ARTIFACTS_DIR') bazel_id_file = os.path.join(bazel_id_directory, 'bazel_invocation_ids') assert os.path.isfile(bazel_id_file), 'bazel_invocation_ids file, written ' \ @@ -66,6 +67,16 @@ def _get_invocation_id(): return f.read().replace('\n', '') +def _parse_test_duration(duration_str): + """Parse test duration string in '123.567s' format""" + try: + if duration_str.endswith('s'): + duration_str = duration_str[:-1] + return float(duration_str) + except: + return None + + def _upload_results_to_bq(rows): """Upload test results to a BQ table. @@ -205,6 +216,8 @@ if __name__ == "__main__": result, 'timestamp': action['timing']['startTime'], + 'duration': + _parse_test_duration(action['timing']['duration']), } }) except Exception as e: From 5f2bb7a7d4d90f09423419a1bc8bc35847c7cb4e Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 12 Sep 2018 11:14:18 -0700 Subject: [PATCH 356/546] s/GRPC/gRPC --- include/grpcpp/impl/codegen/async_stream.h | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index 5df849f610a..9c3c40af542 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -114,7 +114,7 @@ class AsyncWriterInterface { /// queue BEFORE calling Write again. /// This is thread-safe with respect to \a AsyncReaderInterface::Read /// - /// GRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to /// to deallocate once Write returns. /// /// \param[in] msg The message to be written. @@ -130,7 +130,7 @@ class AsyncWriterInterface { /// WriteOptions \a options is used to set the write options of this message. /// This is thread-safe with respect to \a AsyncReaderInterface::Read /// - /// GRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to /// to deallocate once Write returns. /// /// \param[in] msg The message to be written. @@ -150,7 +150,7 @@ class AsyncWriterInterface { /// the flow control window size. If \a msg size is larger than the window /// size, it will be sent on wire without buffering. /// - /// GRPC doesn't take ownership or a reference to \a msg, so it is safe to + /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to /// to deallocate once Write returns. /// /// \param[in] msg The message to be written. @@ -639,7 +639,7 @@ class ServerAsyncReaderInterface /// metadata (if not sent already), response message, and status, or if /// some failure occurred when trying to do so. /// - /// GRPC doesn't take ownership or a reference to \a msg or \a status, so it + /// gRPC doesn't take ownership or a reference to \a msg or \a status, so it /// is safe to to deallocate once Finish returns. /// /// \param[in] tag Tag identifying this request. @@ -662,7 +662,7 @@ class ServerAsyncReaderInterface /// metadata (if not sent already), and status, or if some failure occurred /// when trying to do so. /// - /// GRPC doesn't take ownership or a reference to \a status, so it is safe to + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to /// to deallocate once FinishWithError returns. /// /// \param[in] tag Tag identifying this request. @@ -713,7 +713,7 @@ class ServerAsyncReader final : public ServerAsyncReaderInterface { /// /// Note: \a msg is not sent if \a status has a non-OK code. /// - /// GRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it /// is safe to to deallocate once Finish returns. void Finish(const W& msg, const Status& status, void* tag) override { finish_ops_.set_output_tag(tag); @@ -742,7 +742,7 @@ class ServerAsyncReader final : public ServerAsyncReaderInterface { /// - uses the \a ServerContext associated with this call to send possible /// initial and trailing metadata. /// - /// GRPC doesn't take ownership or a reference to \a status, so it is safe to + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to /// to deallocate once FinishWithError returns. void FinishWithError(const Status& status, void* tag) override { GPR_CODEGEN_ASSERT(!status.ok()); @@ -794,7 +794,7 @@ class ServerAsyncWriterInterface /// metadata (if not sent already), response message, and status, or if /// some failure occurred when trying to do so. /// - /// GRPC doesn't take ownership or a reference to \a status, so it is safe to + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to /// to deallocate once Finish returns. /// /// \param[in] tag Tag identifying this request. @@ -808,7 +808,7 @@ class ServerAsyncWriterInterface /// WriteAndFinish is equivalent of performing WriteLast and Finish /// in a single step. /// - /// GRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it /// is safe to to deallocate once WriteAndFinish returns. /// /// \param[in] msg The message to be written. @@ -875,7 +875,7 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface { /// /// Note: \a status must have an OK code. /// - /// GRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it /// is safe to to deallocate once WriteAndFinish returns. void WriteAndFinish(const W& msg, WriteOptions options, const Status& status, void* tag) override { @@ -896,7 +896,7 @@ class ServerAsyncWriter final : public ServerAsyncWriterInterface { /// Note: there are no restrictions are the code of /// \a status,it may be non-OK /// - /// GRPC doesn't take ownership or a reference to \a status, so it is safe to + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to /// to deallocate once Finish returns. void Finish(const Status& status, void* tag) override { finish_ops_.set_output_tag(tag); @@ -957,7 +957,7 @@ class ServerAsyncReaderWriterInterface /// metadata (if not sent already), response message, and status, or if some /// failure occurred when trying to do so. /// - /// GRPC doesn't take ownership or a reference to \a status, so it is safe to + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to /// to deallocate once Finish returns. /// /// \param[in] tag Tag identifying this request. @@ -971,7 +971,7 @@ class ServerAsyncReaderWriterInterface /// WriteAndFinish is equivalent of performing WriteLast and Finish in a /// single step. /// - /// GRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it /// is safe to to deallocate once WriteAndFinish returns. /// /// \param[in] msg The message to be written. @@ -1046,7 +1046,7 @@ class ServerAsyncReaderWriter final /// /// Note: \a status must have an OK code. // - /// GRPC doesn't take ownership or a reference to \a msg and \a status, so it + /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it /// is safe to to deallocate once WriteAndFinish returns. void WriteAndFinish(const W& msg, WriteOptions options, const Status& status, void* tag) override { @@ -1067,7 +1067,7 @@ class ServerAsyncReaderWriter final /// Note: there are no restrictions are the code of \a status, /// it may be non-OK // - /// GRPC doesn't take ownership or a reference to \a status, so it is safe to + /// gRPC doesn't take ownership or a reference to \a status, so it is safe to /// to deallocate once Finish returns. void Finish(const Status& status, void* tag) override { finish_ops_.set_output_tag(tag); From 094dc6822c894ac4095d955522a08be7111167c2 Mon Sep 17 00:00:00 2001 From: Adele Zhou Date: Wed, 12 Sep 2018 00:05:29 -0700 Subject: [PATCH 357/546] Added long_connection test. --- doc/interop-test-descriptions.md | 5 +++++ test/cpp/interop/client.cc | 8 +++++++- test/cpp/interop/interop_client.cc | 28 ++++++++++++++++++++++++++++ test/cpp/interop/interop_client.h | 2 ++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md index 3c33189196e..79281611006 100644 --- a/doc/interop-test-descriptions.md +++ b/doc/interop-test-descriptions.md @@ -944,6 +944,11 @@ the experimental flag, `soak_iterations`. This tests puts stress on several gRPC components; the resolver, the load balancer, and the RPC hotpath. +#### long_connection + +The client performs a number of large_unary RPCs over a single connection +with a fixed but configuration interval between the RPCs. + ### TODO Tests #### High priority: diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index 7bcf23c0eb6..324f2e694fb 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -57,6 +57,7 @@ DEFINE_string( "half_duplex : half-duplex streaming;\n" "jwt_token_creds: large_unary with JWT token auth;\n" "large_unary : single request and (large) response;\n" + "long_connection: sends large_unary rpcs over a single long connection;\n" "oauth2_auth_token: raw oauth2 access token auth;\n" "per_rpc_creds: raw oauth2 access token on a single rpc;\n" "ping_pong : full-duplex streaming;\n" @@ -84,10 +85,12 @@ DEFINE_bool(do_not_abort_on_transient_failures, false, "whether abort() is called or not. It does not control whether the " "test is retried in case of transient failures (and currently the " "interop tests are not retried even if this flag is set to true)"); - DEFINE_int32(soak_iterations, 1000, "number of iterations to use for the two soak tests; rpc_soak and " "channel_soak"); +DEFINE_int32(iteration_interval, 10, + "The interval in seconds between rpcs. This is used by " + "long_connection test"); using grpc::testing::CreateChannelForTestCase; using grpc::testing::GetServiceAccountJsonKey; @@ -163,6 +166,9 @@ int main(int argc, char** argv) { FLAGS_soak_iterations); actions["rpc_soak"] = std::bind(&grpc::testing::InteropClient::DoRpcSoakTest, &client, FLAGS_soak_iterations); + actions["long_connection"] = + std::bind(&grpc::testing::InteropClient::DoLongConnectionTest, &client, + FLAGS_soak_iterations, FLAGS_iteration_interval); UpdateActions(&actions); diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index b7ce90803ba..42d9c0bb0d5 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -1052,6 +1052,34 @@ bool InteropClient::DoChannelSoakTest(int32_t soak_iterations) { return true; } +bool InteropClient::DoLongConnectionTest(int32_t soak_iterations, + int32_t iteration_interval) { + gpr_log(GPR_DEBUG, "Sending %d RPCs...", soak_iterations); + GPR_ASSERT(soak_iterations > 0); + GPR_ASSERT(iteration_interval > 0); + SimpleRequest request; + SimpleResponse response; + int num_failures = 0; + for (int i = 0; i < soak_iterations; ++i) { + gpr_log(GPR_DEBUG, "Sending RPC number %d...", i); + if (!PerformLargeUnary(&request, &response)) { + gpr_log(GPR_ERROR, "Iteration %d failed.", i); + num_failures++; + } + gpr_sleep_until( + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(iteration_interval, GPR_TIMESPAN))); + } + if (num_failures == 0) { + gpr_log(GPR_DEBUG, "long_connection test done."); + return true; + } else { + gpr_log(GPR_DEBUG, "long_connection test failed with %d rpc failures.", + num_failures); + return false; + } +} + bool InteropClient::DoUnimplementedService() { gpr_log(GPR_DEBUG, "Sending a request for an unimplemented service..."); diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h index e5be44d1d47..8ad063b8245 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.h @@ -76,6 +76,8 @@ class InteropClient { // languages bool DoChannelSoakTest(int32_t soak_iterations); bool DoRpcSoakTest(int32_t soak_iterations); + bool DoLongConnectionTest(int32_t soak_iterations, + int32_t iteration_interval); // Auth tests. // username is a string containing the user email From 165417e4faf4928128fc3492ace5aa907c8f51fe Mon Sep 17 00:00:00 2001 From: Adele Zhou Date: Wed, 12 Sep 2018 14:30:02 -0700 Subject: [PATCH 358/546] Change the test name to long_lived_channel --- doc/interop-test-descriptions.md | 6 +++--- test/cpp/interop/client.cc | 6 +++--- test/cpp/interop/interop_client.cc | 8 ++++---- test/cpp/interop/interop_client.h | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md index 79281611006..1d6535d7ea0 100644 --- a/doc/interop-test-descriptions.md +++ b/doc/interop-test-descriptions.md @@ -944,10 +944,10 @@ the experimental flag, `soak_iterations`. This tests puts stress on several gRPC components; the resolver, the load balancer, and the RPC hotpath. -#### long_connection +#### long_lived_channel -The client performs a number of large_unary RPCs over a single connection -with a fixed but configuration interval between the RPCs. +The client performs a number of large_unary RPCs over a single long-lived +channel with a fixed but configurable interval between each RPC. ### TODO Tests diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index 324f2e694fb..a4b1a85f856 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -57,7 +57,7 @@ DEFINE_string( "half_duplex : half-duplex streaming;\n" "jwt_token_creds: large_unary with JWT token auth;\n" "large_unary : single request and (large) response;\n" - "long_connection: sends large_unary rpcs over a single long connection;\n" + "long_lived_channel: sends large_unary rpcs over a long-lived channel;\n" "oauth2_auth_token: raw oauth2 access token auth;\n" "per_rpc_creds: raw oauth2 access token on a single rpc;\n" "ping_pong : full-duplex streaming;\n" @@ -166,8 +166,8 @@ int main(int argc, char** argv) { FLAGS_soak_iterations); actions["rpc_soak"] = std::bind(&grpc::testing::InteropClient::DoRpcSoakTest, &client, FLAGS_soak_iterations); - actions["long_connection"] = - std::bind(&grpc::testing::InteropClient::DoLongConnectionTest, &client, + actions["long_lived_channel"] = + std::bind(&grpc::testing::InteropClient::DoLongLivedChannelTest, &client, FLAGS_soak_iterations, FLAGS_iteration_interval); UpdateActions(&actions); diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 42d9c0bb0d5..a99cf8122f8 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -1052,8 +1052,8 @@ bool InteropClient::DoChannelSoakTest(int32_t soak_iterations) { return true; } -bool InteropClient::DoLongConnectionTest(int32_t soak_iterations, - int32_t iteration_interval) { +bool InteropClient::DoLongLivedChannelTest(int32_t soak_iterations, + int32_t iteration_interval) { gpr_log(GPR_DEBUG, "Sending %d RPCs...", soak_iterations); GPR_ASSERT(soak_iterations > 0); GPR_ASSERT(iteration_interval > 0); @@ -1071,10 +1071,10 @@ bool InteropClient::DoLongConnectionTest(int32_t soak_iterations, gpr_time_from_seconds(iteration_interval, GPR_TIMESPAN))); } if (num_failures == 0) { - gpr_log(GPR_DEBUG, "long_connection test done."); + gpr_log(GPR_DEBUG, "long_lived_channel test done."); return true; } else { - gpr_log(GPR_DEBUG, "long_connection test failed with %d rpc failures.", + gpr_log(GPR_DEBUG, "long_lived_channel test failed with %d rpc failures.", num_failures); return false; } diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h index 8ad063b8245..0ceff55c5c2 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.h @@ -76,8 +76,8 @@ class InteropClient { // languages bool DoChannelSoakTest(int32_t soak_iterations); bool DoRpcSoakTest(int32_t soak_iterations); - bool DoLongConnectionTest(int32_t soak_iterations, - int32_t iteration_interval); + bool DoLongLivedChannelTest(int32_t soak_iterations, + int32_t iteration_interval); // Auth tests. // username is a string containing the user email From 5b27941372debbae80c1b7d77bb9be3f5e8a79e1 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 12 Sep 2018 14:47:34 -0700 Subject: [PATCH 359/546] Even cleaner implementation that does not modify the grpc_mdelem struct. --- include/grpc/impl/codegen/grpc_types.h | 1 - .../client_channel/lb_policy/grpclb/grpclb.cc | 6 +- .../chttp2/transport/hpack_encoder.cc | 8 +- src/core/lib/transport/metadata.cc | 21 +- src/core/lib/transport/metadata.h | 20 +- src/core/lib/transport/static_metadata.cc | 10 +- src/core/lib/transport/static_metadata.h | 608 ++++++++---------- .../tests/CronetUnitTests/CronetUnitTests.m | 8 +- .../end2end/tests/authority_not_supported.cc | 4 +- test/core/end2end/tests/binary_metadata.cc | 8 +- .../end2end/tests/simple_cacheable_request.cc | 8 +- test/core/end2end/tests/simple_metadata.cc | 8 +- test/core/end2end/tests/trailing_metadata.cc | 12 +- test/core/transport/metadata_test.cc | 5 +- tools/codegen/core/gen_static_metadata.py | 77 ++- 15 files changed, 375 insertions(+), 429 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index d0f77f977be..b5353c1dea8 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -438,7 +438,6 @@ typedef struct grpc_metadata { There is no need to initialize them, and they will be set to garbage during calls to grpc. */ struct /* internal */ { - uint8_t obfuscated_byte; void* obfuscated[4]; } internal_data; } grpc_metadata; 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 b20d8d8c694..25b0149393e 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 @@ -352,13 +352,11 @@ class GrpcLb : public LoadBalancingPolicy { void* lb_token_copy(void* token) { return token == nullptr ? nullptr - : (void*)GRPC_MDELEM_REF( - (grpc_mdelem{(uintptr_t)token, GRPC_MDINDEX_UNUSED})) - .payload; + : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload; } void lb_token_destroy(void* token) { if (token != nullptr) { - GRPC_MDELEM_UNREF((grpc_mdelem{(uintptr_t)token, GRPC_MDINDEX_UNUSED})); + GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token}); } } int lb_token_cmp(void* token1, void* token2) { diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index 9a5af3712d8..eff9b97a8e2 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -689,8 +689,8 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, } for (size_t i = 0; i < extra_headers_size; ++i) { grpc_mdelem md = *extra_headers[i]; - uint8_t static_index = GRPC_MDINDEX(md); - if (static_index != GRPC_MDINDEX_UNUSED) { + uint8_t static_index = grpc_mdelem_get_static_hpack_table_index(md); + if (static_index) { emit_indexed(c, static_index, &st); } else { hpack_enc(c, md, &st); @@ -698,8 +698,8 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, } grpc_metadata_batch_assert_ok(metadata); for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) { - uint8_t static_index = GRPC_MDINDEX(l->md); - if (static_index != GRPC_MDINDEX_UNUSED) { + uint8_t static_index = grpc_mdelem_get_static_hpack_table_index(l->md); + if (static_index) { emit_indexed(c, static_index, &st); } else { hpack_enc(c, l->md, &st); diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index c5458d1d56a..dfcd2e16d8a 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -242,8 +242,7 @@ grpc_mdelem grpc_mdelem_create( if (!grpc_slice_is_interned(key) || !grpc_slice_is_interned(value)) { if (compatible_external_backing_store != nullptr) { return GRPC_MAKE_MDELEM(compatible_external_backing_store, - GRPC_MDELEM_STORAGE_EXTERNAL, - GRPC_MDINDEX_UNUSED); + GRPC_MDELEM_STORAGE_EXTERNAL); } allocated_metadata* allocated = @@ -262,8 +261,7 @@ grpc_mdelem grpc_mdelem_create( gpr_free(value_str); } #endif - return GRPC_MAKE_MDELEM(allocated, GRPC_MDELEM_STORAGE_ALLOCATED, - GRPC_MDINDEX_UNUSED); + return GRPC_MAKE_MDELEM(allocated, GRPC_MDELEM_STORAGE_ALLOCATED); } if (GRPC_IS_STATIC_METADATA_STRING(key) && @@ -291,8 +289,7 @@ grpc_mdelem grpc_mdelem_create( if (grpc_slice_eq(key, md->key) && grpc_slice_eq(value, md->value)) { REF_MD_LOCKED(shard, md); gpr_mu_unlock(&shard->mu); - return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED, - GRPC_MDINDEX_UNUSED); + return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED); } } @@ -324,8 +321,7 @@ grpc_mdelem grpc_mdelem_create( gpr_mu_unlock(&shard->mu); - return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED, - GRPC_MDINDEX_UNUSED); + return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED); } grpc_mdelem grpc_mdelem_from_slices(grpc_slice key, grpc_slice value) { @@ -364,6 +360,15 @@ size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem, } } +uint8_t grpc_mdelem_get_static_hpack_table_index(grpc_mdelem md) { + if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { + return grpc_hpack_static_mdelem_indices[GRPC_MDELEM_DATA(md) - + grpc_static_mdelem_table]; + } else { + return 0; + } +} + grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) { switch (GRPC_MDELEM_STORAGE(gmd)) { case GRPC_MDELEM_STORAGE_EXTERNAL: diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 513ac826ea1..37419c9d2f5 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -92,20 +92,17 @@ struct grpc_mdelem { /* a grpc_mdelem_data* generally, with the two lower bits signalling memory ownership as per grpc_mdelem_data_storage */ uintptr_t payload; - /* The static index of this mdelem. This is equivalent to the - mdelem's index into the hpack static table. 0 if unused. */ - uint8_t static_index; }; #define GRPC_MDELEM_DATA(md) ((grpc_mdelem_data*)((md).payload & ~(uintptr_t)3)) #define GRPC_MDELEM_STORAGE(md) \ ((grpc_mdelem_data_storage)((md).payload & (uintptr_t)3)) #ifdef __cplusplus -#define GRPC_MAKE_MDELEM(data, storage, index) \ - (grpc_mdelem{((uintptr_t)(data)) | ((uintptr_t)storage), index}) +#define GRPC_MAKE_MDELEM(data, storage) \ + (grpc_mdelem{((uintptr_t)(data)) | ((uintptr_t)storage)}) #else -#define GRPC_MAKE_MDELEM(data, storage, index) \ - ((grpc_mdelem){((uintptr_t)(data)) | ((uintptr_t)storage), index}) +#define GRPC_MAKE_MDELEM(data, storage) \ + ((grpc_mdelem){((uintptr_t)(data)) | ((uintptr_t)storage)}) #endif #define GRPC_MDELEM_IS_INTERNED(md) \ ((grpc_mdelem_data_storage)((md).payload & \ @@ -131,6 +128,11 @@ bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b); size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem, bool use_true_binary_metadata); +/* Returns the static hpack table index that corresponds to /a elem. Returns 0 + if /a elem is not statically stored or if it is not in the static hpack + table */ +uint8_t grpc_mdelem_get_static_hpack_table_index(grpc_mdelem md); + /* Mutator and accessor for grpc_mdelem user data. The destructor function is used as a type tag and is checked during user_data fetch. */ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*if_destroy_func)(void*)); @@ -151,10 +153,8 @@ void grpc_mdelem_unref(grpc_mdelem md); #define GRPC_MDKEY(md) (GRPC_MDELEM_DATA(md)->key) #define GRPC_MDVALUE(md) (GRPC_MDELEM_DATA(md)->value) -#define GRPC_MDINDEX(md) (md.static_index) -#define GRPC_MDINDEX_UNUSED 0 -#define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL, 0) +#define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL) #define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL) /* We add 32 bytes of padding as per RFC-7540 section 6.5.2. */ diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 240a55e0abc..fdedd410369 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -334,6 +334,14 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}, }; +const uint8_t grpc_hpack_static_mdelem_indices[GRPC_STATIC_MDELEM_COUNT] = { + 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 13, 6, 7, 0, 1, 2, 0, 4, + 5, 9, 10, 11, 12, 14, 15, 0, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 0, 0, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -390,7 +398,7 @@ grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) { return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], - GRPC_MDELEM_STORAGE_STATIC, 0) + GRPC_MDELEM_STORAGE_STATIC) : GRPC_MDNULL; } diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index e4a9e2a4141..e5319c4c4d4 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -262,350 +262,266 @@ extern grpc_slice_refcount #define GRPC_STATIC_MDELEM_COUNT 86 extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; -/* "grpc-status": "0" Index="0" */ -#define GRPC_MDELEM_GRPC_STATUS_0 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "grpc-status": "1" Index="0" */ -#define GRPC_MDELEM_GRPC_STATUS_1 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "grpc-status": "2" Index="0" */ -#define GRPC_MDELEM_GRPC_STATUS_2 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "grpc-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "grpc-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "grpc-encoding": "deflate" Index="0" */ -#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "te": "trailers" Index="0" */ -#define GRPC_MDELEM_TE_TRAILERS \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "content-type": "application/grpc" Index="0" */ -#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* ":method": "POST" Index="3" */ -#define GRPC_MDELEM_METHOD_POST \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC, \ - 3)) -/* ":status": "200" Index="8" */ -#define GRPC_MDELEM_STATUS_200 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC, \ - 8)) -/* ":status": "404" Index="13" */ -#define GRPC_MDELEM_STATUS_404 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC, \ - 13)) -/* ":scheme": "http" Index="6" */ -#define GRPC_MDELEM_SCHEME_HTTP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC, \ - 6)) -/* ":scheme": "https" Index="7" */ -#define GRPC_MDELEM_SCHEME_HTTPS \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC, \ - 7)) -/* ":scheme": "grpc" Index="0" */ -#define GRPC_MDELEM_SCHEME_GRPC \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* ":authority": "" Index="1" */ -#define GRPC_MDELEM_AUTHORITY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC, \ - 1)) -/* ":method": "GET" Index="2" */ -#define GRPC_MDELEM_METHOD_GET \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC, \ - 2)) -/* ":method": "PUT" Index="0" */ -#define GRPC_MDELEM_METHOD_PUT \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* ":path": "/" Index="4" */ -#define GRPC_MDELEM_PATH_SLASH \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC, \ - 4)) -/* ":path": "/index.html" Index="5" */ -#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC, \ - 5)) -/* ":status": "204" Index="9" */ -#define GRPC_MDELEM_STATUS_204 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC, \ - 9)) -/* ":status": "206" Index="10" */ -#define GRPC_MDELEM_STATUS_206 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC, \ - 10)) -/* ":status": "304" Index="11" */ -#define GRPC_MDELEM_STATUS_304 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC, \ - 11)) -/* ":status": "400" Index="12" */ -#define GRPC_MDELEM_STATUS_400 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC, \ - 12)) -/* ":status": "500" Index="14" */ -#define GRPC_MDELEM_STATUS_500 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC, \ - 14)) -/* "accept-charset": "" Index="15" */ -#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC, \ - 15)) -/* "accept-encoding": "" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "accept-encoding": "gzip, deflate" Index="16" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC, \ - 16)) -/* "accept-language": "" Index="17" */ -#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC, \ - 17)) -/* "accept-ranges": "" Index="18" */ -#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC, \ - 18)) -/* "accept": "" Index="19" */ -#define GRPC_MDELEM_ACCEPT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC, \ - 19)) -/* "access-control-allow-origin": "" Index="20" */ -#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC, \ - 20)) -/* "age": "" Index="21" */ -#define GRPC_MDELEM_AGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC, \ - 21)) -/* "allow": "" Index="22" */ -#define GRPC_MDELEM_ALLOW_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC, \ - 22)) -/* "authorization": "" Index="23" */ -#define GRPC_MDELEM_AUTHORIZATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC, \ - 23)) -/* "cache-control": "" Index="24" */ -#define GRPC_MDELEM_CACHE_CONTROL_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC, \ - 24)) -/* "content-disposition": "" Index="25" */ -#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC, \ - 25)) -/* "content-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "content-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "content-encoding": "" Index="26" */ -#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC, \ - 26)) -/* "content-language": "" Index="27" */ -#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC, \ - 27)) -/* "content-length": "" Index="28" */ -#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC, \ - 28)) -/* "content-location": "" Index="29" */ -#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC, \ - 29)) -/* "content-range": "" Index="30" */ -#define GRPC_MDELEM_CONTENT_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC, \ - 30)) -/* "content-type": "" Index="31" */ -#define GRPC_MDELEM_CONTENT_TYPE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC, \ - 31)) -/* "cookie": "" Index="32" */ -#define GRPC_MDELEM_COOKIE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC, \ - 32)) -/* "date": "" Index="33" */ -#define GRPC_MDELEM_DATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC, \ - 33)) -/* "etag": "" Index="34" */ -#define GRPC_MDELEM_ETAG_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC, \ - 34)) -/* "expect": "" Index="35" */ -#define GRPC_MDELEM_EXPECT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC, \ - 35)) -/* "expires": "" Index="36" */ -#define GRPC_MDELEM_EXPIRES_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC, \ - 36)) -/* "from": "" Index="37" */ -#define GRPC_MDELEM_FROM_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC, \ - 37)) -/* "host": "" Index="38" */ -#define GRPC_MDELEM_HOST_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC, \ - 38)) -/* "if-match": "" Index="39" */ -#define GRPC_MDELEM_IF_MATCH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC, \ - 39)) -/* "if-modified-since": "" Index="40" */ -#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC, \ - 40)) -/* "if-none-match": "" Index="41" */ -#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC, \ - 41)) -/* "if-range": "" Index="42" */ -#define GRPC_MDELEM_IF_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC, \ - 42)) -/* "if-unmodified-since": "" Index="43" */ -#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC, \ - 43)) -/* "last-modified": "" Index="44" */ -#define GRPC_MDELEM_LAST_MODIFIED_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC, \ - 44)) -/* "lb-token": "" Index="0" */ -#define GRPC_MDELEM_LB_TOKEN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "lb-cost-bin": "" Index="0" */ -#define GRPC_MDELEM_LB_COST_BIN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "link": "" Index="45" */ -#define GRPC_MDELEM_LINK_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC, \ - 45)) -/* "location": "" Index="46" */ -#define GRPC_MDELEM_LOCATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC, \ - 46)) -/* "max-forwards": "" Index="47" */ -#define GRPC_MDELEM_MAX_FORWARDS_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC, \ - 47)) -/* "proxy-authenticate": "" Index="48" */ -#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC, \ - 48)) -/* "proxy-authorization": "" Index="49" */ -#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC, \ - 49)) -/* "range": "" Index="50" */ -#define GRPC_MDELEM_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC, \ - 50)) -/* "referer": "" Index="51" */ -#define GRPC_MDELEM_REFERER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC, \ - 51)) -/* "refresh": "" Index="52" */ -#define GRPC_MDELEM_REFRESH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC, \ - 52)) -/* "retry-after": "" Index="53" */ -#define GRPC_MDELEM_RETRY_AFTER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC, \ - 53)) -/* "server": "" Index="54" */ -#define GRPC_MDELEM_SERVER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC, \ - 54)) -/* "set-cookie": "" Index="55" */ -#define GRPC_MDELEM_SET_COOKIE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC, \ - 55)) -/* "strict-transport-security": "" Index="56" */ -#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC, \ - 56)) -/* "transfer-encoding": "" Index="57" */ -#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC, \ - 57)) -/* "user-agent": "" Index="58" */ -#define GRPC_MDELEM_USER_AGENT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC, \ - 58)) -/* "vary": "" Index="59" */ -#define GRPC_MDELEM_VARY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC, \ - 59)) -/* "via": "" Index="60" */ -#define GRPC_MDELEM_VIA_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC, \ - 60)) -/* "www-authenticate": "" Index="61" */ -#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC, \ - 61)) -/* "grpc-accept-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "grpc-accept-encoding": "deflate" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "grpc-accept-encoding": "identity,deflate" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "grpc-accept-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "grpc-accept-encoding": "identity,gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "grpc-accept-encoding": "deflate,gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "grpc-accept-encoding": "identity,deflate,gzip" Index="0" */ -#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "accept-encoding": "identity" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "accept-encoding": "gzip" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) -/* "accept-encoding": "identity,gzip" Index="0" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC, \ - 0)) +/* "grpc-status": "0" */ +#define GRPC_MDELEM_GRPC_STATUS_0 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-status": "1" */ +#define GRPC_MDELEM_GRPC_STATUS_1 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-status": "2" */ +#define GRPC_MDELEM_GRPC_STATUS_2 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-encoding": "identity" */ +#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-encoding": "gzip" */ +#define GRPC_MDELEM_GRPC_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-encoding": "deflate" */ +#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC)) +/* "te": "trailers" */ +#define GRPC_MDELEM_TE_TRAILERS \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-type": "application/grpc" */ +#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC)) +/* ":method": "POST" */ +#define GRPC_MDELEM_METHOD_POST \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC)) +/* ":status": "200" */ +#define GRPC_MDELEM_STATUS_200 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC)) +/* ":status": "404" */ +#define GRPC_MDELEM_STATUS_404 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC)) +/* ":scheme": "http" */ +#define GRPC_MDELEM_SCHEME_HTTP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC)) +/* ":scheme": "https" */ +#define GRPC_MDELEM_SCHEME_HTTPS \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC)) +/* ":scheme": "grpc" */ +#define GRPC_MDELEM_SCHEME_GRPC \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC)) +/* ":authority": "" */ +#define GRPC_MDELEM_AUTHORITY_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC)) +/* ":method": "GET" */ +#define GRPC_MDELEM_METHOD_GET \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC)) +/* ":method": "PUT" */ +#define GRPC_MDELEM_METHOD_PUT \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC)) +/* ":path": "/" */ +#define GRPC_MDELEM_PATH_SLASH \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC)) +/* ":path": "/index.html" */ +#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC)) +/* ":status": "204" */ +#define GRPC_MDELEM_STATUS_204 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC)) +/* ":status": "206" */ +#define GRPC_MDELEM_STATUS_206 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC)) +/* ":status": "304" */ +#define GRPC_MDELEM_STATUS_304 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC)) +/* ":status": "400" */ +#define GRPC_MDELEM_STATUS_400 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC)) +/* ":status": "500" */ +#define GRPC_MDELEM_STATUS_500 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC)) +/* "accept-charset": "" */ +#define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC)) +/* "accept-encoding": "" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC)) +/* "accept-encoding": "gzip, deflate" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC)) +/* "accept-language": "" */ +#define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC)) +/* "accept-ranges": "" */ +#define GRPC_MDELEM_ACCEPT_RANGES_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC)) +/* "accept": "" */ +#define GRPC_MDELEM_ACCEPT_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC)) +/* "access-control-allow-origin": "" */ +#define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC)) +/* "age": "" */ +#define GRPC_MDELEM_AGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC)) +/* "allow": "" */ +#define GRPC_MDELEM_ALLOW_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC)) +/* "authorization": "" */ +#define GRPC_MDELEM_AUTHORIZATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC)) +/* "cache-control": "" */ +#define GRPC_MDELEM_CACHE_CONTROL_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-disposition": "" */ +#define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-encoding": "identity" */ +#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-encoding": "gzip" */ +#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-encoding": "" */ +#define GRPC_MDELEM_CONTENT_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-language": "" */ +#define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-length": "" */ +#define GRPC_MDELEM_CONTENT_LENGTH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-location": "" */ +#define GRPC_MDELEM_CONTENT_LOCATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-range": "" */ +#define GRPC_MDELEM_CONTENT_RANGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-type": "" */ +#define GRPC_MDELEM_CONTENT_TYPE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC)) +/* "cookie": "" */ +#define GRPC_MDELEM_COOKIE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC)) +/* "date": "" */ +#define GRPC_MDELEM_DATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC)) +/* "etag": "" */ +#define GRPC_MDELEM_ETAG_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC)) +/* "expect": "" */ +#define GRPC_MDELEM_EXPECT_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC)) +/* "expires": "" */ +#define GRPC_MDELEM_EXPIRES_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC)) +/* "from": "" */ +#define GRPC_MDELEM_FROM_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC)) +/* "host": "" */ +#define GRPC_MDELEM_HOST_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC)) +/* "if-match": "" */ +#define GRPC_MDELEM_IF_MATCH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC)) +/* "if-modified-since": "" */ +#define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC)) +/* "if-none-match": "" */ +#define GRPC_MDELEM_IF_NONE_MATCH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC)) +/* "if-range": "" */ +#define GRPC_MDELEM_IF_RANGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC)) +/* "if-unmodified-since": "" */ +#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC)) +/* "last-modified": "" */ +#define GRPC_MDELEM_LAST_MODIFIED_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC)) +/* "lb-token": "" */ +#define GRPC_MDELEM_LB_TOKEN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC)) +/* "lb-cost-bin": "" */ +#define GRPC_MDELEM_LB_COST_BIN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC)) +/* "link": "" */ +#define GRPC_MDELEM_LINK_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC)) +/* "location": "" */ +#define GRPC_MDELEM_LOCATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC)) +/* "max-forwards": "" */ +#define GRPC_MDELEM_MAX_FORWARDS_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC)) +/* "proxy-authenticate": "" */ +#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC)) +/* "proxy-authorization": "" */ +#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC)) +/* "range": "" */ +#define GRPC_MDELEM_RANGE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC)) +/* "referer": "" */ +#define GRPC_MDELEM_REFERER_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC)) +/* "refresh": "" */ +#define GRPC_MDELEM_REFRESH_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC)) +/* "retry-after": "" */ +#define GRPC_MDELEM_RETRY_AFTER_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC)) +/* "server": "" */ +#define GRPC_MDELEM_SERVER_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC)) +/* "set-cookie": "" */ +#define GRPC_MDELEM_SET_COOKIE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC)) +/* "strict-transport-security": "" */ +#define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC)) +/* "transfer-encoding": "" */ +#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC)) +/* "user-agent": "" */ +#define GRPC_MDELEM_USER_AGENT_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC)) +/* "vary": "" */ +#define GRPC_MDELEM_VARY_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC)) +/* "via": "" */ +#define GRPC_MDELEM_VIA_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC)) +/* "www-authenticate": "" */ +#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-accept-encoding": "identity" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-accept-encoding": "deflate" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-accept-encoding": "identity,deflate" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-accept-encoding": "gzip" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-accept-encoding": "identity,gzip" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[80], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-accept-encoding": "deflate,gzip" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[81], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-accept-encoding": "identity,deflate,gzip" */ +#define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[82], GRPC_MDELEM_STORAGE_STATIC)) +/* "accept-encoding": "identity" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[83], GRPC_MDELEM_STORAGE_STATIC)) +/* "accept-encoding": "gzip" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[84], GRPC_MDELEM_STORAGE_STATIC)) +/* "accept-encoding": "identity,gzip" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC)) + +extern const uint8_t grpc_hpack_static_mdelem_indices[GRPC_STATIC_MDELEM_COUNT]; grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b); typedef enum { @@ -679,11 +595,11 @@ extern const uint8_t grpc_static_accept_encoding_metadata[8]; #define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \ (GRPC_MAKE_MDELEM( \ &grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], \ - GRPC_MDELEM_STORAGE_STATIC, 0)) + GRPC_MDELEM_STORAGE_STATIC)) extern const uint8_t grpc_static_accept_stream_encoding_metadata[4]; #define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) \ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table \ [grpc_static_accept_stream_encoding_metadata[(algs)]], \ - GRPC_MDELEM_STORAGE_STATIC, 0)) + GRPC_MDELEM_STORAGE_STATIC)) #endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */ diff --git a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m index 79cc8071e74..75a669da4d4 100644 --- a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m +++ b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m @@ -140,11 +140,11 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), grpc_slice_from_static_string("val1"), 0, - {0, {NULL, NULL, NULL, NULL}}}, + {{NULL, NULL, NULL, NULL}}}, {grpc_slice_from_static_string("key2"), grpc_slice_from_static_string("val2"), 0, - {0, {NULL, NULL, NULL, NULL}}}}; + {{NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); char *addr; @@ -274,11 +274,11 @@ grpc_channel_args *add_disable_client_authority_filter_args(grpc_channel_args *a grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), grpc_slice_from_static_string("val1"), 0, - {0, {NULL, NULL, NULL, NULL}}}, + {{NULL, NULL, NULL, NULL}}}, {grpc_slice_from_static_string("key2"), grpc_slice_from_static_string("val2"), 0, - {0, {NULL, NULL, NULL, NULL}}}}; + {{NULL, NULL, NULL, NULL}}}}; int port = grpc_pick_unused_port_or_die(); char *addr; diff --git a/test/core/end2end/tests/authority_not_supported.cc b/test/core/end2end/tests/authority_not_supported.cc index 4ccdb5e72a2..01a95e4e10b 100644 --- a/test/core/end2end/tests/authority_not_supported.cc +++ b/test/core/end2end/tests/authority_not_supported.cc @@ -93,11 +93,11 @@ static void test_with_authority_header(grpc_end2end_test_config config) { grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), grpc_slice_from_static_string("val1"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}, + {{nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key2"), grpc_slice_from_static_string("val2"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}}; + {{nullptr, nullptr, nullptr, nullptr}}}}; grpc_end2end_test_fixture f = begin_test(config, "test_with_authority_header", nullptr, nullptr); cq_verifier* cqv = cq_verifier_create(f.cq); diff --git a/test/core/end2end/tests/binary_metadata.cc b/test/core/end2end/tests/binary_metadata.cc index 2ce050355d6..cdf5b1eb94d 100644 --- a/test/core/end2end/tests/binary_metadata.cc +++ b/test/core/end2end/tests/binary_metadata.cc @@ -101,23 +101,23 @@ static void test_request_response_with_metadata_and_payload( grpc_slice_from_static_string( "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}, + {{nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key2-bin"), grpc_slice_from_static_string( "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}}; + {{nullptr, nullptr, nullptr, nullptr}}}}; grpc_metadata meta_s[2] = { {grpc_slice_from_static_string("key3-bin"), grpc_slice_from_static_string( "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}, + {{nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key4-bin"), grpc_slice_from_static_string( "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}}; + {{nullptr, nullptr, nullptr, nullptr}}}}; grpc_end2end_test_fixture f = begin_test(config, "test_request_response_with_metadata_and_payload", nullptr, nullptr); diff --git a/test/core/end2end/tests/simple_cacheable_request.cc b/test/core/end2end/tests/simple_cacheable_request.cc index 7493818a271..be6d16ecad7 100644 --- a/test/core/end2end/tests/simple_cacheable_request.cc +++ b/test/core/end2end/tests/simple_cacheable_request.cc @@ -101,19 +101,19 @@ static void test_cacheable_request_response_with_metadata_and_payload( grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), grpc_slice_from_static_string("val1"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}, + {{nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key2"), grpc_slice_from_static_string("val2"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}}; + {{nullptr, nullptr, nullptr, nullptr}}}}; grpc_metadata meta_s[2] = {{grpc_slice_from_static_string("key3"), grpc_slice_from_static_string("val3"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}, + {{nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key4"), grpc_slice_from_static_string("val4"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}}; + {{nullptr, nullptr, nullptr, nullptr}}}}; grpc_end2end_test_fixture f = begin_test( config, "test_cacheable_request_response_with_metadata_and_payload", nullptr, nullptr); diff --git a/test/core/end2end/tests/simple_metadata.cc b/test/core/end2end/tests/simple_metadata.cc index a9e86bda3a1..3e476c2129d 100644 --- a/test/core/end2end/tests/simple_metadata.cc +++ b/test/core/end2end/tests/simple_metadata.cc @@ -99,19 +99,19 @@ static void test_request_response_with_metadata_and_payload( grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), grpc_slice_from_static_string("val1"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}, + {{nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key2"), grpc_slice_from_static_string("val2"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}}; + {{nullptr, nullptr, nullptr, nullptr}}}}; grpc_metadata meta_s[2] = {{grpc_slice_from_static_string("key3"), grpc_slice_from_static_string("val3"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}, + {{nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key4"), grpc_slice_from_static_string("val4"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}}; + {{nullptr, nullptr, nullptr, nullptr}}}}; grpc_end2end_test_fixture f = begin_test(config, "test_request_response_with_metadata_and_payload", nullptr, nullptr); diff --git a/test/core/end2end/tests/trailing_metadata.cc b/test/core/end2end/tests/trailing_metadata.cc index 1fb9683ee5f..5cf6f2bb115 100644 --- a/test/core/end2end/tests/trailing_metadata.cc +++ b/test/core/end2end/tests/trailing_metadata.cc @@ -99,27 +99,27 @@ static void test_request_response_with_metadata_and_payload( grpc_metadata meta_c[2] = {{grpc_slice_from_static_string("key1"), grpc_slice_from_static_string("val1"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}, + {{nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key2"), grpc_slice_from_static_string("val2"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}}; + {{nullptr, nullptr, nullptr, nullptr}}}}; grpc_metadata meta_s[2] = {{grpc_slice_from_static_string("key3"), grpc_slice_from_static_string("val3"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}, + {{nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key4"), grpc_slice_from_static_string("val4"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}}; + {{nullptr, nullptr, nullptr, nullptr}}}}; grpc_metadata meta_t[2] = {{grpc_slice_from_static_string("key5"), grpc_slice_from_static_string("val5"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}, + {{nullptr, nullptr, nullptr, nullptr}}}, {grpc_slice_from_static_string("key6"), grpc_slice_from_static_string("val6"), 0, - {0, {nullptr, nullptr, nullptr, nullptr}}}}; + {{nullptr, nullptr, nullptr, nullptr}}}}; grpc_end2end_test_fixture f = begin_test(config, "test_request_response_with_metadata_and_payload", nullptr, nullptr); diff --git a/test/core/transport/metadata_test.cc b/test/core/transport/metadata_test.cc index 7b064c4f2a2..4be34f72d9b 100644 --- a/test/core/transport/metadata_test.cc +++ b/test/core/transport/metadata_test.cc @@ -350,9 +350,8 @@ static void test_copied_static_metadata(bool dup_key, bool dup_value) { grpc_core::ExecCtx exec_ctx; for (size_t i = 0; i < GRPC_STATIC_MDELEM_COUNT; i++) { - grpc_mdelem p = - GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[i], - GRPC_MDELEM_STORAGE_STATIC, GRPC_MDINDEX_UNUSED); + grpc_mdelem p = GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[i], + GRPC_MDELEM_STORAGE_STATIC); grpc_mdelem q = grpc_mdelem_from_slices(maybe_dup(GRPC_MDKEY(p), dup_key), maybe_dup(GRPC_MDVALUE(p), dup_value)); diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index a1de6e0aa1d..784e7540919 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -23,10 +23,13 @@ import subprocess import re import perfection -# configuration: a list of either strings or 2-tuples of strings -# a single string represents a static grpc_mdstr -# a 2-tuple represents a static grpc_mdelem (and appropriate grpc_mdstrs will -# also be created) +# Configuration: a list of either strings or 2-tuples of strings. +# A single string represents a static grpc_mdstr. +# A 2-tuple represents a static grpc_mdelem (and appropriate grpc_mdstrs will +# also be created). +# A 3-tuple represents a static grpc_mdelem (and appropriate grpc_mdstrs will +# also be created), with the last value equivalent to the mdelem's static hpack +# table index as defined by RFC 7541 CONFIG = [ # metadata strings @@ -64,14 +67,14 @@ CONFIG = [ 'gzip', 'stream/gzip', # metadata elements - ('grpc-status', '0', 0), - ('grpc-status', '1', 0), - ('grpc-status', '2', 0), - ('grpc-encoding', 'identity', 0), - ('grpc-encoding', 'gzip', 0), - ('grpc-encoding', 'deflate', 0), - ('te', 'trailers', 0), - ('content-type', 'application/grpc', 0), + ('grpc-status', '0'), + ('grpc-status', '1'), + ('grpc-status', '2'), + ('grpc-encoding', 'identity'), + ('grpc-encoding', 'gzip'), + ('grpc-encoding', 'deflate'), + ('te', 'trailers'), + ('content-type', 'application/grpc'), (':method', 'POST', 3), (':status', '200', 8), (':status', '404', 13), @@ -80,7 +83,7 @@ CONFIG = [ (':scheme', 'grpc', 0), (':authority', '', 1), (':method', 'GET', 2), - (':method', 'PUT', 0), + (':method', 'PUT'), (':path', '/', 4), (':path', '/index.html', 5), (':status', '204', 9), @@ -89,7 +92,7 @@ CONFIG = [ (':status', '400', 12), (':status', '500', 14), ('accept-charset', '', 15), - ('accept-encoding', '', 0), + ('accept-encoding', ''), ('accept-encoding', 'gzip, deflate', 16), ('accept-language', '', 17), ('accept-ranges', '', 18), @@ -100,8 +103,8 @@ CONFIG = [ ('authorization', '', 23), ('cache-control', '', 24), ('content-disposition', '', 25), - ('content-encoding', 'identity', 0), - ('content-encoding', 'gzip', 0), + ('content-encoding', 'identity'), + ('content-encoding', 'gzip'), ('content-encoding', '', 26), ('content-language', '', 27), ('content-length', '', 28), @@ -121,8 +124,8 @@ CONFIG = [ ('if-range', '', 42), ('if-unmodified-since', '', 43), ('last-modified', '', 44), - ('lb-token', '', 0), - ('lb-cost-bin', '', 0), + ('lb-token', ''), + ('lb-cost-bin', ''), ('link', '', 45), ('location', '', 46), ('max-forwards', '', 47), @@ -271,7 +274,7 @@ for mask in range(1, 1 << len(COMPRESSION_ALGORITHMS)): val = ','.join(COMPRESSION_ALGORITHMS[alg] for alg in range(0, len(COMPRESSION_ALGORITHMS)) if (1 << alg) & mask) - elem = ('grpc-accept-encoding', val, 0) + elem = ('grpc-accept-encoding', val) if val not in all_strs: all_strs.append(val) if elem not in all_elems: @@ -283,7 +286,7 @@ for mask in range(1, 1 << len(STREAM_COMPRESSION_ALGORITHMS)): val = ','.join(STREAM_COMPRESSION_ALGORITHMS[alg] for alg in range(0, len(STREAM_COMPRESSION_ALGORITHMS)) if (1 << alg) & mask) - elem = ('accept-encoding', val, 0) + elem = ('accept-encoding', val) if val not in all_strs: all_strs.append(val) if elem not in all_elems: @@ -453,11 +456,28 @@ print >> H, ('extern grpc_mdelem_data ' print >> H, ('extern uintptr_t ' 'grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];') for i, elem in enumerate(all_elems): - print >> H, '/* "%s": "%s" Index="%d" */' % elem + print >> H, '/* "%s": "%s" */' % (elem[0], elem[1]) print >> H, ('#define %s (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[%d], ' - 'GRPC_MDELEM_STORAGE_STATIC, %d))') % (mangle(elem).upper(), i, - elem[2]) + 'GRPC_MDELEM_STORAGE_STATIC))') % (mangle(elem).upper(), i) print >> H + +# Print out the chttp2 mapping between static mdelem index and the hpack static +# table index +print >> H, ('extern const uint8_t grpc_hpack_static_mdelem_indices[' + 'GRPC_STATIC_MDELEM_COUNT];') +print >> H +print >> C, ('const uint8_t grpc_hpack_static_mdelem_indices[' + 'GRPC_STATIC_MDELEM_COUNT] = {') +indices = '' +for i, elem in enumerate(all_elems): + index = 0 + if len(elem) == 3: + index = elem[2] + indices += '%d,' % index +print >> C, ' %s' % indices +print >> C, '};' +print >> C + print >> C, ('uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] ' '= {') print >> C, ' %s' % ','.join( @@ -545,13 +565,14 @@ print >> C, 'grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {' print >> C, ' if (a == -1 || b == -1) return GRPC_MDNULL;' print >> C, ' uint32_t k = (uint32_t)(a * %d + b);' % len(all_strs) print >> C, ' uint32_t h = elems_phash(k);' -print >> C, ' return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC, 0) : GRPC_MDNULL;' +print >> C, ' return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 ? GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[elem_idxs[h]], GRPC_MDELEM_STORAGE_STATIC) : GRPC_MDNULL;' print >> C, '}' print >> C print >> C, 'grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {' -for a, b, c in all_elems: - print >> C, '{%s,%s},' % (slice_def(str_idx(a)), slice_def(str_idx(b))) +for i, elem in enumerate(all_elems): + print >> C, '{%s,%s},' % (slice_def(str_idx(elem[0])), + slice_def(str_idx(elem[1]))) print >> C, '};' print >> H, 'typedef enum {' @@ -588,7 +609,7 @@ print >> C, '0,%s' % ','.join('%d' % md_idx(elem) for elem in compression_elems) print >> C, '};' print >> C -print >> H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC, 0))' +print >> H, '#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC))' print >> H print >> H, 'extern const uint8_t grpc_static_accept_stream_encoding_metadata[%d];' % ( @@ -599,7 +620,7 @@ print >> C, '0,%s' % ','.join( '%d' % md_idx(elem) for elem in stream_compression_elems) print >> C, '};' -print >> H, '#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_stream_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC, 0))' +print >> H, '#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[grpc_static_accept_stream_encoding_metadata[(algs)]], GRPC_MDELEM_STORAGE_STATIC))' print >> H, '#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */' From 2f6640f005196d71cb27d9d47e06cb130fd84502 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 12 Sep 2018 17:09:01 -0700 Subject: [PATCH 360/546] Add logging to be sure about set values --- src/core/lib/iomgr/socket_utils_common_posix.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc index 4ef3d8319fd..50674b08455 100644 --- a/src/core/lib/iomgr/socket_utils_common_posix.cc +++ b/src/core/lib/iomgr/socket_utils_common_posix.cc @@ -287,6 +287,11 @@ grpc_error* grpc_set_socket_tcp_user_timeout( } } if (enable) { + extern grpc_core::TraceFlag grpc_tcp_trace; + if (grpc_tcp_trace.enabled()) { + gpr_log(GPR_INFO, "Enabling TCP_USER_TIMEOUT with a timeout of %d ms", + timeout); + } int newval; socklen_t len = sizeof(newval); if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout, From d0bbb86a2b07d90de0f5fe4cbb2e628708c748e4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 12 Sep 2018 17:39:17 -0700 Subject: [PATCH 361/546] avoid collisions with ephemeral ports on foundry --- test/core/util/port_isolated_runtime_environment.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/core/util/port_isolated_runtime_environment.cc b/test/core/util/port_isolated_runtime_environment.cc index c1ca185a670..1f678c08e57 100644 --- a/test/core/util/port_isolated_runtime_environment.cc +++ b/test/core/util/port_isolated_runtime_environment.cc @@ -30,8 +30,8 @@ #include "test/core/util/port.h" -#define MIN_PORT 49152 -#define MAX_PORT 65535 +#define MIN_PORT 1025 +#define MAX_PORT 32766 static int get_random_port_offset() { srand(gpr_now(GPR_CLOCK_REALTIME).tv_nsec); From db01bf793aeab78b8b8d85686977240afb56a536 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 11 Sep 2018 17:01:19 -0700 Subject: [PATCH 362/546] Add callback-based alarms --- include/grpcpp/alarm.h | 24 ++++++++ src/cpp/common/alarm.cc | 47 +++++++++++---- test/cpp/common/alarm_test.cc | 106 +++++++++++++++++++++++++++++++++- 3 files changed, 165 insertions(+), 12 deletions(-) diff --git a/include/grpcpp/alarm.h b/include/grpcpp/alarm.h index f484610a6ed..f9008c327e4 100644 --- a/include/grpcpp/alarm.h +++ b/include/grpcpp/alarm.h @@ -21,6 +21,8 @@ #ifndef GRPCPP_ALARM_H #define GRPCPP_ALARM_H +#include + #include #include #include @@ -76,8 +78,30 @@ class Alarm : private GrpcLibraryCodegen { /// has already fired has no effect. void Cancel(); + /// NOTE: class experimental_type is not part of the public API of this class + /// TODO(vjpai): Move these contents to the public API of Alarm when + /// they are no longer experimental + class experimental_type { + public: + explicit experimental_type(Alarm* alarm) : alarm_(alarm) {} + + template + void Set(const T& deadline, std::function f) { + alarm_->SetInternal(TimePoint(deadline).raw_time(), std::move(f)); + } + + private: + Alarm* alarm_; + }; + + /// NOTE: The function experimental() is not stable public API. It is a view + /// to the experimental components of this class. It may be changed or removed + /// at any time. + experimental_type experimental() { return experimental_type(this); } + private: void SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag); + void SetInternal(gpr_timespec deadline, std::function f); internal::CompletionQueueTag* alarm_; }; diff --git a/src/cpp/common/alarm.cc b/src/cpp/common/alarm.cc index 15a373d8a54..5819a4210bd 100644 --- a/src/cpp/common/alarm.cc +++ b/src/cpp/common/alarm.cc @@ -39,17 +39,6 @@ class AlarmImpl : public CompletionQueueTag { AlarmImpl() : cq_(nullptr), tag_(nullptr) { gpr_ref_init(&refs_, 1); grpc_timer_init_unset(&timer_); - GRPC_CLOSURE_INIT(&on_alarm_, - [](void* arg, grpc_error* error) { - // queue the op on the completion queue - AlarmImpl* alarm = static_cast(arg); - alarm->Ref(); - grpc_cq_end_op( - alarm->cq_, alarm, error, - [](void* arg, grpc_cq_completion* completion) {}, - arg, &alarm->completion_); - }, - this, grpc_schedule_on_exec_ctx); } ~AlarmImpl() { grpc_core::ExecCtx exec_ctx; @@ -68,6 +57,32 @@ class AlarmImpl : public CompletionQueueTag { cq_ = cq->cq(); tag_ = tag; GPR_ASSERT(grpc_cq_begin_op(cq_, this)); + GRPC_CLOSURE_INIT(&on_alarm_, + [](void* arg, grpc_error* error) { + // queue the op on the completion queue + AlarmImpl* alarm = static_cast(arg); + alarm->Ref(); + grpc_cq_end_op( + alarm->cq_, alarm, error, + [](void* arg, grpc_cq_completion* completion) {}, + arg, &alarm->completion_); + }, + this, grpc_schedule_on_exec_ctx); + grpc_timer_init(&timer_, grpc_timespec_to_millis_round_up(deadline), + &on_alarm_); + } + void Set(gpr_timespec deadline, std::function f) { + grpc_core::ExecCtx exec_ctx; + // Don't use any CQ at all. Instead just use the timer to fire the function + callback_ = std::move(f); + Ref(); + GRPC_CLOSURE_INIT(&on_alarm_, + [](void* arg, grpc_error* error) { + AlarmImpl* alarm = static_cast(arg); + alarm->callback_(error == GRPC_ERROR_NONE); + alarm->Unref(); + }, + this, grpc_schedule_on_exec_ctx); grpc_timer_init(&timer_, grpc_timespec_to_millis_round_up(deadline), &on_alarm_); } @@ -95,6 +110,7 @@ class AlarmImpl : public CompletionQueueTag { // completion queue where events about this alarm will be posted grpc_completion_queue* cq_; void* tag_; + std::function callback_; }; } // namespace internal @@ -113,6 +129,15 @@ void Alarm::SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag) { static_cast(alarm_)->Set(cq, deadline, tag); } +void Alarm::SetInternal(gpr_timespec deadline, std::function f) { + // Note that we know that alarm_ is actually an internal::AlarmImpl + // but we declared it as the base pointer to avoid a forward declaration + // or exposing core data structures in the C++ public headers. + // Thus it is safe to use a static_cast to the subclass here, and the + // C++ style guide allows us to do so in this case + static_cast(alarm_)->Set(deadline, std::move(f)); +} + Alarm::~Alarm() { if (alarm_ != nullptr) { static_cast(alarm_)->Destroy(); diff --git a/test/cpp/common/alarm_test.cc b/test/cpp/common/alarm_test.cc index 57d958349ec..e909d03658c 100644 --- a/test/cpp/common/alarm_test.cc +++ b/test/cpp/common/alarm_test.cc @@ -16,9 +16,13 @@ * */ +#include +#include +#include +#include + #include #include -#include #include @@ -43,6 +47,66 @@ TEST(AlarmTest, RegularExpiry) { EXPECT_EQ(junk, output_tag); } +struct Completion { + bool completed = false; + std::mutex mu; + std::condition_variable cv; +}; + +TEST(AlarmTest, CallbackRegularExpiry) { + Alarm alarm; + + auto c = std::make_shared(); + alarm.experimental().Set( + std::chrono::system_clock::now() + std::chrono::seconds(1), [c](bool ok) { + EXPECT_TRUE(ok); + std::lock_guard l(c->mu); + c->completed = true; + c->cv.notify_one(); + }); + + std::unique_lock l(c->mu); + EXPECT_TRUE(c->cv.wait_until( + l, std::chrono::system_clock::now() + std::chrono::seconds(10), + [c] { return c->completed; })); +} + +TEST(AlarmTest, CallbackZeroExpiry) { + Alarm alarm; + + auto c = std::make_shared(); + alarm.experimental().Set(grpc_timeout_seconds_to_deadline(0), [c](bool ok) { + EXPECT_TRUE(ok); + std::lock_guard l(c->mu); + c->completed = true; + c->cv.notify_one(); + }); + + std::unique_lock l(c->mu); + EXPECT_TRUE(c->cv.wait_until( + l, std::chrono::system_clock::now() + std::chrono::seconds(10), + [c] { return c->completed; })); +} + +TEST(AlarmTest, CallbackNegativeExpiry) { + Alarm alarm; + + auto c = std::make_shared(); + alarm.experimental().Set( + std::chrono::system_clock::now() + std::chrono::seconds(-1), + [c](bool ok) { + EXPECT_TRUE(ok); + std::lock_guard l(c->mu); + c->completed = true; + c->cv.notify_one(); + }); + + std::unique_lock l(c->mu); + EXPECT_TRUE(c->cv.wait_until( + l, std::chrono::system_clock::now() + std::chrono::seconds(10), + [c] { return c->completed; })); +} + TEST(AlarmTest, MultithreadedRegularExpiry) { CompletionQueue cq; void* junk = reinterpret_cast(1618033); @@ -182,6 +246,26 @@ TEST(AlarmTest, Cancellation) { EXPECT_EQ(junk, output_tag); } +TEST(AlarmTest, CallbackCancellation) { + Alarm alarm; + + auto c = std::make_shared(); + alarm.experimental().Set( + std::chrono::system_clock::now() + std::chrono::seconds(10), + [c](bool ok) { + EXPECT_FALSE(ok); + std::lock_guard l(c->mu); + c->completed = true; + c->cv.notify_one(); + }); + alarm.Cancel(); + + std::unique_lock l(c->mu); + EXPECT_TRUE(c->cv.wait_until( + l, std::chrono::system_clock::now() + std::chrono::seconds(1), + [c] { return c->completed; })); +} + TEST(AlarmTest, SetDestruction) { CompletionQueue cq; void* junk = reinterpret_cast(1618033); @@ -200,6 +284,26 @@ TEST(AlarmTest, SetDestruction) { EXPECT_EQ(junk, output_tag); } +TEST(AlarmTest, CallbackSetDestruction) { + auto c = std::make_shared(); + { + Alarm alarm; + alarm.experimental().Set( + std::chrono::system_clock::now() + std::chrono::seconds(10), + [c](bool ok) { + EXPECT_FALSE(ok); + std::lock_guard l(c->mu); + c->completed = true; + c->cv.notify_one(); + }); + } + + std::unique_lock l(c->mu); + EXPECT_TRUE(c->cv.wait_until( + l, std::chrono::system_clock::now() + std::chrono::seconds(1), + [c] { return c->completed; })); +} + TEST(AlarmTest, UnsetDestruction) { CompletionQueue cq; Alarm alarm; From 2062504cd760ca42ed5226270ba8e984456a4cfa Mon Sep 17 00:00:00 2001 From: Alexander Polcyn Date: Thu, 13 Sep 2018 13:44:04 -0700 Subject: [PATCH 363/546] Follow the no_logging param to parse_ipv6_host_port --- .../filters/client_channel/parse_address.cc | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc index b94429e207e..707beb88769 100644 --- a/src/core/ext/filters/client_channel/parse_address.cc +++ b/src/core/ext/filters/client_channel/parse_address.cc @@ -129,30 +129,37 @@ bool grpc_parse_ipv6_hostport(const char* hostport, grpc_resolved_address* addr, size_t host_without_scope_len = static_cast(host_end - host); uint32_t sin6_scope_id = 0; if (host_without_scope_len > GRPC_INET6_ADDRSTRLEN) { - gpr_log(GPR_ERROR, - "invalid ipv6 address length %zu. Length cannot be greater than " - "GRPC_INET6_ADDRSTRLEN i.e %d)", - host_without_scope_len, GRPC_INET6_ADDRSTRLEN); + if (log_errors) { + gpr_log( + GPR_ERROR, + "invalid ipv6 address length %zu. Length cannot be greater than " + "GRPC_INET6_ADDRSTRLEN i.e %d)", + host_without_scope_len, GRPC_INET6_ADDRSTRLEN); + } goto done; } strncpy(host_without_scope, host, host_without_scope_len); host_without_scope[host_without_scope_len] = '\0'; if (grpc_inet_pton(GRPC_AF_INET6, host_without_scope, &in6->sin6_addr) == 0) { - gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host_without_scope); + if (log_errors) { + gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host_without_scope); + } goto done; } if (gpr_parse_bytes_to_uint32(host_end + 1, strlen(host) - host_without_scope_len - 1, &sin6_scope_id) == 0) { - gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1); + if (log_errors) { + gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1); + } goto done; } // Handle "sin6_scope_id" being type "u_long". See grpc issue #10027. in6->sin6_scope_id = sin6_scope_id; } else { if (grpc_inet_pton(GRPC_AF_INET6, host, &in6->sin6_addr) == 0) { - gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host); + if (log_errors) gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host); goto done; } } From 78f3f44efbc1343aa65e376d2adc61a4f8ccf117 Mon Sep 17 00:00:00 2001 From: Dylan Thacker-Smith Date: Sun, 12 Aug 2018 12:02:51 -0400 Subject: [PATCH 364/546] ruby: Raise instead of hanging if grpc is used before and after fork --- src/ruby/ext/grpc/rb_call.c | 1 + src/ruby/ext/grpc/rb_channel.c | 3 +++ src/ruby/ext/grpc/rb_grpc.c | 32 ++++++++++++++++++++++++- src/ruby/ext/grpc/rb_grpc.h | 2 ++ src/ruby/ext/grpc/rb_server.c | 2 ++ src/ruby/spec/channel_spec.rb | 44 ++++++++++++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c index b6c07914693..fc641dae801 100644 --- a/src/ruby/ext/grpc/rb_call.c +++ b/src/ruby/ext/grpc/rb_call.c @@ -819,6 +819,7 @@ static VALUE grpc_rb_call_run_batch(VALUE self, VALUE ops_hash) { unsigned write_flag = 0; void* tag = (void*)&st; + grpc_ruby_fork_guard(); if (RTYPEDDATA_DATA(self) == NULL) { rb_raise(grpc_rb_eCallError, "Cannot run batch on closed call"); return Qnil; diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index 3f0dc530cfe..6d4b2293a24 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -217,6 +217,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE* argv, VALUE self) { MEMZERO(&args, grpc_channel_args, 1); grpc_ruby_once_init(); + grpc_ruby_fork_guard(); rb_thread_call_without_gvl( wait_until_channel_polling_thread_started_no_gil, &stop_waiting_for_thread_start, @@ -374,6 +375,7 @@ static VALUE grpc_rb_channel_watch_connectivity_state(VALUE self, watch_state_stack stack; void* op_success = 0; + grpc_ruby_fork_guard(); TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper); if (wrapper->bg_wrapped == NULL) { @@ -415,6 +417,7 @@ static VALUE grpc_rb_channel_create_call(VALUE self, VALUE parent, VALUE mask, grpc_slice* host_slice_ptr = NULL; char* tmp_str = NULL; + grpc_ruby_fork_guard(); if (host != Qnil) { host_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(host), RSTRING_LEN(host)); diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c index f065a857db8..872aed0cfce 100644 --- a/src/ruby/ext/grpc/rb_grpc.c +++ b/src/ruby/ext/grpc/rb_grpc.c @@ -23,9 +23,13 @@ #include #include +#include #include +#include +#include #include +#include #include #include "rb_call.h" #include "rb_call_credentials.h" @@ -255,7 +259,26 @@ static void Init_grpc_time_consts() { id_tv_nsec = rb_intern("tv_nsec"); } -static void grpc_rb_shutdown(void) { grpc_shutdown(); } +#if GPR_WINDOWS +static void grpc_ruby_set_init_pid(void) {} +static bool grpc_ruby_forked_after_init(void) { return false; } +#else +static pid_t grpc_init_pid; + +static void grpc_ruby_set_init_pid(void) { + GPR_ASSERT(grpc_init_pid == 0); + grpc_init_pid = getpid(); +} + +static bool grpc_ruby_forked_after_init(void) { + GPR_ASSERT(grpc_init_pid != 0); + return grpc_init_pid != getpid(); +} +#endif + +static void grpc_rb_shutdown(void) { + if (!grpc_ruby_forked_after_init()) grpc_shutdown(); +} /* Initialize the GRPC module structs */ @@ -276,10 +299,17 @@ VALUE sym_metadata = Qundef; static gpr_once g_once_init = GPR_ONCE_INIT; static void grpc_ruby_once_init_internal() { + grpc_ruby_set_init_pid(); grpc_init(); atexit(grpc_rb_shutdown); } +void grpc_ruby_fork_guard() { + if (grpc_ruby_forked_after_init()) { + rb_raise(rb_eRuntimeError, "grpc cannot be used before and after forking"); + } +} + static VALUE bg_thread_init_rb_mu = Qundef; static int bg_thread_init_done = 0; diff --git a/src/ruby/ext/grpc/rb_grpc.h b/src/ruby/ext/grpc/rb_grpc.h index 577902319ed..4118435ecf7 100644 --- a/src/ruby/ext/grpc/rb_grpc.h +++ b/src/ruby/ext/grpc/rb_grpc.h @@ -69,4 +69,6 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval); void grpc_ruby_once_init(); +void grpc_ruby_fork_guard(); + #endif /* GRPC_RB_H_ */ diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c index 88e6a0cfd56..2931f344092 100644 --- a/src/ruby/ext/grpc/rb_server.c +++ b/src/ruby/ext/grpc/rb_server.c @@ -243,6 +243,8 @@ static VALUE grpc_rb_server_request_call(VALUE self) { static VALUE grpc_rb_server_start(VALUE self) { grpc_rb_server* s = NULL; TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s); + + grpc_ruby_fork_guard(); if (s->wrapped == NULL) { rb_raise(rb_eRuntimeError, "destroyed!"); } else { diff --git a/src/ruby/spec/channel_spec.rb b/src/ruby/spec/channel_spec.rb index 3c9eca47ecc..adba6db99cf 100644 --- a/src/ruby/spec/channel_spec.rb +++ b/src/ruby/spec/channel_spec.rb @@ -13,6 +13,7 @@ # limitations under the License. require 'spec_helper' +require 'English' def load_test_certs test_root = File.join(File.dirname(__FILE__), 'testdata') @@ -27,6 +28,28 @@ describe GRPC::Core::Channel do GRPC::Core::ChannelCredentials.new(load_test_certs[0]) end + def fork_with_propagated_error_message + pipe_read, pipe_write = IO.pipe + pid = fork do + pipe_read.close + begin + yield + rescue => exc + pipe_write.syswrite(exc.message) + end + pipe_write.close + end + pipe_write.close + + exc_message = pipe_read.read + Process.wait(pid) + + unless $CHILD_STATUS.success? + raise "forked process failed with #{$CHILD_STATUS}" + end + raise exc_message unless exc_message.empty? + end + shared_examples '#new' do it 'take a host name without channel args' do blk = proc do @@ -79,6 +102,14 @@ describe GRPC::Core::Channel do blk = construct_with_args(args) expect(&blk).to_not raise_error end + + it 'raises if grpc was initialized in another process' do + blk = construct_with_args({}) + expect(&blk).not_to raise_error + expect do + fork_with_propagated_error_message(&blk) + end.to raise_error(RuntimeError, 'grpc cannot be used before and after forking') + end end describe '#new for secure channels' do @@ -121,6 +152,19 @@ describe GRPC::Core::Channel do end expect(&blk).to raise_error(RuntimeError) end + + it 'raises if grpc was initialized in another process' do + ch = GRPC::Core::Channel.new(fake_host, nil, :this_channel_is_insecure) + + deadline = Time.now + 5 + + blk = proc do + fork_with_propagated_error_message do + ch.create_call(nil, nil, 'dummy_method', nil, deadline) + end + end + expect(&blk).to raise_error(RuntimeError, 'grpc cannot be used before and after forking') + end end describe '#destroy' do From 967bbcd5d38e37f3640101a630e660c1276d7ee3 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 13 Sep 2018 15:49:52 -0700 Subject: [PATCH 365/546] Fixing benchmark name and adding a new one --- test/cpp/microbenchmarks/bm_chttp2_hpack.cc | 65 +++++++++++++++++++-- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index 6fcf048bf38..8d1aa3f10ca 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -27,6 +27,7 @@ #include "src/core/ext/transport/chttp2/transport/hpack_encoder.h" #include "src/core/ext/transport/chttp2/transport/hpack_parser.h" +#include "src/core/ext/transport/chttp2/transport/incoming_metadata.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/transport/static_metadata.h" @@ -766,8 +767,59 @@ class RepresentativeServerTrailingMetadata { static void free_timeout(void* p) { gpr_free(p); } -// New implementation. -static void OnHeaderNew(void* user_data, grpc_mdelem md) { +// Benchmark the current on_initial_header implementation +static void OnInitialHeader(void* user_data, grpc_mdelem md) { + // Setup for benchmark. this will bloat the absolute values of this benchmark + grpc_chttp2_incoming_metadata_buffer buffer; + gpr_arena* arena = gpr_arena_create(1024); + grpc_chttp2_incoming_metadata_buffer_init(&buffer, arena); + bool seen_error = false; + + // Below here is the code we actually care about benchmarking + if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && + !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { + seen_error = true; + } + if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) { + grpc_millis* cached_timeout = + static_cast(grpc_mdelem_get_user_data(md, free_timeout)); + grpc_millis timeout; + if (cached_timeout != nullptr) { + timeout = *cached_timeout; + } else { + if (GPR_UNLIKELY( + !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) { + char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); + gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val); + gpr_free(val); + timeout = GRPC_MILLIS_INF_FUTURE; + } + if (GRPC_MDELEM_IS_INTERNED(md)) { + /* not already parsed: parse it now, and store the + * result away */ + cached_timeout = + static_cast(gpr_malloc(sizeof(grpc_millis))); + *cached_timeout = timeout; + grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); + } + } + benchmark::DoNotOptimize(timeout); + GRPC_MDELEM_UNREF(md); + } else { + const size_t new_size = buffer.size + GRPC_MDELEM_LENGTH(md); + if (!seen_error) { + buffer.size = new_size; + } + grpc_error* error = grpc_chttp2_incoming_metadata_buffer_add(&buffer, md); + if (error != GRPC_ERROR_NONE) { + GPR_ASSERT(0); + } + } + gpr_arena_destroy(arena); +} + +// Benchmark timeout handling +static void OnHeaderTimeout(void* user_data, grpc_mdelem md) { if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) { grpc_millis* cached_timeout = static_cast(grpc_mdelem_get_user_data(md, free_timeout)); @@ -853,8 +905,13 @@ BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, RepresentativeServerInitialMetadata, UnrefHeader); BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, RepresentativeServerTrailingMetadata, UnrefHeader); - -BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, SameDeadline, OnHeaderNew); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, + RepresentativeClientInitialMetadata, OnInitialHeader); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, + MoreRepresentativeClientInitialMetadata, OnInitialHeader); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, + RepresentativeServerInitialMetadata, OnInitialHeader); +BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, SameDeadline, OnHeaderTimeout); } // namespace hpack_parser_fixtures From 3729329a3fe9fdb37edd913734f1fbb35f3e3d77 Mon Sep 17 00:00:00 2001 From: Stephan Zehetner Date: Fri, 14 Sep 2018 14:35:45 +0200 Subject: [PATCH 366/546] avoid byte[] allocation when reading empty strings from native memory --- src/csharp/Grpc.Core/Internal/MarshalUtils.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs index 3f9605bfddb..73b7a2ef95f 100644 --- a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs +++ b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs @@ -35,6 +35,9 @@ namespace Grpc.Core.Internal /// public static string PtrToStringUTF8(IntPtr ptr, int len) { + if (len == 0) + return ""; + var bytes = new byte[len]; Marshal.Copy(ptr, bytes, 0, len); return EncodingUTF8.GetString(bytes); From d16d13a9762e6b6bb9d91b32bf73e2dc480a1d13 Mon Sep 17 00:00:00 2001 From: Stephan Zehetner Date: Fri, 14 Sep 2018 15:38:15 +0200 Subject: [PATCH 367/546] avoid Tuple allocation in ClientBaseConfigurationInterceptor --- src/csharp/Grpc.Core/ClientBase.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/csharp/Grpc.Core/ClientBase.cs b/src/csharp/Grpc.Core/ClientBase.cs index fac34071bed..05edce7467d 100644 --- a/src/csharp/Grpc.Core/ClientBase.cs +++ b/src/csharp/Grpc.Core/ClientBase.cs @@ -151,12 +151,12 @@ namespace Grpc.Core { private class ClientBaseConfigurationInterceptor : Interceptor { - readonly Func> interceptor; + readonly Func interceptor; /// /// Creates a new instance of ClientBaseConfigurationInterceptor given the specified header and host interceptor function. /// - public ClientBaseConfigurationInterceptor(Func> interceptor) + public ClientBaseConfigurationInterceptor(Func interceptor) { this.interceptor = GrpcPreconditions.CheckNotNull(interceptor, nameof(interceptor)); } @@ -166,7 +166,7 @@ namespace Grpc.Core where TResponse : class { var newHostAndCallOptions = interceptor(context.Method, context.Host, context.Options); - return new ClientInterceptorContext(context.Method, newHostAndCallOptions.Item1, newHostAndCallOptions.Item2); + return new ClientInterceptorContext(context.Method, newHostAndCallOptions.Host, newHostAndCallOptions.CallOptions); } public override TResponse BlockingUnaryCall(TRequest request, ClientInterceptorContext context, BlockingUnaryCallContinuation continuation) @@ -195,6 +195,18 @@ namespace Grpc.Core } } + internal struct ClientBaseConfigurationInfo + { + internal readonly string Host; + internal readonly CallOptions CallOptions; + + internal ClientBaseConfigurationInfo(string host, CallOptions callOptions) + { + Host = host; + CallOptions = callOptions; + } + } + readonly CallInvoker undecoratedCallInvoker; readonly string host; @@ -206,7 +218,7 @@ namespace Grpc.Core internal CallInvoker CreateDecoratedCallInvoker() { - return undecoratedCallInvoker.Intercept(new ClientBaseConfigurationInterceptor((method, host, options) => Tuple.Create(this.host, options))); + return undecoratedCallInvoker.Intercept(new ClientBaseConfigurationInterceptor((method, host, options) => new ClientBaseConfigurationInfo(this.host, options))); } internal ClientBaseConfiguration WithHost(string host) From 59f8157123fa1f1040ee525f7886861850281809 Mon Sep 17 00:00:00 2001 From: Stephan Zehetner Date: Fri, 14 Sep 2018 15:41:00 +0200 Subject: [PATCH 368/546] optimize Metadata.Entry normalization and validation check. Replaced Regex with custom loop, avoid string allocation if input is already lowercase. --- src/csharp/Grpc.Core/Metadata.cs | 37 +++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs index 281952d6d41..122c1e88830 100644 --- a/src/csharp/Grpc.Core/Metadata.cs +++ b/src/csharp/Grpc.Core/Metadata.cs @@ -225,8 +225,6 @@ namespace Grpc.Core /// public class Entry { - private static readonly Regex ValidKeyRegex = new Regex("^[.a-z0-9_-]+$"); - readonly string key; readonly string value; readonly byte[] valueBytes; @@ -358,10 +356,39 @@ namespace Grpc.Core private static string NormalizeKey(string key) { - var normalized = GrpcPreconditions.CheckNotNull(key, "key").ToLowerInvariant(); - GrpcPreconditions.CheckArgument(ValidKeyRegex.IsMatch(normalized), + GrpcPreconditions.CheckNotNull(key, "key"); + + GrpcPreconditions.CheckArgument(IsValidKey(key, out bool isLowercase), "Metadata entry key not valid. Keys can only contain lowercase alphanumeric characters, underscores, hyphens and dots."); - return normalized; + if (isLowercase) + return key; + + return key.ToLowerInvariant(); + } + + private static bool IsValidKey(string input, out bool isLowercase) + { + isLowercase = true; + for (int i = 0; i < input.Length; i++) + { + char c = input[i]; + if ('a' <= c && c <= 'z' || + '0' <= c && c <= '9' || + c == '.' || + c == '_' || + c == '-' ) + continue; + + if ('A' <= c && c <= 'Z') + { + isLowercase = false; + continue; + } + + return false; + } + + return true; } /// From 3fe2c98877f376cc0c8d7da61d6e63eca83f4bec Mon Sep 17 00:00:00 2001 From: Nick Gordon Date: Mon, 16 Jul 2018 10:11:56 -0700 Subject: [PATCH 369/546] Updates to the ruby generator for protobuf 3.6.0 changes test for verifying the ruby_package option added WeWork to the AUTHORS file --- AUTHORS | 1 + src/compiler/ruby_generator.cc | 12 ++++- src/proto/grpc/testing/package_options.proto | 28 ++++++++++ .../spec/pb/codegen/package_option_spec.rb | 53 +++++++++++++++++++ 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 src/proto/grpc/testing/package_options.proto create mode 100644 src/ruby/spec/pb/codegen/package_option_spec.rb diff --git a/AUTHORS b/AUTHORS index e491a9e7f78..3e130afda2d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,2 @@ Google Inc. +WeWork Companies Inc. diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc index c7af9c38fad..e39d8be5d41 100644 --- a/src/compiler/ruby_generator.cc +++ b/src/compiler/ruby_generator.cc @@ -160,12 +160,20 @@ grpc::string GetServices(const FileDescriptor* file) { return output; } + std::string package_name; + + if (file->options().has_ruby_package()) { + package_name = file->options().ruby_package(); + } else { + package_name = file->package(); + } + // Write out a file header. std::map header_comment_vars = ListToDict({ "file.name", file->name(), "file.package", - file->package(), + package_name, }); out.Print("# Generated by the protocol buffer compiler. DO NOT EDIT!\n"); out.Print(header_comment_vars, @@ -190,7 +198,7 @@ grpc::string GetServices(const FileDescriptor* file) { // Write out services within the modules out.Print("\n"); - std::vector modules = Split(file->package(), '.'); + std::vector modules = Split(package_name, '.'); for (size_t i = 0; i < modules.size(); ++i) { std::map module_vars = ListToDict({ "module.name", diff --git a/src/proto/grpc/testing/package_options.proto b/src/proto/grpc/testing/package_options.proto new file mode 100644 index 00000000000..e7ecf8c196a --- /dev/null +++ b/src/proto/grpc/testing/package_options.proto @@ -0,0 +1,28 @@ +// 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. + +syntax = "proto3"; + +package grpc.testing; + +// For sanity checking package definitions +option ruby_package = "Grpc.Testing.Package.Options"; + +message TestRequest { } + +message TestResponse { } + +service TestService { + rpc GetTest(TestRequest) returns (TestResponse) { } +} diff --git a/src/ruby/spec/pb/codegen/package_option_spec.rb b/src/ruby/spec/pb/codegen/package_option_spec.rb new file mode 100644 index 00000000000..46d23cd6518 --- /dev/null +++ b/src/ruby/spec/pb/codegen/package_option_spec.rb @@ -0,0 +1,53 @@ +# 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. + +require 'spec_helper' +require 'open3' +require 'tmpdir' + +describe 'Code Generation Options' do + it 'should generate and respect package options' do + fail 'CONFIG env variable unexpectedly unset' unless ENV['CONFIG'] + bins_sub_dir = ENV['CONFIG'] + + src_dir = File.join(File.dirname(__FILE__), '..', '..', '..', '..') + pb_dir = File.join(src_dir, 'proto') + bins_dir = File.join(src_dir, '..', 'bins', bins_sub_dir) + + plugin = File.join(bins_dir, 'grpc_ruby_plugin') + protoc = File.join(bins_dir, 'protobuf', 'protoc') + + # Generate the service from the proto + Dir.mktmpdir(nil, File.dirname(__FILE__)) do |tmp_dir| + gen_file = system(protoc, + '-I.', + 'grpc/testing/package_options.proto', + "--grpc_out=#{tmp_dir}", # generate the service + "--ruby_out=#{tmp_dir}", # generate the definitions + "--plugin=protoc-gen-grpc=#{plugin}", + chdir: pb_dir, + out: File::NULL) + + expect(gen_file).to be_truthy + begin + $LOAD_PATH.push(tmp_dir) + expect { Grpc::Testing::Package::Options::TestService::Service }.to raise_error(NameError) + expect(require('grpc/testing/package_options_services_pb')).to be_truthy + expect { Grpc::Testing::Package::Options::TestService::Service }.to_not raise_error + ensure + $LOAD_PATH.delete(tmp_dir) + end + end + end +end From 709e1aa111de0016a0e760ee881a8d06c8924cbe Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 14 Sep 2018 17:28:50 +0200 Subject: [PATCH 370/546] C# distrib test flake workaround --- test/distrib/csharp/run_distrib_test.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/distrib/csharp/run_distrib_test.sh b/test/distrib/csharp/run_distrib_test.sh index f9371410e7b..61924b91df8 100755 --- a/test/distrib/csharp/run_distrib_test.sh +++ b/test/distrib/csharp/run_distrib_test.sh @@ -21,7 +21,8 @@ unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets_windows_dotnetcli.zip ./update_version.sh auto -nuget restore +# Retry "nuget restore" to work around https://github.com/grpc/grpc/issues/16312 +nuget restore || nuget restore || nuget restore xbuild DistribTest.sln From bfcde072c9388de75711b8d1a02743c471d01375 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 14 Sep 2018 10:59:32 -0700 Subject: [PATCH 371/546] run_tests_matrix: everything runs on kokoro --- tools/run_tests/run_tests_matrix.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index 0af9e0cbbe1..3bc3bcec23d 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -53,12 +53,7 @@ def _safe_report_name(name): def _report_filename(name): - """Generates report file name""" - return 'report_%s_%s' % (_safe_report_name(name), _REPORT_SUFFIX) - - -def _report_filename_internal_ci(name): - """Generates report file name that leads to better presentation by internal CI""" + """Generates report file name with directory structure that leads to better presentation by internal CI""" return '%s/%s' % (_safe_report_name(name), _REPORT_SUFFIX) @@ -507,8 +502,8 @@ if __name__ == "__main__": default=False, action='store_const', const=True, - help='Put reports into subdirectories to improve presentation of ' - 'results by Internal CI.') + help='(Deprecated, has no effect) Put reports into subdirectories to improve presentation of ' + 'results by Kokoro.') argp.add_argument( '--bq_result_table', default='', @@ -517,9 +512,6 @@ if __name__ == "__main__": help='Upload test results to a specified BQ table.') args = argp.parse_args() - if args.internal_ci: - _report_filename = _report_filename_internal_ci # override the function - extra_args = [] if args.build_only: extra_args.append('--build_only') From ee69685f796f5516d76ea7765f787c4285bd544c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 14 Sep 2018 13:24:26 -0700 Subject: [PATCH 372/546] yapf code --- tools/run_tests/run_tests_matrix.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index 3bc3bcec23d..1bbec94ee12 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -502,7 +502,8 @@ if __name__ == "__main__": default=False, action='store_const', const=True, - help='(Deprecated, has no effect) Put reports into subdirectories to improve presentation of ' + help= + '(Deprecated, has no effect) Put reports into subdirectories to improve presentation of ' 'results by Kokoro.') argp.add_argument( '--bq_result_table', From 73d89a66f90eb8cf5e9b8939690ebf7347fba147 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 14 Sep 2018 14:31:48 -0700 Subject: [PATCH 373/546] Catch exceptions in user callbacks --- include/grpcpp/impl/codegen/callback_common.h | 4 +++ src/cpp/common/callback_common.cc | 28 +++++++++++++++---- .../end2end/client_callback_end2end_test.cc | 20 ++++++++++--- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index 68c318d2b44..8b3ad66a8d3 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -35,6 +35,10 @@ class CQCallbackInterface; namespace grpc { namespace internal { +// The contract on these tags is that they are single-shot. They must be +// constructed and then fired at exactly one point. There is no expectation +// that they can be reused without reconstruction. + class CallbackWithStatusTag { public: // always allocated against a call arena, no memory free required diff --git a/src/cpp/common/callback_common.cc b/src/cpp/common/callback_common.cc index ae47901f1be..fa586286d1c 100644 --- a/src/cpp/common/callback_common.cc +++ b/src/cpp/common/callback_common.cc @@ -26,8 +26,21 @@ namespace grpc { namespace internal { - namespace { + +template +void CatchingCallback(Func&& func, Arg&& arg) { +#if GRPC_ALLOW_EXCEPTIONS + try { + func(arg); + } catch (...) { + // nothing to return or change here, just don't crash the library + } +#else // GRPC_ALLOW_EXCEPTIONS + func(arg); +#endif // GRPC_ALLOW_EXCEPTIONS +} + class CallbackWithSuccessImpl : public grpc_core::CQCallbackInterface { public: static void operator delete(void* ptr, std::size_t size) { @@ -52,8 +65,11 @@ class CallbackWithSuccessImpl : public grpc_core::CQCallbackInterface { bool new_ok = ok; GPR_ASSERT(parent_->ops()->FinalizeResult(&ignored, &new_ok)); GPR_ASSERT(ignored == parent_->ops()); - func_(ok); - func_ = nullptr; // release the function + + // Last use of func_ or ok, so ok to move them out for rvalue call above + CatchingCallback(std::move(func_), std::move(ok)); + + func_ = nullptr; // reset to clear this out for sure grpc_call_unref(call_); } @@ -88,8 +104,10 @@ class CallbackWithStatusImpl : public grpc_core::CQCallbackInterface { GPR_ASSERT(parent_->ops()->FinalizeResult(&ignored, &ok)); GPR_ASSERT(ignored == parent_->ops()); - func_(status_); - func_ = nullptr; // release the function + // Last use of func_ or status_, so ok to move them out + CatchingCallback(std::move(func_), std::move(status_)); + + func_ = nullptr; // reset to clear this out for sure grpc_call_unref(call_); } Status* status_ptr() { return &status_; } diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 75b896b33d8..3b492090dd1 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -64,7 +64,7 @@ class ClientCallbackEnd2endTest : public ::testing::Test { } } - void SendRpcs(int num_rpcs) { + void SendRpcs(int num_rpcs, bool maybe_except) { const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo"); grpc::string test_string(""); for (int i = 0; i < num_rpcs; i++) { @@ -82,7 +82,7 @@ class ClientCallbackEnd2endTest : public ::testing::Test { bool done = false; stub_->experimental().UnaryCall( &cli_ctx, kMethodName, send_buf.get(), &recv_buf, - [&request, &recv_buf, &done, &mu, &cv](Status s) { + [&request, &recv_buf, &done, &mu, &cv, maybe_except](Status s) { GPR_ASSERT(s.ok()); EchoResponse response; @@ -91,6 +91,11 @@ class ClientCallbackEnd2endTest : public ::testing::Test { std::lock_guard l(mu); done = true; cv.notify_one(); +#if GRPC_ALLOW_EXCEPTIONS + if (maybe_except) { + throw - 1; + } +#endif }); std::unique_lock l(mu); while (!done) { @@ -107,14 +112,21 @@ class ClientCallbackEnd2endTest : public ::testing::Test { TEST_F(ClientCallbackEnd2endTest, SimpleRpc) { ResetStub(); - SendRpcs(1); + SendRpcs(1, false); } TEST_F(ClientCallbackEnd2endTest, SequentialRpcs) { ResetStub(); - SendRpcs(10); + SendRpcs(10, false); } +#if GRPC_ALLOW_EXCEPTIONS +TEST_F(ClientCallbackEnd2endTest, ExceptingRpc) { + ResetStub(); + SendRpcs(10, true); +} +#endif + } // namespace } // namespace testing } // namespace grpc From 4009616b581224748b385ffd3d95b024ec4fc1bb Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 14 Sep 2018 18:02:30 -0700 Subject: [PATCH 374/546] Reviewer comments --- .../filters/http/client/http_client_filter.cc | 13 +++--- .../filters/http/server/http_server_filter.cc | 16 +++---- .../message_size/message_size_filter.cc | 14 +++--- .../security/transport/server_auth_filter.cc | 34 ++++++++------- src/core/lib/surface/server.cc | 43 +++++++++++++++---- 5 files changed, 76 insertions(+), 44 deletions(-) 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 e4030afcb45..6b41300f913 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -58,6 +58,8 @@ struct call_data { grpc_metadata_batch* recv_trailing_metadata; grpc_closure* original_recv_trailing_metadata_ready; grpc_closure recv_trailing_metadata_ready; + grpc_error* recv_trailing_metadata_error; + bool seen_recv_trailing_metadata_ready; // State for handling send_message ops. grpc_transport_stream_op_batch* send_message_batch; size_t send_message_bytes_read; @@ -67,8 +69,6 @@ struct call_data { grpc_closure on_send_message_next_done; grpc_closure* original_send_message_on_complete; grpc_closure send_message_on_complete; - grpc_error* recv_trailing_metadata_err; - bool seen_recv_trailing_metadata_ready; }; struct channel_data { @@ -164,7 +164,7 @@ static void recv_initial_metadata_ready(void* user_data, grpc_error* error) { if (calld->seen_recv_trailing_metadata_ready) { GRPC_CALL_COMBINER_START( calld->call_combiner, &calld->recv_trailing_metadata_ready, - calld->recv_trailing_metadata_err, "continue recv trailing metadata"); + calld->recv_trailing_metadata_error, "continue recv_trailing_metadata"); } GRPC_CLOSURE_RUN(closure, error); } @@ -173,12 +173,14 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); if (calld->original_recv_initial_metadata_ready != nullptr) { - calld->recv_trailing_metadata_err = GRPC_ERROR_REF(error); + calld->recv_trailing_metadata_error = GRPC_ERROR_REF(error); calld->seen_recv_trailing_metadata_ready = true; GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, recv_trailing_metadata_ready, elem, grpc_schedule_on_exec_ctx); - GRPC_CALL_COMBINER_STOP(calld->call_combiner, "wait for initial metadata"); + GRPC_CALL_COMBINER_STOP(calld->call_combiner, + "deferring recv_trailing_metadata_ready until " + "after recv_initial_metadata_ready"); return; } if (error == GRPC_ERROR_NONE) { @@ -445,7 +447,6 @@ static grpc_error* init_call_elem(grpc_call_element* elem, const grpc_call_element_args* args) { call_data* calld = static_cast(elem->call_data); calld->call_combiner = args->call_combiner; - calld->seen_recv_trailing_metadata_ready = false; GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready, recv_initial_metadata_ready, elem, grpc_schedule_on_exec_ctx); 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 cd3cab134a0..d5e0663c680 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -63,9 +63,9 @@ struct call_data { grpc_core::OrphanablePtr* recv_message; bool seen_recv_message_ready; + // State for intercepting recv_trailing_metadata grpc_closure recv_trailing_metadata_ready; grpc_closure* original_recv_trailing_metadata_ready; - grpc_error* recv_trailing_metadata_ready_error; bool seen_recv_trailing_metadata_ready; }; @@ -304,15 +304,14 @@ static void hs_recv_initial_metadata_ready(void* user_data, grpc_error* err) { } else { GRPC_ERROR_REF(err); } - grpc_closure* closure = calld->original_recv_initial_metadata_ready; - calld->original_recv_initial_metadata_ready = nullptr; if (calld->seen_recv_trailing_metadata_ready) { GRPC_CALL_COMBINER_START(calld->call_combiner, &calld->recv_trailing_metadata_ready, calld->recv_trailing_metadata_ready_error, - "continue recv trailing metadata"); + "resuming hs_recv_trailing_metadata_ready from " + "hs_recv_initial_metadata_ready"); } - GRPC_CLOSURE_RUN(closure, err); + GRPC_CLOSURE_RUN(calld->original_recv_initial_metadata_ready, err); } static void hs_recv_message_ready(void* user_data, grpc_error* err) { @@ -342,13 +341,15 @@ static void hs_recv_message_ready(void* user_data, grpc_error* err) { static void hs_recv_trailing_metadata_ready(void* user_data, grpc_error* err) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); - if (calld->original_recv_initial_metadata_ready) { + if (!calld->seen_recv_initial_metadata_ready) { calld->recv_trailing_metadata_ready_error = GRPC_ERROR_REF(err); calld->seen_recv_trailing_metadata_ready = true; GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, hs_recv_trailing_metadata_ready, elem, grpc_schedule_on_exec_ctx); - GRPC_CALL_COMBINER_STOP(calld->call_combiner, "wait for initial metadata"); + GRPC_CALL_COMBINER_STOP(calld->call_combiner, + "deferring hs_recv_trailing_metadata_ready until " + "ater hs_recv_initial_metadata_ready"); return; } err = grpc_error_add_child( @@ -435,7 +436,6 @@ static grpc_error* hs_init_call_elem(grpc_call_element* elem, const grpc_call_element_args* args) { call_data* calld = static_cast(elem->call_data); calld->call_combiner = args->call_combiner; - calld->seen_recv_trailing_metadata_ready = false; GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready, hs_recv_initial_metadata_ready, elem, grpc_schedule_on_exec_ctx); 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 d85c299abe8..a32ba21c30e 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -152,9 +152,10 @@ static void recv_message_ready(void* user_data, grpc_error* error) { grpc_closure* closure = calld->next_recv_message_ready; calld->next_recv_message_ready = nullptr; if (calld->seen_recv_trailing_metadata) { - GRPC_CALL_COMBINER_START( - calld->call_combiner, &calld->recv_trailing_metadata_ready, - calld->recv_trailing_metadata_error, "continue recv trailing metadata"); + GRPC_CALL_COMBINER_START(calld->call_combiner, + &calld->recv_trailing_metadata_ready, + calld->recv_trailing_metadata_error, + "continue recv_trailing_metadata_ready"); } GRPC_CLOSURE_RUN(closure, error); } @@ -164,13 +165,15 @@ static void recv_message_ready(void* user_data, grpc_error* error) { static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); - if (calld->next_recv_message_ready) { + if (calld->next_recv_message_ready != nullptr) { calld->seen_recv_trailing_metadata = true; calld->recv_trailing_metadata_error = GRPC_ERROR_REF(error); GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, recv_trailing_metadata_ready, elem, grpc_schedule_on_exec_ctx); - GRPC_CALL_COMBINER_STOP(calld->call_combiner, "wait for recv message"); + GRPC_CALL_COMBINER_STOP(calld->call_combiner, + "deferring recv_trailing_metadata_ready until " + "after recv_message_ready"); return; } error = @@ -227,7 +230,6 @@ static grpc_error* init_call_elem(grpc_call_element* elem, calld->next_recv_message_ready = nullptr; calld->original_recv_trailing_metadata_ready = nullptr; calld->error = GRPC_ERROR_NONE; - calld->seen_recv_trailing_metadata = false; GRPC_CLOSURE_INIT(&calld->recv_message_ready, recv_message_ready, elem, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc index 882f9859599..352355ea678 100644 --- a/src/core/lib/security/transport/server_auth_filter.cc +++ b/src/core/lib/security/transport/server_auth_filter.cc @@ -41,16 +41,16 @@ struct call_data { grpc_transport_stream_op_batch* recv_initial_metadata_batch; grpc_closure* original_recv_initial_metadata_ready; grpc_closure recv_initial_metadata_ready; - grpc_error* error; + grpc_error* recv_initial_metadata_error; grpc_closure recv_trailing_metadata_ready; grpc_closure* original_recv_trailing_metadata_ready; + grpc_error* recv_trailing_metadata_error; + bool seen_recv_trailing_ready; grpc_metadata_array md; const grpc_metadata* consumed_md; size_t num_consumed_md; grpc_closure cancel_closure; gpr_atm state; // async_state - grpc_error* recv_trailing_metadata_error; - bool seen_recv_trailing_ready; }; struct channel_data { @@ -116,13 +116,14 @@ static void on_md_processing_done_inner(grpc_call_element* elem, batch->payload->recv_initial_metadata.recv_initial_metadata, remove_consumed_md, elem, "Response metadata filtering error"); } - calld->error = GRPC_ERROR_REF(error); + calld->recv_initial_metadata_error = GRPC_ERROR_REF(error); grpc_closure* closure = calld->original_recv_initial_metadata_ready; calld->original_recv_initial_metadata_ready = nullptr; if (calld->seen_recv_trailing_ready) { - GRPC_CALL_COMBINER_START( - calld->call_combiner, &calld->recv_trailing_metadata_ready, - calld->recv_trailing_metadata_error, "continue recv trailing metadata"); + GRPC_CALL_COMBINER_START(calld->call_combiner, + &calld->recv_trailing_metadata_ready, + calld->recv_trailing_metadata_error, + "continue recv_trailing_metadata_ready"); } GRPC_CLOSURE_SCHED(closure, error); } @@ -196,9 +197,10 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { grpc_closure* closure = calld->original_recv_initial_metadata_ready; calld->original_recv_initial_metadata_ready = nullptr; if (calld->seen_recv_trailing_ready) { - GRPC_CALL_COMBINER_START( - calld->call_combiner, &calld->recv_trailing_metadata_ready, - calld->recv_trailing_metadata_error, "continue recv trailing metadata"); + GRPC_CALL_COMBINER_START(calld->call_combiner, + &calld->recv_trailing_metadata_ready, + calld->recv_trailing_metadata_error, + "continue recv_trailing_metadata_ready"); } GRPC_CLOSURE_RUN(closure, GRPC_ERROR_REF(error)); } @@ -206,15 +208,18 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { static void recv_trailing_metadata_ready(void* user_data, grpc_error* err) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); - if (calld->original_recv_initial_metadata_ready) { + if (calld->original_recv_initial_metadata_ready != nullptr) { calld->recv_trailing_metadata_error = GRPC_ERROR_REF(err); calld->seen_recv_trailing_ready = true; GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, recv_trailing_metadata_ready, elem, grpc_schedule_on_exec_ctx); - GRPC_CALL_COMBINER_STOP(calld->call_combiner, "wait for initial metadata"); + GRPC_CALL_COMBINER_STOP(calld->call_combiner, + "deferring recv_trailing_metadata_ready until " + "after recv_initial_metadata_ready"); } - err = grpc_error_add_child(GRPC_ERROR_REF(err), GRPC_ERROR_REF(calld->error)); + err = grpc_error_add_child( + GRPC_ERROR_REF(err), GRPC_ERROR_REF(calld->recv_initial_metadata_error)); GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); } @@ -251,7 +256,6 @@ static grpc_error* init_call_elem(grpc_call_element* elem, GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, recv_trailing_metadata_ready, elem, grpc_schedule_on_exec_ctx); - calld->seen_recv_trailing_ready = false; // Create server security context. Set its auth context from channel // data and save it in the call context. grpc_server_security_context* server_ctx = @@ -273,7 +277,7 @@ static void destroy_call_elem(grpc_call_element* elem, const grpc_call_final_info* final_info, grpc_closure* ignored) { call_data* calld = static_cast(elem->call_data); - GRPC_ERROR_UNREF(calld->error); + GRPC_ERROR_UNREF(calld->recv_initial_metadata_error); } /* Constructor for channel_data */ diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 5fa58ffdec2..1b22db98ebf 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -150,12 +150,15 @@ struct call_data { grpc_closure kill_zombie_closure; grpc_closure* on_done_recv_initial_metadata; grpc_closure recv_trailing_metadata_ready; - grpc_error* error; + grpc_error* recv_initial_metadata_error; grpc_closure* original_recv_trailing_metadata_ready; + grpc_error* recv_trailing_metadata_error; + bool seen_recv_trailing_metadata_ready; grpc_closure publish; call_data* pending_next; + grpc_call_combiner* call_combiner; }; struct request_matcher { @@ -730,18 +733,39 @@ static void server_on_recv_initial_metadata(void* ptr, grpc_error* error) { grpc_error* src_error = error; error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Missing :authority or :path", &error, 1); - GRPC_ERROR_UNREF(src_error); - } - - GRPC_CLOSURE_RUN(calld->on_done_recv_initial_metadata, error); + /* Pass the src_error reference to calld->recv_initial_metadata_error */ + calld->recv_initial_metadata_error = src_error; + } + grpc_closure* closure = calld->on_done_recv_initial_metadata; + calld->on_done_recv_initial_metadata = nullptr; + if (calld->seen_recv_trailing_metadata_ready) { + GRPC_CALL_COMBINER_START(calld->call_combiner, + &calld->recv_trailing_metadata_ready, + calld->recv_trailing_metadata_error, + "continue server_recv_trailing_metadata_ready"); + } + GRPC_CLOSURE_RUN(closure, error); } static void server_recv_trailing_metadata_ready(void* user_data, - grpc_error* err) { + grpc_error* error) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); - err = grpc_error_add_child(GRPC_ERROR_REF(err), GRPC_ERROR_REF(calld->error)); - GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); + if (calld->on_done_recv_initial_metadata != nullptr) { + calld->recv_trailing_metadata_error = GRPC_ERROR_REF(error); + calld->seen_recv_trailing_metadata_ready = true; + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, + server_recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); + GRPC_CALL_COMBINER_STOP(calld->call_combiner, + "deferring server_recv_trailing_metadata_ready " + "until after server_on_recv_initial_metadata"); + return; + } + error = + grpc_error_add_child(GRPC_ERROR_REF(error), + GRPC_ERROR_REF(calld->recv_initial_metadata_error)); + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, error); } static void server_mutate_op(grpc_call_element* elem, @@ -845,6 +869,7 @@ static grpc_error* init_call_elem(grpc_call_element* elem, memset(calld, 0, sizeof(call_data)); calld->deadline = GRPC_MILLIS_INF_FUTURE; calld->call = grpc_call_from_top_element(elem); + calld->call_combiner = args->call_combiner; GRPC_CLOSURE_INIT(&calld->server_on_recv_initial_metadata, server_on_recv_initial_metadata, elem, @@ -863,7 +888,7 @@ static void destroy_call_elem(grpc_call_element* elem, call_data* calld = static_cast(elem->call_data); GPR_ASSERT(calld->state != PENDING); - GRPC_ERROR_UNREF(calld->error); + GRPC_ERROR_UNREF(calld->recv_initial_metadata_error); if (calld->host_set) { grpc_slice_unref_internal(calld->host); } From 51dbd906d6d9793a827a3b253f375dd117974ccb Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 14 Sep 2018 18:18:28 -0700 Subject: [PATCH 375/546] Convert status_error to an atomic because it can be accessed from different threads at the same time --- src/core/lib/surface/call.cc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 11b438f5dc8..a9349afa68a 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -207,7 +207,7 @@ struct grpc_call { grpc_server* server; } server; } final_op; - grpc_error* status_error; + gpr_atm status_error; /* recv_state can contain one of the following values: RECV_NONE : : no initial metadata and messages received @@ -519,10 +519,12 @@ static void destroy_call(void* call, grpc_error* error) { GRPC_CQ_INTERNAL_UNREF(c->cq, "bind"); } - grpc_error_get_status(c->status_error, c->send_deadline, + grpc_error* status_error = + reinterpret_cast(gpr_atm_acq_load(&c->status_error)); + grpc_error_get_status(status_error, c->send_deadline, &c->final_info.final_status, nullptr, nullptr, &(c->final_info.error_string)); - GRPC_ERROR_UNREF(c->status_error); + GRPC_ERROR_UNREF(status_error); c->final_info.stats.latency = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time); @@ -705,7 +707,7 @@ static void set_final_status(grpc_call* call, grpc_error* error) { call->final_op.client.error_string); // explicitly take a ref grpc_slice_ref_internal(*call->final_op.client.status_details); - call->status_error = error; + gpr_atm_rel_store(&call->status_error, reinterpret_cast(error)); grpc_core::channelz::ChannelNode* channelz_channel = grpc_channel_get_channelz_node(call->channel); if (channelz_channel != nullptr) { @@ -717,7 +719,9 @@ static void set_final_status(grpc_call* call, grpc_error* error) { } } else { *call->final_op.server.cancelled = - error != GRPC_ERROR_NONE || call->status_error != GRPC_ERROR_NONE; + error != GRPC_ERROR_NONE || + reinterpret_cast(gpr_atm_acq_load(&call->status_error)) != + GRPC_ERROR_NONE; grpc_core::channelz::ServerNode* channelz_server = grpc_server_get_channelz_node(call->final_op.server.server); if (channelz_server != nullptr) { @@ -1686,7 +1690,8 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops, } } - call->status_error = status_error; + gpr_atm_rel_store(&call->status_error, + reinterpret_cast(status_error)); if (!prepare_application_metadata( call, static_cast( From 3586ac1c991f7d33f03e05b258ecfe09c5aa1b11 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Mon, 17 Sep 2018 11:06:13 -0700 Subject: [PATCH 376/546] Fix SSL channel credential when an argument is None --- .../grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 38fd9e78b2d..63048e8da0d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -144,8 +144,14 @@ cdef class SSLChannelCredentials(ChannelCredentials): return grpc_ssl_credentials_create( c_pem_root_certificates, NULL, NULL, NULL) else: - c_pem_key_certificate_pair.private_key = self._private_key - c_pem_key_certificate_pair.certificate_chain = self._certificate_chain + if self._private_key: + c_pem_key_certificate_pair.private_key = self._private_key + else: + c_pem_key_certificate_pair.private_key = NULL + if self._certificate_chain: + c_pem_key_certificate_pair.certificate_chain = self._certificate_chain + else: + c_pem_key_certificate_pair.certificate_chain = NULL return grpc_ssl_credentials_create( c_pem_root_certificates, &c_pem_key_certificate_pair, NULL, NULL) From 98048811a46b107e44f82e02a500e35442079529 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 17 Sep 2018 13:43:56 -0700 Subject: [PATCH 377/546] Reviewer comments --- .../ext/filters/http/client/http_client_filter.cc | 3 --- .../ext/filters/http/server/http_server_filter.cc | 3 --- .../ext/filters/message_size/message_size_filter.cc | 3 --- .../lib/security/transport/server_auth_filter.cc | 12 +++++------- src/core/lib/surface/server.cc | 9 ++++----- 5 files changed, 9 insertions(+), 21 deletions(-) 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 6b41300f913..cd459e47cd2 100644 --- a/src/core/ext/filters/http/client/http_client_filter.cc +++ b/src/core/ext/filters/http/client/http_client_filter.cc @@ -175,9 +175,6 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { if (calld->original_recv_initial_metadata_ready != nullptr) { calld->recv_trailing_metadata_error = GRPC_ERROR_REF(error); calld->seen_recv_trailing_metadata_ready = true; - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, - recv_trailing_metadata_ready, elem, - grpc_schedule_on_exec_ctx); GRPC_CALL_COMBINER_STOP(calld->call_combiner, "deferring recv_trailing_metadata_ready until " "after recv_initial_metadata_ready"); 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 d5e0663c680..436ea09d942 100644 --- a/src/core/ext/filters/http/server/http_server_filter.cc +++ b/src/core/ext/filters/http/server/http_server_filter.cc @@ -344,9 +344,6 @@ static void hs_recv_trailing_metadata_ready(void* user_data, grpc_error* err) { if (!calld->seen_recv_initial_metadata_ready) { calld->recv_trailing_metadata_ready_error = GRPC_ERROR_REF(err); calld->seen_recv_trailing_metadata_ready = true; - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, - hs_recv_trailing_metadata_ready, elem, - grpc_schedule_on_exec_ctx); GRPC_CALL_COMBINER_STOP(calld->call_combiner, "deferring hs_recv_trailing_metadata_ready until " "ater hs_recv_initial_metadata_ready"); 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 a32ba21c30e..6396d656062 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -168,9 +168,6 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error) { if (calld->next_recv_message_ready != nullptr) { calld->seen_recv_trailing_metadata = true; calld->recv_trailing_metadata_error = GRPC_ERROR_REF(error); - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, - recv_trailing_metadata_ready, elem, - grpc_schedule_on_exec_ctx); GRPC_CALL_COMBINER_STOP(calld->call_combiner, "deferring recv_trailing_metadata_ready until " "after recv_message_ready"); diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc index 352355ea678..b99fc5e1783 100644 --- a/src/core/lib/security/transport/server_auth_filter.cc +++ b/src/core/lib/security/transport/server_auth_filter.cc @@ -45,7 +45,7 @@ struct call_data { grpc_closure recv_trailing_metadata_ready; grpc_closure* original_recv_trailing_metadata_ready; grpc_error* recv_trailing_metadata_error; - bool seen_recv_trailing_ready; + bool seen_recv_trailing_metadata_ready; grpc_metadata_array md; const grpc_metadata* consumed_md; size_t num_consumed_md; @@ -119,7 +119,7 @@ static void on_md_processing_done_inner(grpc_call_element* elem, calld->recv_initial_metadata_error = GRPC_ERROR_REF(error); grpc_closure* closure = calld->original_recv_initial_metadata_ready; calld->original_recv_initial_metadata_ready = nullptr; - if (calld->seen_recv_trailing_ready) { + if (calld->seen_recv_trailing_metadata_ready) { GRPC_CALL_COMBINER_START(calld->call_combiner, &calld->recv_trailing_metadata_ready, calld->recv_trailing_metadata_error, @@ -196,7 +196,7 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) { } grpc_closure* closure = calld->original_recv_initial_metadata_ready; calld->original_recv_initial_metadata_ready = nullptr; - if (calld->seen_recv_trailing_ready) { + if (calld->seen_recv_trailing_metadata_ready) { GRPC_CALL_COMBINER_START(calld->call_combiner, &calld->recv_trailing_metadata_ready, calld->recv_trailing_metadata_error, @@ -210,13 +210,11 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* err) { call_data* calld = static_cast(elem->call_data); if (calld->original_recv_initial_metadata_ready != nullptr) { calld->recv_trailing_metadata_error = GRPC_ERROR_REF(err); - calld->seen_recv_trailing_ready = true; - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, - recv_trailing_metadata_ready, elem, - grpc_schedule_on_exec_ctx); + calld->seen_recv_trailing_metadata_ready = true; GRPC_CALL_COMBINER_STOP(calld->call_combiner, "deferring recv_trailing_metadata_ready until " "after recv_initial_metadata_ready"); + return; } err = grpc_error_add_child( GRPC_ERROR_REF(err), GRPC_ERROR_REF(calld->recv_initial_metadata_error)); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 1b22db98ebf..ce6446fcaa0 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -730,11 +730,10 @@ static void server_on_recv_initial_metadata(void* ptr, grpc_error* error) { if (calld->host_set && calld->path_set) { /* do nothing */ } else { - grpc_error* src_error = error; - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Missing :authority or :path", &error, 1); - /* Pass the src_error reference to calld->recv_initial_metadata_error */ - calld->recv_initial_metadata_error = src_error; + /* Pass the error reference to calld->recv_initial_metadata_error */ + calld->recv_initial_metadata_error = + GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Missing :authority or :path", &error, 1); } grpc_closure* closure = calld->on_done_recv_initial_metadata; calld->on_done_recv_initial_metadata = nullptr; From 23ddadb7ca9cd3d30b2440501fb7d1fd4f8859cb Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 17 Sep 2018 15:00:03 -0700 Subject: [PATCH 378/546] Noob mistake --- src/core/lib/surface/server.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index ce6446fcaa0..72ddc2648d9 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -731,9 +731,11 @@ static void server_on_recv_initial_metadata(void* ptr, grpc_error* error) { /* do nothing */ } else { /* Pass the error reference to calld->recv_initial_metadata_error */ - calld->recv_initial_metadata_error = - GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Missing :authority or :path", &error, 1); + grpc_error* src_error = error; + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Missing :authority or :path", &src_error, 1); + GRPC_ERROR_UNREF(src_error); + calld->recv_initial_metadata_error = GRPC_ERROR_REF(error); } grpc_closure* closure = calld->on_done_recv_initial_metadata; calld->on_done_recv_initial_metadata = nullptr; From c33ec79cd8d748e84c87d0000b81adc15d202470 Mon Sep 17 00:00:00 2001 From: Noah Eisen Date: Mon, 17 Sep 2018 14:15:56 -0700 Subject: [PATCH 379/546] Only output stats if they were collected --- test/cpp/microbenchmarks/helpers.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/cpp/microbenchmarks/helpers.cc b/test/cpp/microbenchmarks/helpers.cc index e4ba37e2d6a..bce72985dc2 100644 --- a/test/cpp/microbenchmarks/helpers.cc +++ b/test/cpp/microbenchmarks/helpers.cc @@ -38,6 +38,7 @@ void TrackCounters::AddLabel(const grpc::string& label) { } void TrackCounters::AddToLabel(std::ostream& out, benchmark::State& state) { +#ifdef GRPC_COLLECT_STATS grpc_stats_data stats_end; grpc_stats_collect(&stats_end); grpc_stats_data stats; @@ -53,6 +54,7 @@ void TrackCounters::AddToLabel(std::ostream& out, benchmark::State& state) { << " " << grpc_stats_histogram_name[i] << "-99p:" << grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 99.0); } +#endif #ifdef GPR_LOW_LEVEL_COUNTERS grpc_memory_counters counters_at_end = grpc_memory_counters_snapshot(); out << " locks/iter:" From d374ee9a4f2bf6945f296fe9894aecbbed496f45 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 17 Sep 2018 15:32:57 -0700 Subject: [PATCH 380/546] Switch to `send` instead of `method(...).call` This commit switches `method(...).call` to `send`. The call sites I changed were all immediately calling `call` on the method object, then throwing the method object away. Using `send` should be equivalent and will not allocate the intermediate `method` object. --- src/ruby/lib/grpc/generic/rpc_desc.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ruby/lib/grpc/generic/rpc_desc.rb b/src/ruby/lib/grpc/generic/rpc_desc.rb index 5fd1805aabf..efb0e4233d7 100644 --- a/src/ruby/lib/grpc/generic/rpc_desc.rb +++ b/src/ruby/lib/grpc/generic/rpc_desc.rb @@ -32,7 +32,7 @@ module GRPC # @return [Proc] { |instance| marshalled(instance) } def marshal_proc - proc { |o| o.class.method(marshal_method).call(o).to_s } + proc { |o| o.class.send(marshal_method, o).to_s } end # @param [:input, :output] target determines whether to produce the an @@ -42,9 +42,9 @@ module GRPC # @return [Proc] An unmarshal proc { |marshalled(instance)| instance } def unmarshal_proc(target) fail ArgumentError unless [:input, :output].include?(target) - unmarshal_class = method(target).call + unmarshal_class = send(target) unmarshal_class = unmarshal_class.type if unmarshal_class.is_a? Stream - proc { |o| unmarshal_class.method(unmarshal_method).call(o) } + proc { |o| unmarshal_class.send(unmarshal_method, o) } end def handle_request_response(active_call, mth, inter_ctx) From 268733bd83c9c92809663ba81e2a848962ddbc6f Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 17 Sep 2018 16:28:39 -0700 Subject: [PATCH 381/546] Add v1.15.0 to interop matrix --- tools/interop_matrix/client_matrix.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index c55789f27ee..15b53d1716b 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -99,6 +99,9 @@ LANG_RELEASE_MATRIX = { { 'v1.14.1': None }, + { + 'v1.15.0': None + }, ], 'go': [ { @@ -231,6 +234,9 @@ LANG_RELEASE_MATRIX = { { 'v1.14.1': None }, + { + 'v1.15.0': None + }, ], 'node': [ { @@ -319,6 +325,9 @@ LANG_RELEASE_MATRIX = { { 'v1.14.1': None }, + { + 'v1.15.0': None + }, ], 'php': [ { @@ -363,6 +372,9 @@ LANG_RELEASE_MATRIX = { { 'v1.14.1': None }, + { + 'v1.15.0': None + }, ], 'csharp': [ { @@ -412,6 +424,9 @@ LANG_RELEASE_MATRIX = { { 'v1.14.1': None }, + { + 'v1.15.0': None + }, ], } From 1cd9aacab7896d701e9edd5e4988f99bff726868 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 18 Sep 2018 09:54:26 -0700 Subject: [PATCH 382/546] Add codegen support for client callback unary calls --- src/compiler/cpp_generator.cc | 147 ++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 1e0c36451bb..ff0b40f5878 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -128,6 +128,7 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file, ""); } static const char* headers_strs[] = { + "functional", "grpcpp/impl/codegen/async_generic_service.h", "grpcpp/impl/codegen/async_stream.h", "grpcpp/impl/codegen/async_unary_call.h", @@ -547,6 +548,115 @@ void PrintHeaderClientMethod(grpc_generator::Printer* printer, } } +void PrintHeaderClientMethodCallbackInterfacesStart( + grpc_generator::Printer* printer, + std::map* vars) { + // This declares the interface for the callback-based API. The components + // are pure; even though this is new (post-1.0) API, it can be pure because + // it is an entirely new interface that happens to be scoped within + // StubInterface, not new additions to StubInterface itself + printer->Print("class experimental_async_interface {\n"); + // All methods in this new interface are public. There is no need for private + // "Raw" methods since the callback-based API returns unowned raw pointers + printer->Print(" public:\n"); + printer->Indent(); +} + +void PrintHeaderClientMethodCallbackInterfaces( + grpc_generator::Printer* printer, const grpc_generator::Method* method, + std::map* vars, bool is_public) { + // Reserve is_public for future expansion + assert(is_public); + + (*vars)["Method"] = method->name(); + (*vars)["Request"] = method->input_type_name(); + (*vars)["Response"] = method->output_type_name(); + + if (method->NoStreaming()) { + printer->Print(*vars, + "virtual void $Method$(::grpc::ClientContext* context, " + "const $Request$* request, $Response$* response, " + "std::function) = 0;\n"); + } else if (ClientOnlyStreaming(method)) { + // TODO(vjpai): Add support for client-side streaming + } else if (ServerOnlyStreaming(method)) { + // TODO(vjpai): Add support for server-side streaming + } else if (method->BidiStreaming()) { + // TODO(vjpai): Add support for bidi streaming + } +} + +void PrintHeaderClientMethodCallbackInterfacesEnd( + grpc_generator::Printer* printer, + std::map* vars) { + printer->Outdent(); + printer->Print("};\n"); + + // Declare a function to give the async stub contents. It can't be pure + // since this is new API in StubInterface, but it is meaningless by default + // (since any stub that wants to use it must have its own implementation of + // the callback functions therein), so make the default return value nullptr. + // Intentionally include the word "class" to avoid possible shadowing. + printer->Print( + "virtual class experimental_async_interface* experimental_async() { " + "return nullptr; }\n"); +} + +void PrintHeaderClientMethodCallbackStart( + grpc_generator::Printer* printer, + std::map* vars) { + // This declares the stub entry for the callback-based API. + printer->Print("class experimental_async final :\n"); + printer->Print(" public StubInterface::experimental_async_interface {\n"); + printer->Print(" public:\n"); + printer->Indent(); +} + +void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer, + const grpc_generator::Method* method, + std::map* vars, + bool is_public) { + // Reserve is_public for future expansion + assert(is_public); + + (*vars)["Method"] = method->name(); + (*vars)["Request"] = method->input_type_name(); + (*vars)["Response"] = method->output_type_name(); + + if (method->NoStreaming()) { + printer->Print(*vars, + "void $Method$(::grpc::ClientContext* context, " + "const $Request$* request, $Response$* response, " + "std::function) override;\n"); + } else if (ClientOnlyStreaming(method)) { + // TODO(vjpai): Add support for client-side streaming + } else if (ServerOnlyStreaming(method)) { + // TODO(vjpai): Add support for server-side streaming + } else if (method->BidiStreaming()) { + // TODO(vjpai): Add support for bidi streaming + } +} + +void PrintHeaderClientMethodCallbackEnd( + grpc_generator::Printer* printer, + std::map* vars) { + printer->Outdent(); + printer->Print(" private:\n"); + printer->Indent(); + printer->Print("friend class Stub;\n"); + printer->Print("explicit experimental_async(Stub* stub): stub_(stub) { }\n"); + // include a function with a dummy use of stub_ to avoid an unused + // private member warning for service with no methods + printer->Print("Stub* stub() { return stub_; }\n"); + printer->Print("Stub* stub_;\n"); + printer->Outdent(); + printer->Print("};\n"); + + printer->Print( + "class experimental_async_interface* experimental_async() override { " + "return &async_stub_; }\n"); +} + void PrintHeaderClientMethodData(grpc_generator::Printer* printer, const grpc_generator::Method* method, std::map* vars) { @@ -951,6 +1061,14 @@ void PrintHeaderService(grpc_generator::Printer* printer, true); printer->Print(service->method(i)->GetTrailingComments("//").c_str()); } + PrintHeaderClientMethodCallbackInterfacesStart(printer, vars); + for (int i = 0; i < service->method_count(); ++i) { + printer->Print(service->method(i)->GetLeadingComments("//").c_str()); + PrintHeaderClientMethodCallbackInterfaces(printer, service->method(i).get(), + vars, true); + printer->Print(service->method(i)->GetTrailingComments("//").c_str()); + } + PrintHeaderClientMethodCallbackInterfacesEnd(printer, vars); printer->Outdent(); printer->Print("private:\n"); printer->Indent(); @@ -970,10 +1088,17 @@ void PrintHeaderService(grpc_generator::Printer* printer, for (int i = 0; i < service->method_count(); ++i) { PrintHeaderClientMethod(printer, service->method(i).get(), vars, true); } + PrintHeaderClientMethodCallbackStart(printer, vars); + for (int i = 0; i < service->method_count(); ++i) { + PrintHeaderClientMethodCallback(printer, service->method(i).get(), vars, + true); + } + PrintHeaderClientMethodCallbackEnd(printer, vars); printer->Outdent(); printer->Print("\n private:\n"); printer->Indent(); printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n"); + printer->Print("class experimental_async async_stub_{this};\n"); for (int i = 0; i < service->method_count(); ++i) { PrintHeaderClientMethod(printer, service->method(i).get(), vars, false); } @@ -1199,10 +1324,12 @@ grpc::string GetSourceIncludes(grpc_generator::File* file, std::map vars; static const char* headers_strs[] = { + "functional", "grpcpp/impl/codegen/async_stream.h", "grpcpp/impl/codegen/async_unary_call.h", "grpcpp/impl/codegen/channel_interface.h", "grpcpp/impl/codegen/client_unary_call.h", + "grpcpp/impl/codegen/client_callback.h", "grpcpp/impl/codegen/method_handler_impl.h", "grpcpp/impl/codegen/rpc_service_method.h", "grpcpp/impl/codegen/service_type.h", @@ -1247,6 +1374,17 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, " return ::grpc::internal::BlockingUnaryCall" "(channel_.get(), rpcmethod_$Method$_, " "context, request, response);\n}\n\n"); + + printer->Print(*vars, + "void $ns$$Service$::Stub::experimental_async::$Method$(" + "::grpc::ClientContext* context, " + "const $Request$* request, $Response$* response, " + "std::function f) {\n"); + printer->Print(*vars, + " return ::grpc::internal::CallbackUnaryCall" + "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " + "context, request, response, std::move(f));\n}\n\n"); + for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncStart"] = async_prefix.start; @@ -1277,6 +1415,9 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "rpcmethod_$Method$_, " "context, response);\n" "}\n\n"); + + // TODO(vjpai): Add callback version + for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncStart"] = async_prefix.start; @@ -1308,6 +1449,9 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "rpcmethod_$Method$_, " "context, request);\n" "}\n\n"); + + // TODO(vjpai): Add callback version + for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncStart"] = async_prefix.start; @@ -1339,6 +1483,9 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "rpcmethod_$Method$_, " "context);\n" "}\n\n"); + + // TODO(vjpai): Add callback version + for (auto async_prefix : async_prefixes) { (*vars)["AsyncPrefix"] = async_prefix.prefix; (*vars)["AsyncStart"] = async_prefix.start; From c5afb25905965e3f9213eac72d3ab62640eb28f6 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 18 Sep 2018 09:57:17 -0700 Subject: [PATCH 383/546] fix golden file --- test/cpp/codegen/compiler_test_golden | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index 756f6a0224c..c679880763b 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -26,6 +26,7 @@ #include "src/proto/grpc/testing/compiler_test.pb.h" +#include #include #include #include @@ -105,6 +106,22 @@ class ServiceA final { return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>>(PrepareAsyncMethodA4Raw(context, cq)); } // Method A4 trailing comment 1 + class experimental_async_interface { + public: + // MethodA1 leading comment 1 + virtual void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) = 0; + // MethodA1 trailing comment 1 + // MethodA2 detached leading comment 1 + // + // Method A2 leading comment 1 + // Method A2 leading comment 2 + // MethodA2 trailing comment 1 + // Method A3 leading comment 1 + // Method A3 trailing comment 1 + // Method A4 leading comment 1 + // Method A4 trailing comment 1 + }; + virtual class experimental_async_interface* experimental_async() { return nullptr; } private: virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* PrepareAsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; @@ -155,9 +172,21 @@ class ServiceA final { std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>> PrepareAsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) { return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>>(PrepareAsyncMethodA4Raw(context, cq)); } + class experimental_async final : + public StubInterface::experimental_async_interface { + public: + void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) override; + private: + friend class Stub; + explicit experimental_async(Stub* stub): stub_(stub) { } + Stub* stub() { return stub_; } + Stub* stub_; + }; + class experimental_async_interface* experimental_async() override { return &async_stub_; } private: std::shared_ptr< ::grpc::ChannelInterface> channel_; + class experimental_async async_stub_{this}; ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* PrepareAsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; ::grpc::ClientWriter< ::grpc::testing::Request>* MethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response) override; @@ -488,6 +517,13 @@ class ServiceB final { return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>>(PrepareAsyncMethodB1Raw(context, request, cq)); } // MethodB1 trailing comment 1 + class experimental_async_interface { + public: + // MethodB1 leading comment 1 + virtual void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) = 0; + // MethodB1 trailing comment 1 + }; + virtual class experimental_async_interface* experimental_async() { return nullptr; } private: virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* AsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0; @@ -502,9 +538,21 @@ class ServiceB final { std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>> PrepareAsyncMethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) { return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>>(PrepareAsyncMethodB1Raw(context, request, cq)); } + class experimental_async final : + public StubInterface::experimental_async_interface { + public: + void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) override; + private: + friend class Stub; + explicit experimental_async(Stub* stub): stub_(stub) { } + Stub* stub() { return stub_; } + Stub* stub_; + }; + class experimental_async_interface* experimental_async() override { return &async_stub_; } private: std::shared_ptr< ::grpc::ChannelInterface> channel_; + class experimental_async async_stub_{this}; ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* AsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override; const ::grpc::internal::RpcMethod rpcmethod_MethodB1_; From 42a0ed43cba18b0c9dc1d181ad50b9f2e0b89e69 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 18 Sep 2018 12:04:31 -0700 Subject: [PATCH 384/546] Add a test --- .../end2end/client_callback_end2end_test.cc | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 75b896b33d8..29893b451c1 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -55,7 +55,8 @@ class ClientCallbackEnd2endTest : public ::testing::Test { void ResetStub() { ChannelArguments args; channel_ = server_->InProcessChannel(args); - stub_.reset(new GenericStub(channel_)); + stub_ = grpc::testing::EchoTestService::NewStub(channel_); + generic_stub_.reset(new GenericStub(channel_)); } void TearDown() override { @@ -65,6 +66,36 @@ class ClientCallbackEnd2endTest : public ::testing::Test { } void SendRpcs(int num_rpcs) { + grpc::string test_string(""); + for (int i = 0; i < num_rpcs; i++) { + EchoRequest request; + EchoResponse response; + ClientContext cli_ctx; + + test_string += "Hello world. "; + request.set_message(test_string); + + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub_->experimental_async()->Echo( + &cli_ctx, &request, &response, + [&request, &response, &done, &mu, &cv](Status s) { + GPR_ASSERT(s.ok()); + + EXPECT_EQ(request.message(), response.message()); + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } + } + } + + void SendRpcsGeneric(int num_rpcs) { const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo"); grpc::string test_string(""); for (int i = 0; i < num_rpcs; i++) { @@ -80,7 +111,7 @@ class ClientCallbackEnd2endTest : public ::testing::Test { std::mutex mu; std::condition_variable cv; bool done = false; - stub_->experimental().UnaryCall( + generic_stub_->experimental().UnaryCall( &cli_ctx, kMethodName, send_buf.get(), &recv_buf, [&request, &recv_buf, &done, &mu, &cv](Status s) { GPR_ASSERT(s.ok()); @@ -98,9 +129,11 @@ class ClientCallbackEnd2endTest : public ::testing::Test { } } } + bool is_server_started_; std::shared_ptr channel_; - std::unique_ptr stub_; + std::unique_ptr stub_; + std::unique_ptr generic_stub_; TestServiceImpl service_; std::unique_ptr server_; }; @@ -115,6 +148,11 @@ TEST_F(ClientCallbackEnd2endTest, SequentialRpcs) { SendRpcs(10); } +TEST_F(ClientCallbackEnd2endTest, SequentialGenericRpcs) { + ResetStub(); + SendRpcsGeneric(10); +} + } // namespace } // namespace testing } // namespace grpc From 47ae48e20c9700eb2b5e5e26037bdef401ea7f16 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 18 Sep 2018 12:10:33 -0700 Subject: [PATCH 385/546] Fix conflict --- test/cpp/end2end/client_callback_end2end_test.cc | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 77ff0a5c951..90c88456431 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -65,7 +65,6 @@ class ClientCallbackEnd2endTest : public ::testing::Test { } } -<<<<<<< HEAD void SendRpcs(int num_rpcs) { grpc::string test_string(""); for (int i = 0; i < num_rpcs; i++) { @@ -96,10 +95,7 @@ class ClientCallbackEnd2endTest : public ::testing::Test { } } - void SendRpcsGeneric(int num_rpcs) { -======= - void SendRpcs(int num_rpcs, bool maybe_except) { ->>>>>>> master + void SendRpcsGeneric(int num_rpcs, bool maybe_except) { const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo"); grpc::string test_string(""); for (int i = 0; i < num_rpcs; i++) { @@ -149,23 +145,23 @@ class ClientCallbackEnd2endTest : public ::testing::Test { TEST_F(ClientCallbackEnd2endTest, SimpleRpc) { ResetStub(); - SendRpcs(1, false); + SendRpcs(1); } TEST_F(ClientCallbackEnd2endTest, SequentialRpcs) { ResetStub(); - SendRpcs(10, false); + SendRpcs(10); } TEST_F(ClientCallbackEnd2endTest, SequentialGenericRpcs) { ResetStub(); - SendRpcsGeneric(10); + SendRpcsGeneric(10, false); } #if GRPC_ALLOW_EXCEPTIONS TEST_F(ClientCallbackEnd2endTest, ExceptingRpc) { ResetStub(); - SendRpcs(10, true); + SendRpcsGeneric(10, true); } #endif From cf9b412c97c2fda7bae76450756aed978f38cb6c Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Tue, 11 Sep 2018 01:52:41 -0700 Subject: [PATCH 386/546] test: split fake ALTS handshaker server to lib and main Signed-off-by: Lizan Zhou --- test/core/tsi/alts/fake_handshaker/BUILD | 5 +- .../fake_handshaker/fake_handshaker_server.cc | 31 ++--------- .../fake_handshaker/fake_handshaker_server.h | 12 +++++ .../fake_handshaker_server_main.cc | 53 +++++++++++++++++++ 4 files changed, 73 insertions(+), 28 deletions(-) create mode 100644 test/core/tsi/alts/fake_handshaker/fake_handshaker_server.h create mode 100644 test/core/tsi/alts/fake_handshaker/fake_handshaker_server_main.cc diff --git a/test/core/tsi/alts/fake_handshaker/BUILD b/test/core/tsi/alts/fake_handshaker/BUILD index a09a046d27b..98cd628a7d2 100644 --- a/test/core/tsi/alts/fake_handshaker/BUILD +++ b/test/core/tsi/alts/fake_handshaker/BUILD @@ -37,21 +37,22 @@ grpc_cc_library( name = "fake_handshaker_lib", testonly = True, srcs = ["fake_handshaker_server.cc"], + hdrs = ["fake_handshaker_server.h"], language = "C++", deps = [ "handshaker_proto", "transport_security_common_proto", "//:grpc++", - "//test/cpp/util:test_config", ], ) grpc_cc_binary( name = "fake_handshaker_server", testonly = True, - srcs = ["fake_handshaker_server.cc"], + srcs = ["fake_handshaker_server_main.cc"], language = "C++", deps = [ + "//test/cpp/util:test_config", "fake_handshaker_lib", ], ) diff --git a/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.cc b/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.cc index f6a4791b492..ba246b07eb1 100644 --- a/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.cc +++ b/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.cc @@ -15,12 +15,12 @@ * limitations under the License. * */ +#include "test/core/tsi/alts/fake_handshaker/fake_handshaker_server.h" #include #include #include -#include #include #include #include @@ -32,10 +32,6 @@ #include "test/core/tsi/alts/fake_handshaker/handshaker.grpc.pb.h" #include "test/core/tsi/alts/fake_handshaker/handshaker.pb.h" #include "test/core/tsi/alts/fake_handshaker/transport_security_common.pb.h" -#include "test/cpp/util/test_config.h" - -DEFINE_int32(handshaker_port, 55056, - "TCP port on which the fake handshaker server listens to."); // Fake handshake messages. constexpr char kClientInitFrame[] = "ClientInit"; @@ -243,26 +239,9 @@ class FakeHandshakerService : public HandshakerService::Service { } }; -} // namespace gcp -} // namespace grpc - -void RunServer() { - GPR_ASSERT(FLAGS_handshaker_port != 0); - std::ostringstream server_address; - server_address << "[::1]:" << FLAGS_handshaker_port; - grpc::gcp::FakeHandshakerService service; - grpc::ServerBuilder builder; - builder.AddListeningPort(server_address.str(), - grpc::InsecureServerCredentials()); - builder.RegisterService(&service); - std::unique_ptr server(builder.BuildAndStart()); - gpr_log(GPR_INFO, "Fake handshaker server listening on %s", - server_address.str().c_str()); - server->Wait(); +std::unique_ptr CreateFakeHandshakerService() { + return std::unique_ptr{new grpc::gcp::FakeHandshakerService}; } -int main(int argc, char** argv) { - grpc::testing::InitTest(&argc, &argv, true); - RunServer(); - return 0; -} +} // namespace gcp +} // namespace grpc diff --git a/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.h b/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.h new file mode 100644 index 00000000000..02aeee5bc22 --- /dev/null +++ b/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.h @@ -0,0 +1,12 @@ +#include +#include + +#include + +namespace grpc { +namespace gcp { + +std::unique_ptr CreateFakeHandshakerService(); + +} // namespace gcp +} // namespace grpc diff --git a/test/core/tsi/alts/fake_handshaker/fake_handshaker_server_main.cc b/test/core/tsi/alts/fake_handshaker/fake_handshaker_server_main.cc new file mode 100644 index 00000000000..60351533d94 --- /dev/null +++ b/test/core/tsi/alts/fake_handshaker/fake_handshaker_server_main.cc @@ -0,0 +1,53 @@ +/* + * + * 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 "test/core/tsi/alts/fake_handshaker/fake_handshaker_server.h" + +#include + +#include +#include +#include +#include + +#include "test/cpp/util/test_config.h" + +DEFINE_int32(handshaker_port, 55056, + "TCP port on which the fake handshaker server listens to."); + +static void RunFakeHandshakerServer(const std::string& server_address) { + std::unique_ptr service = + grpc::gcp::CreateFakeHandshakerService(); + grpc::ServerBuilder builder; + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + builder.RegisterService(service.get()); + gpr_log(GPR_INFO, "Fake handshaker server listening on %s", + server_address.c_str()); + std::unique_ptr server = builder.BuildAndStart(); + server->Wait(); +} + +int main(int argc, char** argv) { + grpc::testing::InitTest(&argc, &argv, true); + + GPR_ASSERT(FLAGS_handshaker_port != 0); + std::ostringstream server_address; + server_address << "[::1]:" << FLAGS_handshaker_port; + + RunFakeHandshakerServer(server_address.str()); + return 0; +} From bd9d97a2003322f523d54f7bc9fa89dff3e36ab5 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 12 Sep 2018 11:34:00 -0700 Subject: [PATCH 387/546] Channelz socket support --- include/grpc/grpc.h | 4 + .../chttp2/transport/chttp2_transport.cc | 24 +++ .../transport/chttp2/transport/frame_data.cc | 1 + .../ext/transport/chttp2/transport/internal.h | 7 + .../ext/transport/chttp2/transport/parsing.cc | 6 + .../ext/transport/chttp2/transport/writing.cc | 1 + src/core/lib/channel/channelz.cc | 112 ++++++++++- src/core/lib/channel/channelz.h | 29 ++- src/core/lib/channel/channelz_registry.cc | 18 ++ test/core/end2end/tests/channelz.cc | 176 ++++++++++++++++++ 10 files changed, 372 insertions(+), 6 deletions(-) diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index ce421e93bd8..fc0a0d3cce0 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -510,6 +510,10 @@ GRPCAPI char* grpc_channelz_get_channel(intptr_t channel_id); is allocated and must be freed by the application. */ GRPCAPI char* grpc_channelz_get_subchannel(intptr_t subchannel_id); +/* Returns a single Socket, or else a NOT_FOUND code. The returned string + is allocated and must be freed by the application. */ +GRPCAPI char* grpc_channelz_get_socket(intptr_t socket_id); + #ifdef __cplusplus } #endif diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 26cad2cc9a6..38032d56a60 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -335,6 +335,10 @@ static bool read_channel_args(grpc_chttp2_transport* t, GRPC_ARG_OPTIMIZATION_TARGET, channel_args->args[i].value.string); } + } else if (0 == + strcmp(channel_args->args[i].key, GRPC_ARG_ENABLE_CHANNELZ)) { + t->channelz_socket = + grpc_core::MakeRefCounted(); } else { static const struct { const char* channel_arg_name; @@ -720,6 +724,14 @@ static void destroy_stream_locked(void* sp, grpc_error* error) { grpc_chttp2_stream* s = static_cast(sp); grpc_chttp2_transport* t = s->t; + if (t->channelz_socket != nullptr) { + if ((t->is_client && s->eos_received) || (!t->is_client && s->eos_sent)) { + t->channelz_socket->RecordStreamSucceeded(); + } else { + t->channelz_socket->RecordStreamFailed(); + } + } + GPR_ASSERT((s->write_closed && s->read_closed) || s->id == 0); if (s->id != 0) { GPR_ASSERT(grpc_chttp2_stream_map_find(&t->stream_map, s->id) == nullptr); @@ -1407,6 +1419,9 @@ static void perform_stream_op_locked(void* stream_op, } if (op->send_initial_metadata) { + if (t->is_client && t->channelz_socket != nullptr) { + t->channelz_socket->RecordStreamStartedFromLocal(); + } GRPC_STATS_INC_HTTP2_OP_SEND_INITIAL_METADATA(); GPR_ASSERT(s->send_initial_metadata_finished == nullptr); on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE; @@ -1492,6 +1507,9 @@ static void perform_stream_op_locked(void* stream_op, if (op->send_message) { GRPC_STATS_INC_HTTP2_OP_SEND_MESSAGE(); + if (t->channelz_socket != nullptr) { + t->channelz_socket->RecordMessageSent(); + } GRPC_STATS_INC_HTTP2_SEND_MESSAGE_SIZE( op->payload->send_message.send_message->length()); on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE; @@ -1609,6 +1627,9 @@ static void perform_stream_op_locked(void* stream_op, if (op->recv_message) { GRPC_STATS_INC_HTTP2_OP_RECV_MESSAGE(); + if (t->channelz_socket != nullptr) { + t->channelz_socket->RecordMessageRecieved(); + } size_t before = 0; GPR_ASSERT(s->recv_message_ready == nullptr); GPR_ASSERT(!s->pending_byte_stream); @@ -2707,6 +2728,9 @@ static void start_keepalive_ping_locked(void* arg, grpc_error* error) { if (error != GRPC_ERROR_NONE) { return; } + if (t->channelz_socket != nullptr) { + t->channelz_socket->RecordKeepaliveSent(); + } GRPC_CHTTP2_REF_TRANSPORT(t, "keepalive watchdog"); grpc_timer_init(&t->keepalive_watchdog_timer, grpc_core::ExecCtx::Get()->Now() + t->keepalive_timeout, diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index f8f06f67891..15de8795282 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -62,6 +62,7 @@ grpc_error* grpc_chttp2_data_parser_begin_frame(grpc_chttp2_data_parser* parser, if (flags & GRPC_CHTTP2_DATA_FLAG_END_STREAM) { s->received_last_frame = true; + s->eos_received = true; } else { s->received_last_frame = false; } diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 6b5309bab48..bf0dfa98af8 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -36,6 +36,7 @@ #include "src/core/ext/transport/chttp2/transport/hpack_parser.h" #include "src/core/ext/transport/chttp2/transport/incoming_metadata.h" #include "src/core/ext/transport/chttp2/transport/stream_map.h" +#include "src/core/lib/channel/channelz.h" #include "src/core/lib/compression/stream_compression.h" #include "src/core/lib/gprpp/manual_constructor.h" #include "src/core/lib/iomgr/combiner.h" @@ -471,6 +472,8 @@ struct grpc_chttp2_transport { bool keepalive_permit_without_calls; /** keep-alive state machine state */ grpc_chttp2_keepalive_state keepalive_state; + + grpc_core::RefCountedPtr channelz_socket; }; typedef enum { @@ -534,6 +537,10 @@ struct grpc_chttp2_stream { /** Has trailing metadata been received. */ bool received_trailing_metadata; + /* have we sent or received the EOS bit? */ + bool eos_received; + bool eos_sent; + /** the error that resulted in this stream being read-closed */ grpc_error* read_closed_error; /** the error that resulted in this stream being write-closed */ diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc index 1e491d2ef86..0694ad743bb 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/src/core/ext/transport/chttp2/transport/parsing.cc @@ -598,6 +598,9 @@ static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t, gpr_log(GPR_ERROR, "grpc_chttp2_stream not accepted")); return init_skip_frame_parser(t, 1); } + if (t->channelz_socket != nullptr) { + t->channelz_socket->RecordStreamStartedFromRemote(); + } } else { t->incoming_stream = s; } @@ -611,6 +614,9 @@ static grpc_error* init_header_frame_parser(grpc_chttp2_transport* t, } t->parser = grpc_chttp2_header_parser_parse; t->parser_data = &t->hpack_parser; + if (t->header_eof) { + s->eos_received = true; + } switch (s->header_frames_received) { case 0: if (t->is_client && t->header_eof) { diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 8b73b01dea2..5beaf5491ef 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -569,6 +569,7 @@ class StreamWriteContext { void SentLastFrame() { s_->send_trailing_metadata = nullptr; s_->sent_trailing_metadata = true; + s_->eos_sent = true; if (!t_->is_client && !s_->read_closed) { grpc_slice_buffer_add( diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 375cf25cc66..e1ab2ead626 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -81,11 +81,13 @@ void CallCountingHelper::PopulateCallCounts(grpc_json* json) { json_iterator = grpc_json_add_number_string_child( json, json_iterator, "callsFailed", calls_failed_); } - gpr_timespec ts = - grpc_millis_to_timespec(last_call_started_millis_, GPR_CLOCK_REALTIME); - json_iterator = - grpc_json_create_child(json_iterator, json, "lastCallStartedTimestamp", - gpr_format_timespec(ts), GRPC_JSON_STRING, true); + if (calls_started_ != 0) { + gpr_timespec ts = + grpc_millis_to_timespec(last_call_started_millis_, GPR_CLOCK_REALTIME); + json_iterator = + grpc_json_create_child(json_iterator, json, "lastCallStartedTimestamp", + gpr_format_timespec(ts), GRPC_JSON_STRING, true); + } } ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes, @@ -184,5 +186,105 @@ grpc_json* ServerNode::RenderJson() { return top_level_json; } +void SocketNode::RecordStreamStartedFromLocal() { + gpr_atm_no_barrier_fetch_add(&streams_started_, (gpr_atm)1); + gpr_atm_no_barrier_store(&last_local_stream_created_millis_, + (gpr_atm)ExecCtx::Get()->Now()); +} + +void SocketNode::RecordStreamStartedFromRemote() { + gpr_atm_no_barrier_fetch_add(&streams_started_, (gpr_atm)1); + gpr_atm_no_barrier_store(&last_remote_stream_created_millis_, + (gpr_atm)ExecCtx::Get()->Now()); +} + +void SocketNode::RecordMessageSent() { + gpr_atm_no_barrier_fetch_add(&messages_sent_, (gpr_atm)1); + gpr_atm_no_barrier_store(&last_message_sent_millis_, + (gpr_atm)ExecCtx::Get()->Now()); +} + +void SocketNode::RecordMessageRecieved() { + gpr_atm_no_barrier_fetch_add(&messages_recieved_, (gpr_atm)1); + gpr_atm_no_barrier_store(&last_message_recieved_millis_, + (gpr_atm)ExecCtx::Get()->Now()); +} + +grpc_json* SocketNode::RenderJson() { + // We need to track these three json objects to build our object + grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); + grpc_json* json = top_level_json; + grpc_json* json_iterator = nullptr; + // create and fill the ref child + json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr, + GRPC_JSON_OBJECT, false); + json = json_iterator; + json_iterator = nullptr; + json_iterator = grpc_json_add_number_string_child(json, json_iterator, + "socketId", uuid()); + // reset json iterators to top level object + json = top_level_json; + json_iterator = nullptr; + // create and fill the data child. + grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr, + GRPC_JSON_OBJECT, false); + json = data; + json_iterator = nullptr; + if (streams_started_ != 0) { + json_iterator = grpc_json_add_number_string_child( + json, json_iterator, "streamsStarted", streams_started_); + } + if (streams_succeeded_ != 0) { + json_iterator = grpc_json_add_number_string_child( + json, json_iterator, "streamsSucceeded", streams_succeeded_); + } + if (streams_failed_) { + json_iterator = grpc_json_add_number_string_child( + json, json_iterator, "streamsFailed", streams_failed_); + } + if (messages_sent_ != 0) { + json_iterator = grpc_json_add_number_string_child( + json, json_iterator, "messagesSent", messages_sent_); + } + if (messages_recieved_ != 0) { + json_iterator = grpc_json_add_number_string_child( + json, json_iterator, "messagesRecieved", messages_recieved_); + } + if (keepalives_sent_ != 0) { + json_iterator = grpc_json_add_number_string_child( + json, json_iterator, "keepAlivesSent", keepalives_sent_); + } + gpr_timespec ts; + if (streams_started_ != 0 && last_local_stream_created_millis_ != 0) { + ts = grpc_millis_to_timespec(last_local_stream_created_millis_, + GPR_CLOCK_REALTIME); + json_iterator = grpc_json_create_child( + json_iterator, json, "lastLocalStreamCreatedTimestamp", + gpr_format_timespec(ts), GRPC_JSON_STRING, true); + } + if (streams_started_ != 0 && last_remote_stream_created_millis_ != 0) { + ts = grpc_millis_to_timespec(last_remote_stream_created_millis_, + GPR_CLOCK_REALTIME); + json_iterator = grpc_json_create_child( + json_iterator, json, "lastRemoteStreamCreatedTimestamp", + gpr_format_timespec(ts), GRPC_JSON_STRING, true); + } + if (messages_sent_ != 0) { + ts = grpc_millis_to_timespec(last_message_sent_millis_, GPR_CLOCK_REALTIME); + json_iterator = + grpc_json_create_child(json_iterator, json, "lastMessageSentTimestamp", + gpr_format_timespec(ts), GRPC_JSON_STRING, true); + } + if (messages_recieved_ != 0) { + ts = grpc_millis_to_timespec(last_message_recieved_millis_, + GPR_CLOCK_REALTIME); + json_iterator = grpc_json_create_child( + json_iterator, json, "lastMessageRecievedTimestamp", + gpr_format_timespec(ts), GRPC_JSON_STRING, true); + } + json = top_level_json; + return top_level_json; +} + } // namespace channelz } // namespace grpc_core diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 9be256147bb..24868208632 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -197,11 +197,38 @@ class ServerNode : public BaseNode { }; // Handles channelz bookkeeping for sockets -// TODO(ncteisen): implement in subsequent PR. class SocketNode : public BaseNode { public: SocketNode() : BaseNode(EntityType::kSocket) {} ~SocketNode() override {} + + grpc_json* RenderJson() override; + + void RecordStreamStartedFromLocal(); + void RecordStreamStartedFromRemote(); + void RecordStreamSucceeded() { + gpr_atm_no_barrier_fetch_add(&streams_succeeded_, (gpr_atm(1))); + } + void RecordStreamFailed() { + gpr_atm_no_barrier_fetch_add(&streams_failed_, (gpr_atm(1))); + } + void RecordMessageSent(); + void RecordMessageRecieved(); + void RecordKeepaliveSent() { + gpr_atm_no_barrier_fetch_add(&keepalives_sent_, (gpr_atm(1))); + } + + private: + gpr_atm streams_started_ = 0; + gpr_atm streams_succeeded_ = 0; + gpr_atm streams_failed_ = 0; + gpr_atm messages_sent_ = 0; + gpr_atm messages_recieved_ = 0; + gpr_atm keepalives_sent_ = 0; + gpr_atm last_local_stream_created_millis_ = 0; + gpr_atm last_remote_stream_created_millis_ = 0; + gpr_atm last_message_sent_millis_ = 0; + gpr_atm last_message_recieved_millis_ = 0; }; // Creation functions diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index adc7b6ba441..841f1c6104b 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -197,3 +197,21 @@ char* grpc_channelz_get_subchannel(intptr_t subchannel_id) { grpc_json_destroy(top_level_json); return json_str; } + +char* grpc_channelz_get_socket(intptr_t socket_id) { + grpc_core::channelz::BaseNode* socket_node = + grpc_core::channelz::ChannelzRegistry::Get(socket_id); + if (socket_node == nullptr || + socket_node->type() != + grpc_core::channelz::BaseNode::EntityType::kSocket) { + return nullptr; + } + grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); + grpc_json* json = top_level_json; + grpc_json* socket_json = socket_node->RenderJson(); + socket_json->key = "socket"; + grpc_json_link_child(json, socket_json, nullptr); + char* json_str = grpc_json_dump_to_string(top_level_json, 0); + grpc_json_destroy(top_level_json); + return json_str; +} diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 40a0370f0ea..3ebaea2afc5 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -196,6 +196,178 @@ static void run_one_request(grpc_end2end_test_config config, cq_verifier_destroy(cqv); } +/* Creates and returns a grpc_slice containing random alphanumeric characters. + */ +static grpc_slice generate_random_slice() { + size_t i; + static const char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890"; + char* output; + const size_t output_size = 1024 * 1024; + output = static_cast(gpr_malloc(output_size)); + for (i = 0; i < output_size - 1; ++i) { + output[i] = chars[rand() % static_cast(sizeof(chars) - 1)]; + } + output[output_size - 1] = '\0'; + grpc_slice out = grpc_slice_from_copied_string(output); + gpr_free(output); + return out; +} + +static void run_one_request_with_payload(grpc_end2end_test_config config, + grpc_end2end_test_fixture f) { + /* Create large request and response bodies. These are big enough to require + * multiple round trips to deliver to the peer, and their exact contents of + * will be verified on completion. */ + grpc_slice request_payload_slice = generate_random_slice(); + grpc_slice response_payload_slice = generate_random_slice(); + + grpc_call* c; + grpc_call* s; + 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); + cq_verifier* cqv = cq_verifier_create(f.cq); + 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_byte_buffer* request_payload_recv = nullptr; + grpc_byte_buffer* response_payload_recv = nullptr; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + int was_cancelled = 2; + + gpr_timespec deadline = n_seconds_from_now(60); + c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), nullptr, + deadline, nullptr); + GPR_ASSERT(c); + + 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); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = request_payload; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(c, ops, static_cast(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), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(102), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + cq_verify(cqv); + + 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->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response_payload; + op->flags = 0; + op->reserved = nullptr; + 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; + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + op->data.send_status_from_server.status_details = &status_details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(103), + nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + 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, "/foo")); + GPR_ASSERT(was_cancelled == 0); + GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice)); + GPR_ASSERT( + byte_buffer_eq_slice(response_payload_recv, response_payload_slice)); + + 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_call_unref(c); + grpc_call_unref(s); + + cq_verifier_destroy(cqv); + + 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); +} + static void test_channelz(grpc_end2end_test_config config) { grpc_end2end_test_fixture f; @@ -258,6 +430,10 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); gpr_free(json); + // one successful request with payload to test socket data + // TODO(ncteisen): add some programatic spot checks on the socket json. + run_one_request_with_payload(config, f); + end_test(&f); config.tear_down_data(&f); } From 845bc9ae217a99562fdff2f97a6e984446e601df Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 18 Sep 2018 16:48:46 -0700 Subject: [PATCH 388/546] Add more test cases --- .../end2end/client_callback_end2end_test.cc | 69 ++++++++++++++++++- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 90c88456431..e99703c30f4 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -65,7 +66,7 @@ class ClientCallbackEnd2endTest : public ::testing::Test { } } - void SendRpcs(int num_rpcs) { + void SendRpcs(int num_rpcs, bool with_binary_metadata) { grpc::string test_string(""); for (int i = 0; i < num_rpcs; i++) { EchoRequest request; @@ -75,6 +76,14 @@ class ClientCallbackEnd2endTest : public ::testing::Test { test_string += "Hello world. "; request.set_message(test_string); + if (with_binary_metadata) { + char bytes[8] = {'\0', '\1', '\2', '\3', + '\4', '\5', '\6', static_cast(i)}; + cli_ctx.AddMetadata("custom-bin", grpc::string(bytes, 8)); + } + + cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); + std::mutex mu; std::condition_variable cv; bool done = false; @@ -145,12 +154,17 @@ class ClientCallbackEnd2endTest : public ::testing::Test { TEST_F(ClientCallbackEnd2endTest, SimpleRpc) { ResetStub(); - SendRpcs(1); + SendRpcs(1, false); } TEST_F(ClientCallbackEnd2endTest, SequentialRpcs) { ResetStub(); - SendRpcs(10); + SendRpcs(10, false); +} + +TEST_F(ClientCallbackEnd2endTest, SequentialRpcsWithVariedBinaryMetadataValue) { + ResetStub(); + SendRpcs(10, true); } TEST_F(ClientCallbackEnd2endTest, SequentialGenericRpcs) { @@ -165,6 +179,55 @@ TEST_F(ClientCallbackEnd2endTest, ExceptingRpc) { } #endif +TEST_F(ClientCallbackEnd2endTest, MultipleRpcsWithVariedBinaryMetadataValue) { + ResetStub(); + std::vector threads; + threads.reserve(10); + for (int i = 0; i < 10; ++i) { + threads.emplace_back([this] { SendRpcs(10, true); }); + } + for (int i = 0; i < 10; ++i) { + threads[i].join(); + } +} + +TEST_F(ClientCallbackEnd2endTest, MultipleRpcs) { + ResetStub(); + std::vector threads; + threads.reserve(10); + for (int i = 0; i < 10; ++i) { + threads.emplace_back([this] { SendRpcs(10, false); }); + } + for (int i = 0; i < 10; ++i) { + threads[i].join(); + } +} + +TEST_F(ClientCallbackEnd2endTest, CancelRpcBeforeStart) { + ResetStub(); + EchoRequest request; + EchoResponse response; + ClientContext context; + request.set_message("hello"); + context.TryCancel(); + + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub_->experimental_async()->Echo( + &context, &request, &response, [&response, &done, &mu, &cv](Status s) { + EXPECT_EQ("", response.message()); + EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code()); + std::lock_guard l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock l(mu); + while (!done) { + cv.wait(l); + } +} + } // namespace } // namespace testing } // namespace grpc From 50c31d18e5945b3bbcfa77abac8f805835c6f997 Mon Sep 17 00:00:00 2001 From: ganmacs Date: Sun, 17 Jun 2018 11:01:35 +0900 Subject: [PATCH 389/546] Use logger to suppress output debug output during test --- src/ruby/spec/client_auth_spec.rb | 10 ++--- src/ruby/spec/generic/client_stub_spec.rb | 22 ++++++---- src/ruby/spec/generic/rpc_server_spec.rb | 6 +-- src/ruby/spec/support/services.rb | 50 +++++++++++++---------- 4 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/ruby/spec/client_auth_spec.rb b/src/ruby/spec/client_auth_spec.rb index c563ed32277..5d2e6d24ec8 100644 --- a/src/ruby/spec/client_auth_spec.rb +++ b/src/ruby/spec/client_auth_spec.rb @@ -30,7 +30,7 @@ end def create_server_creds test_root = File.join(File.dirname(__FILE__), 'testdata') - p "test root: #{test_root}" + GRPC.logger.info("test root: #{test_root}") files = ['ca.pem', 'server1.key', 'server1.pem'] creds = files.map { |f| File.open(File.join(test_root, f)).read } GRPC::Core::ServerCredentials.new( @@ -59,7 +59,7 @@ class SslTestService def a_client_streaming_rpc(call) check_peer_cert(call) - call.each_remote_read.each { |r| p r } + call.each_remote_read.each { |r| GRPC.logger.info(r) } EchoMsg.new end @@ -70,7 +70,7 @@ class SslTestService def a_bidi_rpc(requests, call) check_peer_cert(call) - requests.each { |r| p r } + requests.each { |r| GRPC.logger.info(r) } [EchoMsg.new, EchoMsg.new] end end @@ -116,11 +116,11 @@ describe 'client-server auth' do it 'client-server auth with server streaming RPCs' do responses = @stub.a_server_streaming_rpc(EchoMsg.new) - responses.each { |r| p r } + responses.each { |r| GRPC.logger.info(r) } end it 'client-server auth with bidi RPCs' do responses = @stub.a_bidi_rpc([EchoMsg.new, EchoMsg.new]) - responses.each { |r| p r } + responses.each { |r| GRPC.logger.info(r) } end end diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb index fc50362ca5f..200139d8493 100644 --- a/src/ruby/spec/generic/client_stub_spec.rb +++ b/src/ruby/spec/generic/client_stub_spec.rb @@ -293,7 +293,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength describe 'without a call operation' do def get_response(stub, credentials: nil) - puts credentials.inspect + GRPC.logger.info(credentials.inspect) stub.request_response(@method, @sent_msg, noop, noop, metadata: @metadata, credentials: credentials) @@ -342,13 +342,15 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength it 'sends metadata to the server ok when running start_call first' do run_op_view_metadata_test(true) check_op_view_of_finished_client_call( - @op, @server_initial_md, @server_trailing_md) { |r| p r } + @op, @server_initial_md, @server_trailing_md + ) { |r| GRPC.logger.info(r) } end it 'does not crash when used after the call has been finished' do run_op_view_metadata_test(false) check_op_view_of_finished_client_call( - @op, @server_initial_md, @server_trailing_md) { |r| p r } + @op, @server_initial_md, @server_trailing_md + ) { |r| GRPC.logger.info(r) } end end end @@ -435,13 +437,15 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength it 'sends metadata to the server ok when running start_call first' do run_op_view_metadata_test(true) check_op_view_of_finished_client_call( - @op, @server_initial_md, @server_trailing_md) { |r| p r } + @op, @server_initial_md, @server_trailing_md + ) { |r| GRPC.logger.info(r) } end it 'does not crash when used after the call has been finished' do run_op_view_metadata_test(false) check_op_view_of_finished_client_call( - @op, @server_initial_md, @server_trailing_md) { |r| p r } + @op, @server_initial_md, @server_trailing_md + ) { |r| GRPC.logger.info(r) } end end end @@ -578,7 +582,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength run_op_view_metadata_test(true) check_op_view_of_finished_client_call( @op, @server_initial_md, @server_trailing_md) do |responses| - responses.each { |r| p r } + responses.each { |r| GRPC.logger.info(r) } end end @@ -586,7 +590,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength run_op_view_metadata_test(false) check_op_view_of_finished_client_call( @op, @server_initial_md, @server_trailing_md) do |responses| - responses.each { |r| p r } + responses.each { |r| GRPC.logger.info(r) } end end @@ -895,7 +899,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength run_op_view_metadata_test(true) check_op_view_of_finished_client_call( @op, @server_initial_md, @server_trailing_md) do |responses| - responses.each { |r| p r } + responses.each { |r| GRPC.logger.info(r) } end end @@ -903,7 +907,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength run_op_view_metadata_test(false) check_op_view_of_finished_client_call( @op, @server_initial_md, @server_trailing_md) do |responses| - responses.each { |r| p r } + responses.each { |r| GRPC.logger.info(r) } end end diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb index e072d0c45f1..44a61340869 100644 --- a/src/ruby/spec/generic/rpc_server_spec.rb +++ b/src/ruby/spec/generic/rpc_server_spec.rb @@ -125,7 +125,7 @@ class CheckCallAfterFinishedService fail 'shouldnt reuse service' unless @server_side_call.nil? @server_side_call = call # iterate through requests so call can complete - call.each_remote_read.each { |r| p r } + call.each_remote_read.each { |r| GRPC.logger.info(r) } EchoMsg.new end @@ -138,7 +138,7 @@ class CheckCallAfterFinishedService def a_bidi_rpc(requests, call) fail 'shouldnt reuse service' unless @server_side_call.nil? @server_side_call = call - requests.each { |r| p r } + requests.each { |r| GRPC.logger.info(r) } [EchoMsg.new, EchoMsg.new] end end @@ -560,7 +560,7 @@ describe GRPC::RpcServer do 'connect_k1' => 'connect_v1' } wanted_md.each do |key, value| - puts "key: #{key}" + GRPC.logger.info("key: #{key}") expect(op.metadata[key]).to eq(value) end @srv.stop diff --git a/src/ruby/spec/support/services.rb b/src/ruby/spec/support/services.rb index 27239cd66c3..6e693f1cdec 100644 --- a/src/ruby/spec/support/services.rb +++ b/src/ruby/spec/support/services.rb @@ -50,7 +50,9 @@ class EchoService def a_client_streaming_rpc(call) # iterate through requests so call can complete call.output_metadata.update(@trailing_metadata) - call.each_remote_read.each { |r| p r } + call.each_remote_read.each do |r| + GRPC.logger.info(r) + end EchoMsg.new end @@ -61,7 +63,9 @@ class EchoService def a_bidi_rpc(requests, call) call.output_metadata.update(@trailing_metadata) - requests.each { |r| p r } + requests.each do |r| + GRPC.logger.info(r) + end [EchoMsg.new, EchoMsg.new] end end @@ -71,35 +75,37 @@ EchoStub = EchoService.rpc_stub_class # For testing server interceptors class TestServerInterceptor < GRPC::ServerInterceptor def request_response(request:, call:, method:) - p "Received request/response call at method #{method}" \ - " with request #{request} for call #{call}" + GRPC.logger.info("Received request/response call at method #{method}" \ + " with request #{request} for call #{call}") call.output_metadata[:interc] = 'from_request_response' - p "[GRPC::Ok] (#{method.owner.name}.#{method.name})" + GRPC.logger.info("[GRPC::Ok] (#{method.owner.name}.#{method.name})") yield end def client_streamer(call:, method:) call.output_metadata[:interc] = 'from_client_streamer' call.each_remote_read.each do |r| - p "In interceptor: #{r}" + GRPC.logger.info("In interceptor: #{r}") end - p "Received client streamer call at method #{method} for call #{call}" + GRPC.logger.info( + "Received client streamer call at method #{method} for call #{call}" + ) yield end def server_streamer(request:, call:, method:) - p "Received server streamer call at method #{method} with request" \ - " #{request} for call #{call}" + GRPC.logger.info("Received server streamer call at method #{method} with request" \ + " #{request} for call #{call}") call.output_metadata[:interc] = 'from_server_streamer' yield end def bidi_streamer(requests:, call:, method:) requests.each do |r| - p "Bidi request: #{r}" + GRPC.logger.info("Bidi request: #{r}") end - p "Received bidi streamer call at method #{method} with requests" \ - " #{requests} for call #{call}" + GRPC.logger.info("Received bidi streamer call at method #{method} with requests" \ + " #{requests} for call #{call}") call.output_metadata[:interc] = 'from_bidi_streamer' yield end @@ -108,38 +114,38 @@ end # For testing client interceptors class TestClientInterceptor < GRPC::ClientInterceptor def request_response(request:, call:, method:, metadata: {}) - p "Intercepted request/response call at method #{method}" \ + GRPC.logger.info("Intercepted request/response call at method #{method}" \ " with request #{request} for call #{call}" \ - " and metadata: #{metadata}" + " and metadata: #{metadata}") metadata['foo'] = 'bar_from_request_response' yield end def client_streamer(requests:, call:, method:, metadata: {}) - p "Received client streamer call at method #{method}" \ + GRPC.logger.info("Received client streamer call at method #{method}" \ " with requests #{requests} for call #{call}" \ - " and metadata: #{metadata}" + " and metadata: #{metadata}") requests.each do |r| - p "In client interceptor: #{r}" + GRPC.logger.info("In client interceptor: #{r}") end metadata['foo'] = 'bar_from_client_streamer' yield end def server_streamer(request:, call:, method:, metadata: {}) - p "Received server streamer call at method #{method}" \ + GRPC.logger.info("Received server streamer call at method #{method}" \ " with request #{request} for call #{call}" \ - " and metadata: #{metadata}" + " and metadata: #{metadata}") metadata['foo'] = 'bar_from_server_streamer' yield end def bidi_streamer(requests:, call:, method:, metadata: {}) - p "Received bidi streamer call at method #{method}" \ + GRPC.logger.info("Received bidi streamer call at method #{method}" \ "with requests #{requests} for call #{call}" \ - " and metadata: #{metadata}" + " and metadata: #{metadata}") requests.each do |r| - p "In client interceptor: #{r}" + GRPC.logger.info("In client interceptor: #{r}") end metadata['foo'] = 'bar_from_bidi_streamer' yield From 0a650eae58901a3a45313ad61aa641d5804a680a Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 19 Sep 2018 07:41:59 -0700 Subject: [PATCH 390/546] regenerate projects --- grpc.def | 1 + src/ruby/ext/grpc/rb_grpc_imports.generated.c | 2 ++ src/ruby/ext/grpc/rb_grpc_imports.generated.h | 3 +++ test/core/surface/public_headers_must_be_c89.c | 1 + 4 files changed, 7 insertions(+) diff --git a/grpc.def b/grpc.def index b7ba2c5d10e..345c0a786ce 100644 --- a/grpc.def +++ b/grpc.def @@ -77,6 +77,7 @@ EXPORTS grpc_channelz_get_servers grpc_channelz_get_channel grpc_channelz_get_subchannel + grpc_channelz_get_socket grpc_insecure_channel_create_from_fd grpc_server_add_insecure_channel_from_fd grpc_use_signal diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 0c46f6c85a1..1e7d7f687f0 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -100,6 +100,7 @@ grpc_channelz_get_top_channels_type grpc_channelz_get_top_channels_import; grpc_channelz_get_servers_type grpc_channelz_get_servers_import; grpc_channelz_get_channel_type grpc_channelz_get_channel_import; grpc_channelz_get_subchannel_type grpc_channelz_get_subchannel_import; +grpc_channelz_get_socket_type grpc_channelz_get_socket_import; grpc_insecure_channel_create_from_fd_type grpc_insecure_channel_create_from_fd_import; grpc_server_add_insecure_channel_from_fd_type grpc_server_add_insecure_channel_from_fd_import; grpc_use_signal_type grpc_use_signal_import; @@ -356,6 +357,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_channelz_get_servers_import = (grpc_channelz_get_servers_type) GetProcAddress(library, "grpc_channelz_get_servers"); grpc_channelz_get_channel_import = (grpc_channelz_get_channel_type) GetProcAddress(library, "grpc_channelz_get_channel"); grpc_channelz_get_subchannel_import = (grpc_channelz_get_subchannel_type) GetProcAddress(library, "grpc_channelz_get_subchannel"); + grpc_channelz_get_socket_import = (grpc_channelz_get_socket_type) GetProcAddress(library, "grpc_channelz_get_socket"); grpc_insecure_channel_create_from_fd_import = (grpc_insecure_channel_create_from_fd_type) GetProcAddress(library, "grpc_insecure_channel_create_from_fd"); grpc_server_add_insecure_channel_from_fd_import = (grpc_server_add_insecure_channel_from_fd_type) GetProcAddress(library, "grpc_server_add_insecure_channel_from_fd"); grpc_use_signal_import = (grpc_use_signal_type) GetProcAddress(library, "grpc_use_signal"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 6adddb536c9..1375f68bbfb 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -275,6 +275,9 @@ extern grpc_channelz_get_channel_type grpc_channelz_get_channel_import; typedef char*(*grpc_channelz_get_subchannel_type)(intptr_t subchannel_id); extern grpc_channelz_get_subchannel_type grpc_channelz_get_subchannel_import; #define grpc_channelz_get_subchannel grpc_channelz_get_subchannel_import +typedef char*(*grpc_channelz_get_socket_type)(intptr_t socket_id); +extern grpc_channelz_get_socket_type grpc_channelz_get_socket_import; +#define grpc_channelz_get_socket grpc_channelz_get_socket_import typedef grpc_channel*(*grpc_insecure_channel_create_from_fd_type)(const char* target, int fd, const grpc_channel_args* args); extern grpc_insecure_channel_create_from_fd_type grpc_insecure_channel_create_from_fd_import; #define grpc_insecure_channel_create_from_fd grpc_insecure_channel_create_from_fd_import diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index b0af788796f..3ebdb88a08e 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -139,6 +139,7 @@ int main(int argc, char **argv) { printf("%lx", (unsigned long) grpc_channelz_get_servers); printf("%lx", (unsigned long) grpc_channelz_get_channel); printf("%lx", (unsigned long) grpc_channelz_get_subchannel); + printf("%lx", (unsigned long) grpc_channelz_get_socket); printf("%lx", (unsigned long) grpc_auth_property_iterator_next); printf("%lx", (unsigned long) grpc_auth_context_property_iterator); printf("%lx", (unsigned long) grpc_auth_context_peer_identity); From 1359543b47c0ecff8ecd50ae4d3a2989e16a8a94 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 19 Sep 2018 09:39:21 -0700 Subject: [PATCH 391/546] Add a comment to address reviewer feedback --- include/grpcpp/alarm.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/grpcpp/alarm.h b/include/grpcpp/alarm.h index f9008c327e4..365feb4eb95 100644 --- a/include/grpcpp/alarm.h +++ b/include/grpcpp/alarm.h @@ -85,6 +85,9 @@ class Alarm : private GrpcLibraryCodegen { public: explicit experimental_type(Alarm* alarm) : alarm_(alarm) {} + /// Set an alarm to invoke callback \a f. The argument to the callback + /// states whether the alarm expired at \a deadline (true) or was cancelled + /// (false) template void Set(const T& deadline, std::function f) { alarm_->SetInternal(TimePoint(deadline).raw_time(), std::move(f)); From dd10cbc5545f69882847b96d3dc41a64e3ada466 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 19 Sep 2018 10:28:39 -0700 Subject: [PATCH 392/546] Change force_creation from atm to bool --- .../client_channel/subchannel_index.cc | 6 +-- test/cpp/end2end/client_lb_end2end_test.cc | 41 +++++++++++++------ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc index f2b6c24e8ee..1c23a6c4be4 100644 --- a/src/core/ext/filters/client_channel/subchannel_index.cc +++ b/src/core/ext/filters/client_channel/subchannel_index.cc @@ -42,7 +42,7 @@ struct grpc_subchannel_key { grpc_subchannel_args args; }; -static gpr_atm g_force_creation = false; +static bool g_force_creation = false; static grpc_subchannel_key* create_key( const grpc_subchannel_args* args, @@ -74,7 +74,7 @@ static grpc_subchannel_key* subchannel_key_copy(grpc_subchannel_key* k) { int grpc_subchannel_key_compare(const grpc_subchannel_key* a, const grpc_subchannel_key* b) { // To pretend the keys are different, return a non-zero value. - if (GPR_UNLIKELY(gpr_atm_no_barrier_load(&g_force_creation))) return 1; + if (GPR_UNLIKELY(g_force_creation)) return 1; int c = GPR_ICMP(a->args.filter_count, b->args.filter_count); if (c != 0) return c; if (a->args.filter_count > 0) { @@ -251,5 +251,5 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key, } void grpc_subchannel_index_test_only_set_force_creation(bool force_creation) { - gpr_atm_no_barrier_store(&g_force_creation, force_creation); + g_force_creation = force_creation; } diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index e5d6132012a..a9d68ab0582 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -119,6 +119,7 @@ class ClientLbEnd2endTest : public ::testing::Test { } void SetUp() override { + grpc_init(); response_generator_ = grpc_core::MakeRefCounted(); } @@ -127,6 +128,7 @@ class ClientLbEnd2endTest : public ::testing::Test { for (size_t i = 0; i < servers_.size(); ++i) { servers_[i]->Shutdown(); } + grpc_shutdown(); } void CreateServers(size_t num_servers, @@ -560,7 +562,23 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) { EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } -TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { +class ClientLbEnd2endWithParamTest + : public ClientLbEnd2endTest, + public ::testing::WithParamInterface { + protected: + void SetUp() override { + grpc_subchannel_index_test_only_set_force_creation(GetParam()); + ClientLbEnd2endTest::SetUp(); + } + + void TearDown() override { + ClientLbEnd2endTest::TearDown(); + grpc_subchannel_index_test_only_set_force_creation(false); + } +}; + +TEST_P(ClientLbEnd2endWithParamTest, PickFirstManyUpdates) { + gpr_log(GPR_INFO, "subchannel force creation: %d", GetParam()); // Start servers and send one RPC per server. const int kNumServers = 3; StartServers(kNumServers); @@ -570,20 +588,21 @@ TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) { for (size_t i = 0; i < servers_.size(); ++i) { ports.emplace_back(servers_[i]->port_); } - for (const bool force_creation : {true, false}) { - grpc_subchannel_index_test_only_set_force_creation(force_creation); - gpr_log(GPR_INFO, "Force subchannel creation: %d", force_creation); - for (size_t i = 0; i < 1000; ++i) { - std::shuffle(ports.begin(), ports.end(), - std::mt19937(std::random_device()())); - SetNextResolution(ports); - if (i % 10 == 0) CheckRpcSendOk(stub, DEBUG_LOCATION); - } + for (size_t i = 0; i < 1000; ++i) { + std::shuffle(ports.begin(), ports.end(), + std::mt19937(std::random_device()())); + SetNextResolution(ports); + // We should re-enter core at the end of the loop to give the resolution + // setting closure a chance to run. + if ((i + 1) % 10 == 0) CheckRpcSendOk(stub, DEBUG_LOCATION); } // Check LB policy name for the channel. EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); } +INSTANTIATE_TEST_CASE_P(SubchannelForceCreation, ClientLbEnd2endWithParamTest, + ::testing::Bool()); + TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) { // Prepare the ports for up servers and down servers. const int kNumServers = 3; @@ -984,8 +1003,6 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); grpc_test_init(argc, argv); - grpc_init(); const auto result = RUN_ALL_TESTS(); - grpc_shutdown(); return result; } From deb3126611a513b768052d93a976832985640d9f Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 19 Sep 2018 11:29:11 -0700 Subject: [PATCH 393/546] Fix clang-tidy concerns --- src/cpp/common/callback_common.cc | 4 ++-- test/cpp/end2end/client_callback_end2end_test.cc | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cpp/common/callback_common.cc b/src/cpp/common/callback_common.cc index fa586286d1c..a0c8eeb5160 100644 --- a/src/cpp/common/callback_common.cc +++ b/src/cpp/common/callback_common.cc @@ -66,8 +66,8 @@ class CallbackWithSuccessImpl : public grpc_core::CQCallbackInterface { GPR_ASSERT(parent_->ops()->FinalizeResult(&ignored, &new_ok)); GPR_ASSERT(ignored == parent_->ops()); - // Last use of func_ or ok, so ok to move them out for rvalue call above - CatchingCallback(std::move(func_), std::move(ok)); + // Last use of func_, so ok to move it out for rvalue call above + CatchingCallback(std::move(func_), ok); func_ = nullptr; // reset to clear this out for sure grpc_call_unref(call_); diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 3b492090dd1..d8cb44b694a 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -95,6 +95,8 @@ class ClientCallbackEnd2endTest : public ::testing::Test { if (maybe_except) { throw - 1; } +#else + GPR_ASSERT(!maybe_except); #endif }); std::unique_lock l(mu); From 327c514fe77140c57b3144f9425acf512ecf8869 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 19 Sep 2018 13:47:29 -0700 Subject: [PATCH 394/546] Some reorganizing to respond to code review comments --- BUILD | 2 + CMakeLists.txt | 6 +++ Makefile | 6 +++ build.yaml | 2 + config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 ++ grpc.gemspec | 2 + grpc.gyp | 4 ++ package.xml | 2 + .../chttp2/transport/hpack_encoder.cc | 6 +-- .../chttp2/transport/hpack_mapping.cc | 39 ++++++++++++++ .../chttp2/transport/hpack_mapping.h | 38 +++++++++++++ .../transport/chttp2/transport/hpack_table.cc | 29 ++++++++++ .../transport/chttp2/transport/hpack_table.h | 9 ++++ src/core/lib/transport/metadata.cc | 27 ---------- src/core/lib/transport/metadata.h | 8 --- src/core/lib/transport/static_metadata.cc | 8 --- src/core/lib/transport/static_metadata.h | 2 - src/python/grpcio/grpc_core_dependencies.py | 1 + .../transport/chttp2/hpack_encoder_test.cc | 2 +- test/core/transport/metadata_test.cc | 4 +- tools/codegen/core/gen_static_metadata.py | 53 ++++++++++++++++--- tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 3 ++ 26 files changed, 202 insertions(+), 59 deletions(-) create mode 100644 src/core/ext/transport/chttp2/transport/hpack_mapping.cc create mode 100644 src/core/ext/transport/chttp2/transport/hpack_mapping.h diff --git a/BUILD b/BUILD index 925e277cf77..cf147fcead1 100644 --- a/BUILD +++ b/BUILD @@ -1573,6 +1573,7 @@ grpc_cc_library( "src/core/ext/transport/chttp2/transport/frame_window_update.cc", "src/core/ext/transport/chttp2/transport/hpack_encoder.cc", "src/core/ext/transport/chttp2/transport/hpack_parser.cc", + "src/core/ext/transport/chttp2/transport/hpack_mapping.cc", "src/core/ext/transport/chttp2/transport/hpack_table.cc", "src/core/ext/transport/chttp2/transport/http2_settings.cc", "src/core/ext/transport/chttp2/transport/huffsyms.cc", @@ -1597,6 +1598,7 @@ grpc_cc_library( "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_mapping.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", diff --git a/CMakeLists.txt b/CMakeLists.txt index a21bb8b5fae..31c0887fab5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1103,6 +1103,7 @@ add_library(grpc src/core/ext/transport/chttp2/transport/frame_settings.cc src/core/ext/transport/chttp2/transport/frame_window_update.cc src/core/ext/transport/chttp2/transport/hpack_encoder.cc + src/core/ext/transport/chttp2/transport/hpack_mapping.cc src/core/ext/transport/chttp2/transport/hpack_parser.cc src/core/ext/transport/chttp2/transport/hpack_table.cc src/core/ext/transport/chttp2/transport/http2_settings.cc @@ -1514,6 +1515,7 @@ add_library(grpc_cronet src/core/ext/transport/chttp2/transport/frame_settings.cc src/core/ext/transport/chttp2/transport/frame_window_update.cc src/core/ext/transport/chttp2/transport/hpack_encoder.cc + src/core/ext/transport/chttp2/transport/hpack_mapping.cc src/core/ext/transport/chttp2/transport/hpack_parser.cc src/core/ext/transport/chttp2/transport/hpack_table.cc src/core/ext/transport/chttp2/transport/http2_settings.cc @@ -1927,6 +1929,7 @@ add_library(grpc_test_util src/core/ext/transport/chttp2/transport/frame_settings.cc src/core/ext/transport/chttp2/transport/frame_window_update.cc src/core/ext/transport/chttp2/transport/hpack_encoder.cc + src/core/ext/transport/chttp2/transport/hpack_mapping.cc src/core/ext/transport/chttp2/transport/hpack_parser.cc src/core/ext/transport/chttp2/transport/hpack_table.cc src/core/ext/transport/chttp2/transport/http2_settings.cc @@ -2237,6 +2240,7 @@ add_library(grpc_test_util_unsecure src/core/ext/transport/chttp2/transport/frame_settings.cc src/core/ext/transport/chttp2/transport/frame_window_update.cc src/core/ext/transport/chttp2/transport/hpack_encoder.cc + src/core/ext/transport/chttp2/transport/hpack_mapping.cc src/core/ext/transport/chttp2/transport/hpack_parser.cc src/core/ext/transport/chttp2/transport/hpack_table.cc src/core/ext/transport/chttp2/transport/http2_settings.cc @@ -2505,6 +2509,7 @@ add_library(grpc_unsecure src/core/ext/transport/chttp2/transport/frame_settings.cc src/core/ext/transport/chttp2/transport/frame_window_update.cc src/core/ext/transport/chttp2/transport/hpack_encoder.cc + src/core/ext/transport/chttp2/transport/hpack_mapping.cc src/core/ext/transport/chttp2/transport/hpack_parser.cc src/core/ext/transport/chttp2/transport/hpack_table.cc src/core/ext/transport/chttp2/transport/http2_settings.cc @@ -3171,6 +3176,7 @@ add_library(grpc++_cronet src/core/ext/transport/chttp2/transport/frame_settings.cc src/core/ext/transport/chttp2/transport/frame_window_update.cc src/core/ext/transport/chttp2/transport/hpack_encoder.cc + src/core/ext/transport/chttp2/transport/hpack_mapping.cc src/core/ext/transport/chttp2/transport/hpack_parser.cc src/core/ext/transport/chttp2/transport/hpack_table.cc src/core/ext/transport/chttp2/transport/http2_settings.cc diff --git a/Makefile b/Makefile index 96ea890bcb8..e491e4bcd76 100644 --- a/Makefile +++ b/Makefile @@ -3605,6 +3605,7 @@ LIBGRPC_SRC = \ src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ + src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ @@ -4015,6 +4016,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ + src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ @@ -4426,6 +4428,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ + src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ @@ -4727,6 +4730,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ + src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ @@ -4973,6 +4977,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ + src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ @@ -5627,6 +5632,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ + src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ diff --git a/build.yaml b/build.yaml index a50a0a4ab65..d14c19199de 100644 --- a/build.yaml +++ b/build.yaml @@ -936,6 +936,7 @@ filegroups: - 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_mapping.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 @@ -957,6 +958,7 @@ filegroups: - src/core/ext/transport/chttp2/transport/frame_settings.cc - src/core/ext/transport/chttp2/transport/frame_window_update.cc - src/core/ext/transport/chttp2/transport/hpack_encoder.cc + - src/core/ext/transport/chttp2/transport/hpack_mapping.cc - src/core/ext/transport/chttp2/transport/hpack_parser.cc - src/core/ext/transport/chttp2/transport/hpack_table.cc - src/core/ext/transport/chttp2/transport/http2_settings.cc diff --git a/config.m4 b/config.m4 index af3624cdd1b..a6ce55e0a9d 100644 --- a/config.m4 +++ b/config.m4 @@ -249,6 +249,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ + src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ diff --git a/config.w32 b/config.w32 index ad91ee40bd7..333986c50a5 100644 --- a/config.w32 +++ b/config.w32 @@ -224,6 +224,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\transport\\chttp2\\transport\\frame_settings.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\frame_window_update.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\hpack_encoder.cc " + + "src\\core\\ext\\transport\\chttp2\\transport\\hpack_mapping.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\hpack_parser.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\hpack_table.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\http2_settings.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 581b9246bc5..f4cbd275645 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -251,6 +251,7 @@ Pod::Spec.new do |s| '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_mapping.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', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 5a82a4200a2..1efa71a19e0 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -263,6 +263,7 @@ Pod::Spec.new do |s| '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_mapping.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', @@ -681,6 +682,7 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/frame_settings.cc', 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', + 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_table.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', @@ -866,6 +868,7 @@ Pod::Spec.new do |s| '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_mapping.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', diff --git a/grpc.gemspec b/grpc.gemspec index c8e58faec9e..f5cbf796240 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -195,6 +195,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/frame_settings.h ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_window_update.h ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder.h ) + s.files += %w( src/core/ext/transport/chttp2/transport/hpack_mapping.h ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser.h ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_table.h ) s.files += %w( src/core/ext/transport/chttp2/transport/http2_settings.h ) @@ -617,6 +618,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/frame_settings.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_window_update.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder.cc ) + s.files += %w( src/core/ext/transport/chttp2/transport/hpack_mapping.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_table.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/http2_settings.cc ) diff --git a/grpc.gyp b/grpc.gyp index 654a5310923..15d20053f4d 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -441,6 +441,7 @@ 'src/core/ext/transport/chttp2/transport/frame_settings.cc', 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', + 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_table.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', @@ -825,6 +826,7 @@ 'src/core/ext/transport/chttp2/transport/frame_settings.cc', 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', + 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_table.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', @@ -1060,6 +1062,7 @@ 'src/core/ext/transport/chttp2/transport/frame_settings.cc', 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', + 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_table.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', @@ -1252,6 +1255,7 @@ 'src/core/ext/transport/chttp2/transport/frame_settings.cc', 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', + 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_table.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', diff --git a/package.xml b/package.xml index 9c0e078e92c..1e8ae8bb6a9 100644 --- a/package.xml +++ b/package.xml @@ -200,6 +200,7 @@ + @@ -622,6 +623,7 @@ + diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc index eff9b97a8e2..920d52770fc 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc @@ -525,7 +525,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem, /* should this elem be in the table? */ size_t decoder_space_usage = - grpc_mdelem_get_size_in_hpack_table(elem, st->use_true_binary_metadata); + grpc_chttp2_get_size_in_hpack_table(elem, st->use_true_binary_metadata); bool should_add_elem = elem_interned && decoder_space_usage < MAX_DECODER_SPACE_USAGE && c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >= @@ -689,7 +689,7 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, } for (size_t i = 0; i < extra_headers_size; ++i) { grpc_mdelem md = *extra_headers[i]; - uint8_t static_index = grpc_mdelem_get_static_hpack_table_index(md); + uint8_t static_index = grpc_chttp2_get_static_hpack_table_index(md); if (static_index) { emit_indexed(c, static_index, &st); } else { @@ -698,7 +698,7 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c, } grpc_metadata_batch_assert_ok(metadata); for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) { - uint8_t static_index = grpc_mdelem_get_static_hpack_table_index(l->md); + uint8_t static_index = grpc_chttp2_get_static_hpack_table_index(l->md); if (static_index) { emit_indexed(c, static_index, &st); } else { diff --git a/src/core/ext/transport/chttp2/transport/hpack_mapping.cc b/src/core/ext/transport/chttp2/transport/hpack_mapping.cc new file mode 100644 index 00000000000..fd529f0fd4d --- /dev/null +++ b/src/core/ext/transport/chttp2/transport/hpack_mapping.cc @@ -0,0 +1,39 @@ +/* + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * WARNING: Auto-generated code. + * + * To make changes to this file, change + * tools/codegen/core/gen_static_metadata.py, and then re-run it. + * + * This file contains the mapping from the index of each metadata element in the + * grpc static metadata table to the index of that element in the hpack static + * metadata table. If the element is not contained in the static hpack table, + * then the returned index is 0. + */ + +#include + +#include "src/core/ext/transport/chttp2/transport/hpack_mapping.h" + +const uint8_t grpc_hpack_static_mdelem_indices[GRPC_STATIC_MDELEM_COUNT] = { + 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 13, 6, 7, 0, 1, 2, 0, 4, + 5, 9, 10, 11, 12, 14, 15, 0, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 0, 0, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; diff --git a/src/core/ext/transport/chttp2/transport/hpack_mapping.h b/src/core/ext/transport/chttp2/transport/hpack_mapping.h new file mode 100644 index 00000000000..ebcd65bd9fe --- /dev/null +++ b/src/core/ext/transport/chttp2/transport/hpack_mapping.h @@ -0,0 +1,38 @@ +/* + * 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. + */ + +/* + * WARNING: Auto-generated code. + * + * To make changes to this file, change + * tools/codegen/core/gen_static_metadata.py, and then re-run it. + * + * This file contains the mapping from the index of each metadata element in the + * grpc static metadata table to the index of that element in the hpack static + * metadata table. If the element is not contained in the static hpack table, + * then the returned index is 0. + */ + +#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_MAPPING_H +#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_MAPPING_H + +#include + +#include "src/core/lib/transport/static_metadata.h" + +extern const uint8_t grpc_hpack_static_mdelem_indices[GRPC_STATIC_MDELEM_COUNT]; + +#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_MAPPING_H */ diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc index 79292583567..117679ab751 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc @@ -27,8 +27,10 @@ #include #include +#include "src/core/ext/transport/chttp2/transport/hpack_mapping.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/murmur_hash.h" +#include "src/core/lib/transport/static_metadata.h" extern grpc_core::TraceFlag grpc_http_trace; @@ -366,3 +368,30 @@ grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find( return r; } + +static size_t get_base64_encoded_size(size_t raw_length) { + static const uint8_t tail_xtra[3] = {0, 2, 3}; + return raw_length / 3 * 4 + tail_xtra[raw_length % 3]; +} + +size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem, + bool use_true_binary_metadata) { + size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); + size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem)); + if (grpc_is_binary_header(GRPC_MDKEY(elem))) { + return overhead_and_key + (use_true_binary_metadata + ? value_len + 1 + : get_base64_encoded_size(value_len)); + } else { + return overhead_and_key + value_len; + } +} + +uint8_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md) { + if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { + return grpc_hpack_static_mdelem_indices[GRPC_MDELEM_DATA(md) - + grpc_static_mdelem_table]; + } else { + return 0; + } +} diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.h b/src/core/ext/transport/chttp2/transport/hpack_table.h index 98026a4ba4a..a0ffc6fab77 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.h +++ b/src/core/ext/transport/chttp2/transport/hpack_table.h @@ -83,6 +83,15 @@ grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl* tbl, /* add a table entry to the index */ grpc_error* grpc_chttp2_hptbl_add(grpc_chttp2_hptbl* tbl, grpc_mdelem md) GRPC_MUST_USE_RESULT; + +size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem, + bool use_true_binary_metadata); + +/* Returns the static hpack table index that corresponds to /a elem. Returns 0 + if /a elem is not statically stored or if it is not in the static hpack + table */ +uint8_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md); + /* Find a key/value pair in the table... returns the index in the table of the most similar entry, or 0 if the value was not found */ typedef struct { diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index dfcd2e16d8a..d164502280a 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -342,33 +342,6 @@ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata) { changed ? nullptr : reinterpret_cast(metadata)); } -static size_t get_base64_encoded_size(size_t raw_length) { - static const uint8_t tail_xtra[3] = {0, 2, 3}; - return raw_length / 3 * 4 + tail_xtra[raw_length % 3]; -} - -size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem, - bool use_true_binary_metadata) { - size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(GRPC_MDKEY(elem)); - size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem)); - if (grpc_is_binary_header(GRPC_MDKEY(elem))) { - return overhead_and_key + (use_true_binary_metadata - ? value_len + 1 - : get_base64_encoded_size(value_len)); - } else { - return overhead_and_key + value_len; - } -} - -uint8_t grpc_mdelem_get_static_hpack_table_index(grpc_mdelem md) { - if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { - return grpc_hpack_static_mdelem_indices[GRPC_MDELEM_DATA(md) - - grpc_static_mdelem_table]; - } else { - return 0; - } -} - grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) { switch (GRPC_MDELEM_STORAGE(gmd)) { case GRPC_MDELEM_STORAGE_EXTERNAL: diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 37419c9d2f5..338082276cc 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -125,14 +125,6 @@ grpc_mdelem grpc_mdelem_create( bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b); -size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem, - bool use_true_binary_metadata); - -/* Returns the static hpack table index that corresponds to /a elem. Returns 0 - if /a elem is not statically stored or if it is not in the static hpack - table */ -uint8_t grpc_mdelem_get_static_hpack_table_index(grpc_mdelem md); - /* Mutator and accessor for grpc_mdelem user data. The destructor function is used as a type tag and is checked during user_data fetch. */ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*if_destroy_func)(void*)); diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index fdedd410369..6a5144f21a2 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -334,14 +334,6 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}, }; -const uint8_t grpc_hpack_static_mdelem_indices[GRPC_STATIC_MDELEM_COUNT] = { - 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 13, 6, 7, 0, 1, 2, 0, 4, - 5, 9, 10, 11, 12, 14, 15, 0, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 0, 0, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index e5319c4c4d4..b3a10f58730 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -521,8 +521,6 @@ extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; #define GRPC_MDELEM_ACCEPT_ENCODING_IDENTITY_COMMA_GZIP \ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[85], GRPC_MDELEM_STORAGE_STATIC)) -extern const uint8_t grpc_hpack_static_mdelem_indices[GRPC_STATIC_MDELEM_COUNT]; - grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b); typedef enum { GRPC_BATCH_PATH, diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 0f68e823d79..ceacc83e626 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -223,6 +223,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/transport/chttp2/transport/frame_settings.cc', 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', + 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_table.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', diff --git a/test/core/transport/chttp2/hpack_encoder_test.cc b/test/core/transport/chttp2/hpack_encoder_test.cc index 2a57198ab64..ab819f90923 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.cc +++ b/test/core/transport/chttp2/hpack_encoder_test.cc @@ -202,7 +202,7 @@ static void verify_table_size_change_match_elem_size(const char* key, grpc_mdelem elem = grpc_mdelem_from_slices( grpc_slice_intern(grpc_slice_from_static_string(key)), grpc_slice_intern(grpc_slice_from_static_string(value))); - size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem, use_true_binary); + size_t elem_size = grpc_chttp2_get_size_in_hpack_table(elem, use_true_binary); size_t initial_table_size = g_compressor.table_size; grpc_linked_mdelem* e = static_cast(gpr_malloc(sizeof(*e))); diff --git a/test/core/transport/metadata_test.cc b/test/core/transport/metadata_test.cc index 4be34f72d9b..307fcc6da39 100644 --- a/test/core/transport/metadata_test.cc +++ b/test/core/transport/metadata_test.cc @@ -293,7 +293,7 @@ static void verify_ascii_header_size(const char* key, const char* value, grpc_mdelem elem = grpc_mdelem_from_slices( maybe_intern(grpc_slice_from_static_string(key), intern_key), maybe_intern(grpc_slice_from_static_string(value), intern_value)); - size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem, false); + size_t elem_size = grpc_chttp2_get_size_in_hpack_table(elem, false); size_t expected_size = 32 + strlen(key) + strlen(value); GPR_ASSERT(expected_size == elem_size); GRPC_MDELEM_UNREF(elem); @@ -307,7 +307,7 @@ static void verify_binary_header_size(const char* key, const uint8_t* value, maybe_intern(grpc_slice_from_static_buffer(value, value_len), intern_value)); GPR_ASSERT(grpc_is_binary_header(GRPC_MDKEY(elem))); - size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem, false); + size_t elem_size = grpc_chttp2_get_size_in_hpack_table(elem, false); grpc_slice value_slice = grpc_slice_from_copied_buffer( reinterpret_cast(value), value_len); grpc_slice base64_encoded = grpc_chttp2_base64_encode(value_slice); diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index 784e7540919..463047215af 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -326,6 +326,15 @@ else: os.path.dirname(sys.argv[0]), '../../../test/core/end2end/fuzzers/hpack.dictionary'), 'w') +HPACK_H = open( + os.path.join( + os.path.dirname(sys.argv[0]), + '../../../src/core/ext/transport/chttp2/transport/hpack_mapping.h'), 'w') +HPACK_C = open( + os.path.join( + os.path.dirname(sys.argv[0]), + '../../../src/core/ext/transport/chttp2/transport/hpack_mapping.cc'), 'w') + # copy-paste copyright notice from this file with open(sys.argv[0]) as my_source: copyright = [] @@ -340,7 +349,7 @@ with open(sys.argv[0]) as my_source: if line[0] != '#': break copyright.append(line) - put_banner([H, C], [line[2:].rstrip() for line in copyright]) + put_banner([H, C, HPACK_H, HPACK_C], [line[2:].rstrip() for line in copyright]) hex_bytes = [ord(c) for c in 'abcdefABCDEF0123456789'] @@ -367,6 +376,17 @@ See metadata.h for an explanation of the interface here, and metadata.cc for an explanation of what's going on. """.splitlines()) +put_banner([HPACK_H, HPACK_C], """WARNING: Auto-generated code. + +To make changes to this file, change +tools/codegen/core/gen_static_metadata.py, and then re-run it. + +This file contains the mapping from the index of each metadata element in the +grpc static metadata table to the index of that element in the hpack static +metadata table. If the element is not contained in the static hpack table, then +the returned index is 0. +""".splitlines()) + print >> H, '#ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H' print >> H, '#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H' print >> H @@ -380,6 +400,20 @@ print >> C, '#include "src/core/lib/transport/static_metadata.h"' print >> C print >> C, '#include "src/core/lib/slice/slice_internal.h"' print >> C +print >> HPACK_H, ('#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_' + 'MAPPING_H') +print >> HPACK_H, ('#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_' + 'MAPPING_H') +print >> HPACK_H +print >> HPACK_H, '#include ' +print >> HPACK_H +print >> HPACK_H, '#include "src/core/lib/transport/static_metadata.h"' +print >> HPACK_H +print >> HPACK_C, '#include ' +print >> HPACK_C +print >> HPACK_C, ('#include ' + '"src/core/ext/transport/chttp2/transport/hpack_mapping.h"') +print >> HPACK_C str_ofs = 0 id2strofs = {} @@ -463,10 +497,10 @@ print >> H # Print out the chttp2 mapping between static mdelem index and the hpack static # table index -print >> H, ('extern const uint8_t grpc_hpack_static_mdelem_indices[' +print >> HPACK_H, ('extern const uint8_t grpc_hpack_static_mdelem_indices[' 'GRPC_STATIC_MDELEM_COUNT];') -print >> H -print >> C, ('const uint8_t grpc_hpack_static_mdelem_indices[' +print >> HPACK_H +print >> HPACK_C, ('const uint8_t grpc_hpack_static_mdelem_indices[' 'GRPC_STATIC_MDELEM_COUNT] = {') indices = '' for i, elem in enumerate(all_elems): @@ -474,9 +508,9 @@ for i, elem in enumerate(all_elems): if len(elem) == 3: index = elem[2] indices += '%d,' % index -print >> C, ' %s' % indices -print >> C, '};' -print >> C +print >> HPACK_C, ' %s' % indices +print >> HPACK_C, '};' +print >> HPACK_C print >> C, ('uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] ' '= {') @@ -570,7 +604,7 @@ print >> C, '}' print >> C print >> C, 'grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {' -for i, elem in enumerate(all_elems): +for elem in all_elems: print >> C, '{%s,%s},' % (slice_def(str_idx(elem[0])), slice_def(str_idx(elem[1]))) print >> C, '};' @@ -624,5 +658,8 @@ print >> H, '#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GR print >> H, '#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */' +print >> HPACK_H, ('#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_' + 'MAPPING_H */') + H.close() C.close() diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 7cd1dc7bf37..ed0e17a99ef 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1013,6 +1013,8 @@ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.h \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.h \ +src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ +src/core/ext/transport/chttp2/transport/hpack_mapping.h \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.h \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 8ea5126fdef..698ead0c5a8 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10661,6 +10661,7 @@ "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_mapping.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", @@ -10698,6 +10699,8 @@ "src/core/ext/transport/chttp2/transport/frame_window_update.h", "src/core/ext/transport/chttp2/transport/hpack_encoder.cc", "src/core/ext/transport/chttp2/transport/hpack_encoder.h", + "src/core/ext/transport/chttp2/transport/hpack_mapping.cc", + "src/core/ext/transport/chttp2/transport/hpack_mapping.h", "src/core/ext/transport/chttp2/transport/hpack_parser.cc", "src/core/ext/transport/chttp2/transport/hpack_parser.h", "src/core/ext/transport/chttp2/transport/hpack_table.cc", From 4cc1cd7baa2ce3af63f359015ccf1120d72510b3 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 19 Sep 2018 14:12:24 -0700 Subject: [PATCH 395/546] Add needed include --- test/core/transport/metadata_test.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/core/transport/metadata_test.cc b/test/core/transport/metadata_test.cc index 307fcc6da39..8ab9639dfa2 100644 --- a/test/core/transport/metadata_test.cc +++ b/test/core/transport/metadata_test.cc @@ -27,6 +27,7 @@ #include #include "src/core/ext/transport/chttp2/transport/bin_encoder.h" +#include "src/core/ext/transport/chttp2/transport/hpack_table.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" From 0131c7bbb3122e7c02531ae7eb7715a1295ad896 Mon Sep 17 00:00:00 2001 From: easy Date: Wed, 19 Sep 2018 14:26:59 -0700 Subject: [PATCH 396/546] Document that set_deadline() uses absolute time. --- include/grpcpp/impl/codegen/client_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 46635a541a7..24f5c431ceb 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -224,7 +224,7 @@ class ClientContext { /// \warning This method should only be called before invoking the rpc. /// /// \param deadline the deadline for the client call. Units are determined by - /// the type used. + /// the type used. The deadline is an absolute (not relative) time. template void set_deadline(const T& deadline) { TimePoint deadline_tp(deadline); From 2a51d406e8536a7995e7b0a502334bb52532aa82 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 19 Sep 2018 14:26:37 -0700 Subject: [PATCH 397/546] Minor cleanup to gen_static_metadadta.py --- tools/codegen/core/gen_static_metadata.py | 28 +++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index 463047215af..dba01688377 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -23,7 +23,8 @@ import subprocess import re import perfection -# Configuration: a list of either strings or 2-tuples of strings. +# Configuration: a list of either strings or 2-tuples of strings or 3-tuples of +# strings. # A single string represents a static grpc_mdstr. # A 2-tuple represents a static grpc_mdelem (and appropriate grpc_mdstrs will # also be created). @@ -327,13 +328,15 @@ else: '../../../test/core/end2end/fuzzers/hpack.dictionary'), 'w') HPACK_H = open( - os.path.join( - os.path.dirname(sys.argv[0]), - '../../../src/core/ext/transport/chttp2/transport/hpack_mapping.h'), 'w') + os.path.join( + os.path.dirname(sys.argv[0]), + '../../../src/core/ext/transport/chttp2/transport/hpack_mapping.h'), + 'w') HPACK_C = open( - os.path.join( - os.path.dirname(sys.argv[0]), - '../../../src/core/ext/transport/chttp2/transport/hpack_mapping.cc'), 'w') + os.path.join( + os.path.dirname(sys.argv[0]), + '../../../src/core/ext/transport/chttp2/transport/hpack_mapping.cc'), + 'w') # copy-paste copyright notice from this file with open(sys.argv[0]) as my_source: @@ -349,7 +352,8 @@ with open(sys.argv[0]) as my_source: if line[0] != '#': break copyright.append(line) - put_banner([H, C, HPACK_H, HPACK_C], [line[2:].rstrip() for line in copyright]) + put_banner([H, C, HPACK_H, HPACK_C], + [line[2:].rstrip() for line in copyright]) hex_bytes = [ord(c) for c in 'abcdefABCDEF0123456789'] @@ -498,12 +502,12 @@ print >> H # Print out the chttp2 mapping between static mdelem index and the hpack static # table index print >> HPACK_H, ('extern const uint8_t grpc_hpack_static_mdelem_indices[' - 'GRPC_STATIC_MDELEM_COUNT];') + 'GRPC_STATIC_MDELEM_COUNT];') print >> HPACK_H print >> HPACK_C, ('const uint8_t grpc_hpack_static_mdelem_indices[' - 'GRPC_STATIC_MDELEM_COUNT] = {') + 'GRPC_STATIC_MDELEM_COUNT] = {') indices = '' -for i, elem in enumerate(all_elems): +for elem in all_elems: index = 0 if len(elem) == 3: index = elem[2] @@ -658,7 +662,7 @@ print >> H, '#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GR print >> H, '#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */' -print >> HPACK_H, ('#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_' +print >> HPACK_H, ('#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_' 'MAPPING_H */') H.close() From 974d66f94fa15eb28e1eaefed37d40492fd6d026 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 19 Sep 2018 17:27:53 -0700 Subject: [PATCH 398/546] Fix tag variable --- test/cpp/end2end/async_end2end_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index c9246f08068..d97ea071d15 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -178,7 +178,7 @@ class Verifier { EXPECT_EQ(it2->second.ok, ok); } } else { - gpr_log(GPR_ERROR, "Unexpected tag: %p", tag); + gpr_log(GPR_ERROR, "Unexpected tag: %p", got_tag); abort(); } } From 51b79f1757bb09c4b9e3defce338482ced1d2e88 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Sep 2018 17:46:03 -0700 Subject: [PATCH 399/546] Update function signature --- include/grpc/grpc_security.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 02d87a493a1..de90971cc55 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -532,14 +532,14 @@ typedef struct grpc_alts_credentials_options grpc_alts_credentials_options; * It is used for experimental purpose for now and subject to change. */ GRPCAPI grpc_alts_credentials_options* -grpc_alts_credentials_client_options_create(); +grpc_alts_credentials_client_options_create(void); /** * This method creates a grpc ALTS credentials server options instance. * It is used for experimental purpose for now and subject to change. */ GRPCAPI grpc_alts_credentials_options* -grpc_alts_credentials_server_options_create(); +grpc_alts_credentials_server_options_create(void); /** * This method adds a target service account to grpc client's ALTS credentials From 37b9b9e8fd60aa011b8b49b17498d86393d0fcf0 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 19 Sep 2018 17:56:42 -0700 Subject: [PATCH 400/546] Rename the openssl framework to openssl_grpc to avoid conflict --- gRPC-Core.podspec | 3 ++- src/objective-c/BoringSSL-GRPC.podspec | 4 ++-- templates/gRPC-Core.podspec.template | 3 ++- templates/src/objective-c/BoringSSL-GRPC.podspec.template | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 5a82a4200a2..e3914df9f7a 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -181,7 +181,7 @@ Pod::Spec.new do |s| ss.header_mappings_dir = '.' ss.libraries = 'z' ss.dependency "#{s.name}/Interface", version - ss.dependency 'BoringSSL-GRPC', '0.0.1' + ss.dependency 'BoringSSL-GRPC', '0.0.2' ss.dependency 'nanopb', '~> 0.3' ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS' @@ -1307,5 +1307,6 @@ Pod::Spec.new do |s| s.prepare_command = <<-END_OF_COMMAND find src/core/ -type f ! -path '*.grpc_back' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(pb(_.*)?\\.h)";#include ;g' find src/core/ -type f -path '*.grpc_back' -print0 | xargs -0 rm + find src/core/ -type f -path '*.h' -or -path '*.cc' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include ` as opposed to `#include diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index f912154301f..0604fa507bc 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -174,7 +174,7 @@ ss.header_mappings_dir = '.' ss.libraries = 'z' ss.dependency "#{s.name}/Interface", version - ss.dependency 'BoringSSL-GRPC', '0.0.1' + ss.dependency 'BoringSSL-GRPC', '0.0.2' ss.dependency 'nanopb', '~> 0.3' ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS' @@ -223,5 +223,6 @@ s.prepare_command = <<-END_OF_COMMAND find src/core/ -type f ! -path '*.grpc_back' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(pb(_.*)?\\.h)";#include ;g' find src/core/ -type f -path '*.grpc_back' -print0 | xargs -0 rm + find src/core/ -type f -path '*.h' -or -path '*.cc' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include ` as opposed to `#include From 91727bd015c9fd0ac9076b191520504bc227f685 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 13 Sep 2018 18:47:40 -0700 Subject: [PATCH 401/546] Move arena create outside of benchmark, format, and typo fix --- test/cpp/microbenchmarks/bm_chttp2_hpack.cc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index 8d1aa3f10ca..f160e77634e 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -457,8 +457,10 @@ static void BM_HpackParserParseHeader(benchmark::State& state) { std::vector benchmark_slices = Fixture::GetBenchmarkSlices(); grpc_chttp2_hpack_parser p; grpc_chttp2_hpack_parser_init(&p); + const int kArenaSize = 4096; + gpr_arena* arena = gpr_arena_create(kArenaSize); p.on_header = OnHeader; - p.on_header_user_data = nullptr; + p.on_header_user_data = arena; for (auto slice : init_slices) { GPR_ASSERT(GRPC_ERROR_NONE == grpc_chttp2_hpack_parser_parse(&p, slice)); } @@ -467,6 +469,11 @@ static void BM_HpackParserParseHeader(benchmark::State& state) { GPR_ASSERT(GRPC_ERROR_NONE == grpc_chttp2_hpack_parser_parse(&p, slice)); } grpc_core::ExecCtx::Get()->Flush(); + // recreate arena every 64k iterations to avoid oom + if (0 == (state.iterations() & 0xffff)) { + gpr_arena_destroy(arena); + arena = gpr_arena_create(kArenaSize); + } } for (auto slice : init_slices) grpc_slice_unref(slice); for (auto slice : benchmark_slices) grpc_slice_unref(slice); @@ -769,10 +776,9 @@ static void free_timeout(void* p) { gpr_free(p); } // Benchmark the current on_initial_header implementation static void OnInitialHeader(void* user_data, grpc_mdelem md) { - // Setup for benchmark. this will bloat the absolute values of this benchmark + // Setup for benchmark. This will bloat the absolute values of this benchmark grpc_chttp2_incoming_metadata_buffer buffer; - gpr_arena* arena = gpr_arena_create(1024); - grpc_chttp2_incoming_metadata_buffer_init(&buffer, arena); + grpc_chttp2_incoming_metadata_buffer_init(&buffer, (gpr_arena*)user_data); bool seen_error = false; // Below here is the code we actually care about benchmarking @@ -815,7 +821,6 @@ static void OnInitialHeader(void* user_data, grpc_mdelem md) { GPR_ASSERT(0); } } - gpr_arena_destroy(arena); } // Benchmark timeout handling From 29d9489ea9fa4b6249c3243bc122a65746c928ac Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 19 Sep 2018 20:46:17 -0700 Subject: [PATCH 402/546] Increase initial arena size to be more representative of real workload scenario and increase frequency of recreating the arena to avoid oom --- test/cpp/microbenchmarks/bm_chttp2_hpack.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index f160e77634e..741825cadab 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -457,7 +457,7 @@ static void BM_HpackParserParseHeader(benchmark::State& state) { std::vector benchmark_slices = Fixture::GetBenchmarkSlices(); grpc_chttp2_hpack_parser p; grpc_chttp2_hpack_parser_init(&p); - const int kArenaSize = 4096; + const int kArenaSize = 4096 * 4096; gpr_arena* arena = gpr_arena_create(kArenaSize); p.on_header = OnHeader; p.on_header_user_data = arena; @@ -469,8 +469,8 @@ static void BM_HpackParserParseHeader(benchmark::State& state) { GPR_ASSERT(GRPC_ERROR_NONE == grpc_chttp2_hpack_parser_parse(&p, slice)); } grpc_core::ExecCtx::Get()->Flush(); - // recreate arena every 64k iterations to avoid oom - if (0 == (state.iterations() & 0xffff)) { + // Recreate arena every 4k iterations to avoid oom + if (0 == (state.iterations() & 0xfff)) { gpr_arena_destroy(arena); arena = gpr_arena_create(kArenaSize); } From 4b721fbde0b6a623968987b52a9500471242cfcb Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 19 Sep 2018 20:51:45 -0700 Subject: [PATCH 403/546] Destroy arena at end of benchmark to not leak memory --- test/cpp/microbenchmarks/bm_chttp2_hpack.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index 741825cadab..528cabd0e33 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -475,6 +475,8 @@ static void BM_HpackParserParseHeader(benchmark::State& state) { arena = gpr_arena_create(kArenaSize); } } + // Clean up + gpr_arena_destroy(arena); for (auto slice : init_slices) grpc_slice_unref(slice); for (auto slice : benchmark_slices) grpc_slice_unref(slice); grpc_chttp2_hpack_parser_destroy(&p); From 15eb7853da94672413a80ccce88b69695ed9a7e8 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 19 Sep 2018 22:00:03 -0700 Subject: [PATCH 404/546] Skip 2 slice_eq checks on static mdelems on hpack parse path --- .../ext/transport/chttp2/transport/parsing.cc | 121 ++++++++++-------- 1 file changed, 65 insertions(+), 56 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc index 1e491d2ef86..b5d6e6fb09d 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/src/core/ext/transport/chttp2/transport/parsing.cc @@ -409,67 +409,75 @@ static void on_initial_header(void* tp, grpc_mdelem md) { gpr_free(value); } - if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && - !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { - /* TODO(ctiller): check for a status like " 0" */ - s->seen_error = true; - } + if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { + if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload || + md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) { + s->seen_error = true; + } + } else { + if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && + !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { + /* TODO(ctiller): check for a status like " 0" */ + s->seen_error = true; + } - if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) { - grpc_millis* cached_timeout = - static_cast(grpc_mdelem_get_user_data(md, free_timeout)); - grpc_millis timeout; - if (cached_timeout != nullptr) { - timeout = *cached_timeout; - } else { - if (GPR_UNLIKELY( - !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) { - char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); - gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val); - gpr_free(val); - timeout = GRPC_MILLIS_INF_FUTURE; + if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) { + grpc_millis* cached_timeout = static_cast( + grpc_mdelem_get_user_data(md, free_timeout)); + grpc_millis timeout; + if (cached_timeout != nullptr) { + timeout = *cached_timeout; + } else { + if (GPR_UNLIKELY( + !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) { + char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md)); + gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val); + gpr_free(val); + timeout = GRPC_MILLIS_INF_FUTURE; + } + if (GRPC_MDELEM_IS_INTERNED(md)) { + /* store the result */ + cached_timeout = + static_cast(gpr_malloc(sizeof(grpc_millis))); + *cached_timeout = timeout; + grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); + } } - if (GRPC_MDELEM_IS_INTERNED(md)) { - /* store the result */ - cached_timeout = - static_cast(gpr_malloc(sizeof(grpc_millis))); - *cached_timeout = timeout; - grpc_mdelem_set_user_data(md, free_timeout, cached_timeout); + if (timeout != GRPC_MILLIS_INF_FUTURE) { + grpc_chttp2_incoming_metadata_buffer_set_deadline( + &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout); } + GRPC_MDELEM_UNREF(md); + return; } - if (timeout != GRPC_MILLIS_INF_FUTURE) { - grpc_chttp2_incoming_metadata_buffer_set_deadline( - &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout); - } + } + + const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md); + const size_t metadata_size_limit = + t->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; + if (new_size > metadata_size_limit) { + gpr_log(GPR_DEBUG, + "received initial metadata size exceeds limit (%" PRIuPTR + " vs. %" PRIuPTR ")", + new_size, metadata_size_limit); + grpc_chttp2_cancel_stream( + t, s, + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "received initial metadata size exceeds limit"), + GRPC_ERROR_INT_GRPC_STATUS, + GRPC_STATUS_RESOURCE_EXHAUSTED)); + grpc_chttp2_parsing_become_skip_parser(t); + s->seen_error = true; GRPC_MDELEM_UNREF(md); } else { - const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md); - const size_t metadata_size_limit = - t->settings[GRPC_ACKED_SETTINGS] - [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE]; - if (new_size > metadata_size_limit) { - gpr_log(GPR_DEBUG, - "received initial metadata size exceeds limit (%" PRIuPTR - " vs. %" PRIuPTR ")", - new_size, metadata_size_limit); - grpc_chttp2_cancel_stream( - t, s, - grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "received initial metadata size exceeds limit"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED)); + grpc_error* error = + grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md); + if (error != GRPC_ERROR_NONE) { + grpc_chttp2_cancel_stream(t, s, error); grpc_chttp2_parsing_become_skip_parser(t); s->seen_error = true; GRPC_MDELEM_UNREF(md); - } else { - grpc_error* error = - grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md); - if (error != GRPC_ERROR_NONE) { - grpc_chttp2_cancel_stream(t, s, error); - grpc_chttp2_parsing_become_skip_parser(t); - s->seen_error = true; - GRPC_MDELEM_UNREF(md); - } } } } @@ -491,10 +499,11 @@ static void on_trailing_header(void* tp, grpc_mdelem md) { gpr_free(value); } - if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && - !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { - /* TODO(ctiller): check for a status like " 0" */ - s->seen_error = true; + if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { + if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload || + md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) { + s->seen_error = true; + } } const size_t new_size = s->metadata_buffer[1].size + GRPC_MDELEM_LENGTH(md); From 091f8dd51e82e3366a81076d92f4eb0755165d4a Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 19 Sep 2018 22:19:13 -0700 Subject: [PATCH 405/546] Remove unnecessary callout_is_default checks --- src/core/lib/transport/metadata_batch.cc | 4 +- src/core/lib/transport/static_metadata.cc | 29 --------- src/core/lib/transport/static_metadata.h | 4 -- tools/codegen/core/gen_static_metadata.py | 71 ++++++++++------------- 4 files changed, 33 insertions(+), 75 deletions(-) diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc index 49740fcd1e3..761aad19c45 100644 --- a/src/core/lib/transport/metadata_batch.cc +++ b/src/core/lib/transport/metadata_batch.cc @@ -105,7 +105,7 @@ static grpc_error* maybe_link_callout(grpc_metadata_batch* batch, return GRPC_ERROR_NONE; } if (batch->idx.array[idx] == nullptr) { - if (grpc_static_callout_is_default[idx]) ++batch->list.default_count; + ++batch->list.default_count; batch->idx.array[idx] = storage; return GRPC_ERROR_NONE; } @@ -121,7 +121,7 @@ static void maybe_unlink_callout(grpc_metadata_batch* batch, if (idx == GRPC_BATCH_CALLOUTS_COUNT) { return; } - if (grpc_static_callout_is_default[idx]) --batch->list.default_count; + --batch->list.default_count; GPR_ASSERT(batch->idx.array[idx] != nullptr); batch->idx.array[idx] = nullptr; } diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 6a5144f21a2..7574dc965f8 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -24,8 +24,6 @@ * an explanation of what's going on. */ -#include - #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/slice/slice_internal.h" @@ -568,33 +566,6 @@ grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, }; -bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = { - true, // :path - true, // :method - true, // :status - true, // :authority - true, // :scheme - true, // te - true, // grpc-message - true, // grpc-status - true, // grpc-payload-bin - true, // grpc-encoding - true, // grpc-accept-encoding - true, // grpc-server-stats-bin - true, // grpc-tags-bin - true, // grpc-trace-bin - true, // content-type - true, // content-encoding - true, // accept-encoding - true, // grpc-internal-encoding-request - true, // grpc-internal-stream-encoding-request - 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, 79, 80, 81, 82}; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index b3a10f58730..95609b9e96f 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -27,8 +27,6 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H #define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H -#include - #include "src/core/lib/transport/metadata.h" #define GRPC_STATIC_MDSTR_COUNT 105 @@ -587,8 +585,6 @@ typedef union { GRPC_BATCH_CALLOUTS_COUNT) \ : GRPC_BATCH_CALLOUTS_COUNT) -extern bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT]; - extern const uint8_t grpc_static_accept_encoding_metadata[8]; #define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \ (GRPC_MAKE_MDELEM( \ diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index 25da3fdd5f2..717443baeaf 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -142,35 +142,34 @@ CONFIG = [ ('www-authenticate', ''), ] -# Entries marked with is_default=True are ignored when counting -# non-default initial metadata that prevents the chttp2 server from -# sending a Trailers-Only response. +# All entries here are ignored when counting non-default initial metadata that +# prevents the chttp2 server from sending a Trailers-Only response. METADATA_BATCH_CALLOUTS = [ - # (name, is_default) - (':path', True), - (':method', True), - (':status', True), - (':authority', True), - (':scheme', True), - ('te', True), - ('grpc-message', True), - ('grpc-status', True), - ('grpc-payload-bin', True), - ('grpc-encoding', True), - ('grpc-accept-encoding', True), - ('grpc-server-stats-bin', True), - ('grpc-tags-bin', True), - ('grpc-trace-bin', True), - ('content-type', True), - ('content-encoding', True), - ('accept-encoding', True), - ('grpc-internal-encoding-request', True), - ('grpc-internal-stream-encoding-request', True), - ('user-agent', True), - ('host', True), - ('lb-token', True), - ('grpc-previous-rpc-attempts', True), - ('grpc-retry-pushback-ms', True), + # (name) + (':path'), + (':method'), + (':status'), + (':authority'), + (':scheme'), + ('te'), + ('grpc-message'), + ('grpc-status'), + ('grpc-payload-bin'), + ('grpc-encoding'), + ('grpc-accept-encoding'), + ('grpc-server-stats-bin'), + ('grpc-tags-bin'), + ('grpc-trace-bin'), + ('content-type'), + ('content-encoding'), + ('accept-encoding'), + ('grpc-internal-encoding-request'), + ('grpc-internal-stream-encoding-request'), + ('user-agent'), + ('host'), + ('lb-token'), + ('grpc-previous-rpc-attempts'), + ('grpc-retry-pushback-ms'), ] COMPRESSION_ALGORITHMS = [ @@ -252,7 +251,7 @@ all_elems = list() static_userdata = {} # put metadata batch callouts first, to make the check of if a static metadata # string is a callout trivial -for elem, _ in METADATA_BATCH_CALLOUTS: +for elem in METADATA_BATCH_CALLOUTS: if elem not in all_strs: all_strs.append(elem) for elem in CONFIG: @@ -388,7 +387,7 @@ def slice_def(i): # validate configuration -for elem, _ in METADATA_BATCH_CALLOUTS: +for elem in METADATA_BATCH_CALLOUTS: assert elem in all_strs print >> H, '#define GRPC_STATIC_MDSTR_COUNT %d' % len(all_strs) @@ -551,7 +550,7 @@ for a, b in all_elems: print >> C, '};' print >> H, 'typedef enum {' -for elem, _ in METADATA_BATCH_CALLOUTS: +for elem in METADATA_BATCH_CALLOUTS: print >> H, ' %s,' % mangle(elem, 'batch').upper() print >> H, ' GRPC_BATCH_CALLOUTS_COUNT' print >> H, '} grpc_metadata_batch_callouts_index;' @@ -559,7 +558,7 @@ print >> H print >> H, 'typedef union {' print >> H, ' struct grpc_linked_mdelem *array[GRPC_BATCH_CALLOUTS_COUNT];' print >> H, ' struct {' -for elem, _ in METADATA_BATCH_CALLOUTS: +for elem in METADATA_BATCH_CALLOUTS: print >> H, ' struct grpc_linked_mdelem *%s;' % mangle(elem, '').lower() print >> H, ' } named;' print >> H, '} grpc_metadata_batch_callouts;' @@ -567,14 +566,6 @@ print >> H print >> H, '#define GRPC_BATCH_INDEX_OF(slice) \\' print >> H, ' (GRPC_IS_STATIC_METADATA_STRING((slice)) ? (grpc_metadata_batch_callouts_index)GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, GRPC_BATCH_CALLOUTS_COUNT) : GRPC_BATCH_CALLOUTS_COUNT)' print >> H -print >> H, ('extern bool grpc_static_callout_is_default[' - 'GRPC_BATCH_CALLOUTS_COUNT];') -print >> H -print >> C, 'bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = {' -for elem, is_default in METADATA_BATCH_CALLOUTS: - print >> C, ' %s, // %s' % (str(is_default).lower(), elem) -print >> C, '};' -print >> C print >> H, 'extern const uint8_t grpc_static_accept_encoding_metadata[%d];' % ( 1 << len(COMPRESSION_ALGORITHMS)) From 7e21b10cf28fa98a022f1a133b296f011706248f Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 19 Sep 2018 22:26:40 -0700 Subject: [PATCH 406/546] Add in port_platform.h. The permanent fix for this is currently in a pending PR that should get merged soon --- src/core/lib/transport/static_metadata.cc | 2 ++ src/core/lib/transport/static_metadata.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index 7574dc965f8..ed88aa3f289 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 + #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/slice/slice_internal.h" diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 95609b9e96f..1e95f4e5bb7 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -27,6 +27,8 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H #define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H +#include + #include "src/core/lib/transport/metadata.h" #define GRPC_STATIC_MDSTR_COUNT 105 From 9e6511ae2eb3c982bcea88096cbe079147b25fa4 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 19 Sep 2018 23:51:24 -0700 Subject: [PATCH 407/546] Make the core callback interface API so that it can be used in generated code --- BUILD | 1 - CMakeLists.txt | 3 - Makefile | 3 - build.yaml | 1 - gRPC-C++.podspec | 1 - grpc.gyp | 2 - include/grpc/grpc.h | 3 +- include/grpc/impl/codegen/grpc_types.h | 15 +- include/grpcpp/impl/codegen/callback_common.h | 92 ++++++++--- include/grpcpp/impl/codegen/client_callback.h | 2 +- src/core/lib/surface/completion_queue.cc | 34 ++-- src/core/lib/surface/completion_queue.h | 19 +-- .../lib/surface/completion_queue_factory.cc | 6 +- src/cpp/client/channel_cc.cc | 10 +- src/cpp/common/callback_common.cc | 149 ------------------ src/ruby/ext/grpc/rb_grpc_imports.generated.h | 2 +- test/core/end2end/inproc_callback_test.cc | 31 ++-- test/core/surface/completion_queue_test.cc | 25 +-- tools/doxygen/Doxyfile.c++.internal | 1 - .../generated/sources_and_headers.json | 1 - 20 files changed, 156 insertions(+), 245 deletions(-) delete mode 100644 src/cpp/common/callback_common.cc diff --git a/BUILD b/BUILD index 271e57e36cf..5b4c5e4130d 100644 --- a/BUILD +++ b/BUILD @@ -119,7 +119,6 @@ GRPCXX_SRCS = [ "src/cpp/client/credentials_cc.cc", "src/cpp/client/generic_stub.cc", "src/cpp/common/alarm.cc", - "src/cpp/common/callback_common.cc", "src/cpp/common/channel_arguments.cc", "src/cpp/common/channel_filter.cc", "src/cpp/common/completion_queue_cc.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index c358e9bd43b..4f260c65ec6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2773,7 +2773,6 @@ add_library(grpc++ src/cpp/client/credentials_cc.cc src/cpp/client/generic_stub.cc src/cpp/common/alarm.cc - src/cpp/common/callback_common.cc src/cpp/common/channel_arguments.cc src/cpp/common/channel_filter.cc src/cpp/common/completion_queue_cc.cc @@ -3135,7 +3134,6 @@ add_library(grpc++_cronet src/cpp/client/credentials_cc.cc src/cpp/client/generic_stub.cc src/cpp/common/alarm.cc - src/cpp/common/callback_common.cc src/cpp/common/channel_arguments.cc src/cpp/common/channel_filter.cc src/cpp/common/completion_queue_cc.cc @@ -4261,7 +4259,6 @@ add_library(grpc++_unsecure src/cpp/client/credentials_cc.cc src/cpp/client/generic_stub.cc src/cpp/common/alarm.cc - src/cpp/common/callback_common.cc src/cpp/common/channel_arguments.cc src/cpp/common/channel_filter.cc src/cpp/common/completion_queue_cc.cc diff --git a/Makefile b/Makefile index 2f2537228cf..79d10f94d76 100644 --- a/Makefile +++ b/Makefile @@ -5228,7 +5228,6 @@ LIBGRPC++_SRC = \ src/cpp/client/credentials_cc.cc \ src/cpp/client/generic_stub.cc \ src/cpp/common/alarm.cc \ - src/cpp/common/callback_common.cc \ src/cpp/common/channel_arguments.cc \ src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue_cc.cc \ @@ -5598,7 +5597,6 @@ LIBGRPC++_CRONET_SRC = \ src/cpp/client/credentials_cc.cc \ src/cpp/client/generic_stub.cc \ src/cpp/common/alarm.cc \ - src/cpp/common/callback_common.cc \ src/cpp/common/channel_arguments.cc \ src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue_cc.cc \ @@ -6682,7 +6680,6 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/client/credentials_cc.cc \ src/cpp/client/generic_stub.cc \ src/cpp/common/alarm.cc \ - src/cpp/common/callback_common.cc \ src/cpp/common/channel_arguments.cc \ src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue_cc.cc \ diff --git a/build.yaml b/build.yaml index d6e67aa7ee3..c8512186d5d 100644 --- a/build.yaml +++ b/build.yaml @@ -1327,7 +1327,6 @@ filegroups: - src/cpp/client/credentials_cc.cc - src/cpp/client/generic_stub.cc - src/cpp/common/alarm.cc - - src/cpp/common/callback_common.cc - src/cpp/common/channel_arguments.cc - src/cpp/common/channel_filter.cc - src/cpp/common/completion_queue_cc.cc diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 03ec223279e..4b758657515 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -190,7 +190,6 @@ Pod::Spec.new do |s| 'src/cpp/client/credentials_cc.cc', 'src/cpp/client/generic_stub.cc', 'src/cpp/common/alarm.cc', - 'src/cpp/common/callback_common.cc', 'src/cpp/common/channel_arguments.cc', 'src/cpp/common/channel_filter.cc', 'src/cpp/common/completion_queue_cc.cc', diff --git a/grpc.gyp b/grpc.gyp index b8aae44de30..654a5310923 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -1381,7 +1381,6 @@ 'src/cpp/client/credentials_cc.cc', 'src/cpp/client/generic_stub.cc', 'src/cpp/common/alarm.cc', - 'src/cpp/common/callback_common.cc', 'src/cpp/common/channel_arguments.cc', 'src/cpp/common/channel_filter.cc', 'src/cpp/common/completion_queue_cc.cc', @@ -1529,7 +1528,6 @@ 'src/cpp/client/credentials_cc.cc', 'src/cpp/client/generic_stub.cc', 'src/cpp/common/alarm.cc', - 'src/cpp/common/callback_common.cc', 'src/cpp/common/channel_arguments.cc', 'src/cpp/common/channel_filter.cc', 'src/cpp/common/completion_queue_cc.cc', diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 3ef95ff4626..787d6ae6d7c 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -111,7 +111,8 @@ GRPCAPI grpc_completion_queue* grpc_completion_queue_create_for_pluck( of GRPC_CQ_CALLBACK and grpc_cq_polling_type of GRPC_CQ_DEFAULT_POLLING. This function is experimental. */ GRPCAPI grpc_completion_queue* grpc_completion_queue_create_for_callback( - void* shutdown_callback, void* reserved); + grpc_experimental_completion_queue_functor* shutdown_callback, + void* reserved); /** Create a completion queue */ GRPCAPI grpc_completion_queue* grpc_completion_queue_create( diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 5f3b96f40b5..5bd50bc9ac2 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -660,6 +660,19 @@ typedef enum { GRPC_CQ_CALLBACK } grpc_cq_completion_type; +/** EXPERIMENTAL: Specifies an interface class to be used as a tag + for callback-based completion queues. This can be used directly, + as the first element of a struct in C, or as a base class in C++. + Its "run" value should be assigned to some non-member function, such as + a static method. */ +typedef struct grpc_experimental_completion_queue_functor { + /** The run member specifies a function that will be called when this + tag is extracted from the completion queue. Its arguments will be a + pointer to this functor and a boolean that indicates whether the + success status of this operation */ + void (*functor_run)(struct grpc_experimental_completion_queue_functor*, int); +} grpc_experimental_completion_queue_functor; + /* The upgrade to version 2 is currently experimental. */ #define GRPC_CQ_CURRENT_VERSION 2 @@ -678,7 +691,7 @@ typedef struct grpc_completion_queue_attributes { /* EXPERIMENTAL: START OF VERSION 2 CQ ATTRIBUTES */ /** When creating a callbackable CQ, pass in a functor to get invoked when * shutdown is complete */ - void* cq_shutdown_cb; + grpc_experimental_completion_queue_functor* cq_shutdown_cb; /* END OF VERSION 2 CQ ATTRIBUTES */ } grpc_completion_queue_attributes; diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index 8b3ad66a8d3..044045034c9 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -21,25 +21,36 @@ #include +#include #include #include #include #include #include -// Forward declarations -namespace grpc_core { -class CQCallbackInterface; -}; - namespace grpc { namespace internal { +/// An exception-safe way of invoking a user-specified callback function +template +void CatchingCallback(Func&& func, Arg&& arg) { +#if GRPC_ALLOW_EXCEPTIONS + try { + func(arg); + } catch (...) { + // nothing to return or change here, just don't crash the library + } +#else // GRPC_ALLOW_EXCEPTIONS + func(arg); +#endif // GRPC_ALLOW_EXCEPTIONS +} + // The contract on these tags is that they are single-shot. They must be // constructed and then fired at exactly one point. There is no expectation // that they can be reused without reconstruction. -class CallbackWithStatusTag { +class CallbackWithStatusTag + : public grpc_experimental_completion_queue_functor { public: // always allocated against a call arena, no memory free required static void operator delete(void* ptr, std::size_t size) { @@ -54,24 +65,48 @@ class CallbackWithStatusTag { static void operator delete(void*, void*) { assert(0); } CallbackWithStatusTag(grpc_call* call, std::function f, - CompletionQueueTag* ops); + CompletionQueueTag* ops) + : call_(call), func_(std::move(f)), ops_(ops), status_() { + g_core_codegen_interface->grpc_call_ref(call); + functor_run = &CallbackWithStatusTag::StaticRun; + } ~CallbackWithStatusTag() {} - void* tag() { return static_cast(impl_); } - Status* status_ptr() { return status_; } - CompletionQueueTag* ops() { return ops_; } + Status* status_ptr() { return &status_; } // force_run can not be performed on a tag if operations using this tag // have been sent to PerformOpsOnCall. It is intended for error conditions // that are detected before the operations are internally processed. - void force_run(Status s); + void force_run(Status s) { + status_ = std::move(s); + Run(true); + } private: - grpc_core::CQCallbackInterface* impl_; - Status* status_; + grpc_call* call_; + std::function func_; CompletionQueueTag* ops_; + Status status_; + + static void StaticRun(grpc_experimental_completion_queue_functor* cb, + int ok) { + static_cast(cb)->Run(static_cast(ok)); + } + void Run(bool ok) { + void* ignored = ops_; + + GPR_ASSERT(ops_->FinalizeResult(&ignored, &ok)); + GPR_ASSERT(ignored == ops_); + + // Last use of func_ or status_, so ok to move them out + CatchingCallback(std::move(func_), std::move(status_)); + + func_ = nullptr; // reset to clear this out for sure + g_core_codegen_interface->grpc_call_unref(call_); + } }; -class CallbackWithSuccessTag { +class CallbackWithSuccessTag + : public grpc_experimental_completion_queue_functor { public: // always allocated against a call arena, no memory free required static void operator delete(void* ptr, std::size_t size) { @@ -86,19 +121,40 @@ class CallbackWithSuccessTag { static void operator delete(void*, void*) { assert(0); } CallbackWithSuccessTag(grpc_call* call, std::function f, - CompletionQueueTag* ops); + CompletionQueueTag* ops) + : call_(call), func_(std::move(f)), ops_(ops) { + g_core_codegen_interface->grpc_call_ref(call); + functor_run = &CallbackWithSuccessTag::StaticRun; + } - void* tag() { return static_cast(impl_); } CompletionQueueTag* ops() { return ops_; } // force_run can not be performed on a tag if operations using this tag // have been sent to PerformOpsOnCall. It is intended for error conditions // that are detected before the operations are internally processed. - void force_run(bool ok); + void force_run(bool ok) { Run(ok); } private: - grpc_core::CQCallbackInterface* impl_; + grpc_call* call_; + std::function func_; CompletionQueueTag* ops_; + + static void StaticRun(grpc_experimental_completion_queue_functor* cb, + int ok) { + static_cast(cb)->Run(static_cast(ok)); + } + void Run(bool ok) { + void* ignored = ops_; + bool new_ok = ok; + GPR_ASSERT(ops_->FinalizeResult(&ignored, &new_ok)); + GPR_ASSERT(ignored == ops_); + + // Last use of func_, so ok to move it out for rvalue call above + CatchingCallback(std::move(func_), ok); + + func_ = nullptr; // reset to clear this out for sure + g_core_codegen_interface->grpc_call_unref(call_); + } }; } // namespace internal diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index fc81c8aa0ae..4d4faea0635 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -84,7 +84,7 @@ class CallbackUnaryCallImpl { ops->AllowNoMessage(); ops->ClientSendClose(); ops->ClientRecvStatus(context, tag->status_ptr()); - ops->set_cq_tag(tag->tag()); + ops->set_cq_tag(tag); call.PerformOps(ops); } }; diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index c2cf450e949..01797d493a9 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -184,7 +184,8 @@ static const cq_poller_vtable g_poller_vtable_by_poller_type[] = { typedef struct cq_vtable { grpc_cq_completion_type cq_completion_type; size_t data_size; - void (*init)(void* data, grpc_core::CQCallbackInterface* shutdown_callback); + void (*init)(void* data, + grpc_experimental_completion_queue_functor* shutdown_callback); void (*shutdown)(grpc_completion_queue* cq); void (*destroy)(void* data); bool (*begin_op)(grpc_completion_queue* cq, void* tag); @@ -267,7 +268,7 @@ typedef struct cq_callback_data { bool shutdown_called; /** A callback that gets invoked when the CQ completes shutdown */ - grpc_core::CQCallbackInterface* shutdown_callback; + grpc_experimental_completion_queue_functor* shutdown_callback; } cq_callback_data; /* Completion queue structure */ @@ -333,12 +334,12 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, gpr_timespec deadline, void* reserved); // Note that cq_init_next and cq_init_pluck do not use the shutdown_callback -static void cq_init_next(void* data, - grpc_core::CQCallbackInterface* shutdown_callback); -static void cq_init_pluck(void* data, - grpc_core::CQCallbackInterface* shutdown_callback); -static void cq_init_callback(void* data, - grpc_core::CQCallbackInterface* shutdown_callback); +static void cq_init_next( + void* data, grpc_experimental_completion_queue_functor* shutdown_callback); +static void cq_init_pluck( + void* data, grpc_experimental_completion_queue_functor* shutdown_callback); +static void cq_init_callback( + void* data, grpc_experimental_completion_queue_functor* shutdown_callback); static void cq_destroy_next(void* data); static void cq_destroy_pluck(void* data); static void cq_destroy_callback(void* data); @@ -462,7 +463,7 @@ static long cq_event_queue_num_items(grpc_cq_event_queue* q) { grpc_completion_queue* grpc_completion_queue_create_internal( grpc_cq_completion_type completion_type, grpc_cq_polling_type polling_type, - grpc_core::CQCallbackInterface* shutdown_callback) { + grpc_experimental_completion_queue_functor* shutdown_callback) { GPR_TIMER_SCOPE("grpc_completion_queue_create_internal", 0); grpc_completion_queue* cq; @@ -497,8 +498,8 @@ grpc_completion_queue* grpc_completion_queue_create_internal( return cq; } -static void cq_init_next(void* data, - grpc_core::CQCallbackInterface* shutdown_callback) { +static void cq_init_next( + void* data, grpc_experimental_completion_queue_functor* shutdown_callback) { cq_next_data* cqd = static_cast(data); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); @@ -513,8 +514,8 @@ static void cq_destroy_next(void* data) { cq_event_queue_destroy(&cqd->queue); } -static void cq_init_pluck(void* data, - grpc_core::CQCallbackInterface* shutdown_callback) { +static void cq_init_pluck( + void* data, grpc_experimental_completion_queue_functor* shutdown_callback) { cq_pluck_data* cqd = static_cast(data); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); @@ -532,7 +533,7 @@ static void cq_destroy_pluck(void* data) { } static void cq_init_callback( - void* data, grpc_core::CQCallbackInterface* shutdown_callback) { + void* data, grpc_experimental_completion_queue_functor* shutdown_callback) { cq_callback_data* cqd = static_cast(data); /* Initial count is dropped by grpc_completion_queue_shutdown */ gpr_atm_no_barrier_store(&cqd->pending_events, 1); @@ -859,7 +860,8 @@ static void cq_end_op_for_callback( GRPC_ERROR_UNREF(error); - (static_cast(tag))->Run(is_success); + auto* functor = static_cast(tag); + (*functor->functor_run)(functor, is_success); } void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error, @@ -1343,7 +1345,7 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); - callback->Run(true); + callback->functor_run(callback, true); } static void cq_shutdown_callback(grpc_completion_queue* cq) { diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h index a7c524d8e8f..d60fe6d6efe 100644 --- a/src/core/lib/surface/completion_queue.h +++ b/src/core/lib/surface/completion_queue.h @@ -48,23 +48,6 @@ typedef struct grpc_cq_completion { uintptr_t next; } grpc_cq_completion; -/// For callback CQs, the tag that is passed in for an operation must -/// actually be a pointer to an implementation of the following class. -/// When the operation completes, the tag will be typecasted from void* -/// to grpc_core::CQCallbackInterface* and then the Run method will be -/// invoked on it. In practice, the language binding (e.g., C++ API -/// implementation) is responsible for providing and using an implementation -/// of this abstract base class. -namespace grpc_core { -class CQCallbackInterface { - public: - virtual ~CQCallbackInterface() {} - virtual void Run(bool) GRPC_ABSTRACT; - - GRPC_ABSTRACT_BASE_CLASS -}; -} // namespace grpc_core - #ifndef NDEBUG void grpc_cq_internal_ref(grpc_completion_queue* cc, const char* reason, const char* file, int line); @@ -106,6 +89,6 @@ int grpc_get_cq_poll_num(grpc_completion_queue* cc); grpc_completion_queue* grpc_completion_queue_create_internal( grpc_cq_completion_type completion_type, grpc_cq_polling_type polling_type, - grpc_core::CQCallbackInterface* shutdown_callback); + grpc_experimental_completion_queue_functor* shutdown_callback); #endif /* GRPC_CORE_LIB_SURFACE_COMPLETION_QUEUE_H */ diff --git a/src/core/lib/surface/completion_queue_factory.cc b/src/core/lib/surface/completion_queue_factory.cc index ed92dd7eba6..2616c156e45 100644 --- a/src/core/lib/surface/completion_queue_factory.cc +++ b/src/core/lib/surface/completion_queue_factory.cc @@ -31,8 +31,7 @@ static grpc_completion_queue* default_create( const grpc_completion_queue_factory* factory, const grpc_completion_queue_attributes* attr) { return grpc_completion_queue_create_internal( - attr->cq_completion_type, attr->cq_polling_type, - static_cast(attr->cq_shutdown_cb)); + attr->cq_completion_type, attr->cq_polling_type, attr->cq_shutdown_cb); } static grpc_completion_queue_factory_vtable default_vtable = {default_create}; @@ -73,7 +72,8 @@ grpc_completion_queue* grpc_completion_queue_create_for_pluck(void* reserved) { } grpc_completion_queue* grpc_completion_queue_create_for_callback( - void* shutdown_callback, void* reserved) { + grpc_experimental_completion_queue_functor* shutdown_callback, + void* reserved) { GPR_ASSERT(!reserved); grpc_completion_queue_attributes attr = { 2, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING, shutdown_callback}; diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index ad71286e051..c59059f0450 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -193,17 +193,19 @@ bool Channel::WaitForStateChangeImpl(grpc_connectivity_state last_observed, } namespace { -class ShutdownCallback : public grpc_core::CQCallbackInterface { +class ShutdownCallback : public grpc_experimental_completion_queue_functor { public: + ShutdownCallback() { functor_run = &ShutdownCallback::Run; } // TakeCQ takes ownership of the cq into the shutdown callback // so that the shutdown callback will be responsible for destroying it void TakeCQ(CompletionQueue* cq) { cq_ = cq; } // The Run function will get invoked by the completion queue library // when the shutdown is actually complete - void Run(bool) override { - delete cq_; - grpc_core::Delete(this); + static void Run(grpc_experimental_completion_queue_functor* cb, int) { + auto* callback = static_cast(cb); + delete callback->cq_; + grpc_core::Delete(callback); } private: diff --git a/src/cpp/common/callback_common.cc b/src/cpp/common/callback_common.cc deleted file mode 100644 index a0c8eeb5160..00000000000 --- a/src/cpp/common/callback_common.cc +++ /dev/null @@ -1,149 +0,0 @@ -/* - * - * 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 - -#include -#include - -#include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/surface/completion_queue.h" - -namespace grpc { -namespace internal { -namespace { - -template -void CatchingCallback(Func&& func, Arg&& arg) { -#if GRPC_ALLOW_EXCEPTIONS - try { - func(arg); - } catch (...) { - // nothing to return or change here, just don't crash the library - } -#else // GRPC_ALLOW_EXCEPTIONS - func(arg); -#endif // GRPC_ALLOW_EXCEPTIONS -} - -class CallbackWithSuccessImpl : public grpc_core::CQCallbackInterface { - public: - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(CallbackWithSuccessImpl)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - CallbackWithSuccessImpl(grpc_call* call, CallbackWithSuccessTag* parent, - std::function f) - : call_(call), parent_(parent), func_(std::move(f)) { - grpc_call_ref(call); - } - - void Run(bool ok) override { - void* ignored = parent_->ops(); - bool new_ok = ok; - GPR_ASSERT(parent_->ops()->FinalizeResult(&ignored, &new_ok)); - GPR_ASSERT(ignored == parent_->ops()); - - // Last use of func_, so ok to move it out for rvalue call above - CatchingCallback(std::move(func_), ok); - - func_ = nullptr; // reset to clear this out for sure - grpc_call_unref(call_); - } - - private: - grpc_call* call_; - CallbackWithSuccessTag* parent_; - std::function func_; -}; - -class CallbackWithStatusImpl : public grpc_core::CQCallbackInterface { - public: - static void operator delete(void* ptr, std::size_t size) { - assert(size == sizeof(CallbackWithStatusImpl)); - } - - // This operator should never be called as the memory should be freed as part - // of the arena destruction. It only exists to provide a matching operator - // delete to the operator new so that some compilers will not complain (see - // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this - // there are no tests catching the compiler warning. - static void operator delete(void*, void*) { assert(0); } - - CallbackWithStatusImpl(grpc_call* call, CallbackWithStatusTag* parent, - std::function f) - : call_(call), parent_(parent), func_(std::move(f)), status_() { - grpc_call_ref(call); - } - - void Run(bool ok) override { - void* ignored = parent_->ops(); - - GPR_ASSERT(parent_->ops()->FinalizeResult(&ignored, &ok)); - GPR_ASSERT(ignored == parent_->ops()); - - // Last use of func_ or status_, so ok to move them out - CatchingCallback(std::move(func_), std::move(status_)); - - func_ = nullptr; // reset to clear this out for sure - grpc_call_unref(call_); - } - Status* status_ptr() { return &status_; } - - private: - grpc_call* call_; - CallbackWithStatusTag* parent_; - std::function func_; - Status status_; -}; - -} // namespace - -CallbackWithSuccessTag::CallbackWithSuccessTag(grpc_call* call, - std::function f, - CompletionQueueTag* ops) - : impl_(new (grpc_call_arena_alloc(call, sizeof(CallbackWithSuccessImpl))) - CallbackWithSuccessImpl(call, this, std::move(f))), - ops_(ops) {} - -void CallbackWithSuccessTag::force_run(bool ok) { impl_->Run(ok); } - -CallbackWithStatusTag::CallbackWithStatusTag(grpc_call* call, - std::function f, - CompletionQueueTag* ops) - : ops_(ops) { - auto* impl = new (grpc_call_arena_alloc(call, sizeof(CallbackWithStatusImpl))) - CallbackWithStatusImpl(call, this, std::move(f)); - impl_ = impl; - status_ = impl->status_ptr(); -} - -void CallbackWithStatusTag::force_run(Status s) { - *status_ = std::move(s); - impl_->Run(true); -} - -} // namespace internal -} // namespace grpc diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index d00e75c3260..e25d953a186 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -107,7 +107,7 @@ extern grpc_completion_queue_create_for_next_type grpc_completion_queue_create_f typedef grpc_completion_queue*(*grpc_completion_queue_create_for_pluck_type)(void* reserved); extern grpc_completion_queue_create_for_pluck_type grpc_completion_queue_create_for_pluck_import; #define grpc_completion_queue_create_for_pluck grpc_completion_queue_create_for_pluck_import -typedef grpc_completion_queue*(*grpc_completion_queue_create_for_callback_type)(void* shutdown_callback, void* reserved); +typedef grpc_completion_queue*(*grpc_completion_queue_create_for_callback_type)(grpc_experimental_completion_queue_functor* shutdown_callback, void* reserved); extern grpc_completion_queue_create_for_callback_type grpc_completion_queue_create_for_callback_import; #define grpc_completion_queue_create_for_callback grpc_completion_queue_create_for_callback_import typedef grpc_completion_queue*(*grpc_completion_queue_create_type)(const grpc_completion_queue_factory* factory, const grpc_completion_queue_attributes* attributes, void* reserved); diff --git a/test/core/end2end/inproc_callback_test.cc b/test/core/end2end/inproc_callback_test.cc index 0d6c7c75a8b..310030046af 100644 --- a/test/core/end2end/inproc_callback_test.cc +++ b/test/core/end2end/inproc_callback_test.cc @@ -37,13 +37,16 @@ typedef struct inproc_fixture_data { namespace { template -class CQDeletingCallback : public grpc_core::CQCallbackInterface { +class CQDeletingCallback : public grpc_experimental_completion_queue_functor { public: - explicit CQDeletingCallback(F f) : func_(f) {} - ~CQDeletingCallback() override {} - void Run(bool ok) override { - func_(ok); - grpc_core::Delete(this); + explicit CQDeletingCallback(F f) : func_(f) { + functor_run = &CQDeletingCallback::Run; + } + ~CQDeletingCallback() {} + static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + auto* callback = static_cast(cb); + callback->func_(static_cast(ok)); + grpc_core::Delete(callback); } private: @@ -51,18 +54,24 @@ class CQDeletingCallback : public grpc_core::CQCallbackInterface { }; template -grpc_core::CQCallbackInterface* NewDeletingCallback(F f) { +grpc_experimental_completion_queue_functor* NewDeletingCallback(F f) { return grpc_core::New>(f); } -class ShutdownCallback : public grpc_core::CQCallbackInterface { +class ShutdownCallback : public grpc_experimental_completion_queue_functor { public: ShutdownCallback() : done_(false) { + functor_run = &ShutdownCallback::StaticRun; gpr_mu_init(&mu_); gpr_cv_init(&cv_); } - ~ShutdownCallback() override {} - void Run(bool ok) override { + ~ShutdownCallback() {} + static void StaticRun(grpc_experimental_completion_queue_functor* cb, + int ok) { + auto* callback = static_cast(cb); + callback->Run(static_cast(ok)); + } + void Run(bool ok) { gpr_log(GPR_DEBUG, "CQ shutdown notification invoked"); gpr_mu_lock(&mu_); done_ = true; @@ -170,7 +179,7 @@ static void verify_tags(gpr_timespec deadline) { // This function creates a callback functor that emits the // desired tag into the global tag set -static grpc_core::CQCallbackInterface* tag(intptr_t t) { +static grpc_experimental_completion_queue_functor* tag(intptr_t t) { auto func = [t](bool ok) { gpr_mu_lock(&tags_mu); gpr_log(GPR_DEBUG, "Completing operation %" PRIdPTR, t); diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc index b889fd0fc66..f7ce8a7042e 100644 --- a/test/core/surface/completion_queue_test.cc +++ b/test/core/surface/completion_queue_test.cc @@ -369,11 +369,15 @@ static void test_callback(void) { LOG_TEST("test_callback"); bool got_shutdown = false; - class ShutdownCallback : public grpc_core::CQCallbackInterface { + class ShutdownCallback : public grpc_experimental_completion_queue_functor { public: - ShutdownCallback(bool* done) : done_(done) {} + ShutdownCallback(bool* done) : done_(done) { + functor_run = &ShutdownCallback::Run; + } ~ShutdownCallback() {} - void Run(bool ok) override { *done_ = ok; } + static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + *static_cast(cb)->done_ = static_cast(ok); + } private: bool* done_; @@ -391,14 +395,17 @@ static void test_callback(void) { grpc_completion_queue_factory_lookup(&attr), &attr, nullptr); int counter = 0; - class TagCallback : public grpc_core::CQCallbackInterface { + class TagCallback : public grpc_experimental_completion_queue_functor { public: - TagCallback(int* counter, int tag) : counter_(counter), tag_(tag) {} + TagCallback(int* counter, int tag) : counter_(counter), tag_(tag) { + functor_run = &TagCallback::Run; + } ~TagCallback() {} - void Run(bool ok) override { - GPR_ASSERT(ok); - *counter_ += tag_; - grpc_core::Delete(this); + static void Run(grpc_experimental_completion_queue_functor* cb, int ok) { + GPR_ASSERT(static_cast(ok)); + auto* callback = static_cast(cb); + *callback->counter_ += callback->tag_; + grpc_core::Delete(callback); }; private: diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index a72390d9f8f..cfc5ef98e7b 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1190,7 +1190,6 @@ src/cpp/client/secure_credentials.h \ src/cpp/codegen/codegen_init.cc \ src/cpp/common/alarm.cc \ src/cpp/common/auth_property_iterator.cc \ -src/cpp/common/callback_common.cc \ src/cpp/common/channel_arguments.cc \ src/cpp/common/channel_filter.cc \ src/cpp/common/channel_filter.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index f3e93a08746..97f3e4c1faa 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11470,7 +11470,6 @@ "src/cpp/client/credentials_cc.cc", "src/cpp/client/generic_stub.cc", "src/cpp/common/alarm.cc", - "src/cpp/common/callback_common.cc", "src/cpp/common/channel_arguments.cc", "src/cpp/common/channel_filter.cc", "src/cpp/common/channel_filter.h", From aee8271fe34d358041df72a554c844f4fc4d7185 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 20 Sep 2018 00:08:54 -0700 Subject: [PATCH 408/546] Fix a Status, and resolve reviewer comments --- src/compiler/cpp_generator.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index ff0b40f5878..0acd2110091 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -593,7 +593,7 @@ void PrintHeaderClientMethodCallbackInterfacesEnd( printer->Print("};\n"); // Declare a function to give the async stub contents. It can't be pure - // since this is new API in StubInterface, but it is meaningless by default + // since this is a new API in StubInterface, but it is meaningless by default // (since any stub that wants to use it must have its own implementation of // the callback functions therein), so make the default return value nullptr. // Intentionally include the word "class" to avoid possible shadowing. @@ -1379,7 +1379,7 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer, "void $ns$$Service$::Stub::experimental_async::$Method$(" "::grpc::ClientContext* context, " "const $Request$* request, $Response$* response, " - "std::function f) {\n"); + "std::function f) {\n"); printer->Print(*vars, " return ::grpc::internal::CallbackUnaryCall" "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, " From fc1e35444b311d74e878a45ae4c8120687fa01b5 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 20 Sep 2018 00:39:49 -0700 Subject: [PATCH 409/546] Reset status field in tag as well as func --- include/grpcpp/impl/codegen/callback_common.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index 044045034c9..ce0d451b60a 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -100,7 +100,8 @@ class CallbackWithStatusTag // Last use of func_ or status_, so ok to move them out CatchingCallback(std::move(func_), std::move(status_)); - func_ = nullptr; // reset to clear this out for sure + func_ = nullptr; // reset to clear this out for sure + status_ = Status(); // reset to clear this out for sure g_core_codegen_interface->grpc_call_unref(call_); } }; From 0db69018b0ac0d58bd4b17fdafdacff3b1a2fc69 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 20 Sep 2018 00:58:29 -0700 Subject: [PATCH 410/546] Use GPR_CODEGEN_ASSERT in impl/codegen --- include/grpcpp/impl/codegen/callback_common.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index ce0d451b60a..ab96241ce8e 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -94,8 +94,8 @@ class CallbackWithStatusTag void Run(bool ok) { void* ignored = ops_; - GPR_ASSERT(ops_->FinalizeResult(&ignored, &ok)); - GPR_ASSERT(ignored == ops_); + GPR_CODEGEN_ASSERT(ops_->FinalizeResult(&ignored, &ok)); + GPR_CODEGEN_ASSERT(ignored == ops_); // Last use of func_ or status_, so ok to move them out CatchingCallback(std::move(func_), std::move(status_)); @@ -147,8 +147,8 @@ class CallbackWithSuccessTag void Run(bool ok) { void* ignored = ops_; bool new_ok = ok; - GPR_ASSERT(ops_->FinalizeResult(&ignored, &new_ok)); - GPR_ASSERT(ignored == ops_); + GPR_CODEGEN_ASSERT(ops_->FinalizeResult(&ignored, &new_ok)); + GPR_CODEGEN_ASSERT(ignored == ops_); // Last use of func_, so ok to move it out for rvalue call above CatchingCallback(std::move(func_), ok); From d44feec92ffd1edff7836409f38069edc0836d63 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 19 Sep 2018 22:40:59 -0700 Subject: [PATCH 411/546] Reassign arena pointer instead of stomping on memory --- test/cpp/microbenchmarks/bm_chttp2_hpack.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index 528cabd0e33..ba712548e62 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -458,9 +458,8 @@ static void BM_HpackParserParseHeader(benchmark::State& state) { grpc_chttp2_hpack_parser p; grpc_chttp2_hpack_parser_init(&p); const int kArenaSize = 4096 * 4096; - gpr_arena* arena = gpr_arena_create(kArenaSize); + p.on_header_user_data = gpr_arena_create(kArenaSize); p.on_header = OnHeader; - p.on_header_user_data = arena; for (auto slice : init_slices) { GPR_ASSERT(GRPC_ERROR_NONE == grpc_chttp2_hpack_parser_parse(&p, slice)); } @@ -471,12 +470,12 @@ static void BM_HpackParserParseHeader(benchmark::State& state) { grpc_core::ExecCtx::Get()->Flush(); // Recreate arena every 4k iterations to avoid oom if (0 == (state.iterations() & 0xfff)) { - gpr_arena_destroy(arena); - arena = gpr_arena_create(kArenaSize); + gpr_arena_destroy((gpr_arena*)p.on_header_user_data); + p.on_header_user_data = gpr_arena_create(kArenaSize); } } // Clean up - gpr_arena_destroy(arena); + gpr_arena_destroy((gpr_arena*)p.on_header_user_data); for (auto slice : init_slices) grpc_slice_unref(slice); for (auto slice : benchmark_slices) grpc_slice_unref(slice); grpc_chttp2_hpack_parser_destroy(&p); From 74fc60e9aff49023f52db6b9e467bbc64dc551d1 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 20 Sep 2018 10:20:30 -0700 Subject: [PATCH 412/546] Make our C function pointer use consistent --- src/core/lib/surface/completion_queue.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc index 01797d493a9..5dc9991f703 100644 --- a/src/core/lib/surface/completion_queue.cc +++ b/src/core/lib/surface/completion_queue.cc @@ -1345,7 +1345,7 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) { GPR_ASSERT(cqd->shutdown_called); cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done); - callback->functor_run(callback, true); + (*callback->functor_run)(callback, true); } static void cq_shutdown_callback(grpc_completion_queue* cq) { From 17fc4d4029e0525e8cb0a25686e078f5842b3644 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 20 Sep 2018 10:49:00 -0700 Subject: [PATCH 413/546] Address reviewer comments --- include/grpc/impl/codegen/grpc_types.h | 2 +- include/grpcpp/impl/codegen/callback_common.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 5bd50bc9ac2..9ed5b3c1d4b 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -669,7 +669,7 @@ typedef struct grpc_experimental_completion_queue_functor { /** The run member specifies a function that will be called when this tag is extracted from the completion queue. Its arguments will be a pointer to this functor and a boolean that indicates whether the - success status of this operation */ + operation succeeded (non-zero) or failed (zero) */ void (*functor_run)(struct grpc_experimental_completion_queue_functor*, int); } grpc_experimental_completion_queue_functor; diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index ab96241ce8e..ca2f867d04d 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -66,7 +66,7 @@ class CallbackWithStatusTag CallbackWithStatusTag(grpc_call* call, std::function f, CompletionQueueTag* ops) - : call_(call), func_(std::move(f)), ops_(ops), status_() { + : call_(call), func_(std::move(f)), ops_(ops) { g_core_codegen_interface->grpc_call_ref(call); functor_run = &CallbackWithStatusTag::StaticRun; } From d0029bac1495201302ee62db45854ac386379282 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 20 Sep 2018 11:35:57 -0700 Subject: [PATCH 414/546] generate_projects.sh --- src/ruby/ext/grpc/rb_grpc_imports.generated.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index d00e75c3260..908abd7e85c 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -407,10 +407,10 @@ extern grpc_call_set_credentials_type grpc_call_set_credentials_import; typedef void(*grpc_server_credentials_set_auth_metadata_processor_type)(grpc_server_credentials* creds, grpc_auth_metadata_processor processor); extern grpc_server_credentials_set_auth_metadata_processor_type grpc_server_credentials_set_auth_metadata_processor_import; #define grpc_server_credentials_set_auth_metadata_processor grpc_server_credentials_set_auth_metadata_processor_import -typedef grpc_alts_credentials_options*(*grpc_alts_credentials_client_options_create_type)(); +typedef grpc_alts_credentials_options*(*grpc_alts_credentials_client_options_create_type)(void); extern grpc_alts_credentials_client_options_create_type grpc_alts_credentials_client_options_create_import; #define grpc_alts_credentials_client_options_create grpc_alts_credentials_client_options_create_import -typedef grpc_alts_credentials_options*(*grpc_alts_credentials_server_options_create_type)(); +typedef grpc_alts_credentials_options*(*grpc_alts_credentials_server_options_create_type)(void); extern grpc_alts_credentials_server_options_create_type grpc_alts_credentials_server_options_create_import; #define grpc_alts_credentials_server_options_create grpc_alts_credentials_server_options_create_import typedef void(*grpc_alts_credentials_client_options_add_target_service_account_type)(grpc_alts_credentials_options* options, const char* service_account); From 4c6e7ce15dea5cdb51ef2021aa539d16cbd30991 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 20 Sep 2018 12:56:56 -0700 Subject: [PATCH 415/546] Destroy metadata buffer at end of benchmark loop --- test/cpp/microbenchmarks/bm_chttp2_hpack.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index ba712548e62..ba4b57ad228 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -822,6 +822,7 @@ static void OnInitialHeader(void* user_data, grpc_mdelem md) { GPR_ASSERT(0); } } + grpc_chttp2_incoming_metadata_buffer_destroy(&buffer); } // Benchmark timeout handling From cc7939060460d1b09a7ce0909d3784308fa3091c Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 20 Sep 2018 12:36:18 -0700 Subject: [PATCH 416/546] Fix on_trailing_header --- src/core/ext/transport/chttp2/transport/parsing.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc index b5d6e6fb09d..8ffd4de17c6 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/src/core/ext/transport/chttp2/transport/parsing.cc @@ -504,6 +504,10 @@ static void on_trailing_header(void* tp, grpc_mdelem md) { md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) { s->seen_error = true; } + } else if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) && + !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) { + /* TODO(ctiller): check for a status like " 0" */ + s->seen_error = true; } const size_t new_size = s->metadata_buffer[1].size + GRPC_MDELEM_LENGTH(md); From 3f4fef6116bb3e9b749792f90afdc3edb8d84770 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 20 Sep 2018 12:03:25 -0700 Subject: [PATCH 417/546] replace #include library name in BoringSSL files --- src/objective-c/BoringSSL-GRPC.podspec | 1 + templates/src/objective-c/BoringSSL-GRPC.podspec.template | 1 + 2 files changed, 2 insertions(+) diff --git a/src/objective-c/BoringSSL-GRPC.podspec b/src/objective-c/BoringSSL-GRPC.podspec index ed32b3c5763..b6f85c6adbb 100644 --- a/src/objective-c/BoringSSL-GRPC.podspec +++ b/src/objective-c/BoringSSL-GRPC.podspec @@ -1546,6 +1546,7 @@ Pod::Spec.new do |s| sed -i'.back' '/^#define \\([A-Za-z0-9_]*\\) \\1/d' include/openssl/ssl.h sed -i'.back' 'N;/^#define \\([A-Za-z0-9_]*\\) *\\\\\\n *\\1/d' include/openssl/ssl.h sed -i'.back' 's/#ifndef md5_block_data_order/#ifndef GRPC_SHADOW_md5_block_data_order/g' crypto/fipsmodule/md5/md5.c + find . -type f -path '*.h' -or -path '*.cc' -or -path '*.c' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include Date: Thu, 20 Sep 2018 12:06:55 -0700 Subject: [PATCH 418/546] Add a virtual destructor to the new class with virtual methods --- src/compiler/cpp_generator.cc | 1 + test/cpp/codegen/compiler_test_golden | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 0acd2110091..56716493dc3 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -560,6 +560,7 @@ void PrintHeaderClientMethodCallbackInterfacesStart( // "Raw" methods since the callback-based API returns unowned raw pointers printer->Print(" public:\n"); printer->Indent(); + printer->Print("virtual ~experimental_async_interface() {}\n"); } void PrintHeaderClientMethodCallbackInterfaces( diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index c679880763b..93e1e686546 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -108,6 +108,7 @@ class ServiceA final { // Method A4 trailing comment 1 class experimental_async_interface { public: + virtual ~experimental_async_interface() {} // MethodA1 leading comment 1 virtual void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) = 0; // MethodA1 trailing comment 1 @@ -519,6 +520,7 @@ class ServiceB final { // MethodB1 trailing comment 1 class experimental_async_interface { public: + virtual ~experimental_async_interface() {} // MethodB1 leading comment 1 virtual void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function) = 0; // MethodB1 trailing comment 1 From ae6f620d6c3cb65f0b534b99a3737ea56005bfa9 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 20 Sep 2018 14:55:05 -0700 Subject: [PATCH 419/546] Add comment to explain obscure performance choice --- src/core/ext/transport/chttp2/transport/parsing.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc index 8ffd4de17c6..8e9aa613a6e 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/src/core/ext/transport/chttp2/transport/parsing.cc @@ -410,6 +410,12 @@ static void on_initial_header(void* tp, grpc_mdelem md) { } if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { + // We don't use grpc_mdelem_eq here to avoid executing additional + // instructions. The reasoning is if the payload is not equal, we already + // know that the metadata elements are not equal because the md is + // confirmed to be static. If we had used grpc_mdelem_eq here, then if the + // payloads are not equal, grpc_mdelem_eq executes more instructions to + // determine if they're equal or not. if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload || md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) { s->seen_error = true; @@ -500,6 +506,12 @@ static void on_trailing_header(void* tp, grpc_mdelem md) { } if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { + // We don't use grpc_mdelem_eq here to avoid executing additional + // instructions. The reasoning is if the payload is not equal, we already + // know that the metadata elements are not equal because the md is + // confirmed to be static. If we had used grpc_mdelem_eq here, then if the + // payloads are not equal, grpc_mdelem_eq executes more instructions to + // determine if they're equal or not. if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload || md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) { s->seen_error = true; From f511f247dd32bdba21bc5313343fd58b97bf02a3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 20 Sep 2018 16:13:16 -0700 Subject: [PATCH 420/546] bug fix --- gRPC-Core.podspec | 2 +- src/objective-c/BoringSSL-GRPC.podspec | 2 +- templates/gRPC-Core.podspec.template | 2 +- templates/src/objective-c/BoringSSL-GRPC.podspec.template | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index e3914df9f7a..04284200498 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -1307,6 +1307,6 @@ Pod::Spec.new do |s| s.prepare_command = <<-END_OF_COMMAND find src/core/ -type f ! -path '*.grpc_back' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(pb(_.*)?\\.h)";#include ;g' find src/core/ -type f -path '*.grpc_back' -print0 | xargs -0 rm - find src/core/ -type f -path '*.h' -or -path '*.cc' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include ;g' find src/core/ -type f -path '*.grpc_back' -print0 | xargs -0 rm - find src/core/ -type f -path '*.h' -or -path '*.cc' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include Date: Thu, 20 Sep 2018 16:54:35 -0700 Subject: [PATCH 421/546] Warn on non-virtual destructor if class has virtual functions --- Makefile | 1 + build.yaml | 1 + test/cpp/microbenchmarks/fullstack_fixtures.h | 1 + test/cpp/microbenchmarks/helpers.h | 1 + 4 files changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 82454a54d88..65ff9972bf8 100644 --- a/Makefile +++ b/Makefile @@ -352,6 +352,7 @@ CXXFLAGS += -std=c++11 ifeq ($(SYSTEM),Darwin) CXXFLAGS += -stdlib=libc++ endif +CXXFLAGS += -Wnon-virtual-dtor CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1 -Wno-deprecated-declarations -Ithird_party/nanopb -DPB_FIELD_32BIT COREFLAGS += -fno-rtti -fno-exceptions LDFLAGS += -g diff --git a/build.yaml b/build.yaml index 98e315711ca..60600b7dcec 100644 --- a/build.yaml +++ b/build.yaml @@ -5860,6 +5860,7 @@ defaults: COREFLAGS: -fno-rtti -fno-exceptions CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1 -Wno-deprecated-declarations -Ithird_party/nanopb -DPB_FIELD_32BIT + CXXFLAGS: -Wnon-virtual-dtor LDFLAGS: -g zlib: CFLAGS: -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index 9d70277fbcd..d390ae08f61 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -48,6 +48,7 @@ namespace testing { class FixtureConfiguration { public: + virtual ~FixtureConfiguration() {} virtual void ApplyCommonChannelArguments(ChannelArguments* c) const { c->SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, INT_MAX); c->SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, INT_MAX); diff --git a/test/cpp/microbenchmarks/helpers.h b/test/cpp/microbenchmarks/helpers.h index 4aabd4094a8..25d34b5f871 100644 --- a/test/cpp/microbenchmarks/helpers.h +++ b/test/cpp/microbenchmarks/helpers.h @@ -63,6 +63,7 @@ extern gpr_atm gpr_now_call_count; class TrackCounters { public: TrackCounters() { grpc_stats_collect(&stats_begin_); } + virtual ~TrackCounters() {} virtual void Finish(benchmark::State& state); virtual void AddLabel(const grpc::string& label); virtual void AddToLabel(std::ostream& out, benchmark::State& state); From 4e7ede8dd21e831362547c1ba46607b9b0f81b76 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 20 Sep 2018 18:30:42 -0700 Subject: [PATCH 422/546] Set seen_recv_trailing_metadata to false --- .../message_size/message_size_filter.cc | 1 + src/core/lib/surface/server.cc | 42 ++++--------------- 2 files changed, 9 insertions(+), 34 deletions(-) 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 6396d656062..6a3e14aa139 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -152,6 +152,7 @@ static void recv_message_ready(void* user_data, grpc_error* error) { grpc_closure* closure = calld->next_recv_message_ready; calld->next_recv_message_ready = nullptr; if (calld->seen_recv_trailing_metadata) { + calld->seen_recv_trailing_metadata = false; GRPC_CALL_COMBINER_START(calld->call_combiner, &calld->recv_trailing_metadata_ready, calld->recv_trailing_metadata_error, diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 72ddc2648d9..5fa58ffdec2 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -150,15 +150,12 @@ struct call_data { grpc_closure kill_zombie_closure; grpc_closure* on_done_recv_initial_metadata; grpc_closure recv_trailing_metadata_ready; - grpc_error* recv_initial_metadata_error; + grpc_error* error; grpc_closure* original_recv_trailing_metadata_ready; - grpc_error* recv_trailing_metadata_error; - bool seen_recv_trailing_metadata_ready; grpc_closure publish; call_data* pending_next; - grpc_call_combiner* call_combiner; }; struct request_matcher { @@ -730,43 +727,21 @@ static void server_on_recv_initial_metadata(void* ptr, grpc_error* error) { if (calld->host_set && calld->path_set) { /* do nothing */ } else { - /* Pass the error reference to calld->recv_initial_metadata_error */ grpc_error* src_error = error; error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Missing :authority or :path", &src_error, 1); + "Missing :authority or :path", &error, 1); GRPC_ERROR_UNREF(src_error); - calld->recv_initial_metadata_error = GRPC_ERROR_REF(error); } - grpc_closure* closure = calld->on_done_recv_initial_metadata; - calld->on_done_recv_initial_metadata = nullptr; - if (calld->seen_recv_trailing_metadata_ready) { - GRPC_CALL_COMBINER_START(calld->call_combiner, - &calld->recv_trailing_metadata_ready, - calld->recv_trailing_metadata_error, - "continue server_recv_trailing_metadata_ready"); - } - GRPC_CLOSURE_RUN(closure, error); + + GRPC_CLOSURE_RUN(calld->on_done_recv_initial_metadata, error); } static void server_recv_trailing_metadata_ready(void* user_data, - grpc_error* error) { + grpc_error* err) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); - if (calld->on_done_recv_initial_metadata != nullptr) { - calld->recv_trailing_metadata_error = GRPC_ERROR_REF(error); - calld->seen_recv_trailing_metadata_ready = true; - GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, - server_recv_trailing_metadata_ready, elem, - grpc_schedule_on_exec_ctx); - GRPC_CALL_COMBINER_STOP(calld->call_combiner, - "deferring server_recv_trailing_metadata_ready " - "until after server_on_recv_initial_metadata"); - return; - } - error = - grpc_error_add_child(GRPC_ERROR_REF(error), - GRPC_ERROR_REF(calld->recv_initial_metadata_error)); - GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, error); + err = grpc_error_add_child(GRPC_ERROR_REF(err), GRPC_ERROR_REF(calld->error)); + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); } static void server_mutate_op(grpc_call_element* elem, @@ -870,7 +845,6 @@ static grpc_error* init_call_elem(grpc_call_element* elem, memset(calld, 0, sizeof(call_data)); calld->deadline = GRPC_MILLIS_INF_FUTURE; calld->call = grpc_call_from_top_element(elem); - calld->call_combiner = args->call_combiner; GRPC_CLOSURE_INIT(&calld->server_on_recv_initial_metadata, server_on_recv_initial_metadata, elem, @@ -889,7 +863,7 @@ static void destroy_call_elem(grpc_call_element* elem, call_data* calld = static_cast(elem->call_data); GPR_ASSERT(calld->state != PENDING); - GRPC_ERROR_UNREF(calld->recv_initial_metadata_error); + GRPC_ERROR_UNREF(calld->error); if (calld->host_set) { grpc_slice_unref_internal(calld->host); } From 0049ba865d4a2d61aff3975ff9778d21d4203bd2 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 21 Sep 2018 08:05:16 -0700 Subject: [PATCH 423/546] Rename openssl in test --- src/objective-c/tests/CronetUnitTests/CronetUnitTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m index 75a669da4d4..84893b92c1a 100644 --- a/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m +++ b/src/objective-c/tests/CronetUnitTests/CronetUnitTests.m @@ -39,7 +39,7 @@ #import "src/core/tsi/grpc_shadow_boringssl.h" -#import +#import static void drain_cq(grpc_completion_queue *cq) { grpc_event ev; From fc136beecdd22b623e82691d536b588f40057b65 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 21 Sep 2018 08:21:42 -0700 Subject: [PATCH 424/546] Change function signature --- .../credentials/alts/grpc_alts_credentials_client_options.cc | 3 ++- .../credentials/alts/grpc_alts_credentials_server_options.cc | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc b/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc index 0a39c6c4858..118d18d1191 100644 --- a/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc +++ b/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc @@ -72,7 +72,8 @@ static void target_service_account_destroy( static const grpc_alts_credentials_options_vtable vtable = { alts_client_options_copy, alts_client_options_destroy}; -grpc_alts_credentials_options* grpc_alts_credentials_client_options_create() { +grpc_alts_credentials_options* grpc_alts_credentials_client_options_create( + void) { auto client_options = static_cast( gpr_zalloc(sizeof(grpc_alts_credentials_client_options))); client_options->base.vtable = &vtable; diff --git a/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc b/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc index 62aa7a620a0..1a59c456758 100644 --- a/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc +++ b/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc @@ -36,7 +36,8 @@ static void alts_server_options_destroy( static const grpc_alts_credentials_options_vtable vtable = { alts_server_options_copy, alts_server_options_destroy}; -grpc_alts_credentials_options* grpc_alts_credentials_server_options_create() { +grpc_alts_credentials_options* grpc_alts_credentials_server_options_create( + void) { grpc_alts_credentials_server_options* server_options = static_cast( gpr_zalloc(sizeof(*server_options))); From a12740f0ae20cbead056df8c2231052c218d0d02 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 21 Sep 2018 10:59:44 -0700 Subject: [PATCH 425/546] Revert the revert to server.cc --- src/core/lib/surface/server.cc | 42 +++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 5fa58ffdec2..72ddc2648d9 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -150,12 +150,15 @@ struct call_data { grpc_closure kill_zombie_closure; grpc_closure* on_done_recv_initial_metadata; grpc_closure recv_trailing_metadata_ready; - grpc_error* error; + grpc_error* recv_initial_metadata_error; grpc_closure* original_recv_trailing_metadata_ready; + grpc_error* recv_trailing_metadata_error; + bool seen_recv_trailing_metadata_ready; grpc_closure publish; call_data* pending_next; + grpc_call_combiner* call_combiner; }; struct request_matcher { @@ -727,21 +730,43 @@ static void server_on_recv_initial_metadata(void* ptr, grpc_error* error) { if (calld->host_set && calld->path_set) { /* do nothing */ } else { + /* Pass the error reference to calld->recv_initial_metadata_error */ grpc_error* src_error = error; error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - "Missing :authority or :path", &error, 1); + "Missing :authority or :path", &src_error, 1); GRPC_ERROR_UNREF(src_error); + calld->recv_initial_metadata_error = GRPC_ERROR_REF(error); } - - GRPC_CLOSURE_RUN(calld->on_done_recv_initial_metadata, error); + grpc_closure* closure = calld->on_done_recv_initial_metadata; + calld->on_done_recv_initial_metadata = nullptr; + if (calld->seen_recv_trailing_metadata_ready) { + GRPC_CALL_COMBINER_START(calld->call_combiner, + &calld->recv_trailing_metadata_ready, + calld->recv_trailing_metadata_error, + "continue server_recv_trailing_metadata_ready"); + } + GRPC_CLOSURE_RUN(closure, error); } static void server_recv_trailing_metadata_ready(void* user_data, - grpc_error* err) { + grpc_error* error) { grpc_call_element* elem = static_cast(user_data); call_data* calld = static_cast(elem->call_data); - err = grpc_error_add_child(GRPC_ERROR_REF(err), GRPC_ERROR_REF(calld->error)); - GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, err); + if (calld->on_done_recv_initial_metadata != nullptr) { + calld->recv_trailing_metadata_error = GRPC_ERROR_REF(error); + calld->seen_recv_trailing_metadata_ready = true; + GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready, + server_recv_trailing_metadata_ready, elem, + grpc_schedule_on_exec_ctx); + GRPC_CALL_COMBINER_STOP(calld->call_combiner, + "deferring server_recv_trailing_metadata_ready " + "until after server_on_recv_initial_metadata"); + return; + } + error = + grpc_error_add_child(GRPC_ERROR_REF(error), + GRPC_ERROR_REF(calld->recv_initial_metadata_error)); + GRPC_CLOSURE_RUN(calld->original_recv_trailing_metadata_ready, error); } static void server_mutate_op(grpc_call_element* elem, @@ -845,6 +870,7 @@ static grpc_error* init_call_elem(grpc_call_element* elem, memset(calld, 0, sizeof(call_data)); calld->deadline = GRPC_MILLIS_INF_FUTURE; calld->call = grpc_call_from_top_element(elem); + calld->call_combiner = args->call_combiner; GRPC_CLOSURE_INIT(&calld->server_on_recv_initial_metadata, server_on_recv_initial_metadata, elem, @@ -863,7 +889,7 @@ static void destroy_call_elem(grpc_call_element* elem, call_data* calld = static_cast(elem->call_data); GPR_ASSERT(calld->state != PENDING); - GRPC_ERROR_UNREF(calld->error); + GRPC_ERROR_UNREF(calld->recv_initial_metadata_error); if (calld->host_set) { grpc_slice_unref_internal(calld->host); } From 9af7c7258987280bc6305b329e709400cde0e799 Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Fri, 21 Sep 2018 15:58:50 -0700 Subject: [PATCH 426/546] add copyright header Signed-off-by: Lizan Zhou --- .../fake_handshaker/fake_handshaker_server.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.h b/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.h index 02aeee5bc22..eb4bfdffa12 100644 --- a/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.h +++ b/test/core/tsi/alts/fake_handshaker/fake_handshaker_server.h @@ -1,3 +1,20 @@ +/* + * + * 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 #include From cd1992bc04f01279be9e00226633fa5984713cd6 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 21 Sep 2018 16:50:14 -0700 Subject: [PATCH 427/546] Add comment --- src/core/ext/filters/message_size/message_size_filter.cc | 5 +++++ 1 file changed, 5 insertions(+) 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 6a3e14aa139..2d3b16d992c 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -152,6 +152,11 @@ static void recv_message_ready(void* user_data, grpc_error* error) { grpc_closure* closure = calld->next_recv_message_ready; calld->next_recv_message_ready = nullptr; if (calld->seen_recv_trailing_metadata) { + /* We might potentially see another RECV_MESSAGE op. In that case, we do not + * want to run the recv_trailing_metadata_ready closure again. The newer + * RECV_MESSAGE op cannot cause any errors since the transport has already + * invoked the recv_trailing_metadata_ready closure and all further + * RECV_MESSAGE ops will get null payloads. */ calld->seen_recv_trailing_metadata = false; GRPC_CALL_COMBINER_START(calld->call_combiner, &calld->recv_trailing_metadata_ready, From be18cedf90c61352b52039c6298347fe1c321494 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 21 Sep 2018 23:26:46 -0700 Subject: [PATCH 428/546] Delete epollsig poller and tests using it --- BUILD | 2 - CMakeLists.txt | 74 - Makefile | 78 - bazel/grpc_build_system.bzl | 2 +- build.yaml | 31 - config.m4 | 1 - config.w32 | 1 - gRPC-C++.podspec | 2 - gRPC-Core.podspec | 3 - grpc.gemspec | 2 - grpc.gyp | 4 - package.xml | 2 - src/core/lib/iomgr/ev_epollsig_linux.cc | 1743 ----------------- src/core/lib/iomgr/ev_epollsig_linux.h | 35 - src/core/lib/iomgr/ev_posix.cc | 15 +- src/core/lib/iomgr/port.h | 2 - src/python/grpcio/grpc_core_dependencies.py | 1 - test/core/end2end/generate_tests.bzl | 2 +- test/core/iomgr/BUILD | 32 +- test/core/iomgr/ev_epollsig_linux_test.cc | 321 --- test/core/iomgr/pollset_set_test.cc | 447 ----- tools/doxygen/Doxyfile.c++.internal | 1 - tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 37 - tools/run_tests/generated/tests.json | 40 - tools/run_tests/run_tests.py | 4 +- 26 files changed, 14 insertions(+), 2870 deletions(-) delete mode 100644 src/core/lib/iomgr/ev_epollsig_linux.cc delete mode 100644 src/core/lib/iomgr/ev_epollsig_linux.h delete mode 100644 test/core/iomgr/ev_epollsig_linux_test.cc delete mode 100644 test/core/iomgr/pollset_set_test.cc diff --git a/BUILD b/BUILD index 76d78d737f2..6348c4e6ff2 100644 --- a/BUILD +++ b/BUILD @@ -707,7 +707,6 @@ grpc_cc_library( "src/core/lib/iomgr/error.cc", "src/core/lib/iomgr/ev_epoll1_linux.cc", "src/core/lib/iomgr/ev_epollex_linux.cc", - "src/core/lib/iomgr/ev_epollsig_linux.cc", "src/core/lib/iomgr/ev_poll_posix.cc", "src/core/lib/iomgr/ev_posix.cc", "src/core/lib/iomgr/ev_windows.cc", @@ -859,7 +858,6 @@ grpc_cc_library( "src/core/lib/iomgr/error_internal.h", "src/core/lib/iomgr/ev_epoll1_linux.h", "src/core/lib/iomgr/ev_epollex_linux.h", - "src/core/lib/iomgr/ev_epollsig_linux.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 124bd0dc60e..51788be1086 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -253,9 +253,6 @@ add_dependencies(buildtests_c error_test) if(_gRPC_PLATFORM_LINUX) add_dependencies(buildtests_c ev_epollex_linux_test) endif() -if(_gRPC_PLATFORM_LINUX) -add_dependencies(buildtests_c ev_epollsig_linux_test) -endif() add_dependencies(buildtests_c fake_resolver_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c fake_transport_security_test) @@ -355,9 +352,6 @@ add_dependencies(buildtests_c no_server_test) add_dependencies(buildtests_c num_external_connectivity_watchers_test) add_dependencies(buildtests_c parse_address_test) add_dependencies(buildtests_c percent_encoding_test) -if(_gRPC_PLATFORM_LINUX) -add_dependencies(buildtests_c pollset_set_test) -endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c resolve_address_posix_test) endif() @@ -974,7 +968,6 @@ add_library(grpc src/core/lib/iomgr/error.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc - src/core/lib/iomgr/ev_epollsig_linux.cc src/core/lib/iomgr/ev_poll_posix.cc src/core/lib/iomgr/ev_posix.cc src/core/lib/iomgr/ev_windows.cc @@ -1383,7 +1376,6 @@ add_library(grpc_cronet src/core/lib/iomgr/error.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc - src/core/lib/iomgr/ev_epollsig_linux.cc src/core/lib/iomgr/ev_poll_posix.cc src/core/lib/iomgr/ev_posix.cc src/core/lib/iomgr/ev_windows.cc @@ -1778,7 +1770,6 @@ add_library(grpc_test_util src/core/lib/iomgr/error.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc - src/core/lib/iomgr/ev_epollsig_linux.cc src/core/lib/iomgr/ev_poll_posix.cc src/core/lib/iomgr/ev_posix.cc src/core/lib/iomgr/ev_windows.cc @@ -2089,7 +2080,6 @@ add_library(grpc_test_util_unsecure src/core/lib/iomgr/error.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc - src/core/lib/iomgr/ev_epollsig_linux.cc src/core/lib/iomgr/ev_poll_posix.cc src/core/lib/iomgr/ev_posix.cc src/core/lib/iomgr/ev_windows.cc @@ -2379,7 +2369,6 @@ add_library(grpc_unsecure src/core/lib/iomgr/error.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc - src/core/lib/iomgr/ev_epollsig_linux.cc src/core/lib/iomgr/ev_poll_posix.cc src/core/lib/iomgr/ev_posix.cc src/core/lib/iomgr/ev_windows.cc @@ -3226,7 +3215,6 @@ add_library(grpc++_cronet src/core/lib/iomgr/error.cc src/core/lib/iomgr/ev_epoll1_linux.cc src/core/lib/iomgr/ev_epollex_linux.cc - src/core/lib/iomgr/ev_epollsig_linux.cc src/core/lib/iomgr/ev_poll_posix.cc src/core/lib/iomgr/ev_posix.cc src/core/lib/iomgr/ev_windows.cc @@ -6393,37 +6381,6 @@ target_link_libraries(ev_epollex_linux_test gpr ) -endif() -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) -if(_gRPC_PLATFORM_LINUX) - -add_executable(ev_epollsig_linux_test - test/core/iomgr/ev_epollsig_linux_test.cc -) - - -target_include_directories(ev_epollsig_linux_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 ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} -) - -target_link_libraries(ev_epollsig_linux_test - ${_gRPC_ALLTARGETS_LIBRARIES} - grpc_test_util - grpc - gpr_test_util - gpr -) - endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8509,37 +8466,6 @@ target_link_libraries(percent_encoding_test gpr ) -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) -if(_gRPC_PLATFORM_LINUX) - -add_executable(pollset_set_test - test/core/iomgr/pollset_set_test.cc -) - - -target_include_directories(pollset_set_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 ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} -) - -target_link_libraries(pollset_set_test - ${_gRPC_ALLTARGETS_LIBRARIES} - grpc_test_util - grpc - gpr_test_util - gpr -) - -endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) diff --git a/Makefile b/Makefile index 65ff9972bf8..baaebd1803c 100644 --- a/Makefile +++ b/Makefile @@ -998,7 +998,6 @@ dualstack_socket_test: $(BINDIR)/$(CONFIG)/dualstack_socket_test endpoint_pair_test: $(BINDIR)/$(CONFIG)/endpoint_pair_test error_test: $(BINDIR)/$(CONFIG)/error_test ev_epollex_linux_test: $(BINDIR)/$(CONFIG)/ev_epollex_linux_test -ev_epollsig_linux_test: $(BINDIR)/$(CONFIG)/ev_epollsig_linux_test fake_resolver_test: $(BINDIR)/$(CONFIG)/fake_resolver_test fake_transport_security_test: $(BINDIR)/$(CONFIG)/fake_transport_security_test fd_conservation_posix_test: $(BINDIR)/$(CONFIG)/fd_conservation_posix_test @@ -1080,7 +1079,6 @@ parse_address_test: $(BINDIR)/$(CONFIG)/parse_address_test percent_decode_fuzzer: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer percent_encoding_test: $(BINDIR)/$(CONFIG)/percent_encoding_test -pollset_set_test: $(BINDIR)/$(CONFIG)/pollset_set_test resolve_address_posix_test: $(BINDIR)/$(CONFIG)/resolve_address_posix_test resolve_address_using_ares_resolver_test: $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test resolve_address_using_native_resolver_test: $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test @@ -1455,7 +1453,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/endpoint_pair_test \ $(BINDIR)/$(CONFIG)/error_test \ $(BINDIR)/$(CONFIG)/ev_epollex_linux_test \ - $(BINDIR)/$(CONFIG)/ev_epollsig_linux_test \ $(BINDIR)/$(CONFIG)/fake_resolver_test \ $(BINDIR)/$(CONFIG)/fake_transport_security_test \ $(BINDIR)/$(CONFIG)/fd_conservation_posix_test \ @@ -1525,7 +1522,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/num_external_connectivity_watchers_test \ $(BINDIR)/$(CONFIG)/parse_address_test \ $(BINDIR)/$(CONFIG)/percent_encoding_test \ - $(BINDIR)/$(CONFIG)/pollset_set_test \ $(BINDIR)/$(CONFIG)/resolve_address_posix_test \ $(BINDIR)/$(CONFIG)/resolve_address_using_ares_resolver_test \ $(BINDIR)/$(CONFIG)/resolve_address_using_native_resolver_test \ @@ -1992,8 +1988,6 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/error_test || ( echo test error_test failed ; exit 1 ) $(E) "[RUN] Testing ev_epollex_linux_test" $(Q) $(BINDIR)/$(CONFIG)/ev_epollex_linux_test || ( echo test ev_epollex_linux_test failed ; exit 1 ) - $(E) "[RUN] Testing ev_epollsig_linux_test" - $(Q) $(BINDIR)/$(CONFIG)/ev_epollsig_linux_test || ( echo test ev_epollsig_linux_test failed ; exit 1 ) $(E) "[RUN] Testing fake_resolver_test" $(Q) $(BINDIR)/$(CONFIG)/fake_resolver_test || ( echo test fake_resolver_test failed ; exit 1 ) $(E) "[RUN] Testing fake_transport_security_test" @@ -2120,8 +2114,6 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/parse_address_test || ( echo test parse_address_test failed ; exit 1 ) $(E) "[RUN] Testing percent_encoding_test" $(Q) $(BINDIR)/$(CONFIG)/percent_encoding_test || ( echo test percent_encoding_test failed ; exit 1 ) - $(E) "[RUN] Testing pollset_set_test" - $(Q) $(BINDIR)/$(CONFIG)/pollset_set_test || ( echo test pollset_set_test failed ; exit 1 ) $(E) "[RUN] Testing resolve_address_posix_test" $(Q) $(BINDIR)/$(CONFIG)/resolve_address_posix_test || ( echo test resolve_address_posix_test failed ; exit 1 ) $(E) "[RUN] Testing resolve_address_using_ares_resolver_test" @@ -3484,7 +3476,6 @@ LIBGRPC_SRC = \ src/core/lib/iomgr/error.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ - src/core/lib/iomgr/ev_epollsig_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ src/core/lib/iomgr/ev_posix.cc \ src/core/lib/iomgr/ev_windows.cc \ @@ -3892,7 +3883,6 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/iomgr/error.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ - src/core/lib/iomgr/ev_epollsig_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ src/core/lib/iomgr/ev_posix.cc \ src/core/lib/iomgr/ev_windows.cc \ @@ -4285,7 +4275,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/iomgr/error.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ - src/core/lib/iomgr/ev_epollsig_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ src/core/lib/iomgr/ev_posix.cc \ src/core/lib/iomgr/ev_windows.cc \ @@ -4587,7 +4576,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/lib/iomgr/error.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ - src/core/lib/iomgr/ev_epollsig_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ src/core/lib/iomgr/ev_posix.cc \ src/core/lib/iomgr/ev_windows.cc \ @@ -4855,7 +4843,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/iomgr/error.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ - src/core/lib/iomgr/ev_epollsig_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ src/core/lib/iomgr/ev_posix.cc \ src/core/lib/iomgr/ev_windows.cc \ @@ -5690,7 +5677,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/lib/iomgr/error.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ - src/core/lib/iomgr/ev_epollsig_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ src/core/lib/iomgr/ev_posix.cc \ src/core/lib/iomgr/ev_windows.cc \ @@ -11354,38 +11340,6 @@ endif endif -EV_EPOLLSIG_LINUX_TEST_SRC = \ - test/core/iomgr/ev_epollsig_linux_test.cc \ - -EV_EPOLLSIG_LINUX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(EV_EPOLLSIG_LINUX_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/ev_epollsig_linux_test: openssl_dep_error - -else - - - -$(BINDIR)/$(CONFIG)/ev_epollsig_linux_test: $(EV_EPOLLSIG_LINUX_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) $(EV_EPOLLSIG_LINUX_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)/ev_epollsig_linux_test - -endif - -$(OBJDIR)/$(CONFIG)/test/core/iomgr/ev_epollsig_linux_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_ev_epollsig_linux_test: $(EV_EPOLLSIG_LINUX_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(EV_EPOLLSIG_LINUX_TEST_OBJS:.o=.dep) -endif -endif - - FAKE_RESOLVER_TEST_SRC = \ test/core/client_channel/resolvers/fake_resolver_test.cc \ @@ -13996,38 +13950,6 @@ endif endif -POLLSET_SET_TEST_SRC = \ - test/core/iomgr/pollset_set_test.cc \ - -POLLSET_SET_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(POLLSET_SET_TEST_SRC)))) -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL. - -$(BINDIR)/$(CONFIG)/pollset_set_test: openssl_dep_error - -else - - - -$(BINDIR)/$(CONFIG)/pollset_set_test: $(POLLSET_SET_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) $(POLLSET_SET_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)/pollset_set_test - -endif - -$(OBJDIR)/$(CONFIG)/test/core/iomgr/pollset_set_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_pollset_set_test: $(POLLSET_SET_TEST_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(POLLSET_SET_TEST_OBJS:.o=.dep) -endif -endif - - RESOLVE_ADDRESS_POSIX_TEST_SRC = \ test/core/iomgr/resolve_address_posix_test.cc \ diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl index b3f97650e8c..159ebd5d1fe 100644 --- a/bazel/grpc_build_system.bzl +++ b/bazel/grpc_build_system.bzl @@ -24,7 +24,7 @@ # # The set of pollers to test against if a test exercises polling -POLLERS = ["epollex", "epollsig", "epoll1", "poll", "poll-cv"] +POLLERS = ["epollex", "epoll1", "poll", "poll-cv"] def if_not_windows(a): return select({ diff --git a/build.yaml b/build.yaml index 60600b7dcec..f3895bb7026 100644 --- a/build.yaml +++ b/build.yaml @@ -266,7 +266,6 @@ filegroups: - src/core/lib/iomgr/error.cc - src/core/lib/iomgr/ev_epoll1_linux.cc - src/core/lib/iomgr/ev_epollex_linux.cc - - src/core/lib/iomgr/ev_epollsig_linux.cc - src/core/lib/iomgr/ev_poll_posix.cc - src/core/lib/iomgr/ev_posix.cc - src/core/lib/iomgr/ev_windows.cc @@ -446,7 +445,6 @@ filegroups: - src/core/lib/iomgr/error_internal.h - src/core/lib/iomgr/ev_epoll1_linux.h - src/core/lib/iomgr/ev_epollex_linux.h - - src/core/lib/iomgr/ev_epollsig_linux.h - src/core/lib/iomgr/ev_poll_posix.h - src/core/lib/iomgr/ev_posix.h - src/core/lib/iomgr/exec_ctx.h @@ -2372,21 +2370,6 @@ targets: - uv platforms: - linux -- name: ev_epollsig_linux_test - cpu_cost: 3 - build: test - language: c - src: - - test/core/iomgr/ev_epollsig_linux_test.cc - deps: - - grpc_test_util - - grpc - - gpr_test_util - - gpr - exclude_iomgrs: - - uv - platforms: - - linux - name: fake_resolver_test build: test language: c @@ -3338,20 +3321,6 @@ targets: - gpr_test_util - gpr uses_polling: false -- name: pollset_set_test - build: test - language: c - src: - - test/core/iomgr/pollset_set_test.cc - deps: - - grpc_test_util - - grpc - - gpr_test_util - - gpr - exclude_iomgrs: - - uv - platforms: - - linux - name: resolve_address_posix_test build: test language: c diff --git a/config.m4 b/config.m4 index a6ce55e0a9d..1796c8c8e21 100644 --- a/config.m4 +++ b/config.m4 @@ -118,7 +118,6 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/iomgr/error.cc \ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.cc \ - src/core/lib/iomgr/ev_epollsig_linux.cc \ src/core/lib/iomgr/ev_poll_posix.cc \ src/core/lib/iomgr/ev_posix.cc \ src/core/lib/iomgr/ev_windows.cc \ diff --git a/config.w32 b/config.w32 index 333986c50a5..6cdd2dac8b0 100644 --- a/config.w32 +++ b/config.w32 @@ -93,7 +93,6 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\iomgr\\error.cc " + "src\\core\\lib\\iomgr\\ev_epoll1_linux.cc " + "src\\core\\lib\\iomgr\\ev_epollex_linux.cc " + - "src\\core\\lib\\iomgr\\ev_epollsig_linux.cc " + "src\\core\\lib\\iomgr\\ev_poll_posix.cc " + "src\\core\\lib\\iomgr\\ev_posix.cc " + "src\\core\\lib\\iomgr\\ev_windows.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index d45e0c519b3..3ca132f7c38 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -396,7 +396,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error_internal.h', 'src/core/lib/iomgr/ev_epoll1_linux.h', 'src/core/lib/iomgr/ev_epollex_linux.h', - 'src/core/lib/iomgr/ev_epollsig_linux.h', 'src/core/lib/iomgr/ev_poll_posix.h', 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', @@ -586,7 +585,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error_internal.h', 'src/core/lib/iomgr/ev_epoll1_linux.h', 'src/core/lib/iomgr/ev_epollex_linux.h', - 'src/core/lib/iomgr/ev_epollsig_linux.h', 'src/core/lib/iomgr/ev_poll_posix.h', 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 964039186c4..0c3fbe0a254 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -405,7 +405,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error_internal.h', 'src/core/lib/iomgr/ev_epoll1_linux.h', 'src/core/lib/iomgr/ev_epollex_linux.h', - 'src/core/lib/iomgr/ev_epollsig_linux.h', 'src/core/lib/iomgr/ev_poll_posix.h', 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', @@ -551,7 +550,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', - 'src/core/lib/iomgr/ev_epollsig_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', 'src/core/lib/iomgr/ev_posix.cc', 'src/core/lib/iomgr/ev_windows.cc', @@ -1010,7 +1008,6 @@ Pod::Spec.new do |s| 'src/core/lib/iomgr/error_internal.h', 'src/core/lib/iomgr/ev_epoll1_linux.h', 'src/core/lib/iomgr/ev_epollex_linux.h', - 'src/core/lib/iomgr/ev_epollsig_linux.h', 'src/core/lib/iomgr/ev_poll_posix.h', 'src/core/lib/iomgr/ev_posix.h', 'src/core/lib/iomgr/exec_ctx.h', diff --git a/grpc.gemspec b/grpc.gemspec index f5cbf796240..5780dd7a072 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -341,7 +341,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/error_internal.h ) s.files += %w( src/core/lib/iomgr/ev_epoll1_linux.h ) s.files += %w( src/core/lib/iomgr/ev_epollex_linux.h ) - s.files += %w( src/core/lib/iomgr/ev_epollsig_linux.h ) s.files += %w( src/core/lib/iomgr/ev_poll_posix.h ) s.files += %w( src/core/lib/iomgr/ev_posix.h ) s.files += %w( src/core/lib/iomgr/exec_ctx.h ) @@ -487,7 +486,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/iomgr/error.cc ) s.files += %w( src/core/lib/iomgr/ev_epoll1_linux.cc ) s.files += %w( src/core/lib/iomgr/ev_epollex_linux.cc ) - s.files += %w( src/core/lib/iomgr/ev_epollsig_linux.cc ) s.files += %w( src/core/lib/iomgr/ev_poll_posix.cc ) s.files += %w( src/core/lib/iomgr/ev_posix.cc ) s.files += %w( src/core/lib/iomgr/ev_windows.cc ) diff --git a/grpc.gyp b/grpc.gyp index 15d20053f4d..1ef44eb4ad2 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -310,7 +310,6 @@ 'src/core/lib/iomgr/error.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', - 'src/core/lib/iomgr/ev_epollsig_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', 'src/core/lib/iomgr/ev_posix.cc', 'src/core/lib/iomgr/ev_windows.cc', @@ -673,7 +672,6 @@ 'src/core/lib/iomgr/error.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', - 'src/core/lib/iomgr/ev_epollsig_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', 'src/core/lib/iomgr/ev_posix.cc', 'src/core/lib/iomgr/ev_windows.cc', @@ -909,7 +907,6 @@ 'src/core/lib/iomgr/error.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', - 'src/core/lib/iomgr/ev_epollsig_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', 'src/core/lib/iomgr/ev_posix.cc', 'src/core/lib/iomgr/ev_windows.cc', @@ -1123,7 +1120,6 @@ 'src/core/lib/iomgr/error.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', - 'src/core/lib/iomgr/ev_epollsig_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', 'src/core/lib/iomgr/ev_posix.cc', 'src/core/lib/iomgr/ev_windows.cc', diff --git a/package.xml b/package.xml index 1e8ae8bb6a9..fddc676d512 100644 --- a/package.xml +++ b/package.xml @@ -346,7 +346,6 @@ - @@ -492,7 +491,6 @@ - diff --git a/src/core/lib/iomgr/ev_epollsig_linux.cc b/src/core/lib/iomgr/ev_epollsig_linux.cc deleted file mode 100644 index 5695ac795d7..00000000000 --- a/src/core/lib/iomgr/ev_epollsig_linux.cc +++ /dev/null @@ -1,1743 +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 - -#include "src/core/lib/iomgr/port.h" - -#include -#include - -/* This polling engine is only relevant on linux kernels supporting epoll() */ -#ifdef GRPC_LINUX_EPOLL_CREATE1 - -#include "src/core/lib/iomgr/ev_epollsig_linux.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "src/core/lib/debug/stats.h" -#include "src/core/lib/gpr/tls.h" -#include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/manual_constructor.h" -#include "src/core/lib/iomgr/block_annotate.h" -#include "src/core/lib/iomgr/ev_posix.h" -#include "src/core/lib/iomgr/iomgr_internal.h" -#include "src/core/lib/iomgr/lockfree_event.h" -#include "src/core/lib/iomgr/timer.h" -#include "src/core/lib/iomgr/wakeup_fd_posix.h" -#include "src/core/lib/profiling/timers.h" - -#define GRPC_POLLSET_KICK_BROADCAST ((grpc_pollset_worker*)1) - -#define GRPC_POLLING_TRACE(...) \ - if (grpc_polling_trace.enabled()) { \ - gpr_log(GPR_INFO, __VA_ARGS__); \ - } - -static int grpc_wakeup_signal = -1; -static bool is_grpc_wakeup_signal_initialized = false; - -/* Implements the function defined in grpc_posix.h. This function might be - * called before even calling grpc_init() to set either a different signal to - * use. If signum == -1, then the use of signals is disabled */ -void grpc_use_signal(int signum) { - grpc_wakeup_signal = signum; - is_grpc_wakeup_signal_initialized = true; - - if (grpc_wakeup_signal < 0) { - gpr_log(GPR_INFO, - "Use of signals is disabled. Epoll engine will not be used"); - } else { - gpr_log(GPR_INFO, "epoll engine will be using signal: %d", - grpc_wakeup_signal); - } -} - -struct polling_island; - -typedef enum { - POLL_OBJ_FD, - POLL_OBJ_POLLSET, - POLL_OBJ_POLLSET_SET -} poll_obj_type; - -typedef struct poll_obj { -#ifndef NDEBUG - poll_obj_type obj_type; -#endif - gpr_mu mu; - struct polling_island* pi; -} poll_obj; - -const char* poll_obj_string(poll_obj_type po_type) { - switch (po_type) { - case POLL_OBJ_FD: - return "fd"; - case POLL_OBJ_POLLSET: - return "pollset"; - case POLL_OBJ_POLLSET_SET: - return "pollset_set"; - } - - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - - /******************************************************************************* - * Fd Declarations - */ - -#define FD_FROM_PO(po) ((grpc_fd*)(po)) - -struct grpc_fd { - poll_obj po; - - int fd; - /* refst format: - bit 0 : 1=Active / 0=Orphaned - bits 1-n : refcount - Ref/Unref by two to avoid altering the orphaned bit */ - gpr_atm refst; - - /* The fd is either closed or we relinquished control of it. In either - cases, this indicates that the 'fd' on this structure is no longer - valid */ - bool orphaned; - - grpc_core::ManualConstructor read_closure; - grpc_core::ManualConstructor write_closure; - grpc_core::ManualConstructor error_closure; - - struct grpc_fd* freelist_next; - grpc_closure* on_done_closure; - - grpc_iomgr_object iomgr_object; - - /* Do we need to track EPOLLERR events separately? */ - bool track_err; -}; - -/* Reference counting for fds */ -#ifndef NDEBUG -static void fd_ref(grpc_fd* fd, const char* reason, const char* file, int line); -static void fd_unref(grpc_fd* fd, const char* reason, const char* file, - int line); -#define GRPC_FD_REF(fd, reason) fd_ref(fd, reason, __FILE__, __LINE__) -#define GRPC_FD_UNREF(fd, reason) fd_unref(fd, reason, __FILE__, __LINE__) -#else -static void fd_ref(grpc_fd* fd); -static void fd_unref(grpc_fd* fd); -#define GRPC_FD_REF(fd, reason) fd_ref(fd) -#define GRPC_FD_UNREF(fd, reason) fd_unref(fd) -#endif - -static void fd_global_init(void); -static void fd_global_shutdown(void); - -/******************************************************************************* - * Polling island Declarations - */ - -#ifndef NDEBUG - -#define PI_ADD_REF(p, r) pi_add_ref_dbg((p), (r), __FILE__, __LINE__) -#define PI_UNREF(p, r) pi_unref_dbg((p), (r), __FILE__, __LINE__) - -#else - -#define PI_ADD_REF(p, r) pi_add_ref((p)) -#define PI_UNREF(p, r) pi_unref((p)) - -#endif - -/* This is also used as grpc_workqueue (by directly casing it) */ -typedef struct polling_island { - gpr_mu mu; - /* Ref count. Use PI_ADD_REF() and PI_UNREF() macros to increment/decrement - the refcount. - Once the ref count becomes zero, this structure is destroyed which means - we should ensure that there is never a scenario where a PI_ADD_REF() is - racing with a PI_UNREF() that just made the ref_count zero. */ - gpr_atm ref_count; - - /* Pointer to the polling_island this merged into. - * merged_to value is only set once in polling_island's lifetime (and that too - * only if the island is merged with another island). Because of this, we can - * use gpr_atm type here so that we can do atomic access on this and reduce - * lock contention on 'mu' mutex. - * - * Note that if this field is not NULL (i.e not 0), all the remaining fields - * (except mu and ref_count) are invalid and must be ignored. */ - gpr_atm merged_to; - - /* Number of threads currently polling on this island */ - gpr_atm poller_count; - - /* The fd of the underlying epoll set */ - int epoll_fd; - - /* The file descriptors in the epoll set */ - size_t fd_cnt; - size_t fd_capacity; - grpc_fd** fds; -} polling_island; - -/******************************************************************************* - * Pollset Declarations - */ -struct grpc_pollset_worker { - /* Thread id of this worker */ - pthread_t pt_id; - - /* Used to prevent a worker from getting kicked multiple times */ - gpr_atm is_kicked; - struct grpc_pollset_worker* next; - struct grpc_pollset_worker* prev; -}; - -struct grpc_pollset { - poll_obj po; - - grpc_pollset_worker root_worker; - bool kicked_without_pollers; - - bool shutting_down; /* Is the pollset shutting down ? */ - bool finish_shutdown_called; /* Is the 'finish_shutdown_locked()' called ? */ - grpc_closure* shutdown_done; /* Called after after shutdown is complete */ -}; - -/******************************************************************************* - * Pollset-set Declarations - */ -struct grpc_pollset_set { - poll_obj po; -}; - -/******************************************************************************* - * Common helpers - */ - -static bool append_error(grpc_error** composite, grpc_error* error, - const char* desc) { - if (error == GRPC_ERROR_NONE) return true; - if (*composite == GRPC_ERROR_NONE) { - *composite = GRPC_ERROR_CREATE_FROM_COPIED_STRING(desc); - } - *composite = grpc_error_add_child(*composite, error); - return false; -} - -/******************************************************************************* - * Polling island Definitions - */ - -/* The wakeup fd that is used to wake up all threads in a Polling island. This - is useful in the polling island merge operation where we need to wakeup all - the threads currently polling the smaller polling island (so that they can - start polling the new/merged polling island) - - NOTE: This fd is initialized to be readable and MUST NOT be consumed i.e the - threads that woke up MUST NOT call grpc_wakeup_fd_consume_wakeup() */ -static grpc_wakeup_fd polling_island_wakeup_fd; - -/* The polling island being polled right now. - See comments in workqueue_maybe_wakeup for why this is tracked. */ -static __thread polling_island* g_current_thread_polling_island; - -/* Forward declaration */ -static void polling_island_delete(polling_island* pi); - -#ifdef GRPC_TSAN -/* Currently TSAN may incorrectly flag data races between epoll_ctl and - epoll_wait for any grpc_fd structs that are added to the epoll set via - epoll_ctl and are returned (within a very short window) via epoll_wait(). - - To work-around this race, we establish a happens-before relation between - the code just-before epoll_ctl() and the code after epoll_wait() by using - this atomic */ -gpr_atm g_epoll_sync; -#endif /* defined(GRPC_TSAN) */ - -static void pi_add_ref(polling_island* pi); -static void pi_unref(polling_island* pi); - -#ifndef NDEBUG -static void pi_add_ref_dbg(polling_island* pi, const char* reason, - const char* file, int line) { - if (grpc_polling_trace.enabled()) { - gpr_atm old_cnt = gpr_atm_acq_load(&pi->ref_count); - gpr_log(GPR_INFO, - "Add ref pi: %p, old:%" PRIdPTR " -> new:%" PRIdPTR - " (%s) - (%s, %d)", - pi, old_cnt, old_cnt + 1, reason, file, line); - } - pi_add_ref(pi); -} - -static void pi_unref_dbg(polling_island* pi, const char* reason, - const char* file, int line) { - if (grpc_polling_trace.enabled()) { - gpr_atm old_cnt = gpr_atm_acq_load(&pi->ref_count); - gpr_log(GPR_INFO, - "Unref pi: %p, old:%" PRIdPTR " -> new:%" PRIdPTR - " (%s) - (%s, %d)", - pi, old_cnt, (old_cnt - 1), reason, file, line); - } - pi_unref(pi); -} -#endif - -static void pi_add_ref(polling_island* pi) { - gpr_atm_no_barrier_fetch_add(&pi->ref_count, 1); -} - -static void pi_unref(polling_island* pi) { - /* If ref count went to zero, delete the polling island. - Note that this deletion not be done under a lock. Once the ref count goes - to zero, we are guaranteed that no one else holds a reference to the - polling island (and that there is no racing pi_add_ref() call either). - - Also, if we are deleting the polling island and the merged_to field is - non-empty, we should remove a ref to the merged_to polling island - */ - if (1 == gpr_atm_full_fetch_add(&pi->ref_count, -1)) { - polling_island* next = (polling_island*)gpr_atm_acq_load(&pi->merged_to); - polling_island_delete(pi); - if (next != nullptr) { - PI_UNREF(next, "pi_delete"); /* Recursive call */ - } - } -} - -/* The caller is expected to hold pi->mu lock before calling this function */ -static void polling_island_add_fds_locked(polling_island* pi, grpc_fd** fds, - size_t fd_count, bool add_fd_refs, - grpc_error** error) { - int err; - size_t i; - struct epoll_event ev; - char* err_msg; - const char* err_desc = "polling_island_add_fds"; - -#ifdef GRPC_TSAN - /* See the definition of g_epoll_sync for more context */ - gpr_atm_rel_store(&g_epoll_sync, (gpr_atm)0); -#endif /* defined(GRPC_TSAN) */ - - for (i = 0; i < fd_count; i++) { - ev.events = static_cast(EPOLLIN | EPOLLOUT | EPOLLET); - /* Use the least significant bit of ev.data.ptr to store track_err to avoid - * synchronization issues when accessing it after receiving an event */ - ev.data.ptr = reinterpret_cast(reinterpret_cast(fds[i]) | - (fds[i]->track_err ? 1 : 0)); - err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_ADD, fds[i]->fd, &ev); - - if (err < 0) { - if (errno != EEXIST) { - gpr_asprintf( - &err_msg, - "epoll_ctl (epoll_fd: %d) add fd: %d failed with error: %d (%s)", - pi->epoll_fd, fds[i]->fd, errno, strerror(errno)); - append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc); - gpr_free(err_msg); - } - - continue; - } - - if (pi->fd_cnt == pi->fd_capacity) { - pi->fd_capacity = GPR_MAX(pi->fd_capacity + 8, pi->fd_cnt * 3 / 2); - pi->fds = static_cast( - gpr_realloc(pi->fds, sizeof(grpc_fd*) * pi->fd_capacity)); - } - - pi->fds[pi->fd_cnt++] = fds[i]; - if (add_fd_refs) { - GRPC_FD_REF(fds[i], "polling_island"); - } - } -} - -/* The caller is expected to hold pi->mu before calling this */ -static void polling_island_add_wakeup_fd_locked(polling_island* pi, - grpc_wakeup_fd* wakeup_fd, - grpc_error** error) { - struct epoll_event ev; - int err; - char* err_msg; - const char* err_desc = "polling_island_add_wakeup_fd"; - - ev.events = static_cast(EPOLLIN | EPOLLET); - ev.data.ptr = wakeup_fd; - err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_ADD, - GRPC_WAKEUP_FD_GET_READ_FD(wakeup_fd), &ev); - if (err < 0 && errno != EEXIST) { - gpr_asprintf(&err_msg, - "epoll_ctl (epoll_fd: %d) add wakeup fd: %d failed with " - "error: %d (%s)", - pi->epoll_fd, GRPC_WAKEUP_FD_GET_READ_FD(wakeup_fd), errno, - strerror(errno)); - append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc); - gpr_free(err_msg); - } -} - -/* The caller is expected to hold pi->mu lock before calling this function */ -static void polling_island_remove_all_fds_locked(polling_island* pi, - bool remove_fd_refs, - grpc_error** error) { - int err; - size_t i; - char* err_msg; - const char* err_desc = "polling_island_remove_fds"; - - for (i = 0; i < pi->fd_cnt; i++) { - err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_DEL, pi->fds[i]->fd, nullptr); - if (err < 0 && errno != ENOENT) { - gpr_asprintf(&err_msg, - "epoll_ctl (epoll_fd: %d) delete fds[%zu]: %d failed with " - "error: %d (%s)", - pi->epoll_fd, i, pi->fds[i]->fd, errno, strerror(errno)); - append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc); - gpr_free(err_msg); - } - - if (remove_fd_refs) { - GRPC_FD_UNREF(pi->fds[i], "polling_island"); - } - } - - pi->fd_cnt = 0; -} - -/* The caller is expected to hold pi->mu lock before calling this function */ -static void polling_island_remove_fd_locked(polling_island* pi, grpc_fd* fd, - grpc_error** error) { - int err; - size_t i; - char* err_msg; - const char* err_desc = "polling_island_remove_fd"; - - /* If fd is already closed, then it would have been automatically been removed - from the epoll set */ - err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_DEL, fd->fd, nullptr); - if (err < 0 && errno != ENOENT) { - gpr_asprintf( - &err_msg, - "epoll_ctl (epoll_fd: %d) del fd: %d failed with error: %d (%s)", - pi->epoll_fd, fd->fd, errno, strerror(errno)); - append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc); - gpr_free(err_msg); - } - - for (i = 0; i < pi->fd_cnt; i++) { - if (pi->fds[i] == fd) { - pi->fds[i] = pi->fds[--pi->fd_cnt]; - GRPC_FD_UNREF(fd, "polling_island"); - break; - } - } -} - -/* Might return NULL in case of an error */ -static polling_island* polling_island_create(grpc_fd* initial_fd, - grpc_error** error) { - polling_island* pi = nullptr; - const char* err_desc = "polling_island_create"; - - *error = GRPC_ERROR_NONE; - - pi = static_cast(gpr_malloc(sizeof(*pi))); - gpr_mu_init(&pi->mu); - pi->fd_cnt = 0; - pi->fd_capacity = 0; - pi->fds = nullptr; - pi->epoll_fd = -1; - - gpr_atm_rel_store(&pi->ref_count, 0); - gpr_atm_rel_store(&pi->poller_count, 0); - gpr_atm_rel_store(&pi->merged_to, (gpr_atm) nullptr); - - pi->epoll_fd = epoll_create1(EPOLL_CLOEXEC); - - if (pi->epoll_fd < 0) { - append_error(error, GRPC_OS_ERROR(errno, "epoll_create1"), err_desc); - goto done; - } - - if (initial_fd != nullptr) { - polling_island_add_fds_locked(pi, &initial_fd, 1, true, error); - } - -done: - if (*error != GRPC_ERROR_NONE) { - polling_island_delete(pi); - pi = nullptr; - } - return pi; -} - -static void polling_island_delete(polling_island* pi) { - GPR_ASSERT(pi->fd_cnt == 0); - - if (pi->epoll_fd >= 0) { - close(pi->epoll_fd); - } - gpr_mu_destroy(&pi->mu); - gpr_free(pi->fds); - gpr_free(pi); -} - -/* Attempts to gets the last polling island in the linked list (liked by the - * 'merged_to' field). Since this does not lock the polling island, there are no - * guarantees that the island returned is the last island */ -static polling_island* polling_island_maybe_get_latest(polling_island* pi) { - polling_island* next = (polling_island*)gpr_atm_acq_load(&pi->merged_to); - while (next != nullptr) { - pi = next; - next = (polling_island*)gpr_atm_acq_load(&pi->merged_to); - } - - return pi; -} - -/* Gets the lock on the *latest* polling island i.e the last polling island in - the linked list (linked by the 'merged_to' field). Call gpr_mu_unlock on the - returned polling island's mu. - Usage: To lock/unlock polling island "pi", do the following: - polling_island *pi_latest = polling_island_lock(pi); - ... - ... critical section .. - ... - gpr_mu_unlock(&pi_latest->mu); // NOTE: use pi_latest->mu. NOT pi->mu */ -static polling_island* polling_island_lock(polling_island* pi) { - polling_island* next = nullptr; - - while (true) { - next = (polling_island*)gpr_atm_acq_load(&pi->merged_to); - if (next == nullptr) { - /* Looks like 'pi' is the last node in the linked list but unless we check - this by holding the pi->mu lock, we cannot be sure (i.e without the - pi->mu lock, we don't prevent island merges). - To be absolutely sure, check once more by holding the pi->mu lock */ - gpr_mu_lock(&pi->mu); - next = (polling_island*)gpr_atm_acq_load(&pi->merged_to); - if (next == nullptr) { - /* pi is infact the last node and we have the pi->mu lock. we're done */ - break; - } - - /* pi->merged_to is not NULL i.e pi isn't the last node anymore. pi->mu - * isn't the lock we are interested in. Continue traversing the list */ - gpr_mu_unlock(&pi->mu); - } - - pi = next; - } - - return pi; -} - -/* Gets the lock on the *latest* polling islands in the linked lists pointed by - *p and *q (and also updates *p and *q to point to the latest polling islands) - - This function is needed because calling the following block of code to obtain - locks on polling islands (*p and *q) is prone to deadlocks. - { - polling_island_lock(*p, true); - polling_island_lock(*q, true); - } - - Usage/example: - polling_island *p1; - polling_island *p2; - .. - polling_island_lock_pair(&p1, &p2); - .. - .. Critical section with both p1 and p2 locked - .. - // Release locks: Always call polling_island_unlock_pair() to release locks - polling_island_unlock_pair(p1, p2); -*/ -static void polling_island_lock_pair(polling_island** p, polling_island** q) { - polling_island* pi_1 = *p; - polling_island* pi_2 = *q; - polling_island* next_1 = nullptr; - polling_island* next_2 = nullptr; - - /* The algorithm is simple: - - Go to the last polling islands in the linked lists *pi_1 and *pi_2 (and - keep updating pi_1 and pi_2) - - Then obtain locks on the islands by following a lock order rule of - locking polling_island with lower address first - Special case: Before obtaining the locks, check if pi_1 and pi_2 are - pointing to the same island. If that is the case, we can just call - polling_island_lock() - - After obtaining both the locks, double check that the polling islands - are still the last polling islands in their respective linked lists - (this is because there might have been polling island merges before - we got the lock) - - If the polling islands are the last islands, we are done. If not, - release the locks and continue the process from the first step */ - while (true) { - next_1 = (polling_island*)gpr_atm_acq_load(&pi_1->merged_to); - while (next_1 != nullptr) { - pi_1 = next_1; - next_1 = (polling_island*)gpr_atm_acq_load(&pi_1->merged_to); - } - - next_2 = (polling_island*)gpr_atm_acq_load(&pi_2->merged_to); - while (next_2 != nullptr) { - pi_2 = next_2; - next_2 = (polling_island*)gpr_atm_acq_load(&pi_2->merged_to); - } - - if (pi_1 == pi_2) { - pi_1 = pi_2 = polling_island_lock(pi_1); - break; - } - - if (pi_1 < pi_2) { - gpr_mu_lock(&pi_1->mu); - gpr_mu_lock(&pi_2->mu); - } else { - gpr_mu_lock(&pi_2->mu); - gpr_mu_lock(&pi_1->mu); - } - - next_1 = (polling_island*)gpr_atm_acq_load(&pi_1->merged_to); - next_2 = (polling_island*)gpr_atm_acq_load(&pi_2->merged_to); - if (next_1 == nullptr && next_2 == nullptr) { - break; - } - - gpr_mu_unlock(&pi_1->mu); - gpr_mu_unlock(&pi_2->mu); - } - - *p = pi_1; - *q = pi_2; -} - -static void polling_island_unlock_pair(polling_island* p, polling_island* q) { - if (p == q) { - gpr_mu_unlock(&p->mu); - } else { - gpr_mu_unlock(&p->mu); - gpr_mu_unlock(&q->mu); - } -} - -static polling_island* polling_island_merge(polling_island* p, - polling_island* q, - grpc_error** error) { - /* Get locks on both the polling islands */ - polling_island_lock_pair(&p, &q); - - if (p != q) { - /* Make sure that p points to the polling island with fewer fds than q */ - if (p->fd_cnt > q->fd_cnt) { - GPR_SWAP(polling_island*, p, q); - } - - /* Merge p with q i.e move all the fds from p (The one with fewer fds) to q - Note that the refcounts on the fds being moved will not change here. - This is why the last param in the following two functions is 'false') */ - polling_island_add_fds_locked(q, p->fds, p->fd_cnt, false, error); - polling_island_remove_all_fds_locked(p, false, error); - - /* Wakeup all the pollers (if any) on p so that they pickup this change */ - polling_island_add_wakeup_fd_locked(p, &polling_island_wakeup_fd, error); - - /* Add the 'merged_to' link from p --> q */ - gpr_atm_rel_store(&p->merged_to, (gpr_atm)q); - PI_ADD_REF(q, "pi_merge"); /* To account for the new incoming ref from p */ - } - /* else if p == q, nothing needs to be done */ - - polling_island_unlock_pair(p, q); - - /* Return the merged polling island (Note that no merge would have happened - if p == q which is ok) */ - return q; -} - -static grpc_error* polling_island_global_init() { - grpc_error* error = GRPC_ERROR_NONE; - - error = grpc_wakeup_fd_init(&polling_island_wakeup_fd); - if (error == GRPC_ERROR_NONE) { - error = grpc_wakeup_fd_wakeup(&polling_island_wakeup_fd); - } - - return error; -} - -static void polling_island_global_shutdown() { - grpc_wakeup_fd_destroy(&polling_island_wakeup_fd); -} - -/******************************************************************************* - * Fd Definitions - */ - -/* We need to keep a freelist not because of any concerns of malloc performance - * but instead so that implementations with multiple threads in (for example) - * epoll_wait deal with the race between pollset removal and incoming poll - * notifications. - * - * The problem is that the poller ultimately holds a reference to this - * object, so it is very difficult to know when is safe to free it, at least - * without some expensive synchronization. - * - * If we keep the object freelisted, in the worst case losing this race just - * becomes a spurious read notification on a reused fd. - */ - -/* The alarm system needs to be able to wakeup 'some poller' sometimes - * (specifically when a new alarm needs to be triggered earlier than the next - * alarm 'epoch'). This wakeup_fd gives us something to alert on when such a - * case occurs. */ - -static grpc_fd* fd_freelist = nullptr; -static gpr_mu fd_freelist_mu; - -#ifndef NDEBUG -#define REF_BY(fd, n, reason) ref_by(fd, n, reason, __FILE__, __LINE__) -#define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__) -static void ref_by(grpc_fd* fd, int n, const char* reason, const char* file, - int line) { - if (grpc_trace_fd_refcount.enabled()) { - gpr_log(GPR_DEBUG, - "FD %d %p ref %d %" PRIdPTR " -> %" PRIdPTR " [%s; %s:%d]", - fd->fd, fd, n, gpr_atm_no_barrier_load(&fd->refst), - gpr_atm_no_barrier_load(&fd->refst) + n, reason, file, line); - } -#else -#define REF_BY(fd, n, reason) ref_by(fd, n) -#define UNREF_BY(fd, n, reason) unref_by(fd, n) -static void ref_by(grpc_fd* fd, int n) { -#endif - GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0); -} - -#ifndef NDEBUG -static void unref_by(grpc_fd* fd, int n, const char* reason, const char* file, - int line) { - if (grpc_trace_fd_refcount.enabled()) { - gpr_log(GPR_DEBUG, - "FD %d %p unref %d %" PRIdPTR " -> %" PRIdPTR " [%s; %s:%d]", - fd->fd, fd, n, gpr_atm_no_barrier_load(&fd->refst), - gpr_atm_no_barrier_load(&fd->refst) - n, reason, file, line); - } -#else -static void unref_by(grpc_fd* fd, int n) { -#endif - gpr_atm old = gpr_atm_full_fetch_add(&fd->refst, -n); - if (old == n) { - /* Add the fd to the freelist */ - gpr_mu_lock(&fd_freelist_mu); - fd->freelist_next = fd_freelist; - fd_freelist = fd; - grpc_iomgr_unregister_object(&fd->iomgr_object); - - fd->read_closure->DestroyEvent(); - fd->write_closure->DestroyEvent(); - fd->error_closure->DestroyEvent(); - - gpr_mu_unlock(&fd_freelist_mu); - } else { - GPR_ASSERT(old > n); - } -} - -/* Increment refcount by two to avoid changing the orphan bit */ -#ifndef NDEBUG -static void fd_ref(grpc_fd* fd, const char* reason, const char* file, - int line) { - ref_by(fd, 2, reason, file, line); -} - -static void fd_unref(grpc_fd* fd, const char* reason, const char* file, - int line) { - unref_by(fd, 2, reason, file, line); -} -#else -static void fd_ref(grpc_fd* fd) { ref_by(fd, 2); } -static void fd_unref(grpc_fd* fd) { unref_by(fd, 2); } -#endif - -static void fd_global_init(void) { gpr_mu_init(&fd_freelist_mu); } - -static void fd_global_shutdown(void) { - gpr_mu_lock(&fd_freelist_mu); - gpr_mu_unlock(&fd_freelist_mu); - while (fd_freelist != nullptr) { - grpc_fd* fd = fd_freelist; - fd_freelist = fd_freelist->freelist_next; - gpr_mu_destroy(&fd->po.mu); - gpr_free(fd); - } - gpr_mu_destroy(&fd_freelist_mu); -} - -static grpc_fd* fd_create(int fd, const char* name, bool track_err) { - grpc_fd* new_fd = nullptr; - - gpr_mu_lock(&fd_freelist_mu); - if (fd_freelist != nullptr) { - new_fd = fd_freelist; - fd_freelist = fd_freelist->freelist_next; - } - gpr_mu_unlock(&fd_freelist_mu); - - if (new_fd == nullptr) { - new_fd = static_cast(gpr_malloc(sizeof(grpc_fd))); - gpr_mu_init(&new_fd->po.mu); - new_fd->read_closure.Init(); - new_fd->write_closure.Init(); - new_fd->error_closure.Init(); - } - - /* Note: It is not really needed to get the new_fd->po.mu lock here. If this - * is a newly created fd (or an fd we got from the freelist), no one else - * would be holding a lock to it anyway. */ - gpr_mu_lock(&new_fd->po.mu); - new_fd->po.pi = nullptr; -#ifndef NDEBUG - new_fd->po.obj_type = POLL_OBJ_FD; -#endif - - gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1); - new_fd->fd = fd; - new_fd->orphaned = false; - new_fd->read_closure->InitEvent(); - new_fd->write_closure->InitEvent(); - new_fd->error_closure->InitEvent(); - new_fd->track_err = track_err; - - new_fd->freelist_next = nullptr; - new_fd->on_done_closure = nullptr; - - gpr_mu_unlock(&new_fd->po.mu); - - char* fd_name; - gpr_asprintf(&fd_name, "%s fd=%d", name, fd); - grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name); - gpr_free(fd_name); - return new_fd; -} - -static int fd_wrapped_fd(grpc_fd* fd) { - int ret_fd = -1; - gpr_mu_lock(&fd->po.mu); - if (!fd->orphaned) { - ret_fd = fd->fd; - } - gpr_mu_unlock(&fd->po.mu); - - return ret_fd; -} - -static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, - const char* reason) { - grpc_error* error = GRPC_ERROR_NONE; - polling_island* unref_pi = nullptr; - - gpr_mu_lock(&fd->po.mu); - fd->on_done_closure = on_done; - - /* Remove the active status but keep referenced. We want this grpc_fd struct - to be alive (and not added to freelist) until the end of this function */ - REF_BY(fd, 1, reason); - - /* Remove the fd from the polling island: - - Get a lock on the latest polling island (i.e the last island in the - linked list pointed by fd->po.pi). This is the island that - would actually contain the fd - - Remove the fd from the latest polling island - - Unlock the latest polling island - - Set fd->po.pi to NULL (but remove the ref on the polling island - before doing this.) */ - if (fd->po.pi != nullptr) { - polling_island* pi_latest = polling_island_lock(fd->po.pi); - polling_island_remove_fd_locked(pi_latest, fd, &error); - gpr_mu_unlock(&pi_latest->mu); - - unref_pi = fd->po.pi; - fd->po.pi = nullptr; - } - - /* If release_fd is not NULL, we should be relinquishing control of the file - descriptor fd->fd (but we still own the grpc_fd structure). */ - if (release_fd != nullptr) { - *release_fd = fd->fd; - } else { - close(fd->fd); - } - - fd->orphaned = true; - - GRPC_CLOSURE_SCHED(fd->on_done_closure, GRPC_ERROR_REF(error)); - - gpr_mu_unlock(&fd->po.mu); - UNREF_BY(fd, 2, reason); /* Drop the reference */ - if (unref_pi != nullptr) { - /* Unref stale polling island here, outside the fd lock above. - The polling island owns a workqueue which owns an fd, and unreffing - inside the lock can cause an eventual lock loop that makes TSAN very - unhappy. */ - PI_UNREF(unref_pi, "fd_orphan"); - } - if (error != GRPC_ERROR_NONE) { - const char* msg = grpc_error_string(error); - gpr_log(GPR_DEBUG, "fd_orphan: %s", msg); - } - GRPC_ERROR_UNREF(error); -} - -static bool fd_is_shutdown(grpc_fd* fd) { - return fd->read_closure->IsShutdown(); -} - -/* Might be called multiple times */ -static void fd_shutdown(grpc_fd* fd, grpc_error* why) { - if (fd->read_closure->SetShutdown(GRPC_ERROR_REF(why))) { - shutdown(fd->fd, SHUT_RDWR); - fd->write_closure->SetShutdown(GRPC_ERROR_REF(why)); - fd->error_closure->SetShutdown(GRPC_ERROR_REF(why)); - } - GRPC_ERROR_UNREF(why); -} - -static void fd_notify_on_read(grpc_fd* fd, grpc_closure* closure) { - fd->read_closure->NotifyOn(closure); -} - -static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) { - fd->write_closure->NotifyOn(closure); -} - -static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) { - fd->error_closure->NotifyOn(closure); -} - -static void fd_become_readable(grpc_fd* fd) { fd->read_closure->SetReady(); } - -static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); } - -static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); } - -/******************************************************************************* - * Pollset Definitions - */ -GPR_TLS_DECL(g_current_thread_pollset); -GPR_TLS_DECL(g_current_thread_worker); -static __thread bool g_initialized_sigmask; -static __thread sigset_t g_orig_sigmask; - -static void sig_handler(int sig_num) { -#ifdef GRPC_EPOLL_DEBUG - gpr_log(GPR_INFO, "Received signal %d", sig_num); -#endif -} - -static void poller_kick_init() { signal(grpc_wakeup_signal, sig_handler); } - -/* Global state management */ -static grpc_error* pollset_global_init(void) { - gpr_tls_init(&g_current_thread_pollset); - gpr_tls_init(&g_current_thread_worker); - poller_kick_init(); - return GRPC_ERROR_NONE; -} - -static void pollset_global_shutdown(void) { - gpr_tls_destroy(&g_current_thread_pollset); - gpr_tls_destroy(&g_current_thread_worker); -} - -static grpc_error* pollset_worker_kick(grpc_pollset_worker* worker) { - grpc_error* err = GRPC_ERROR_NONE; - - /* Kick the worker only if it was not already kicked */ - if (gpr_atm_no_barrier_cas(&worker->is_kicked, static_cast(0), - static_cast(1))) { - GRPC_POLLING_TRACE( - "pollset_worker_kick: Kicking worker: %p (thread id: %ld)", - (void*)worker, (long int)worker->pt_id); - int err_num = pthread_kill(worker->pt_id, grpc_wakeup_signal); - if (err_num != 0) { - err = GRPC_OS_ERROR(err_num, "pthread_kill"); - } - } - return err; -} - -/* Return 1 if the pollset has active threads in pollset_work (pollset must - * be locked) */ -static int pollset_has_workers(grpc_pollset* p) { - return p->root_worker.next != &p->root_worker; -} - -static void remove_worker(grpc_pollset* p, grpc_pollset_worker* worker) { - worker->prev->next = worker->next; - worker->next->prev = worker->prev; -} - -static grpc_pollset_worker* pop_front_worker(grpc_pollset* p) { - if (pollset_has_workers(p)) { - grpc_pollset_worker* w = p->root_worker.next; - remove_worker(p, w); - return w; - } else { - return nullptr; - } -} - -static void push_back_worker(grpc_pollset* p, grpc_pollset_worker* worker) { - worker->next = &p->root_worker; - worker->prev = worker->next->prev; - worker->prev->next = worker->next->prev = worker; -} - -static void push_front_worker(grpc_pollset* p, grpc_pollset_worker* worker) { - worker->prev = &p->root_worker; - worker->next = worker->prev->next; - worker->prev->next = worker->next->prev = worker; -} - -/* p->mu must be held before calling this function */ -static grpc_error* pollset_kick(grpc_pollset* p, - grpc_pollset_worker* specific_worker) { - GPR_TIMER_SCOPE("pollset_kick", 0); - grpc_error* error = GRPC_ERROR_NONE; - GRPC_STATS_INC_POLLSET_KICK(); - const char* err_desc = "Kick Failure"; - grpc_pollset_worker* worker = specific_worker; - if (worker != nullptr) { - if (worker == GRPC_POLLSET_KICK_BROADCAST) { - if (pollset_has_workers(p)) { - GPR_TIMER_SCOPE("pollset_kick.broadcast", 0); - for (worker = p->root_worker.next; worker != &p->root_worker; - worker = worker->next) { - if (gpr_tls_get(&g_current_thread_worker) != (intptr_t)worker) { - append_error(&error, pollset_worker_kick(worker), err_desc); - } - } - } else { - p->kicked_without_pollers = true; - } - } else { - GPR_TIMER_MARK("kicked_specifically", 0); - if (gpr_tls_get(&g_current_thread_worker) != (intptr_t)worker) { - append_error(&error, pollset_worker_kick(worker), err_desc); - } - } - } else if (gpr_tls_get(&g_current_thread_pollset) != (intptr_t)p) { - /* Since worker == NULL, it means that we can kick "any" worker on this - pollset 'p'. If 'p' happens to be the same pollset this thread is - currently polling (i.e in pollset_work() function), then there is no need - to kick any other worker since the current thread can just absorb the - kick. This is the reason why we enter this case only when - g_current_thread_pollset is != p */ - - GPR_TIMER_MARK("kick_anonymous", 0); - worker = pop_front_worker(p); - if (worker != nullptr) { - GPR_TIMER_MARK("finally_kick", 0); - push_back_worker(p, worker); - append_error(&error, pollset_worker_kick(worker), err_desc); - } else { - GPR_TIMER_MARK("kicked_no_pollers", 0); - p->kicked_without_pollers = true; - } - } - - GRPC_LOG_IF_ERROR("pollset_kick", GRPC_ERROR_REF(error)); - return error; -} - -static void pollset_init(grpc_pollset* pollset, gpr_mu** mu) { - gpr_mu_init(&pollset->po.mu); - *mu = &pollset->po.mu; - pollset->po.pi = nullptr; -#ifndef NDEBUG - pollset->po.obj_type = POLL_OBJ_POLLSET; -#endif - - pollset->root_worker.next = pollset->root_worker.prev = &pollset->root_worker; - pollset->kicked_without_pollers = false; - - pollset->shutting_down = false; - pollset->finish_shutdown_called = false; - pollset->shutdown_done = nullptr; -} - -static int poll_deadline_to_millis_timeout(grpc_millis millis) { - if (millis == GRPC_MILLIS_INF_FUTURE) return -1; - grpc_millis delta = millis - grpc_core::ExecCtx::Get()->Now(); - if (delta > INT_MAX) - return INT_MAX; - else if (delta < 0) - return 0; - else - return static_cast(delta); -} - -static void pollset_release_polling_island(grpc_pollset* ps, - const char* reason) { - if (ps->po.pi != nullptr) { - PI_UNREF(ps->po.pi, reason); - } - ps->po.pi = nullptr; -} - -static void finish_shutdown_locked(grpc_pollset* pollset) { - /* The pollset cannot have any workers if we are at this stage */ - GPR_ASSERT(!pollset_has_workers(pollset)); - - pollset->finish_shutdown_called = true; - - /* Release the ref and set pollset->po.pi to NULL */ - pollset_release_polling_island(pollset, "ps_shutdown"); - GRPC_CLOSURE_SCHED(pollset->shutdown_done, GRPC_ERROR_NONE); -} - -/* pollset->po.mu lock must be held by the caller before calling this */ -static void pollset_shutdown(grpc_pollset* pollset, grpc_closure* closure) { - GPR_TIMER_SCOPE("pollset_shutdown", 0); - GPR_ASSERT(!pollset->shutting_down); - pollset->shutting_down = true; - pollset->shutdown_done = closure; - pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST); - - /* If the pollset has any workers, we cannot call finish_shutdown_locked() - because it would release the underlying polling island. In such a case, we - let the last worker call finish_shutdown_locked() from pollset_work() */ - if (!pollset_has_workers(pollset)) { - GPR_ASSERT(!pollset->finish_shutdown_called); - GPR_TIMER_MARK("pollset_shutdown.finish_shutdown_locked", 0); - finish_shutdown_locked(pollset); - } -} - -/* pollset_shutdown is guaranteed to be called before pollset_destroy. So other - * than destroying the mutexes, there is nothing special that needs to be done - * here */ -static void pollset_destroy(grpc_pollset* pollset) { - GPR_ASSERT(!pollset_has_workers(pollset)); - gpr_mu_destroy(&pollset->po.mu); -} - -#define GRPC_EPOLL_MAX_EVENTS 100 -/* Note: sig_mask contains the signal mask to use *during* epoll_wait() */ -static void pollset_work_and_unlock(grpc_pollset* pollset, - grpc_pollset_worker* worker, int timeout_ms, - sigset_t* sig_mask, grpc_error** error) { - GPR_TIMER_SCOPE("pollset_work_and_unlock", 0); - struct epoll_event ep_ev[GRPC_EPOLL_MAX_EVENTS]; - int epoll_fd = -1; - int ep_rv; - polling_island* pi = nullptr; - char* err_msg; - const char* err_desc = "pollset_work_and_unlock"; - - /* We need to get the epoll_fd to wait on. The epoll_fd is in inside the - latest polling island pointed by pollset->po.pi - - Since epoll_fd is immutable, we can read it without obtaining the polling - island lock. There is however a possibility that the polling island (from - which we got the epoll_fd) got merged with another island while we are - in this function. This is still okay because in such a case, we will wakeup - right-away from epoll_wait() and pick up the latest polling_island the next - this function (i.e pollset_work_and_unlock()) is called */ - - if (pollset->po.pi == nullptr) { - pollset->po.pi = polling_island_create(nullptr, error); - if (pollset->po.pi == nullptr) { - return; /* Fatal error. We cannot continue */ - } - - PI_ADD_REF(pollset->po.pi, "ps"); - GRPC_POLLING_TRACE("pollset_work: pollset: %p created new pi: %p", - (void*)pollset, (void*)pollset->po.pi); - } - - pi = polling_island_maybe_get_latest(pollset->po.pi); - epoll_fd = pi->epoll_fd; - - /* Update the pollset->po.pi since the island being pointed by - pollset->po.pi maybe older than the one pointed by pi) */ - if (pollset->po.pi != pi) { - /* Always do PI_ADD_REF before PI_UNREF because PI_UNREF may cause the - polling island to be deleted */ - PI_ADD_REF(pi, "ps"); - PI_UNREF(pollset->po.pi, "ps"); - pollset->po.pi = pi; - } - - /* Add an extra ref so that the island does not get destroyed (which means - the epoll_fd won't be closed) while we are are doing an epoll_wait() on the - epoll_fd */ - PI_ADD_REF(pi, "ps_work"); - gpr_mu_unlock(&pollset->po.mu); - - gpr_atm_no_barrier_fetch_add(&pi->poller_count, 1); - g_current_thread_polling_island = pi; - - GRPC_SCHEDULING_START_BLOCKING_REGION; - GRPC_STATS_INC_SYSCALL_POLL(); - ep_rv = - epoll_pwait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, timeout_ms, sig_mask); - GRPC_SCHEDULING_END_BLOCKING_REGION; - if (ep_rv < 0) { - if (errno != EINTR) { - gpr_asprintf(&err_msg, - "epoll_wait() epoll fd: %d failed with error: %d (%s)", - epoll_fd, errno, strerror(errno)); - append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc); - } else { - /* We were interrupted. Save an interation by doing a zero timeout - epoll_wait to see if there are any other events of interest */ - GRPC_POLLING_TRACE("pollset_work: pollset: %p, worker: %p received kick", - (void*)pollset, (void*)worker); - ep_rv = epoll_wait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, 0); - } - } - -#ifdef GRPC_TSAN - /* See the definition of g_poll_sync for more details */ - gpr_atm_acq_load(&g_epoll_sync); -#endif /* defined(GRPC_TSAN) */ - - for (int i = 0; i < ep_rv; ++i) { - void* data_ptr = ep_ev[i].data.ptr; - if (data_ptr == &polling_island_wakeup_fd) { - GRPC_POLLING_TRACE( - "pollset_work: pollset: %p, worker: %p polling island (epoll_fd: " - "%d) got merged", - (void*)pollset, (void*)worker, epoll_fd); - /* This means that our polling island is merged with a different - island. We do not have to do anything here since the subsequent call - to the function pollset_work_and_unlock() will pick up the correct - epoll_fd */ - } else { - grpc_fd* fd = reinterpret_cast( - reinterpret_cast(data_ptr) & ~static_cast(1)); - bool track_err = - reinterpret_cast(data_ptr) & ~static_cast(1); - bool cancel = (ep_ev[i].events & EPOLLHUP) != 0; - bool error = (ep_ev[i].events & EPOLLERR) != 0; - bool read_ev = (ep_ev[i].events & (EPOLLIN | EPOLLPRI)) != 0; - bool write_ev = (ep_ev[i].events & EPOLLOUT) != 0; - bool err_fallback = error && !track_err; - - if (error && !err_fallback) { - fd_has_errors(fd); - } - if (read_ev || cancel || err_fallback) { - fd_become_readable(fd); - } - if (write_ev || cancel || err_fallback) { - fd_become_writable(fd); - } - } - } - - g_current_thread_polling_island = nullptr; - gpr_atm_no_barrier_fetch_add(&pi->poller_count, -1); - - GPR_ASSERT(pi != nullptr); - - /* Before leaving, release the extra ref we added to the polling island. It - is important to use "pi" here (i.e our old copy of pollset->po.pi - that we got before releasing the polling island lock). This is because - pollset->po.pi pointer might get udpated in other parts of the - code when there is an island merge while we are doing epoll_wait() above */ - PI_UNREF(pi, "ps_work"); -} - -/* pollset->po.mu lock must be held by the caller before calling this. - The function pollset_work() may temporarily release the lock (pollset->po.mu) - during the course of its execution but it will always re-acquire the lock and - ensure that it is held by the time the function returns */ -static grpc_error* pollset_work(grpc_pollset* pollset, - grpc_pollset_worker** worker_hdl, - grpc_millis deadline) { - GPR_TIMER_SCOPE("pollset_work", 0); - grpc_error* error = GRPC_ERROR_NONE; - int timeout_ms = poll_deadline_to_millis_timeout(deadline); - - sigset_t new_mask; - - grpc_pollset_worker worker; - worker.next = worker.prev = nullptr; - worker.pt_id = pthread_self(); - gpr_atm_no_barrier_store(&worker.is_kicked, (gpr_atm)0); - - if (worker_hdl) *worker_hdl = &worker; - - gpr_tls_set(&g_current_thread_pollset, (intptr_t)pollset); - gpr_tls_set(&g_current_thread_worker, (intptr_t)&worker); - - if (pollset->kicked_without_pollers) { - /* If the pollset was kicked without pollers, pretend that the current - worker got the kick and skip polling. A kick indicates that there is some - work that needs attention like an event on the completion queue or an - alarm */ - GPR_TIMER_MARK("pollset_work.kicked_without_pollers", 0); - pollset->kicked_without_pollers = 0; - } else if (!pollset->shutting_down) { - /* We use the posix-signal with number 'grpc_wakeup_signal' for waking up - (i.e 'kicking') a worker in the pollset. A 'kick' is a way to inform the - worker that there is some pending work that needs immediate attention - (like an event on the completion queue, or a polling island merge that - results in a new epoll-fd to wait on) and that the worker should not - spend time waiting in epoll_pwait(). - - A worker can be kicked anytime from the point it is added to the pollset - via push_front_worker() (or push_back_worker()) to the point it is - removed via remove_worker(). - If the worker is kicked before/during it calls epoll_pwait(), it should - immediately exit from epoll_wait(). If the worker is kicked after it - returns from epoll_wait(), then nothing really needs to be done. - - To accomplish this, we mask 'grpc_wakeup_signal' on this thread at all - times *except* when it is in epoll_pwait(). This way, the worker never - misses acting on a kick */ - - if (!g_initialized_sigmask) { - sigemptyset(&new_mask); - sigaddset(&new_mask, grpc_wakeup_signal); - pthread_sigmask(SIG_BLOCK, &new_mask, &g_orig_sigmask); - sigdelset(&g_orig_sigmask, grpc_wakeup_signal); - g_initialized_sigmask = true; - /* new_mask: The new thread mask which blocks 'grpc_wakeup_signal'. - This is the mask used at all times *except during - epoll_wait()*" - g_orig_sigmask: The thread mask which allows 'grpc_wakeup_signal' and - this is the mask to use *during epoll_wait()* - - The new_mask is set on the worker before it is added to the pollset - (i.e before it can be kicked) */ - } - - push_front_worker(pollset, &worker); /* Add worker to pollset */ - - pollset_work_and_unlock(pollset, &worker, timeout_ms, &g_orig_sigmask, - &error); - grpc_core::ExecCtx::Get()->Flush(); - - gpr_mu_lock(&pollset->po.mu); - - /* Note: There is no need to reset worker.is_kicked to 0 since we are no - longer going to use this worker */ - remove_worker(pollset, &worker); - } - - /* If we are the last worker on the pollset (i.e pollset_has_workers() is - false at this point) and the pollset is shutting down, we may have to - finish the shutdown process by calling finish_shutdown_locked(). - See pollset_shutdown() for more details. - - Note: Continuing to access pollset here is safe; it is the caller's - responsibility to not destroy a pollset when it has outstanding calls to - pollset_work() */ - if (pollset->shutting_down && !pollset_has_workers(pollset) && - !pollset->finish_shutdown_called) { - GPR_TIMER_MARK("pollset_work.finish_shutdown_locked", 0); - finish_shutdown_locked(pollset); - - gpr_mu_unlock(&pollset->po.mu); - grpc_core::ExecCtx::Get()->Flush(); - gpr_mu_lock(&pollset->po.mu); - } - - if (worker_hdl) *worker_hdl = nullptr; - - gpr_tls_set(&g_current_thread_pollset, (intptr_t)0); - gpr_tls_set(&g_current_thread_worker, (intptr_t)0); - - GRPC_LOG_IF_ERROR("pollset_work", GRPC_ERROR_REF(error)); - return error; -} - -static void add_poll_object(poll_obj* bag, poll_obj_type bag_type, - poll_obj* item, poll_obj_type item_type) { - GPR_TIMER_SCOPE("add_poll_object", 0); - -#ifndef NDEBUG - GPR_ASSERT(item->obj_type == item_type); - GPR_ASSERT(bag->obj_type == bag_type); -#endif - - grpc_error* error = GRPC_ERROR_NONE; - polling_island* pi_new = nullptr; - - gpr_mu_lock(&bag->mu); - gpr_mu_lock(&item->mu); - -retry: - /* - * 1) If item->pi and bag->pi are both non-NULL and equal, do nothing - * 2) If item->pi and bag->pi are both NULL, create a new polling island (with - * a refcount of 2) and point item->pi and bag->pi to the new island - * 3) If exactly one of item->pi or bag->pi is NULL, update it to point to - * the other's non-NULL pi - * 4) Finally if item->pi and bag-pi are non-NULL and not-equal, merge the - * polling islands and update item->pi and bag->pi to point to the new - * island - */ - - /* Early out if we are trying to add an 'fd' to a 'bag' but the fd is already - * orphaned */ - if (item_type == POLL_OBJ_FD && (FD_FROM_PO(item))->orphaned) { - gpr_mu_unlock(&item->mu); - gpr_mu_unlock(&bag->mu); - return; - } - - if (item->pi == bag->pi) { - pi_new = item->pi; - if (pi_new == nullptr) { - /* GPR_ASSERT(item->pi == bag->pi == NULL) */ - - /* If we are adding an fd to a bag (i.e pollset or pollset_set), then - * we need to do some extra work to make TSAN happy */ - if (item_type == POLL_OBJ_FD) { - /* Unlock before creating a new polling island: the polling island will - create a workqueue which creates a file descriptor, and holding an fd - lock here can eventually cause a loop to appear to TSAN (making it - unhappy). We don't think it's a real loop (there's an epoch point - where that loop possibility disappears), but the advantages of - keeping TSAN happy outweigh any performance advantage we might have - by keeping the lock held. */ - gpr_mu_unlock(&item->mu); - pi_new = polling_island_create(FD_FROM_PO(item), &error); - gpr_mu_lock(&item->mu); - - /* Need to reverify any assumptions made between the initial lock and - getting to this branch: if they've changed, we need to throw away our - work and figure things out again. */ - if (item->pi != nullptr) { - GRPC_POLLING_TRACE( - "add_poll_object: Raced creating new polling island. pi_new: %p " - "(fd: %d, %s: %p)", - (void*)pi_new, FD_FROM_PO(item)->fd, poll_obj_string(bag_type), - (void*)bag); - /* No need to lock 'pi_new' here since this is a new polling island - and no one has a reference to it yet */ - polling_island_remove_all_fds_locked(pi_new, true, &error); - - /* Ref and unref so that the polling island gets deleted during unref - */ - PI_ADD_REF(pi_new, "dance_of_destruction"); - PI_UNREF(pi_new, "dance_of_destruction"); - goto retry; - } - } else { - pi_new = polling_island_create(nullptr, &error); - } - - GRPC_POLLING_TRACE( - "add_poll_object: Created new polling island. pi_new: %p (%s: %p, " - "%s: %p)", - (void*)pi_new, poll_obj_string(item_type), (void*)item, - poll_obj_string(bag_type), (void*)bag); - } else { - GRPC_POLLING_TRACE( - "add_poll_object: Same polling island. pi: %p (%s, %s)", - (void*)pi_new, poll_obj_string(item_type), poll_obj_string(bag_type)); - } - } else if (item->pi == nullptr) { - /* GPR_ASSERT(bag->pi != NULL) */ - /* Make pi_new point to latest pi*/ - pi_new = polling_island_lock(bag->pi); - - if (item_type == POLL_OBJ_FD) { - grpc_fd* fd = FD_FROM_PO(item); - polling_island_add_fds_locked(pi_new, &fd, 1, true, &error); - } - - gpr_mu_unlock(&pi_new->mu); - GRPC_POLLING_TRACE( - "add_poll_obj: item->pi was NULL. pi_new: %p (item(%s): %p, " - "bag(%s): %p)", - (void*)pi_new, poll_obj_string(item_type), (void*)item, - poll_obj_string(bag_type), (void*)bag); - } else if (bag->pi == nullptr) { - /* GPR_ASSERT(item->pi != NULL) */ - /* Make pi_new to point to latest pi */ - pi_new = polling_island_lock(item->pi); - gpr_mu_unlock(&pi_new->mu); - GRPC_POLLING_TRACE( - "add_poll_obj: bag->pi was NULL. pi_new: %p (item(%s): %p, " - "bag(%s): %p)", - (void*)pi_new, poll_obj_string(item_type), (void*)item, - poll_obj_string(bag_type), (void*)bag); - } else { - pi_new = polling_island_merge(item->pi, bag->pi, &error); - GRPC_POLLING_TRACE( - "add_poll_obj: polling islands merged. pi_new: %p (item(%s): %p, " - "bag(%s): %p)", - (void*)pi_new, poll_obj_string(item_type), (void*)item, - poll_obj_string(bag_type), (void*)bag); - } - - /* At this point, pi_new is the polling island that both item->pi and bag->pi - MUST be pointing to */ - - if (item->pi != pi_new) { - PI_ADD_REF(pi_new, poll_obj_string(item_type)); - if (item->pi != nullptr) { - PI_UNREF(item->pi, poll_obj_string(item_type)); - } - item->pi = pi_new; - } - - if (bag->pi != pi_new) { - PI_ADD_REF(pi_new, poll_obj_string(bag_type)); - if (bag->pi != nullptr) { - PI_UNREF(bag->pi, poll_obj_string(bag_type)); - } - bag->pi = pi_new; - } - - gpr_mu_unlock(&item->mu); - gpr_mu_unlock(&bag->mu); - - GRPC_LOG_IF_ERROR("add_poll_object", error); -} - -static void pollset_add_fd(grpc_pollset* pollset, grpc_fd* fd) { - add_poll_object(&pollset->po, POLL_OBJ_POLLSET, &fd->po, POLL_OBJ_FD); -} - -/******************************************************************************* - * Pollset-set Definitions - */ - -static grpc_pollset_set* pollset_set_create(void) { - grpc_pollset_set* pss = - static_cast(gpr_malloc(sizeof(*pss))); - gpr_mu_init(&pss->po.mu); - pss->po.pi = nullptr; -#ifndef NDEBUG - pss->po.obj_type = POLL_OBJ_POLLSET_SET; -#endif - return pss; -} - -static void pollset_set_destroy(grpc_pollset_set* pss) { - gpr_mu_destroy(&pss->po.mu); - - if (pss->po.pi != nullptr) { - PI_UNREF(pss->po.pi, "pss_destroy"); - } - - gpr_free(pss); -} - -static void pollset_set_add_fd(grpc_pollset_set* pss, grpc_fd* fd) { - add_poll_object(&pss->po, POLL_OBJ_POLLSET_SET, &fd->po, POLL_OBJ_FD); -} - -static void pollset_set_del_fd(grpc_pollset_set* pss, grpc_fd* fd) { - /* Nothing to do */ -} - -static void pollset_set_add_pollset(grpc_pollset_set* pss, grpc_pollset* ps) { - add_poll_object(&pss->po, POLL_OBJ_POLLSET_SET, &ps->po, POLL_OBJ_POLLSET); -} - -static void pollset_set_del_pollset(grpc_pollset_set* pss, grpc_pollset* ps) { - /* Nothing to do */ -} - -static void pollset_set_add_pollset_set(grpc_pollset_set* bag, - grpc_pollset_set* item) { - add_poll_object(&bag->po, POLL_OBJ_POLLSET_SET, &item->po, - POLL_OBJ_POLLSET_SET); -} - -static void pollset_set_del_pollset_set(grpc_pollset_set* bag, - grpc_pollset_set* item) { - /* Nothing to do */ -} - -/* Test helper functions - * */ -void* grpc_fd_get_polling_island(grpc_fd* fd) { - polling_island* pi; - - gpr_mu_lock(&fd->po.mu); - pi = fd->po.pi; - gpr_mu_unlock(&fd->po.mu); - - return pi; -} - -void* grpc_pollset_get_polling_island(grpc_pollset* ps) { - polling_island* pi; - - gpr_mu_lock(&ps->po.mu); - pi = ps->po.pi; - gpr_mu_unlock(&ps->po.mu); - - return pi; -} - -bool grpc_are_polling_islands_equal(void* p, void* q) { - polling_island* p1 = static_cast(p); - polling_island* p2 = static_cast(q); - - /* Note: polling_island_lock_pair() may change p1 and p2 to point to the - latest polling islands in their respective linked lists */ - polling_island_lock_pair(&p1, &p2); - polling_island_unlock_pair(p1, p2); - - return p1 == p2; -} - -/******************************************************************************* - * Event engine binding - */ - -static void shutdown_engine(void) { - fd_global_shutdown(); - pollset_global_shutdown(); - polling_island_global_shutdown(); -} - -static const grpc_event_engine_vtable vtable = { - sizeof(grpc_pollset), - true, - - fd_create, - fd_wrapped_fd, - fd_orphan, - fd_shutdown, - fd_notify_on_read, - fd_notify_on_write, - fd_notify_on_error, - fd_become_readable, - fd_become_writable, - fd_has_errors, - fd_is_shutdown, - - pollset_init, - pollset_shutdown, - pollset_destroy, - pollset_work, - pollset_kick, - pollset_add_fd, - - pollset_set_create, - pollset_set_destroy, - pollset_set_add_pollset, - pollset_set_del_pollset, - pollset_set_add_pollset_set, - pollset_set_del_pollset_set, - pollset_set_add_fd, - pollset_set_del_fd, - - shutdown_engine, -}; - -/* It is possible that GLIBC has epoll but the underlying kernel doesn't. - * Create a dummy epoll_fd to make sure epoll support is available */ -static bool is_epoll_available() { - int fd = epoll_create1(EPOLL_CLOEXEC); - if (fd < 0) { - gpr_log( - GPR_ERROR, - "epoll_create1 failed with error: %d. Not using epoll polling engine", - fd); - return false; - } - close(fd); - return true; -} - -const grpc_event_engine_vtable* grpc_init_epollsig_linux( - bool explicit_request) { - /* If use of signals is disabled, we cannot use epoll engine*/ - if (is_grpc_wakeup_signal_initialized && grpc_wakeup_signal < 0) { - gpr_log(GPR_ERROR, "Skipping epollsig because use of signals is disabled."); - return nullptr; - } - - if (!grpc_has_wakeup_fd()) { - gpr_log(GPR_ERROR, "Skipping epollsig because of no wakeup fd."); - return nullptr; - } - - if (!is_epoll_available()) { - gpr_log(GPR_ERROR, "Skipping epollsig because epoll is unavailable."); - return nullptr; - } - - if (!is_grpc_wakeup_signal_initialized) { - if (explicit_request) { - grpc_use_signal(SIGRTMIN + 6); - } else { - gpr_log(GPR_ERROR, - "Skipping epollsig because uninitialized wakeup signal."); - return nullptr; - } - } - - fd_global_init(); - - if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) { - return nullptr; - } - - if (!GRPC_LOG_IF_ERROR("polling_island_global_init", - polling_island_global_init())) { - return nullptr; - } - - return &vtable; -} - -#else /* defined(GRPC_LINUX_EPOLL_CREATE1) */ -#if defined(GRPC_POSIX_SOCKET_EV_EPOLLSIG) -#include "src/core/lib/iomgr/ev_epollsig_linux.h" -/* If GRPC_LINUX_EPOLL_CREATE1 is not defined, it means - epoll_create1 is not available. Return NULL */ -const grpc_event_engine_vtable* grpc_init_epollsig_linux( - bool explicit_request) { - return nullptr; -} -#endif /* defined(GRPC_POSIX_SOCKET) */ - -void grpc_use_signal(int signum) {} -#endif /* !defined(GRPC_LINUX_EPOLL_CREATE1) */ diff --git a/src/core/lib/iomgr/ev_epollsig_linux.h b/src/core/lib/iomgr/ev_epollsig_linux.h deleted file mode 100644 index 2ba2f0a63b4..00000000000 --- a/src/core/lib/iomgr/ev_epollsig_linux.h +++ /dev/null @@ -1,35 +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_IOMGR_EV_EPOLLSIG_LINUX_H -#define GRPC_CORE_LIB_IOMGR_EV_EPOLLSIG_LINUX_H - -#include - -#include "src/core/lib/iomgr/ev_posix.h" -#include "src/core/lib/iomgr/port.h" - -const grpc_event_engine_vtable* grpc_init_epollsig_linux(bool explicit_request); - -#ifdef GRPC_LINUX_EPOLL_CREATE1 -void* grpc_fd_get_polling_island(grpc_fd* fd); -void* grpc_pollset_get_polling_island(grpc_pollset* ps); -bool grpc_are_polling_islands_equal(void* p, void* q); -#endif /* defined(GRPC_LINUX_EPOLL_CREATE1) */ - -#endif /* GRPC_CORE_LIB_IOMGR_EV_EPOLLSIG_LINUX_H */ diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index d4377e2d504..8a7dc7b004a 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -35,7 +35,6 @@ #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/ev_epoll1_linux.h" #include "src/core/lib/iomgr/ev_epollex_linux.h" -#include "src/core/lib/iomgr/ev_epollsig_linux.h" #include "src/core/lib/iomgr/ev_poll_posix.h" grpc_core::TraceFlag grpc_polling_trace(false, @@ -123,13 +122,13 @@ const grpc_event_engine_vtable* init_non_polling(bool explicit_request) { // environment variable if that variable is set (which should be a // comma-separated list of one or more event engine names) static event_engine_factory g_factories[] = { - {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, - {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, - {"epollex", grpc_init_epollex_linux}, {"epoll1", grpc_init_epoll1_linux}, - {"epollsig", grpc_init_epollsig_linux}, {"poll", grpc_init_poll_posix}, - {"poll-cv", grpc_init_poll_cv_posix}, {"none", init_non_polling}, - {ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr}, - {ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr}, + {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, + {ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr}, + {"epollex", grpc_init_epollex_linux}, {"epoll1", grpc_init_epoll1_linux}, + {"poll", grpc_init_poll_posix}, {"poll-cv", grpc_init_poll_cv_posix}, + {"none", init_non_polling}, {ENGINE_TAIL_CUSTOM, nullptr}, + {ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr}, + {ENGINE_TAIL_CUSTOM, nullptr}, }; static void add(const char* beg, const char* end, char*** ss, size_t* ns) { diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h index 3d459059d71..c8046b21dcd 100644 --- a/src/core/lib/iomgr/port.h +++ b/src/core/lib/iomgr/port.h @@ -115,7 +115,6 @@ #define GRPC_POSIX_SOCKET_EV 1 #define GRPC_POSIX_SOCKET_EV_EPOLL1 1 #define GRPC_POSIX_SOCKET_EV_EPOLLEX 1 -#define GRPC_POSIX_SOCKET_EV_EPOLLSIG 1 #define GRPC_POSIX_SOCKET_EV_POLL 1 #define GRPC_POSIX_SOCKET_RESOLVE_ADDRESS 1 #define GRPC_POSIX_SOCKET_SOCKADDR 1 @@ -183,7 +182,6 @@ #define GRPC_POSIX_SOCKET_ARES_EV_DRIVER 1 #define GRPC_POSIX_SOCKET_EV 1 #define GRPC_POSIX_SOCKET_EV_EPOLLEX 1 -#define GRPC_POSIX_SOCKET_EV_EPOLLSIG 1 #define GRPC_POSIX_SOCKET_EV_POLL 1 #define GRPC_POSIX_SOCKET_EV_EPOLL1 1 #define GRPC_POSIX_SOCKET_IOMGR 1 diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index ceacc83e626..3ad82e9cadc 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -92,7 +92,6 @@ CORE_SOURCE_FILES = [ 'src/core/lib/iomgr/error.cc', 'src/core/lib/iomgr/ev_epoll1_linux.cc', 'src/core/lib/iomgr/ev_epollex_linux.cc', - 'src/core/lib/iomgr/ev_epollsig_linux.cc', 'src/core/lib/iomgr/ev_poll_posix.cc', 'src/core/lib/iomgr/ev_posix.cc', 'src/core/lib/iomgr/ev_windows.cc', diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index db2886d8e34..55451887203 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -POLLERS = ['epollex', 'epollsig', 'epoll1', 'poll', 'poll-cv'] +POLLERS = ['epollex', 'epoll1', 'poll', 'poll-cv'] load("//bazel:grpc_build_system.bzl", "grpc_sh_test", "grpc_cc_binary", "grpc_cc_library") diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index 7754bc49708..70ee83acd23 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -40,6 +40,7 @@ grpc_cc_library( grpc_cc_test( name = "combiner_test", srcs = ["combiner_test.cc"], + data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"], language = "C++", deps = [ "//:gpr", @@ -47,7 +48,6 @@ grpc_cc_test( "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"], ) grpc_cc_test( @@ -88,18 +88,6 @@ grpc_cc_test( ], ) -grpc_cc_test( - name = "ev_epollsig_linux_test", - srcs = ["ev_epollsig_linux_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//:grpc", - "//test/core/util:gpr_test_util", - "//test/core/util:grpc_test_util", - ], -) - grpc_cc_test( name = "fd_conservation_posix_test", srcs = ["fd_conservation_posix_test.cc"], @@ -136,7 +124,6 @@ grpc_cc_test( ], ) - grpc_cc_test( name = "load_file_test", srcs = ["load_file_test.cc"], @@ -149,18 +136,6 @@ grpc_cc_test( ], ) -grpc_cc_test( - name = "pollset_set_test", - srcs = ["pollset_set_test.cc"], - language = "C++", - deps = [ - "//:gpr", - "//:grpc", - "//test/core/util:gpr_test_util", - "//test/core/util:grpc_test_util", - ], -) - grpc_cc_test( name = "resolve_address_posix_test", srcs = ["resolve_address_posix_test.cc"], @@ -176,10 +151,10 @@ grpc_cc_test( grpc_cc_test( name = "resolve_address_using_ares_resolver_test", srcs = ["resolve_address_test.cc"], - language = "C++", args = [ "--resolver=ares", ], + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -191,10 +166,10 @@ grpc_cc_test( grpc_cc_test( name = "resolve_address_using_native_resolver_test", srcs = ["resolve_address_test.cc"], - language = "C++", args = [ "--resolver=native", ], + language = "C++", deps = [ "//:gpr", "//:grpc", @@ -276,7 +251,6 @@ grpc_cc_test( ], ) - grpc_cc_test( name = "tcp_server_posix_test", srcs = ["tcp_server_posix_test.cc"], diff --git a/test/core/iomgr/ev_epollsig_linux_test.cc b/test/core/iomgr/ev_epollsig_linux_test.cc deleted file mode 100644 index 28c9dd408ce..00000000000 --- a/test/core/iomgr/ev_epollsig_linux_test.cc +++ /dev/null @@ -1,321 +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. - * - */ -#include "src/core/lib/iomgr/port.h" - -/* This test only relevant on linux systems where epoll() is available */ -#ifdef GRPC_LINUX_EPOLL_CREATE1 -#include "src/core/lib/iomgr/ev_epollsig_linux.h" -#include "src/core/lib/iomgr/ev_posix.h" - -#include -#include -#include - -#include -#include -#include - -#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" - -typedef struct test_pollset { - grpc_pollset* pollset; - gpr_mu* mu; -} test_pollset; - -typedef struct test_fd { - int inner_fd; - grpc_fd* fd; -} test_fd; - -/* num_fds should be an even number */ -static void test_fd_init(test_fd* tfds, int* fds, int num_fds) { - int i; - int r; - - /* Create some dummy file descriptors. Currently using pipe file descriptors - * for this test but we could use any other type of file descriptors. Also, - * since pipe() used in this test creates two fds in each call, num_fds should - * be an even number */ - GPR_ASSERT((num_fds % 2) == 0); - for (i = 0; i < num_fds; i = i + 2) { - r = pipe(fds + i); - if (r != 0) { - gpr_log(GPR_ERROR, "Error in creating pipe. %d (%s)", errno, - strerror(errno)); - return; - } - } - - for (i = 0; i < num_fds; i++) { - tfds[i].inner_fd = fds[i]; - tfds[i].fd = grpc_fd_create(fds[i], "test_fd", false); - } -} - -static void test_fd_cleanup(test_fd* tfds, int num_fds) { - int release_fd; - int i; - - for (i = 0; i < num_fds; i++) { - grpc_fd_shutdown(tfds[i].fd, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("test_fd_cleanup")); - grpc_core::ExecCtx::Get()->Flush(); - - grpc_fd_orphan(tfds[i].fd, nullptr, &release_fd, "test_fd_cleanup"); - grpc_core::ExecCtx::Get()->Flush(); - - GPR_ASSERT(release_fd == tfds[i].inner_fd); - close(tfds[i].inner_fd); - } -} - -static void test_pollset_init(test_pollset* pollsets, int num_pollsets) { - int i; - for (i = 0; i < num_pollsets; i++) { - pollsets[i].pollset = - static_cast(gpr_zalloc(grpc_pollset_size())); - grpc_pollset_init(pollsets[i].pollset, &pollsets[i].mu); - } -} - -static void destroy_pollset(void* p, grpc_error* error) { - grpc_pollset_destroy(static_cast(p)); -} - -static void test_pollset_cleanup(test_pollset* pollsets, int num_pollsets) { - grpc_closure destroyed; - int i; - - for (i = 0; i < num_pollsets; i++) { - GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, pollsets[i].pollset, - grpc_schedule_on_exec_ctx); - grpc_pollset_shutdown(pollsets[i].pollset, &destroyed); - - grpc_core::ExecCtx::Get()->Flush(); - gpr_free(pollsets[i].pollset); - } -} - - /* - * Cases to test: - * case 1) Polling islands of both fd and pollset are NULL - * case 2) Polling island of fd is NULL but that of pollset is not-NULL - * case 3) Polling island of fd is not-NULL but that of pollset is NULL - * case 4) Polling islands of both fd and pollset are not-NULL and: - * case 4.1) Polling islands of fd and pollset are equal - * case 4.2) Polling islands of fd and pollset are NOT-equal (This results - * in a merge) - * */ - -#define NUM_FDS 8 -#define NUM_POLLSETS 4 - -static void test_add_fd_to_pollset() { - grpc_core::ExecCtx exec_ctx; - test_fd tfds[NUM_FDS]; - int fds[NUM_FDS]; - test_pollset pollsets[NUM_POLLSETS]; - void* expected_pi = nullptr; - int i; - - test_fd_init(tfds, fds, NUM_FDS); - test_pollset_init(pollsets, NUM_POLLSETS); - - /*Step 1. - * Create three polling islands (This will exercise test case 1 and 2) with - * the following configuration: - * polling island 0 = { fds:0,1,2, pollsets:0} - * polling island 1 = { fds:3,4, pollsets:1} - * polling island 2 = { fds:5,6,7 pollsets:2} - * - *Step 2. - * Add pollset 3 to polling island 0 (by adding fds 0 and 1 to pollset 3) - * (This will exercise test cases 3 and 4.1). The configuration becomes: - * polling island 0 = { fds:0,1,2, pollsets:0,3} <<< pollset 3 added here - * polling island 1 = { fds:3,4, pollsets:1} - * polling island 2 = { fds:5,6,7 pollsets:2} - * - *Step 3. - * Merge polling islands 0 and 1 by adding fd 0 to pollset 1 (This will - * exercise test case 4.2). The configuration becomes: - * polling island (merged) = {fds: 0,1,2,3,4, pollsets: 0,1,3} - * polling island 2 = {fds: 5,6,7 pollsets: 2} - * - *Step 4. - * Finally do one more merge by adding fd 3 to pollset 2. - * polling island (merged) = {fds: 0,1,2,3,4,5,6,7, pollsets: 0,1,2,3} - */ - - /* == Step 1 == */ - for (i = 0; i <= 2; i++) { - grpc_pollset_add_fd(pollsets[0].pollset, tfds[i].fd); - grpc_core::ExecCtx::Get()->Flush(); - } - - for (i = 3; i <= 4; i++) { - grpc_pollset_add_fd(pollsets[1].pollset, tfds[i].fd); - grpc_core::ExecCtx::Get()->Flush(); - } - - for (i = 5; i <= 7; i++) { - grpc_pollset_add_fd(pollsets[2].pollset, tfds[i].fd); - grpc_core::ExecCtx::Get()->Flush(); - } - - /* == Step 2 == */ - for (i = 0; i <= 1; i++) { - grpc_pollset_add_fd(pollsets[3].pollset, tfds[i].fd); - grpc_core::ExecCtx::Get()->Flush(); - } - - /* == Step 3 == */ - grpc_pollset_add_fd(pollsets[1].pollset, tfds[0].fd); - grpc_core::ExecCtx::Get()->Flush(); - - /* == Step 4 == */ - grpc_pollset_add_fd(pollsets[2].pollset, tfds[3].fd); - grpc_core::ExecCtx::Get()->Flush(); - - /* All polling islands are merged at this point */ - - /* Compare Fd:0's polling island with that of all other Fds */ - expected_pi = grpc_fd_get_polling_island(tfds[0].fd); - for (i = 1; i < NUM_FDS; i++) { - GPR_ASSERT(grpc_are_polling_islands_equal( - expected_pi, grpc_fd_get_polling_island(tfds[i].fd))); - } - - /* Compare Fd:0's polling island with that of all other pollsets */ - for (i = 0; i < NUM_POLLSETS; i++) { - GPR_ASSERT(grpc_are_polling_islands_equal( - expected_pi, grpc_pollset_get_polling_island(pollsets[i].pollset))); - } - - test_fd_cleanup(tfds, NUM_FDS); - test_pollset_cleanup(pollsets, NUM_POLLSETS); -} - -#undef NUM_FDS -#undef NUM_POLLSETS - -typedef struct threading_shared { - gpr_mu* mu; - grpc_pollset* pollset; - grpc_wakeup_fd* wakeup_fd; - grpc_fd* wakeup_desc; - grpc_closure on_wakeup; - int wakeups; -} threading_shared; - -static __thread int thread_wakeups = 0; - -static void test_threading_loop(void* arg) { - threading_shared* shared = static_cast(arg); - while (thread_wakeups < 1000000) { - grpc_core::ExecCtx exec_ctx; - grpc_pollset_worker* worker; - gpr_mu_lock(shared->mu); - GPR_ASSERT(GRPC_LOG_IF_ERROR( - "pollset_work", - grpc_pollset_work(shared->pollset, &worker, GRPC_MILLIS_INF_FUTURE))); - gpr_mu_unlock(shared->mu); - } -} - -static void test_threading_wakeup(void* arg, grpc_error* error) { - threading_shared* shared = static_cast(arg); - ++shared->wakeups; - ++thread_wakeups; - if (error == GRPC_ERROR_NONE) { - GPR_ASSERT(GRPC_LOG_IF_ERROR( - "consume_wakeup", grpc_wakeup_fd_consume_wakeup(shared->wakeup_fd))); - grpc_fd_notify_on_read(shared->wakeup_desc, &shared->on_wakeup); - GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_next", - grpc_wakeup_fd_wakeup(shared->wakeup_fd))); - } -} - -static void test_threading(void) { - threading_shared shared; - shared.pollset = static_cast(gpr_zalloc(grpc_pollset_size())); - grpc_pollset_init(shared.pollset, &shared.mu); - - 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))); - shared.wakeup_fd = &fd; - shared.wakeup_desc = grpc_fd_create(fd.read_fd, "wakeup", false); - shared.wakeups = 0; - { - grpc_core::ExecCtx exec_ctx; - grpc_pollset_add_fd(shared.pollset, shared.wakeup_desc); - grpc_fd_notify_on_read( - shared.wakeup_desc, - GRPC_CLOSURE_INIT(&shared.on_wakeup, test_threading_wakeup, &shared, - grpc_schedule_on_exec_ctx)); - } - GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_first", - grpc_wakeup_fd_wakeup(shared.wakeup_fd))); - for (auto& th : thds) { - th.Join(); - } - fd.read_fd = 0; - grpc_wakeup_fd_destroy(&fd); - { - grpc_core::ExecCtx exec_ctx; - grpc_fd_shutdown(shared.wakeup_desc, GRPC_ERROR_CANCELLED); - grpc_fd_orphan(shared.wakeup_desc, nullptr, nullptr, "done"); - grpc_pollset_shutdown(shared.pollset, - GRPC_CLOSURE_CREATE(destroy_pollset, shared.pollset, - grpc_schedule_on_exec_ctx)); - } - gpr_free(shared.pollset); -} - -int main(int argc, char** argv) { - const char* poll_strategy = nullptr; - grpc_test_init(argc, argv); - grpc_init(); - { - grpc_core::ExecCtx exec_ctx; - - poll_strategy = grpc_get_poll_strategy_name(); - if (poll_strategy != nullptr && strcmp(poll_strategy, "epollsig") == 0) { - test_add_fd_to_pollset(); - test_threading(); - } else { - gpr_log(GPR_INFO, - "Skipping the test. The test is only relevant for 'epollsig' " - "strategy. and the current strategy is: '%s'", - poll_strategy); - } - } - - grpc_shutdown(); - return 0; -} -#else /* defined(GRPC_LINUX_EPOLL_CREATE1) */ -int main(int argc, char** argv) { return 0; } -#endif /* !defined(GRPC_LINUX_EPOLL_CREATE1) */ diff --git a/test/core/iomgr/pollset_set_test.cc b/test/core/iomgr/pollset_set_test.cc deleted file mode 100644 index 1aae1daa026..00000000000 --- a/test/core/iomgr/pollset_set_test.cc +++ /dev/null @@ -1,447 +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/iomgr/port.h" - -/* This test only relevant on linux systems where epoll is available */ -#ifdef GRPC_LINUX_EPOLL_CREATE1 - -#include -#include -#include - -#include -#include -#include - -#include "src/core/lib/gpr/useful.h" -#include "src/core/lib/iomgr/ev_posix.h" -#include "src/core/lib/iomgr/iomgr.h" -#include "test/core/util/test_config.h" - -/******************************************************************************* - * test_pollset_set - */ - -typedef struct test_pollset_set { - grpc_pollset_set* pss; -} test_pollset_set; - -void init_test_pollset_sets(test_pollset_set* pollset_sets, const int num_pss) { - for (int i = 0; i < num_pss; i++) { - pollset_sets[i].pss = grpc_pollset_set_create(); - } -} - -void cleanup_test_pollset_sets(test_pollset_set* pollset_sets, - const int num_pss) { - for (int i = 0; i < num_pss; i++) { - grpc_pollset_set_destroy(pollset_sets[i].pss); - pollset_sets[i].pss = nullptr; - } -} - -/******************************************************************************* - * test_pollset - */ - -typedef struct test_pollset { - grpc_pollset* ps; - gpr_mu* mu; -} test_pollset; - -static void init_test_pollsets(test_pollset* pollsets, const int num_pollsets) { - for (int i = 0; i < num_pollsets; i++) { - pollsets[i].ps = - static_cast(gpr_zalloc(grpc_pollset_size())); - grpc_pollset_init(pollsets[i].ps, &pollsets[i].mu); - } -} - -static void destroy_pollset(void* p, grpc_error* error) { - grpc_pollset_destroy(static_cast(p)); -} - -static void cleanup_test_pollsets(test_pollset* pollsets, - const int num_pollsets) { - grpc_closure destroyed; - for (int i = 0; i < num_pollsets; i++) { - GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, pollsets[i].ps, - grpc_schedule_on_exec_ctx); - grpc_pollset_shutdown(pollsets[i].ps, &destroyed); - - grpc_core::ExecCtx::Get()->Flush(); - gpr_free(pollsets[i].ps); - pollsets[i].ps = nullptr; - } -} - -/******************************************************************************* - * test_fd - */ - -typedef struct test_fd { - grpc_fd* fd; - grpc_wakeup_fd wakeup_fd; - - bool is_on_readable_called; /* Is on_readable closure is called ? */ - grpc_closure on_readable; /* Closure to call when this fd is readable */ -} test_fd; - -void on_readable(void* tfd, grpc_error* error) { - (static_cast(tfd))->is_on_readable_called = true; -} - -static void reset_test_fd(test_fd* tfd) { - tfd->is_on_readable_called = false; - - GRPC_CLOSURE_INIT(&tfd->on_readable, on_readable, tfd, - grpc_schedule_on_exec_ctx); - grpc_fd_notify_on_read(tfd->fd, &tfd->on_readable); -} - -static void init_test_fds(test_fd* tfds, const int num_fds) { - for (int i = 0; i < num_fds; i++) { - GPR_ASSERT(GRPC_ERROR_NONE == grpc_wakeup_fd_init(&tfds[i].wakeup_fd)); - tfds[i].fd = grpc_fd_create(GRPC_WAKEUP_FD_GET_READ_FD(&tfds[i].wakeup_fd), - "test_fd", false); - reset_test_fd(&tfds[i]); - } -} - -static void cleanup_test_fds(test_fd* tfds, const int num_fds) { - int release_fd; - - for (int i = 0; i < num_fds; i++) { - grpc_fd_shutdown(tfds[i].fd, - GRPC_ERROR_CREATE_FROM_STATIC_STRING("fd cleanup")); - grpc_core::ExecCtx::Get()->Flush(); - - /* grpc_fd_orphan frees the memory allocated for grpc_fd. Normally it also - * calls close() on the underlying fd. In our case, we are using - * grpc_wakeup_fd and we would like to destroy it ourselves (by calling - * grpc_wakeup_fd_destroy). To prevent grpc_fd from calling close() on the - * underlying fd, call it with a non-NULL 'release_fd' parameter */ - grpc_fd_orphan(tfds[i].fd, nullptr, &release_fd, "test_fd_cleanup"); - grpc_core::ExecCtx::Get()->Flush(); - - grpc_wakeup_fd_destroy(&tfds[i].wakeup_fd); - } -} - -static void make_test_fds_readable(test_fd* tfds, const int num_fds) { - for (int i = 0; i < num_fds; i++) { - GPR_ASSERT(GRPC_ERROR_NONE == grpc_wakeup_fd_wakeup(&tfds[i].wakeup_fd)); - } -} - -static void verify_readable_and_reset(test_fd* tfds, const int num_fds) { - for (int i = 0; i < num_fds; i++) { - /* Verify that the on_readable callback was called */ - GPR_ASSERT(tfds[i].is_on_readable_called); - - /* Reset the tfd[i] structure */ - GPR_ASSERT(GRPC_ERROR_NONE == - grpc_wakeup_fd_consume_wakeup(&tfds[i].wakeup_fd)); - reset_test_fd(&tfds[i]); - } -} - -/******************************************************************************* - * Main tests - */ - -/* Test some typical scenarios in pollset_set */ -static void pollset_set_test_basic() { - /* We construct the following structure for this test: - * - * +---> FD0 (Added before PSS1, PS1 and PS2 are added to PSS0) - * | - * +---> FD5 (Added after PSS1, PS1 and PS2 are added to PSS0) - * | - * | - * | +---> FD1 (Added before PSS1 is added to PSS0) - * | | - * | +---> FD6 (Added after PSS1 is added to PSS0) - * | | - * +---> PSS1--+ +--> FD2 (Added before PS0 is added to PSS1) - * | | | - * | +---> PS0---+ - * | | - * PSS0---+ +--> FD7 (Added after PS0 is added to PSS1) - * | - * | - * | +---> FD3 (Added before PS1 is added to PSS0) - * | | - * +---> PS1---+ - * | | - * | +---> FD8 (Added after PS1 added to PSS0) - * | - * | - * | +---> FD4 (Added before PS2 is added to PSS0) - * | | - * +---> PS2---+ - * | - * +---> FD9 (Added after PS2 is added to PSS0) - */ - grpc_core::ExecCtx exec_ctx; - grpc_pollset_worker* worker; - grpc_millis deadline; - - test_fd tfds[10]; - test_pollset pollsets[3]; - test_pollset_set pollset_sets[2]; - const int num_fds = GPR_ARRAY_SIZE(tfds); - const int num_ps = GPR_ARRAY_SIZE(pollsets); - const int num_pss = GPR_ARRAY_SIZE(pollset_sets); - - init_test_fds(tfds, num_fds); - init_test_pollsets(pollsets, num_ps); - init_test_pollset_sets(pollset_sets, num_pss); - - /* Construct the pollset_set/pollset/fd tree (see diagram above) */ - - grpc_pollset_set_add_fd(pollset_sets[0].pss, tfds[0].fd); - grpc_pollset_set_add_fd(pollset_sets[1].pss, tfds[1].fd); - - grpc_pollset_add_fd(pollsets[0].ps, tfds[2].fd); - grpc_pollset_add_fd(pollsets[1].ps, tfds[3].fd); - grpc_pollset_add_fd(pollsets[2].ps, tfds[4].fd); - - grpc_pollset_set_add_pollset_set(pollset_sets[0].pss, pollset_sets[1].pss); - - grpc_pollset_set_add_pollset(pollset_sets[1].pss, pollsets[0].ps); - grpc_pollset_set_add_pollset(pollset_sets[0].pss, pollsets[1].ps); - grpc_pollset_set_add_pollset(pollset_sets[0].pss, pollsets[2].ps); - - grpc_pollset_set_add_fd(pollset_sets[0].pss, tfds[5].fd); - grpc_pollset_set_add_fd(pollset_sets[1].pss, tfds[6].fd); - - grpc_pollset_add_fd(pollsets[0].ps, tfds[7].fd); - grpc_pollset_add_fd(pollsets[1].ps, tfds[8].fd); - grpc_pollset_add_fd(pollsets[2].ps, tfds[9].fd); - - grpc_core::ExecCtx::Get()->Flush(); - - /* Test that if any FD in the above structure is readable, it is observable by - * doing grpc_pollset_work on any pollset - * - * For every pollset, do the following: - * - (Ensure that all FDs are in reset state) - * - Make all FDs readable - * - Call grpc_pollset_work() on the pollset - * - Flush the exec_ctx - * - Verify that on_readable call back was called for all FDs (and - * reset the FDs) - * */ - for (int i = 0; i < num_ps; i++) { - make_test_fds_readable(tfds, num_fds); - - gpr_mu_lock(pollsets[i].mu); - deadline = grpc_timespec_to_millis_round_up( - grpc_timeout_milliseconds_to_deadline(2)); - GPR_ASSERT(GRPC_ERROR_NONE == - grpc_pollset_work(pollsets[i].ps, &worker, deadline)); - gpr_mu_unlock(pollsets[i].mu); - - grpc_core::ExecCtx::Get()->Flush(); - - verify_readable_and_reset(tfds, num_fds); - grpc_core::ExecCtx::Get()->Flush(); - } - - /* Test tear down */ - grpc_pollset_set_del_fd(pollset_sets[0].pss, tfds[0].fd); - grpc_pollset_set_del_fd(pollset_sets[0].pss, tfds[5].fd); - grpc_pollset_set_del_fd(pollset_sets[1].pss, tfds[1].fd); - grpc_pollset_set_del_fd(pollset_sets[1].pss, tfds[6].fd); - grpc_core::ExecCtx::Get()->Flush(); - - grpc_pollset_set_del_pollset(pollset_sets[1].pss, pollsets[0].ps); - grpc_pollset_set_del_pollset(pollset_sets[0].pss, pollsets[1].ps); - grpc_pollset_set_del_pollset(pollset_sets[0].pss, pollsets[2].ps); - - grpc_pollset_set_del_pollset_set(pollset_sets[0].pss, pollset_sets[1].pss); - grpc_core::ExecCtx::Get()->Flush(); - - cleanup_test_fds(tfds, num_fds); - cleanup_test_pollsets(pollsets, num_ps); - cleanup_test_pollset_sets(pollset_sets, num_pss); -} - -/* Same FD added multiple times to the pollset_set tree */ -void pollset_set_test_dup_fds() { - /* We construct the following structure for this test: - * - * +---> FD0 - * | - * | - * PSS0---+ - * | +---> FD0 (also under PSS0) - * | | - * +---> PSS1--+ +--> FD1 (also under PSS1) - * | | - * +---> PS ---+ - * | | - * | +--> FD2 - * +---> FD1 - */ - grpc_core::ExecCtx exec_ctx; - grpc_pollset_worker* worker; - grpc_millis deadline; - - test_fd tfds[3]; - test_pollset pollset; - test_pollset_set pollset_sets[2]; - const int num_fds = GPR_ARRAY_SIZE(tfds); - const int num_ps = 1; - const int num_pss = GPR_ARRAY_SIZE(pollset_sets); - - init_test_fds(tfds, num_fds); - init_test_pollsets(&pollset, num_ps); - init_test_pollset_sets(pollset_sets, num_pss); - - /* Construct the structure */ - grpc_pollset_set_add_fd(pollset_sets[0].pss, tfds[0].fd); - grpc_pollset_set_add_fd(pollset_sets[1].pss, tfds[0].fd); - grpc_pollset_set_add_fd(pollset_sets[1].pss, tfds[1].fd); - - grpc_pollset_add_fd(pollset.ps, tfds[1].fd); - grpc_pollset_add_fd(pollset.ps, tfds[2].fd); - - grpc_pollset_set_add_pollset(pollset_sets[1].pss, pollset.ps); - grpc_pollset_set_add_pollset_set(pollset_sets[0].pss, pollset_sets[1].pss); - - /* Test. Make all FDs readable and make sure that can be observed by doing a - * grpc_pollset_work on the pollset 'PS' */ - make_test_fds_readable(tfds, num_fds); - - gpr_mu_lock(pollset.mu); - deadline = grpc_timespec_to_millis_round_up( - grpc_timeout_milliseconds_to_deadline(2)); - GPR_ASSERT(GRPC_ERROR_NONE == - grpc_pollset_work(pollset.ps, &worker, deadline)); - gpr_mu_unlock(pollset.mu); - grpc_core::ExecCtx::Get()->Flush(); - - verify_readable_and_reset(tfds, num_fds); - grpc_core::ExecCtx::Get()->Flush(); - - /* Tear down */ - grpc_pollset_set_del_fd(pollset_sets[0].pss, tfds[0].fd); - grpc_pollset_set_del_fd(pollset_sets[1].pss, tfds[0].fd); - grpc_pollset_set_del_fd(pollset_sets[1].pss, tfds[1].fd); - - grpc_pollset_set_del_pollset(pollset_sets[1].pss, pollset.ps); - grpc_pollset_set_del_pollset_set(pollset_sets[0].pss, pollset_sets[1].pss); - grpc_core::ExecCtx::Get()->Flush(); - - cleanup_test_fds(tfds, num_fds); - cleanup_test_pollsets(&pollset, num_ps); - cleanup_test_pollset_sets(pollset_sets, num_pss); -} - -/* Pollset_set with an empty pollset */ -void pollset_set_test_empty_pollset() { - /* We construct the following structure for this test: - * - * +---> PS0 (EMPTY) - * | - * +---> FD0 - * | - * PSS0---+ - * | +---> FD1 - * | | - * +---> PS1--+ - * | - * +---> FD2 - */ - grpc_core::ExecCtx exec_ctx; - grpc_pollset_worker* worker; - grpc_millis deadline; - - test_fd tfds[3]; - test_pollset pollsets[2]; - test_pollset_set pollset_set; - const int num_fds = GPR_ARRAY_SIZE(tfds); - const int num_ps = GPR_ARRAY_SIZE(pollsets); - const int num_pss = 1; - - init_test_fds(tfds, num_fds); - init_test_pollsets(pollsets, num_ps); - init_test_pollset_sets(&pollset_set, num_pss); - - /* Construct the structure */ - grpc_pollset_set_add_fd(pollset_set.pss, tfds[0].fd); - grpc_pollset_add_fd(pollsets[1].ps, tfds[1].fd); - grpc_pollset_add_fd(pollsets[1].ps, tfds[2].fd); - - grpc_pollset_set_add_pollset(pollset_set.pss, pollsets[0].ps); - grpc_pollset_set_add_pollset(pollset_set.pss, pollsets[1].ps); - - /* Test. Make all FDs readable and make sure that can be observed by doing - * grpc_pollset_work on the empty pollset 'PS0' */ - make_test_fds_readable(tfds, num_fds); - - gpr_mu_lock(pollsets[0].mu); - deadline = grpc_timespec_to_millis_round_up( - grpc_timeout_milliseconds_to_deadline(2)); - GPR_ASSERT(GRPC_ERROR_NONE == - grpc_pollset_work(pollsets[0].ps, &worker, deadline)); - gpr_mu_unlock(pollsets[0].mu); - grpc_core::ExecCtx::Get()->Flush(); - - verify_readable_and_reset(tfds, num_fds); - grpc_core::ExecCtx::Get()->Flush(); - - /* Tear down */ - grpc_pollset_set_del_fd(pollset_set.pss, tfds[0].fd); - grpc_pollset_set_del_pollset(pollset_set.pss, pollsets[0].ps); - grpc_pollset_set_del_pollset(pollset_set.pss, pollsets[1].ps); - grpc_core::ExecCtx::Get()->Flush(); - - cleanup_test_fds(tfds, num_fds); - cleanup_test_pollsets(pollsets, num_ps); - cleanup_test_pollset_sets(&pollset_set, num_pss); -} - -int main(int argc, char** argv) { - grpc_test_init(argc, argv); - grpc_init(); - { - grpc_core::ExecCtx exec_ctx; - const char* poll_strategy = grpc_get_poll_strategy_name(); - - if (poll_strategy != nullptr && - (strcmp(poll_strategy, "epollsig") == 0 || - strcmp(poll_strategy, "epoll-threadpool") == 0)) { - pollset_set_test_basic(); - pollset_set_test_dup_fds(); - pollset_set_test_empty_pollset(); - } else { - gpr_log(GPR_INFO, - "Skipping the test. The test is only relevant for 'epoll' " - "strategy. and the current strategy is: '%s'", - poll_strategy); - } - } - grpc_shutdown(); - return 0; -} -#else /* defined(GRPC_LINUX_EPOLL_CREATE1) */ -int main(int argc, char** argv) { return 0; } -#endif /* !defined(GRPC_LINUX_EPOLL_CREATE1) */ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index cfc5ef98e7b..c1bcdfd3d09 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1080,7 +1080,6 @@ src/core/lib/iomgr/error.h \ src/core/lib/iomgr/error_internal.h \ src/core/lib/iomgr/ev_epoll1_linux.h \ src/core/lib/iomgr/ev_epollex_linux.h \ -src/core/lib/iomgr/ev_epollsig_linux.h \ src/core/lib/iomgr/ev_poll_posix.h \ src/core/lib/iomgr/ev_posix.h \ src/core/lib/iomgr/exec_ctx.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index ed0e17a99ef..91860567339 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1181,8 +1181,6 @@ src/core/lib/iomgr/ev_epoll1_linux.cc \ src/core/lib/iomgr/ev_epoll1_linux.h \ src/core/lib/iomgr/ev_epollex_linux.cc \ src/core/lib/iomgr/ev_epollex_linux.h \ -src/core/lib/iomgr/ev_epollsig_linux.cc \ -src/core/lib/iomgr/ev_epollsig_linux.h \ src/core/lib/iomgr/ev_poll_posix.cc \ src/core/lib/iomgr/ev_poll_posix.h \ src/core/lib/iomgr/ev_posix.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 3f7393ae94a..29b72dca43f 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -483,23 +483,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "gpr", - "gpr_test_util", - "grpc", - "grpc_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "ev_epollsig_linux_test", - "src": [ - "test/core/iomgr/ev_epollsig_linux_test.cc" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "gpr", @@ -1853,23 +1836,6 @@ "third_party": false, "type": "target" }, - { - "deps": [ - "gpr", - "gpr_test_util", - "grpc", - "grpc_test_util" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "pollset_set_test", - "src": [ - "test/core/iomgr/pollset_set_test.cc" - ], - "third_party": false, - "type": "target" - }, { "deps": [ "gpr", @@ -9551,7 +9517,6 @@ "src/core/lib/iomgr/error.cc", "src/core/lib/iomgr/ev_epoll1_linux.cc", "src/core/lib/iomgr/ev_epollex_linux.cc", - "src/core/lib/iomgr/ev_epollsig_linux.cc", "src/core/lib/iomgr/ev_poll_posix.cc", "src/core/lib/iomgr/ev_posix.cc", "src/core/lib/iomgr/ev_windows.cc", @@ -9732,7 +9697,6 @@ "src/core/lib/iomgr/error_internal.h", "src/core/lib/iomgr/ev_epoll1_linux.h", "src/core/lib/iomgr/ev_epollex_linux.h", - "src/core/lib/iomgr/ev_epollsig_linux.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", @@ -9884,7 +9848,6 @@ "src/core/lib/iomgr/error_internal.h", "src/core/lib/iomgr/ev_epoll1_linux.h", "src/core/lib/iomgr/ev_epollex_linux.h", - "src/core/lib/iomgr/ev_epollsig_linux.h", "src/core/lib/iomgr/ev_poll_posix.h", "src/core/lib/iomgr/ev_posix.h", "src/core/lib/iomgr/exec_ctx.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index b3c07d9215a..4fdd26efa48 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -601,26 +601,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux" - ], - "cpu_cost": 3, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "gtest": false, - "language": "c", - "name": "ev_epollsig_linux_test", - "platforms": [ - "linux" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, @@ -2101,26 +2081,6 @@ ], "uses_polling": false }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [ - "uv" - ], - "flaky": false, - "gtest": false, - "language": "c", - "name": "pollset_set_test", - "platforms": [ - "linux" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index ecb5e1d899e..3d73f9ec0eb 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -61,7 +61,7 @@ _FORCE_ENVIRON_FOR_WRAPPERS = { } _POLLING_STRATEGIES = { - 'linux': ['epollex', 'epollsig', 'epoll1', 'poll', 'poll-cv'], + 'linux': ['epollex', 'epoll1', 'poll', 'poll-cv'], 'mac': ['poll'], } @@ -1430,7 +1430,7 @@ argp.add_argument( default=None, type=str, help='Only use the specified comma-delimited list of polling engines. ' - 'Example: --force_use_pollers epollsig,poll ' + 'Example: --force_use_pollers epoll1,poll ' ' (This flag has no effect if --force_default_poller flag is also used)') argp.add_argument( '--max_time', default=-1, type=int, help='Maximum test runtime in seconds') From 63a31d85f1557f1c0e2b1be04e7bd4d07a88607e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sun, 23 Sep 2018 18:58:37 -0700 Subject: [PATCH 429/546] contextual marshaller test --- .../ContextualMarshallerTest.cs | 119 ++++++++++++++++++ src/csharp/tests.json | 1 + 2 files changed, 120 insertions(+) create mode 100644 src/csharp/Grpc.Core.Tests/ContextualMarshallerTest.cs diff --git a/src/csharp/Grpc.Core.Tests/ContextualMarshallerTest.cs b/src/csharp/Grpc.Core.Tests/ContextualMarshallerTest.cs new file mode 100644 index 00000000000..c3aee726f26 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/ContextualMarshallerTest.cs @@ -0,0 +1,119 @@ +#region Copyright notice and license + +// Copyright 2018 The 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.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; + +namespace Grpc.Core.Tests +{ + public class ContextualMarshallerTest + { + const string Host = "127.0.0.1"; + + MockServiceHelper helper; + Server server; + Channel channel; + + [SetUp] + public void Init() + { + var contextualMarshaller = new Marshaller( + (str, serializationContext) => + { + if (str == "UNSERIALIZABLE_VALUE") + { + // Google.Protobuf throws exception inherited from IOException + throw new IOException("Error serializing the message."); + } + if (str == "SERIALIZE_TO_NULL") + { + return; + } + var bytes = System.Text.Encoding.UTF8.GetBytes(str); + serializationContext.Complete(bytes); + }, + (deserializationContext) => + { + var buffer = deserializationContext.PayloadAsNewBuffer(); + Assert.AreEqual(buffer.Length, deserializationContext.PayloadLength); + var s = System.Text.Encoding.UTF8.GetString(buffer); + if (s == "UNPARSEABLE_VALUE") + { + // Google.Protobuf throws exception inherited from IOException + throw new IOException("Error parsing the message."); + } + return s; + }); + helper = new MockServiceHelper(Host, contextualMarshaller); + server = helper.GetServer(); + server.Start(); + channel = helper.GetChannel(); + } + + [TearDown] + public void Cleanup() + { + channel.ShutdownAsync().Wait(); + server.ShutdownAsync().Wait(); + } + + [Test] + public void UnaryCall() + { + helper.UnaryHandler = new UnaryServerMethod((request, context) => + { + return Task.FromResult(request); + }); + Assert.AreEqual("ABC", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "ABC")); + } + + [Test] + public void ResponseParsingError_UnaryResponse() + { + helper.UnaryHandler = new UnaryServerMethod((request, context) => + { + return Task.FromResult("UNPARSEABLE_VALUE"); + }); + + var ex = Assert.Throws(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "REQUEST")); + Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode); + } + + [Test] + public void RequestSerializationError_BlockingUnary() + { + Assert.Throws(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "UNSERIALIZABLE_VALUE")); + } + + [Test] + public void SerializationResultIsNull_BlockingUnary() + { + Assert.Throws(() => Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "SERIALIZE_TO_NULL")); + } + } +} diff --git a/src/csharp/tests.json b/src/csharp/tests.json index c2f243fe0ae..e4feb4dc3ad 100644 --- a/src/csharp/tests.json +++ b/src/csharp/tests.json @@ -23,6 +23,7 @@ "Grpc.Core.Tests.ClientServerTest", "Grpc.Core.Tests.CompressionTest", "Grpc.Core.Tests.ContextPropagationTest", + "Grpc.Core.Tests.ContextualMarshallerTest", "Grpc.Core.Tests.GrpcEnvironmentTest", "Grpc.Core.Tests.HalfcloseTest", "Grpc.Core.Tests.MarshallingErrorsTest", From a2a4629614bb79e3a4d7ea6594e31e33d63a65be Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sun, 23 Sep 2018 21:10:03 -0700 Subject: [PATCH 430/546] add MarshallerTest --- src/csharp/Grpc.Core.Tests/MarshallerTest.cs | 105 +++++++++++++++++++ src/csharp/tests.json | 1 + 2 files changed, 106 insertions(+) create mode 100644 src/csharp/Grpc.Core.Tests/MarshallerTest.cs diff --git a/src/csharp/Grpc.Core.Tests/MarshallerTest.cs b/src/csharp/Grpc.Core.Tests/MarshallerTest.cs new file mode 100644 index 00000000000..97f64a0575e --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/MarshallerTest.cs @@ -0,0 +1,105 @@ +#region Copyright notice and license + +// Copyright 2018 The 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.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; + +namespace Grpc.Core.Tests +{ + public class MarshallerTest + { + [Test] + public void ContextualSerializerEmulation() + { + Func simpleSerializer = System.Text.Encoding.UTF8.GetBytes; + Func simpleDeserializer = System.Text.Encoding.UTF8.GetString; + var marshaller = new Marshaller(simpleSerializer, + simpleDeserializer); + + Assert.AreSame(simpleSerializer, marshaller.Serializer); + Assert.AreSame(simpleDeserializer, marshaller.Deserializer); + + // test that emulated contextual serializer and deserializer work + string origMsg = "abc"; + var serializationContext = new FakeSerializationContext(); + marshaller.ContextualSerializer(origMsg, serializationContext); + + var deserializationContext = new FakeDeserializationContext(serializationContext.Payload); + Assert.AreEqual(origMsg, marshaller.ContextualDeserializer(deserializationContext)); + } + + [Test] + public void SimpleSerializerEmulation() + { + Action contextualSerializer = (str, context) => + { + var bytes = System.Text.Encoding.UTF8.GetBytes(str); + context.Complete(bytes); + }; + Func contextualDeserializer = (context) => + { + return System.Text.Encoding.UTF8.GetString(context.PayloadAsNewBuffer()); + }; + var marshaller = new Marshaller(contextualSerializer, contextualDeserializer); + + Assert.AreSame(contextualSerializer, marshaller.ContextualSerializer); + Assert.AreSame(contextualDeserializer, marshaller.ContextualDeserializer); + + // test that emulated serializer and deserializer work + var origMsg = "abc"; + var serialized = marshaller.Serializer(origMsg); + Assert.AreEqual(origMsg, marshaller.Deserializer(serialized)); + } + + class FakeSerializationContext : SerializationContext + { + public byte[] Payload; + public override void Complete(byte[] payload) + { + this.Payload = payload; + } + } + + class FakeDeserializationContext : DeserializationContext + { + public byte[] payload; + + public FakeDeserializationContext(byte[] payload) + { + this.payload = payload; + } + + public override int PayloadLength => payload.Length; + + public override byte[] PayloadAsNewBuffer() + { + return payload; + } + } + } +} diff --git a/src/csharp/tests.json b/src/csharp/tests.json index e4feb4dc3ad..5683d164c6a 100644 --- a/src/csharp/tests.json +++ b/src/csharp/tests.json @@ -26,6 +26,7 @@ "Grpc.Core.Tests.ContextualMarshallerTest", "Grpc.Core.Tests.GrpcEnvironmentTest", "Grpc.Core.Tests.HalfcloseTest", + "Grpc.Core.Tests.MarshallerTest", "Grpc.Core.Tests.MarshallingErrorsTest", "Grpc.Core.Tests.MetadataTest", "Grpc.Core.Tests.PerformanceTest", From 93ef74c25c8aa4607c82cb47b9161e613664b0c3 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 24 Sep 2018 11:19:14 -0700 Subject: [PATCH 431/546] Fix .bzl format --- test/core/end2end/generate_tests.bzl | 564 +++++++++++++++------------ 1 file changed, 317 insertions(+), 247 deletions(-) diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 55451887203..6d9ffcfb913 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -13,277 +13,347 @@ # See the License for the specific language governing permissions and # limitations under the License. -POLLERS = ['epollex', 'epoll1', 'poll', 'poll-cv'] - -load("//bazel:grpc_build_system.bzl", "grpc_sh_test", "grpc_cc_binary", "grpc_cc_library") - """Generates the appropriate build.json data for all the end2end tests.""" +load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_library") -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, client_channel=True): - return struct( - fullstack=fullstack, - includes_proxy=includes_proxy, - dns_resolver=dns_resolver, - name_resolution=name_resolution, - secure=secure, - tracing=tracing, - is_inproc=is_inproc, - is_http2=is_http2, - supports_proxy_auth=supports_proxy_auth, - supports_write_buffering=supports_write_buffering, - client_channel=client_channel, - #platforms=platforms, - ) +POLLERS = ["epollex", "epoll1", "poll", "poll-cv"] +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, + client_channel = True): + return struct( + fullstack = fullstack, + includes_proxy = includes_proxy, + dns_resolver = dns_resolver, + name_resolution = name_resolution, + secure = secure, + tracing = tracing, + is_inproc = is_inproc, + is_http2 = is_http2, + supports_proxy_auth = supports_proxy_auth, + supports_write_buffering = supports_write_buffering, + client_channel = client_channel, + #_platforms=_platforms, + ) # maps fixture name to whether it requires the security library END2END_FIXTURES = { - 'h2_compress': fixture_options(), - 'h2_census': fixture_options(), + "h2_compress": _fixture_options(), + "h2_census": _fixture_options(), # TODO(juanlishen): This is disabled for now, but should be considered to re-enable once we have # decided how the load reporting service should be enabled. - #'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']), - 'h2_full+trace': fixture_options(tracing=True), - 'h2_full+workarounds': fixture_options(), - '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, - 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, client_channel=False), - 'h2_ssl': fixture_options(secure=True), - 'h2_local': fixture_options(secure=True, dns_resolver=False, platforms=['linux', 'mac', 'posix']), - '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, - client_channel=False), + #'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"]), + "h2_full+trace": _fixture_options(tracing = True), + "h2_full+workarounds": _fixture_options(), + "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, + 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, + client_channel = False, + ), + "h2_ssl": _fixture_options(secure = True), + "h2_local": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), + "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, + 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_client_channel=False): - return struct( - needs_fullstack=needs_fullstack, - needs_dns=needs_dns, - needs_names=needs_names, - proxyable=proxyable, - secure=secure, - traceable=traceable, - exclude_inproc=exclude_inproc, - needs_http2=needs_http2, - needs_proxy_auth=needs_proxy_auth, - needs_write_buffering=needs_write_buffering, - needs_client_channel=needs_client_channel, - ) - +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_client_channel = False): + return struct( + needs_fullstack = needs_fullstack, + needs_dns = needs_dns, + needs_names = needs_names, + proxyable = proxyable, + secure = secure, + traceable = traceable, + exclude_inproc = exclude_inproc, + needs_http2 = needs_http2, + needs_proxy_auth = needs_proxy_auth, + needs_write_buffering = needs_write_buffering, + needs_client_channel = needs_client_channel, + ) # maps test names to options END2END_TESTS = { - 'bad_hostname': test_options(needs_names=True), - 'bad_ping': test_options(needs_fullstack=True,proxyable=False), - 'binary_metadata': test_options(), - 'resource_quota_server': test_options(proxyable=False), - 'call_creds': test_options(secure=True), - 'call_host_override': test_options(needs_fullstack=True, needs_dns=True, - needs_names=True), - 'cancel_after_accept': test_options(), - 'cancel_after_client_done': test_options(), - 'cancel_after_invoke': test_options(), - 'cancel_after_round_trip': test_options(), - 'cancel_before_invoke': test_options(), - 'cancel_in_a_vacuum': test_options(), - 'cancel_with_status': test_options(), - 'compressed_payload': test_options(proxyable=False, exclude_inproc=True), - 'connectivity': test_options(needs_fullstack=True, needs_names=True, - proxyable=False), - 'channelz': test_options(), - 'default_host': test_options(needs_fullstack=True, needs_dns=True, - needs_names=True), - 'disappearing_server': test_options(needs_fullstack=True,needs_names=True), - 'empty_batch': test_options(), - 'filter_causes_close': test_options(), - 'filter_call_init_fails': test_options(), - 'graceful_server_shutdown': test_options(exclude_inproc=True), - 'hpack_size': test_options(proxyable=False, traceable=False, - exclude_inproc=True), - 'high_initial_seqno': test_options(), - 'idempotent_request': test_options(), - '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_connection_age': test_options(exclude_inproc=True), - 'max_connection_idle': test_options(needs_fullstack=True, proxyable=False), - 'max_message_length': test_options(), - 'negative_deadline': test_options(), - 'network_status_change': test_options(), - 'no_error_on_hotpath': test_options(proxyable=False), - 'no_logging': test_options(traceable=False), - 'no_op': test_options(), - 'payload': test_options(), + "bad_hostname": _test_options(needs_names = True), + "bad_ping": _test_options(needs_fullstack = True, proxyable = False), + "binary_metadata": _test_options(), + "resource_quota_server": _test_options(proxyable = False), + "call_creds": _test_options(secure = True), + "call_host_override": _test_options( + needs_fullstack = True, + needs_dns = True, + needs_names = True, + ), + "cancel_after_accept": _test_options(), + "cancel_after_client_done": _test_options(), + "cancel_after_invoke": _test_options(), + "cancel_after_round_trip": _test_options(), + "cancel_before_invoke": _test_options(), + "cancel_in_a_vacuum": _test_options(), + "cancel_with_status": _test_options(), + "compressed_payload": _test_options(proxyable = False, exclude_inproc = True), + "connectivity": _test_options( + needs_fullstack = True, + needs_names = True, + proxyable = False, + ), + "channelz": _test_options(), + "default_host": _test_options( + needs_fullstack = True, + needs_dns = True, + needs_names = True, + ), + "disappearing_server": _test_options(needs_fullstack = True, needs_names = True), + "empty_batch": _test_options(), + "filter_causes_close": _test_options(), + "filter_call_init_fails": _test_options(), + "graceful_server_shutdown": _test_options(exclude_inproc = True), + "hpack_size": _test_options( + proxyable = False, + traceable = False, + exclude_inproc = True, + ), + "high_initial_seqno": _test_options(), + "idempotent_request": _test_options(), + "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_connection_age": _test_options(exclude_inproc = True), + "max_connection_idle": _test_options(needs_fullstack = True, proxyable = False), + "max_message_length": _test_options(), + "negative_deadline": _test_options(), + "network_status_change": _test_options(), + "no_error_on_hotpath": _test_options(proxyable = False), + "no_logging": _test_options(traceable = False), + "no_op": _test_options(), + "payload": _test_options(), # TODO(juanlishen): This is disabled for now because it depends on some generated functions in # end2end_tests.cc, which are not generated because they would depend on OpenCensus while # OpenCensus can only be built via Bazel so far. - # 'load_reporting_hook': test_options(), - 'ping_pong_streaming': test_options(), - 'ping': test_options(needs_fullstack=True, proxyable=False), - 'proxy_auth': test_options(needs_proxy_auth=True), - 'registered_call': test_options(), - 'request_with_flags': test_options(proxyable=False), - 'request_with_payload': test_options(), + # 'load_reporting_hook': _test_options(), + "ping_pong_streaming": _test_options(), + "ping": _test_options(needs_fullstack = True, proxyable = False), + "proxy_auth": _test_options(needs_proxy_auth = True), + "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_non_retriable_status_before_recv_trailing_metadata_started': - 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(), - 'simple_cacheable_request': test_options(), - 'simple_delayed_request': test_options(needs_fullstack=True), - '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_payload': test_options(exclude_inproc=True), - 'stream_compression_ping_pong_streaming': test_options(exclude_inproc=True), - 'trailing_metadata': test_options(), - 'authority_not_supported': test_options(), - 'filter_latency': test_options(), - 'filter_status_code': test_options(), - 'workaround_cronet_compression': test_options(), - 'write_buffering': test_options(needs_write_buffering=True), - 'write_buffering_at_end': test_options(needs_write_buffering=True), + "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_non_retriable_status_before_recv_trailing_metadata_started": _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(), + "simple_cacheable_request": _test_options(), + "simple_delayed_request": _test_options(needs_fullstack = True), + "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_payload": _test_options(exclude_inproc = True), + "stream_compression_ping_pong_streaming": _test_options(exclude_inproc = True), + "trailing_metadata": _test_options(), + "authority_not_supported": _test_options(), + "filter_latency": _test_options(), + "filter_status_code": _test_options(), + "workaround_cronet_compression": _test_options(), + "write_buffering": _test_options(needs_write_buffering = True), + "write_buffering_at_end": _test_options(needs_write_buffering = True), } - -def compatible(fopt, topt): - if topt.needs_fullstack: - if not fopt.fullstack: - return False - if topt.needs_dns: - if not fopt.dns_resolver: - return False - if topt.needs_names: - if not fopt.name_resolution: - return False - if not topt.proxyable: - if fopt.includes_proxy: - return False - if not topt.traceable: - if fopt.tracing: - return False - if topt.exclude_inproc: - if fopt.is_inproc: - return False - if topt.needs_http2: - if not fopt.is_http2: - return False - if topt.needs_proxy_auth: - if not fopt.supports_proxy_auth: - return False - 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 - +def _compatible(fopt, topt): + if topt.needs_fullstack: + if not fopt.fullstack: + return False + if topt.needs_dns: + if not fopt.dns_resolver: + return False + if topt.needs_names: + if not fopt.name_resolution: + return False + if not topt.proxyable: + if fopt.includes_proxy: + return False + if not topt.traceable: + if fopt.tracing: + return False + if topt.exclude_inproc: + if fopt.is_inproc: + return False + if topt.needs_http2: + if not fopt.is_http2: + return False + if topt.needs_proxy_auth: + if not fopt.supports_proxy_auth: + return False + 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 def grpc_end2end_tests(): - grpc_cc_library( - name = 'end2end_tests', - srcs = ['end2end_tests.cc', 'end2end_test_utils.cc'] + [ - 'tests/%s.cc' % t - for t in sorted(END2END_TESTS.keys())], - hdrs = [ - 'tests/cancel_test_helpers.h', - 'end2end_tests.h' - ], - language = "C++", - deps = [ - ':cq_verifier', - ':ssl_test_data', - ':http_proxy', - ':proxy', - ] - ) - - for f, fopt in END2END_FIXTURES.items(): - grpc_cc_binary( - name = '%s_test' % f, - srcs = ['fixtures/%s.cc' % f], - language = "C++", - deps = [ - ':end2end_tests', - '//test/core/util:grpc_test_util', - '//:grpc', - '//test/core/util:gpr_test_util', - '//:gpr', - ], + grpc_cc_library( + name = "end2end_tests", + srcs = ["end2end_tests.cc", "end2end_test_utils.cc"] + [ + "tests/%s.cc" % t + for t in sorted(END2END_TESTS.keys()) + ], + hdrs = [ + "tests/cancel_test_helpers.h", + "end2end_tests.h", + ], + language = "C++", + deps = [ + ":cq_verifier", + ":ssl_test_data", + ":http_proxy", + ":proxy", + ], ) - for t, topt in END2END_TESTS.items(): - #print(compatible(fopt, topt), f, t, fopt, topt) - if not compatible(fopt, topt): continue - for poller in POLLERS: - native.sh_test( - name = '%s_test@%s@poller=%s' % (f, t, poller), - data = [':%s_test' % f], - srcs = ['end2end_test.sh'], - args = [ - '$(location %s_test)' % f, - t, - poller, - ], + + for f, fopt in END2END_FIXTURES.items(): + grpc_cc_binary( + name = "%s_test" % f, + srcs = ["fixtures/%s.cc" % f], + language = "C++", + deps = [ + ":end2end_tests", + "//test/core/util:grpc_test_util", + "//:grpc", + "//test/core/util:gpr_test_util", + "//:gpr", + ], ) + for t, topt in END2END_TESTS.items(): + #print(_compatible(fopt, topt), f, t, fopt, topt) + if not _compatible(fopt, topt): + continue + for poller in POLLERS: + native.sh_test( + name = "%s_test@%s@poller=%s" % (f, t, poller), + data = [":%s_test" % f], + srcs = ["end2end_test.sh"], + args = [ + "$(location %s_test)" % f, + t, + poller, + ], + ) From d194cc378e7e34ec36cde00d62f459cc446b2397 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Mon, 24 Sep 2018 13:36:28 -0700 Subject: [PATCH 432/546] Free result of grpc_dump_slice --- .../ext/filters/client_channel/lb_policy/grpclb/grpclb.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 1ee1925a259..00611900169 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 @@ -852,10 +852,12 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked( } } else { // No valid initial response or serverlist found. + char* response_slice_str = + grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX); gpr_log(GPR_ERROR, "[grpclb %p] Invalid LB response received: '%s'. Ignoring.", - grpclb_policy, - grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX)); + grpclb_policy, response_slice_str); + gpr_free(response_slice_str); } grpc_slice_unref_internal(response_slice); if (!grpclb_policy->shutting_down_) { From 86600071b0ec7dd405b970c2a2b0ef808b130967 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 24 Sep 2018 16:12:00 -0700 Subject: [PATCH 433/546] reviewer feedback --- .../chttp2/transport/chttp2_transport.cc | 7 +- .../transport/chttp2/transport/frame_data.cc | 3 + .../ext/transport/chttp2/transport/internal.h | 1 + .../ext/transport/chttp2/transport/writing.cc | 5 ++ src/core/lib/channel/channelz.cc | 74 +++++++++---------- src/core/lib/channel/channelz.h | 21 +++--- test/core/end2end/tests/channelz.cc | 32 ++++++-- 7 files changed, 84 insertions(+), 59 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 38032d56a60..9da9a7a63c3 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1507,9 +1507,7 @@ static void perform_stream_op_locked(void* stream_op, if (op->send_message) { GRPC_STATS_INC_HTTP2_OP_SEND_MESSAGE(); - if (t->channelz_socket != nullptr) { - t->channelz_socket->RecordMessageSent(); - } + t->num_messages_in_next_write++; GRPC_STATS_INC_HTTP2_SEND_MESSAGE_SIZE( op->payload->send_message.send_message->length()); on_complete->next_data.scratch |= CLOSURE_BARRIER_MAY_COVER_WRITE; @@ -1627,9 +1625,6 @@ static void perform_stream_op_locked(void* stream_op, if (op->recv_message) { GRPC_STATS_INC_HTTP2_OP_RECV_MESSAGE(); - if (t->channelz_socket != nullptr) { - t->channelz_socket->RecordMessageRecieved(); - } size_t before = 0; GPR_ASSERT(s->recv_message_ready == nullptr); GPR_ASSERT(!s->pending_byte_stream); diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc index 15de8795282..933b32c03c0 100644 --- a/src/core/ext/transport/chttp2/transport/frame_data.cc +++ b/src/core/ext/transport/chttp2/transport/frame_data.cc @@ -192,6 +192,9 @@ grpc_error* grpc_deframe_unprocessed_incoming_frames( GPR_ASSERT(stream_out != nullptr); GPR_ASSERT(p->parsing_frame == nullptr); p->frame_size |= (static_cast(*cur)); + if (t->channelz_socket != nullptr) { + t->channelz_socket->RecordMessageReceived(); + } p->state = GRPC_CHTTP2_DATA_FRAME; ++cur; message_flags = 0; diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index bf0dfa98af8..ff26dd9255d 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -474,6 +474,7 @@ struct grpc_chttp2_transport { grpc_chttp2_keepalive_state keepalive_state; grpc_core::RefCountedPtr channelz_socket; + uint32_t num_messages_in_next_write; }; typedef enum { diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc index 5beaf5491ef..d533989444c 100644 --- a/src/core/ext/transport/chttp2/transport/writing.cc +++ b/src/core/ext/transport/chttp2/transport/writing.cc @@ -633,6 +633,11 @@ void grpc_chttp2_end_write(grpc_chttp2_transport* t, grpc_error* error) { GPR_TIMER_SCOPE("grpc_chttp2_end_write", 0); grpc_chttp2_stream* s; + if (t->channelz_socket != nullptr) { + t->channelz_socket->RecordMessagesSent(t->num_messages_in_next_write); + } + t->num_messages_in_next_write = 0; + while (grpc_chttp2_list_pop_writing_stream(t, &s)) { if (s->sending_bytes != 0) { update_list(t, s, static_cast(s->sending_bytes), diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index e1ab2ead626..df5c99f91e2 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -62,7 +62,7 @@ CallCountingHelper::CallCountingHelper() { CallCountingHelper::~CallCountingHelper() {} void CallCountingHelper::RecordCallStarted() { - gpr_atm_no_barrier_fetch_add(&calls_started_, (gpr_atm)1); + gpr_atm_no_barrier_fetch_add(&calls_started_, static_cast(1)); gpr_atm_no_barrier_store(&last_call_started_millis_, (gpr_atm)ExecCtx::Get()->Now()); } @@ -182,31 +182,32 @@ grpc_json* ServerNode::RenderJson() { } // ask CallCountingHelper to populate trace and call count data. call_counter_.PopulateCallCounts(json); - json = top_level_json; return top_level_json; } +SocketNode::SocketNode() : BaseNode(EntityType::kSocket) {} + void SocketNode::RecordStreamStartedFromLocal() { - gpr_atm_no_barrier_fetch_add(&streams_started_, (gpr_atm)1); + gpr_atm_no_barrier_fetch_add(&streams_started_, static_cast(1)); gpr_atm_no_barrier_store(&last_local_stream_created_millis_, (gpr_atm)ExecCtx::Get()->Now()); } void SocketNode::RecordStreamStartedFromRemote() { - gpr_atm_no_barrier_fetch_add(&streams_started_, (gpr_atm)1); + gpr_atm_no_barrier_fetch_add(&streams_started_, static_cast(1)); gpr_atm_no_barrier_store(&last_remote_stream_created_millis_, (gpr_atm)ExecCtx::Get()->Now()); } -void SocketNode::RecordMessageSent() { - gpr_atm_no_barrier_fetch_add(&messages_sent_, (gpr_atm)1); +void SocketNode::RecordMessagesSent(uint32_t num_sent) { + gpr_atm_no_barrier_fetch_add(&messages_sent_, static_cast(num_sent)); gpr_atm_no_barrier_store(&last_message_sent_millis_, (gpr_atm)ExecCtx::Get()->Now()); } -void SocketNode::RecordMessageRecieved() { - gpr_atm_no_barrier_fetch_add(&messages_recieved_, (gpr_atm)1); - gpr_atm_no_barrier_store(&last_message_recieved_millis_, +void SocketNode::RecordMessageReceived() { + gpr_atm_no_barrier_fetch_add(&messages_received_, static_cast(1)); + gpr_atm_no_barrier_store(&last_message_received_millis_, (gpr_atm)ExecCtx::Get()->Now()); } @@ -242,47 +243,44 @@ grpc_json* SocketNode::RenderJson() { json_iterator = grpc_json_add_number_string_child( json, json_iterator, "streamsFailed", streams_failed_); } + gpr_timespec ts; if (messages_sent_ != 0) { json_iterator = grpc_json_add_number_string_child( json, json_iterator, "messagesSent", messages_sent_); - } - if (messages_recieved_ != 0) { - json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "messagesRecieved", messages_recieved_); - } - if (keepalives_sent_ != 0) { - json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "keepAlivesSent", keepalives_sent_); - } - gpr_timespec ts; - if (streams_started_ != 0 && last_local_stream_created_millis_ != 0) { - ts = grpc_millis_to_timespec(last_local_stream_created_millis_, - GPR_CLOCK_REALTIME); - json_iterator = grpc_json_create_child( - json_iterator, json, "lastLocalStreamCreatedTimestamp", - gpr_format_timespec(ts), GRPC_JSON_STRING, true); - } - if (streams_started_ != 0 && last_remote_stream_created_millis_ != 0) { - ts = grpc_millis_to_timespec(last_remote_stream_created_millis_, - GPR_CLOCK_REALTIME); - json_iterator = grpc_json_create_child( - json_iterator, json, "lastRemoteStreamCreatedTimestamp", - gpr_format_timespec(ts), GRPC_JSON_STRING, true); - } - if (messages_sent_ != 0) { ts = grpc_millis_to_timespec(last_message_sent_millis_, GPR_CLOCK_REALTIME); json_iterator = grpc_json_create_child(json_iterator, json, "lastMessageSentTimestamp", gpr_format_timespec(ts), GRPC_JSON_STRING, true); } - if (messages_recieved_ != 0) { - ts = grpc_millis_to_timespec(last_message_recieved_millis_, + if (messages_received_ != 0) { + json_iterator = grpc_json_add_number_string_child( + json, json_iterator, "messagesReceived", messages_received_); + ts = grpc_millis_to_timespec(last_message_received_millis_, GPR_CLOCK_REALTIME); json_iterator = grpc_json_create_child( - json_iterator, json, "lastMessageRecievedTimestamp", + json_iterator, json, "lastMessageReceivedTimestamp", gpr_format_timespec(ts), GRPC_JSON_STRING, true); } - json = top_level_json; + if (keepalives_sent_ != 0) { + json_iterator = grpc_json_add_number_string_child( + json, json_iterator, "keepAlivesSent", keepalives_sent_); + } + if (streams_started_ != 0) { + if (last_local_stream_created_millis_ != 0) { + ts = grpc_millis_to_timespec(last_local_stream_created_millis_, + GPR_CLOCK_REALTIME); + json_iterator = grpc_json_create_child( + json_iterator, json, "lastLocalStreamCreatedTimestamp", + gpr_format_timespec(ts), GRPC_JSON_STRING, true); + } + if (last_remote_stream_created_millis_ != 0) { + ts = grpc_millis_to_timespec(last_remote_stream_created_millis_, + GPR_CLOCK_REALTIME); + json_iterator = grpc_json_create_child( + json_iterator, json, "lastRemoteStreamCreatedTimestamp", + gpr_format_timespec(ts), GRPC_JSON_STRING, true); + } + } return top_level_json; } diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 24868208632..b7ae1012389 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -92,10 +92,10 @@ class CallCountingHelper { void RecordCallStarted(); void RecordCallFailed() { - gpr_atm_no_barrier_fetch_add(&calls_failed_, (gpr_atm(1))); + gpr_atm_no_barrier_fetch_add(&calls_failed_, static_cast(1)); } void RecordCallSucceeded() { - gpr_atm_no_barrier_fetch_add(&calls_succeeded_, (gpr_atm(1))); + gpr_atm_no_barrier_fetch_add(&calls_succeeded_, static_cast(1)); } // Common rendering of the call count data and last_call_started_timestamp. @@ -199,7 +199,7 @@ class ServerNode : public BaseNode { // Handles channelz bookkeeping for sockets class SocketNode : public BaseNode { public: - SocketNode() : BaseNode(EntityType::kSocket) {} + SocketNode(); ~SocketNode() override {} grpc_json* RenderJson() override; @@ -207,15 +207,15 @@ class SocketNode : public BaseNode { void RecordStreamStartedFromLocal(); void RecordStreamStartedFromRemote(); void RecordStreamSucceeded() { - gpr_atm_no_barrier_fetch_add(&streams_succeeded_, (gpr_atm(1))); + gpr_atm_no_barrier_fetch_add(&streams_succeeded_, static_cast(1)); } void RecordStreamFailed() { - gpr_atm_no_barrier_fetch_add(&streams_failed_, (gpr_atm(1))); + gpr_atm_no_barrier_fetch_add(&streams_failed_, static_cast(1)); } - void RecordMessageSent(); - void RecordMessageRecieved(); + void RecordMessagesSent(uint32_t num_sent); + void RecordMessageReceived(); void RecordKeepaliveSent() { - gpr_atm_no_barrier_fetch_add(&keepalives_sent_, (gpr_atm(1))); + gpr_atm_no_barrier_fetch_add(&keepalives_sent_, static_cast(1)); } private: @@ -223,12 +223,13 @@ class SocketNode : public BaseNode { gpr_atm streams_succeeded_ = 0; gpr_atm streams_failed_ = 0; gpr_atm messages_sent_ = 0; - gpr_atm messages_recieved_ = 0; + gpr_atm messages_received_ = 0; gpr_atm keepalives_sent_ = 0; gpr_atm last_local_stream_created_millis_ = 0; gpr_atm last_remote_stream_created_millis_ = 0; gpr_atm last_message_sent_millis_ = 0; - gpr_atm last_message_recieved_millis_ = 0; + gpr_atm last_message_received_millis_ = 0; + UniquePtr peer_string_; }; // Creation functions diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 3ebaea2afc5..bb99045d1e5 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -202,12 +202,12 @@ static grpc_slice generate_random_slice() { size_t i; static const char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890"; char* output; - const size_t output_size = 1024 * 1024; - output = static_cast(gpr_malloc(output_size)); - for (i = 0; i < output_size - 1; ++i) { + const size_t kOutputSize = 1024 * 1024; + output = static_cast(gpr_malloc(kOutputSize)); + for (i = 0; i < kOutputSize - 1; ++i) { output[i] = chars[rand() % static_cast(sizeof(chars) - 1)]; } - output[output_size - 1] = '\0'; + output[kOutputSize - 1] = '\0'; grpc_slice out = grpc_slice_from_copied_string(output); gpr_free(output); return out; @@ -430,10 +430,32 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); gpr_free(json); + // TODO(ncteisen): add logic to query for socket id once child socket support + // is in place. For now, we hardcode uuid=5, which we know is a socket. + json = grpc_channelz_get_socket(5); + GPR_ASSERT(json != nullptr); + gpr_log(GPR_INFO, "%s", json); + GPR_ASSERT(nullptr != strstr(json, "\"socketId\":\"5\"")); + GPR_ASSERT(nullptr != strstr(json, "\"streamsStarted\":\"2\"")); + GPR_ASSERT(nullptr != strstr(json, "\"streamsSucceeded\":\"2\"")); + // no messaged sent yet. + GPR_ASSERT(nullptr == strstr(json, "\"messagesSent\"")); + GPR_ASSERT(nullptr == strstr(json, "\"messagesReceived\"")); + gpr_free(json); + // one successful request with payload to test socket data - // TODO(ncteisen): add some programatic spot checks on the socket json. run_one_request_with_payload(config, f); + json = grpc_channelz_get_socket(5); + GPR_ASSERT(json != nullptr); + gpr_log(GPR_INFO, "%s", json); + GPR_ASSERT(nullptr != strstr(json, "\"socketId\":\"5\"")); + GPR_ASSERT(nullptr != strstr(json, "\"streamsStarted\":\"3\"")); + GPR_ASSERT(nullptr != strstr(json, "\"streamsSucceeded\":\"3\"")); + GPR_ASSERT(nullptr != strstr(json, "\"messagesSent\":\"1\"")); + GPR_ASSERT(nullptr != strstr(json, "\"messagesReceived\":\"1\"")); + gpr_free(json); + end_test(&f); config.tear_down_data(&f); } From 7e34212e50b4275be556fe806bb7c259d77ab7d3 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 24 Sep 2018 16:36:55 -0700 Subject: [PATCH 434/546] Don't test socket in core end2end test --- test/core/end2end/tests/channelz.cc | 198 ---------------------------- 1 file changed, 198 deletions(-) diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index bb99045d1e5..40a0370f0ea 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -196,178 +196,6 @@ static void run_one_request(grpc_end2end_test_config config, cq_verifier_destroy(cqv); } -/* Creates and returns a grpc_slice containing random alphanumeric characters. - */ -static grpc_slice generate_random_slice() { - size_t i; - static const char chars[] = "abcdefghijklmnopqrstuvwxyz1234567890"; - char* output; - const size_t kOutputSize = 1024 * 1024; - output = static_cast(gpr_malloc(kOutputSize)); - for (i = 0; i < kOutputSize - 1; ++i) { - output[i] = chars[rand() % static_cast(sizeof(chars) - 1)]; - } - output[kOutputSize - 1] = '\0'; - grpc_slice out = grpc_slice_from_copied_string(output); - gpr_free(output); - return out; -} - -static void run_one_request_with_payload(grpc_end2end_test_config config, - grpc_end2end_test_fixture f) { - /* Create large request and response bodies. These are big enough to require - * multiple round trips to deliver to the peer, and their exact contents of - * will be verified on completion. */ - grpc_slice request_payload_slice = generate_random_slice(); - grpc_slice response_payload_slice = generate_random_slice(); - - grpc_call* c; - grpc_call* s; - 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); - cq_verifier* cqv = cq_verifier_create(f.cq); - 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_byte_buffer* request_payload_recv = nullptr; - grpc_byte_buffer* response_payload_recv = nullptr; - grpc_call_details call_details; - grpc_status_code status; - grpc_call_error error; - grpc_slice details; - int was_cancelled = 2; - - gpr_timespec deadline = n_seconds_from_now(60); - c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, - grpc_slice_from_static_string("/foo"), nullptr, - deadline, nullptr); - GPR_ASSERT(c); - - 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); - - memset(ops, 0, sizeof(ops)); - op = ops; - op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = 0; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_SEND_MESSAGE; - op->data.send_message.send_message = request_payload; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_INITIAL_METADATA; - op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message.recv_message = &response_payload_recv; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; - op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; - op->data.recv_status_on_client.status = &status; - op->data.recv_status_on_client.status_details = &details; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(c, ops, static_cast(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), 1); - cq_verify(cqv); - - memset(ops, 0, sizeof(ops)); - op = ops; - op->op = GRPC_OP_SEND_INITIAL_METADATA; - op->data.send_initial_metadata.count = 0; - op->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message.recv_message = &request_payload_recv; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(102), - nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - CQ_EXPECT_COMPLETION(cqv, tag(102), 1); - cq_verify(cqv); - - 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->flags = 0; - op->reserved = nullptr; - op++; - op->op = GRPC_OP_SEND_MESSAGE; - op->data.send_message.send_message = response_payload; - op->flags = 0; - op->reserved = nullptr; - 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; - grpc_slice status_details = grpc_slice_from_static_string("xyz"); - op->data.send_status_from_server.status_details = &status_details; - op->flags = 0; - op->reserved = nullptr; - op++; - error = grpc_call_start_batch(s, ops, static_cast(op - ops), tag(103), - nullptr); - GPR_ASSERT(GRPC_CALL_OK == error); - - CQ_EXPECT_COMPLETION(cqv, tag(103), 1); - CQ_EXPECT_COMPLETION(cqv, tag(1), 1); - 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, "/foo")); - GPR_ASSERT(was_cancelled == 0); - GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice)); - GPR_ASSERT( - byte_buffer_eq_slice(response_payload_recv, response_payload_slice)); - - 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_call_unref(c); - grpc_call_unref(s); - - cq_verifier_destroy(cqv); - - 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); -} - static void test_channelz(grpc_end2end_test_config config) { grpc_end2end_test_fixture f; @@ -430,32 +258,6 @@ static void test_channelz(grpc_end2end_test_config config) { GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\"")); gpr_free(json); - // TODO(ncteisen): add logic to query for socket id once child socket support - // is in place. For now, we hardcode uuid=5, which we know is a socket. - json = grpc_channelz_get_socket(5); - GPR_ASSERT(json != nullptr); - gpr_log(GPR_INFO, "%s", json); - GPR_ASSERT(nullptr != strstr(json, "\"socketId\":\"5\"")); - GPR_ASSERT(nullptr != strstr(json, "\"streamsStarted\":\"2\"")); - GPR_ASSERT(nullptr != strstr(json, "\"streamsSucceeded\":\"2\"")); - // no messaged sent yet. - GPR_ASSERT(nullptr == strstr(json, "\"messagesSent\"")); - GPR_ASSERT(nullptr == strstr(json, "\"messagesReceived\"")); - gpr_free(json); - - // one successful request with payload to test socket data - run_one_request_with_payload(config, f); - - json = grpc_channelz_get_socket(5); - GPR_ASSERT(json != nullptr); - gpr_log(GPR_INFO, "%s", json); - GPR_ASSERT(nullptr != strstr(json, "\"socketId\":\"5\"")); - GPR_ASSERT(nullptr != strstr(json, "\"streamsStarted\":\"3\"")); - GPR_ASSERT(nullptr != strstr(json, "\"streamsSucceeded\":\"3\"")); - GPR_ASSERT(nullptr != strstr(json, "\"messagesSent\":\"1\"")); - GPR_ASSERT(nullptr != strstr(json, "\"messagesReceived\":\"1\"")); - gpr_free(json); - end_test(&f); config.tear_down_data(&f); } From a4345934a3e8c2ca9531b5aec1630b9d468bd8f8 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 24 Sep 2018 16:50:39 -0700 Subject: [PATCH 435/546] Use unique port in php test --- src/php/tests/unit_tests/ChannelTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/php/tests/unit_tests/ChannelTest.php b/src/php/tests/unit_tests/ChannelTest.php index 49b0e350f72..583c618d32a 100644 --- a/src/php/tests/unit_tests/ChannelTest.php +++ b/src/php/tests/unit_tests/ChannelTest.php @@ -599,10 +599,10 @@ class ChannelTest extends PHPUnit_Framework_TestCase public function testPersistentChannelForceNewOldChannelIdle2() { - $this->channel1 = new Grpc\Channel('localhost:50029', [ + $this->channel1 = new Grpc\Channel('localhost:50032', [ "grpc_target_persist_bound" => 2, ]); - $this->channel2 = new Grpc\Channel('localhost:50029', []); + $this->channel2 = new Grpc\Channel('localhost:50032', []); // try to connect on channel2 $state = $this->channel1->getConnectivityState(true); From 805b8db33ced4888b325fdaf8980afdb7c155769 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 24 Sep 2018 22:07:56 -0700 Subject: [PATCH 436/546] fix asan --- src/core/ext/transport/chttp2/transport/chttp2_transport.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 9da9a7a63c3..d3232f4d268 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -157,6 +157,10 @@ bool g_flow_control_enabled = true; static void destruct_transport(grpc_chttp2_transport* t) { size_t i; + if (t->channelz_socket != nullptr) { + t->channelz_socket.reset(); + } + grpc_endpoint_destroy(t->ep); grpc_slice_buffer_destroy_internal(&t->qbuf); From cc0a1e1d7eca67f35f3c5bf002b1485df548e67e Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 25 Sep 2018 09:39:41 -0700 Subject: [PATCH 437/546] reviewer feedback: --- src/core/lib/channel/channelz.cc | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index df5c99f91e2..339c827525c 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -231,9 +231,24 @@ grpc_json* SocketNode::RenderJson() { GRPC_JSON_OBJECT, false); json = data; json_iterator = nullptr; + gpr_timespec ts; if (streams_started_ != 0) { json_iterator = grpc_json_add_number_string_child( json, json_iterator, "streamsStarted", streams_started_); + if (last_local_stream_created_millis_ != 0) { + ts = grpc_millis_to_timespec(last_local_stream_created_millis_, + GPR_CLOCK_REALTIME); + json_iterator = grpc_json_create_child( + json_iterator, json, "lastLocalStreamCreatedTimestamp", + gpr_format_timespec(ts), GRPC_JSON_STRING, true); + } + if (last_remote_stream_created_millis_ != 0) { + ts = grpc_millis_to_timespec(last_remote_stream_created_millis_, + GPR_CLOCK_REALTIME); + json_iterator = grpc_json_create_child( + json_iterator, json, "lastRemoteStreamCreatedTimestamp", + gpr_format_timespec(ts), GRPC_JSON_STRING, true); + } } if (streams_succeeded_ != 0) { json_iterator = grpc_json_add_number_string_child( @@ -243,7 +258,6 @@ grpc_json* SocketNode::RenderJson() { json_iterator = grpc_json_add_number_string_child( json, json_iterator, "streamsFailed", streams_failed_); } - gpr_timespec ts; if (messages_sent_ != 0) { json_iterator = grpc_json_add_number_string_child( json, json_iterator, "messagesSent", messages_sent_); @@ -265,22 +279,6 @@ grpc_json* SocketNode::RenderJson() { json_iterator = grpc_json_add_number_string_child( json, json_iterator, "keepAlivesSent", keepalives_sent_); } - if (streams_started_ != 0) { - if (last_local_stream_created_millis_ != 0) { - ts = grpc_millis_to_timespec(last_local_stream_created_millis_, - GPR_CLOCK_REALTIME); - json_iterator = grpc_json_create_child( - json_iterator, json, "lastLocalStreamCreatedTimestamp", - gpr_format_timespec(ts), GRPC_JSON_STRING, true); - } - if (last_remote_stream_created_millis_ != 0) { - ts = grpc_millis_to_timespec(last_remote_stream_created_millis_, - GPR_CLOCK_REALTIME); - json_iterator = grpc_json_create_child( - json_iterator, json, "lastRemoteStreamCreatedTimestamp", - gpr_format_timespec(ts), GRPC_JSON_STRING, true); - } - } return top_level_json; } From f83ca91702f666b6e8fb07e5004817e60b390dd7 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 25 Sep 2018 10:52:31 -0700 Subject: [PATCH 438/546] Fix crash in grpc_errorFromStatusCode --- .../GRPCClient/private/NSError+GRPC.h | 2 +- .../GRPCClient/private/NSError+GRPC.m | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/objective-c/GRPCClient/private/NSError+GRPC.h b/src/objective-c/GRPCClient/private/NSError+GRPC.h index a63e76ee4d0..fb05638b784 100644 --- a/src/objective-c/GRPCClient/private/NSError+GRPC.h +++ b/src/objective-c/GRPCClient/private/NSError+GRPC.h @@ -25,6 +25,6 @@ * and whose domain is |kGRPCErrorDomain|. */ + (instancetype)grpc_errorFromStatusCode:(grpc_status_code)statusCode - details:(char *)details + details:(const char *)details errorString:(const char *)errorString; @end diff --git a/src/objective-c/GRPCClient/private/NSError+GRPC.m b/src/objective-c/GRPCClient/private/NSError+GRPC.m index 199b2ebb6c3..c0f7e019a23 100644 --- a/src/objective-c/GRPCClient/private/NSError+GRPC.m +++ b/src/objective-c/GRPCClient/private/NSError+GRPC.m @@ -24,18 +24,20 @@ NSString *const kGRPCErrorDomain = @"io.grpc"; @implementation NSError (GRPC) + (instancetype)grpc_errorFromStatusCode:(grpc_status_code)statusCode - details:(char *)details + details:(const char *)details errorString:(const char *)errorString { if (statusCode == GRPC_STATUS_OK) { return nil; } - NSString *message = [NSString stringWithCString:details encoding:NSUTF8StringEncoding]; - NSString *debugMessage = [NSString stringWithCString:errorString encoding:NSUTF8StringEncoding]; + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + if (details) { + userInfo[NSLocalizedDescriptionKey] = [NSString stringWithCString:details encoding:NSUTF8StringEncoding]; + } + if (errorString) { + userInfo[NSDebugDescriptionErrorKey] = [NSString stringWithCString:errorString encoding:NSUTF8StringEncoding]; + } return [NSError errorWithDomain:kGRPCErrorDomain code:statusCode - userInfo:@{ - NSLocalizedDescriptionKey : message, - NSDebugDescriptionErrorKey : debugMessage - }]; + userInfo:userInfo]; } @end From bd1279ebf11960a29f726a56d3d62fc8f5c7ef79 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 25 Sep 2018 10:52:55 -0700 Subject: [PATCH 439/546] Add tests for NSError+GRPC --- src/objective-c/tests/Podfile | 1 + .../tests/Tests.xcodeproj/project.pbxproj | 257 ++++++++++++++++++ .../xcshareddata/xcschemes/UnitTests.xcscheme | 92 +++++++ src/objective-c/tests/UnitTests/Info.plist | 22 ++ src/objective-c/tests/UnitTests/UnitTests.m | 54 ++++ src/objective-c/tests/run_tests.sh | 10 + 6 files changed, 436 insertions(+) create mode 100644 src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/UnitTests.xcscheme create mode 100644 src/objective-c/tests/UnitTests/Info.plist create mode 100644 src/objective-c/tests/UnitTests/UnitTests.m diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 507d251b481..5d2f1340daa 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -14,6 +14,7 @@ GRPC_LOCAL_SRC = '../../..' InteropTestsLocalSSL InteropTestsLocalCleartext InteropTestsRemoteWithCronet + UnitTests ).each do |target_name| target target_name do pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index 0e0e8babc0f..f0d81232635 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -13,6 +13,8 @@ 16A9E77B6E336B3C0B9BA6E0 /* libPods-InteropTestsLocalSSL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */; }; 20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; }; 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; + 5E0282E9215AA697007AC99D /* UnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0282E8215AA697007AC99D /* UnitTests.m */; }; + 5E0282EB215AA697007AC99D /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */; }; 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; 5EAD6D271E27047400002378 /* CronetUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EAD6D261E27047400002378 /* CronetUnitTests.m */; }; @@ -54,10 +56,18 @@ 91D4B3C85B6D8562F409CB48 /* libPods-InteropTestsLocalSSLCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */; }; BC111C80CBF7068B62869352 /* libPods-InteropTestsRemoteCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */; }; C3D6F4270A2FFF634D8849ED /* libPods-InteropTestsLocalCleartextCFStream.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */; }; + CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */; }; F15EF7852DC70770EFDB1D2C /* libPods-AllTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 5E0282EC215AA697007AC99D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; 5E8A5DAA1D3840B4000F8BC4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 635697BF1B14FC11007A7283 /* Project object */; @@ -138,6 +148,7 @@ 1588C85DEAF7FC0ACDEA4C02 /* Pods-InteropTestsLocalCleartext.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.test.xcconfig"; sourceTree = ""; }; 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; sourceTree = ""; }; 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-UnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 2B89F3037963E6EDDD48D8C3 /* Pods-InteropTestsRemoteWithCronet.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.test.xcconfig"; sourceTree = ""; }; 303F4A17EB1650FC44603D17 /* Pods-InteropTestsRemoteCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.release.xcconfig"; sourceTree = ""; }; 32748C4078AEB05F8F954361 /* Pods-InteropTestsRemoteCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream.debug.xcconfig"; sourceTree = ""; }; @@ -155,6 +166,9 @@ 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig"; sourceTree = ""; }; 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; sourceTree = ""; }; 5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.release.xcconfig"; sourceTree = ""; }; + 5E0282E6215AA697007AC99D /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E0282E8215AA697007AC99D /* UnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnitTests.m; sourceTree = ""; }; + 5E0282EA215AA697007AC99D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CoreCronetEnd2EndTests.mm; sourceTree = ""; }; 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSLCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSLCFStream/Pods-InteropTestsLocalSSLCFStream.release.xcconfig"; sourceTree = ""; }; @@ -192,7 +206,9 @@ 7BA53C6D224288D5870FE6F3 /* Pods-InteropTestsLocalCleartextCFStream.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.release.xcconfig"; sourceTree = ""; }; 8B498B05C6DA0818B2FA91D4 /* Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.cronet.xcconfig"; sourceTree = ""; }; 943138072A9605B5B8DC1FC0 /* Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.debug.xcconfig"; sourceTree = ""; }; + 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.test.xcconfig"; sourceTree = ""; }; 9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteWithCronet.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + A2DCF2570BE515B62CB924CA /* Pods-UnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.debug.xcconfig"; sourceTree = ""; }; A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RxLibraryUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A6F832FCEFA6F6881E620F12 /* Pods-InteropTestsRemote.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.test.xcconfig"; sourceTree = ""; }; AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.cronet.xcconfig"; sourceTree = ""; }; @@ -208,9 +224,11 @@ DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalSSL.a"; sourceTree = BUILT_PRODUCTS_DIR; }; DC3CA1D948F068E76957A861 /* Pods-InteropTestsRemote.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.debug.xcconfig"; sourceTree = ""; }; E1486220285AF123EB124008 /* Pods-InteropTestsLocalCleartext.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.debug.xcconfig"; sourceTree = ""; }; + E1E7660656D902104F728892 /* Pods-UnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.cronet.xcconfig"; sourceTree = ""; }; E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.release.xcconfig"; sourceTree = ""; }; E4FD4606D4AB8D5A314D72F0 /* Pods-InteropTestsLocalCleartextCFStream.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartextCFStream.test.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartextCFStream/Pods-InteropTestsLocalCleartextCFStream.test.xcconfig"; sourceTree = ""; }; E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.cronet.xcconfig"; sourceTree = ""; }; + EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests.release.xcconfig"; sourceTree = ""; }; F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalSSLCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteCFStream.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CoreCronetEnd2EndTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -219,6 +237,15 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 5E0282E3215AA697007AC99D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E0282EB215AA697007AC99D /* libTests.a in Frameworks */, + CCF5C0719EF608276AE16374 /* libPods-UnitTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E8A5DA11D3840B4000F8BC4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -341,6 +368,7 @@ F44AC3F44E3491A8C0D890FE /* libPods-InteropTestsRemoteCFStream.a */, 0BDA4BA011779D5D25B5618C /* libPods-InteropTestsLocalCleartextCFStream.a */, F3AB031E0E26AC8EF30A2A2A /* libPods-InteropTestsLocalSSLCFStream.a */, + 22A3EBB488699C8CEA19707B /* libPods-UnitTests.a */, ); name = Frameworks; sourceTree = ""; @@ -394,10 +422,23 @@ 41AA59529240A6BBBD3DB904 /* Pods-InteropTestsLocalSSLCFStream.test.xcconfig */, 55B630C1FF8C36D1EFC4E0A4 /* Pods-InteropTestsLocalSSLCFStream.cronet.xcconfig */, 5EA908CF4CDA4CE218352A06 /* Pods-InteropTestsLocalSSLCFStream.release.xcconfig */, + A2DCF2570BE515B62CB924CA /* Pods-UnitTests.debug.xcconfig */, + 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */, + E1E7660656D902104F728892 /* Pods-UnitTests.cronet.xcconfig */, + EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */, ); name = Pods; sourceTree = ""; }; + 5E0282E7215AA697007AC99D /* UnitTests */ = { + isa = PBXGroup; + children = ( + 5E0282E8215AA697007AC99D /* UnitTests.m */, + 5E0282EA215AA697007AC99D /* Info.plist */, + ); + path = UnitTests; + sourceTree = ""; + }; 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { isa = PBXGroup; children = ( @@ -432,6 +473,7 @@ 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */, 5EE84BF21D4717E40050C6CC /* InteropTestsRemoteWithCronet */, 5EAD6D251E27047400002378 /* CronetUnitTests */, + 5E0282E7215AA697007AC99D /* UnitTests */, 635697C81B14FC11007A7283 /* Products */, 51E4650F34F854F41FF053B3 /* Pods */, 136D535E19727099B941D7B1 /* Frameworks */, @@ -453,6 +495,7 @@ 5EC5E421208177CC000EF4AD /* InteropTestsRemoteCFStream.xctest */, 5EC5E4312081856B000EF4AD /* InteropTestsLocalCleartextCFStream.xctest */, 5EC5E442208185CE000EF4AD /* InteropTestsLocalSSLCFStream.xctest */, + 5E0282E6215AA697007AC99D /* UnitTests.xctest */, ); name = Products; sourceTree = ""; @@ -485,6 +528,26 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 5E0282E5215AA697007AC99D /* UnitTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E0282F2215AA697007AC99D /* Build configuration list for PBXNativeTarget "UnitTests" */; + buildPhases = ( + F07941C0BAF6A7C67AA60C48 /* [CP] Check Pods Manifest.lock */, + 5E0282E2215AA697007AC99D /* Sources */, + 5E0282E3215AA697007AC99D /* Frameworks */, + 5E0282E4215AA697007AC99D /* Resources */, + 9AD0B5E94F2AA5962EA6AA36 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5E0282ED215AA697007AC99D /* PBXTargetDependency */, + ); + name = UnitTests; + productName = UnitTests; + productReference = 5E0282E6215AA697007AC99D /* UnitTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { isa = PBXNativeTarget; buildConfigurationList = 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */; @@ -729,6 +792,10 @@ LastUpgradeCheck = 0630; ORGANIZATIONNAME = gRPC; TargetAttributes = { + 5E0282E5215AA697007AC99D = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + }; 5E8A5DA31D3840B4000F8BC4 = { CreatedOnToolsVersion = 7.3.1; }; @@ -794,11 +861,19 @@ 5EC5E420208177CC000EF4AD /* InteropTestsRemoteCFStream */, 5EC5E4302081856B000EF4AD /* InteropTestsLocalCleartextCFStream */, 5EC5E441208185CE000EF4AD /* InteropTestsLocalSSLCFStream */, + 5E0282E5215AA697007AC99D /* UnitTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 5E0282E4215AA697007AC99D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E8A5DA21D3840B4000F8BC4 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1098,6 +1173,24 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteCFStream/Pods-InteropTestsRemoteCFStream-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 9AD0B5E94F2AA5962EA6AA36 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-UnitTests/Pods-UnitTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; A023FB55205A7EA37D413549 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1260,6 +1353,24 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + F07941C0BAF6A7C67AA60C48 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-UnitTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; F3D5B2CDA172580341682830 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1299,6 +1410,14 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 5E0282E2215AA697007AC99D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E0282E9215AA697007AC99D /* UnitTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5E8A5DA01D3840B4000F8BC4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1412,6 +1531,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 5E0282ED215AA697007AC99D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5E0282EC215AA697007AC99D /* PBXContainerItemProxy */; + }; 5E8A5DAB1D3840B4000F8BC4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 635697C61B14FC11007A7283 /* Tests */; @@ -1455,6 +1579,128 @@ /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ + 5E0282EE215AA697007AC99D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A2DCF2570BE515B62CB924CA /* Pods-UnitTests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = UnitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = "\"$(PODS_ROOT)/../../../..\""; + }; + name = Debug; + }; + 5E0282EF215AA697007AC99D /* Test */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 94D7A5FAA13480E9A5166D7A /* Pods-UnitTests.test.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = UnitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = "\"$(PODS_ROOT)/../../../..\""; + }; + name = Test; + }; + 5E0282F0215AA697007AC99D /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E1E7660656D902104F728892 /* Pods-UnitTests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = UnitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = "\"$(PODS_ROOT)/../../../..\""; + }; + name = Cronet; + }; + 5E0282F1215AA697007AC99D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EBFFEC04B514CB0D4922DC40 /* Pods-UnitTests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = UnitTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.UnitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = "\"$(PODS_ROOT)/../../../..\""; + }; + name = Release; + }; 5E1228981E4D400F00E8504F /* Test */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2602,6 +2848,17 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 5E0282F2215AA697007AC99D /* Build configuration list for PBXNativeTarget "UnitTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E0282EE215AA697007AC99D /* Debug */, + 5E0282EF215AA697007AC99D /* Test */, + 5E0282F0215AA697007AC99D /* Cronet */, + 5E0282F1215AA697007AC99D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/UnitTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/UnitTests.xcscheme new file mode 100644 index 00000000000..3af3555f48e --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/UnitTests.xcscheme @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/UnitTests/Info.plist b/src/objective-c/tests/UnitTests/Info.plist new file mode 100644 index 00000000000..6c40a6cd0c4 --- /dev/null +++ b/src/objective-c/tests/UnitTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/src/objective-c/tests/UnitTests/UnitTests.m b/src/objective-c/tests/UnitTests/UnitTests.m new file mode 100644 index 00000000000..002c4f86594 --- /dev/null +++ b/src/objective-c/tests/UnitTests/UnitTests.m @@ -0,0 +1,54 @@ +/* + * + * 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. + * + */ + +#import + +#import + +#import "src/objective-c/GRPCClient/private/NSError+GRPC.h" + +@interface UnitTests : XCTestCase + +@end + +@implementation UnitTests + +- (void)testNSError { + const char *kDetails = "test details"; + const char *kErrorString = "test errorString"; + NSError *error1 = [NSError grpc_errorFromStatusCode:GRPC_STATUS_OK details:nil errorString:nil]; + NSError *error2 = [NSError grpc_errorFromStatusCode:GRPC_STATUS_CANCELLED details:kDetails errorString:kErrorString]; + NSError *error3 = [NSError grpc_errorFromStatusCode:GRPC_STATUS_UNAUTHENTICATED details:kDetails errorString:nil]; + NSError *error4 = [NSError grpc_errorFromStatusCode:GRPC_STATUS_UNAVAILABLE details:nil errorString:nil]; + + XCTAssertNil(error1); + XCTAssertEqual(error2.code, 1); + XCTAssertEqualObjects(error2.domain, @"io.grpc"); + XCTAssertEqualObjects(error2.userInfo[NSLocalizedDescriptionKey], [NSString stringWithUTF8String:kDetails]); + XCTAssertEqualObjects(error2.userInfo[NSDebugDescriptionErrorKey], [NSString stringWithUTF8String:kErrorString]); + XCTAssertEqual(error3.code, 16); + XCTAssertEqualObjects(error3.domain, @"io.grpc"); + XCTAssertEqualObjects(error3.userInfo[NSLocalizedDescriptionKey], [NSString stringWithUTF8String:kDetails]); + XCTAssertNil(error3.userInfo[NSDebugDescriptionErrorKey]); + XCTAssertEqual(error4.code, 14); + XCTAssertEqualObjects(error4.domain, @"io.grpc"); + XCTAssertNil(error4.userInfo[NSLocalizedDescriptionKey]); + XCTAssertNil(error4.userInfo[NSDebugDescriptionErrorKey]); +} + +@end diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index 9dde07d55c8..f37c6cf9f62 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -163,4 +163,14 @@ xcodebuild \ | egrep -v '^$' \ | egrep -v "(GPBDictionary|GPBArray)" - +echo "TIME: $(date)" +xcodebuild \ + -workspace Tests.xcworkspace \ + -scheme UnitTests \ + -destination name="iPhone 8" \ + test \ + | egrep -v "$XCODEBUILD_FILTER" \ + | egrep -v '^$' \ + | egrep -v "(GPBDictionary|GPBArray)" - + exit 0 From 10447318588a281d737af159a5dceec142135a43 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 25 Sep 2018 20:37:02 +0200 Subject: [PATCH 440/546] add DeserializationContext implementation note --- src/csharp/Grpc.Core/DeserializationContext.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/csharp/Grpc.Core/DeserializationContext.cs b/src/csharp/Grpc.Core/DeserializationContext.cs index 96de08f76d7..5b6372ef85d 100644 --- a/src/csharp/Grpc.Core/DeserializationContext.cs +++ b/src/csharp/Grpc.Core/DeserializationContext.cs @@ -37,6 +37,8 @@ namespace Grpc.Core /// Also, allocating a new buffer each time can put excessive pressure on GC, especially if /// the payload is more than 86700 bytes large (which means the newly allocated buffer will be placed in LOH, /// and LOH object can only be garbage collected via a full ("stop the world") GC run). + /// NOTE: Deserializers are expected not to call this method more than once per received message + /// (as there is no practical reason for doing so) and DeserializationContext implementations are free to assume so. /// /// byte array containing the entire payload. public abstract byte[] PayloadAsNewBuffer(); From 46a97e5f550f12c9b1dbef7657a0ff42694a0932 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 25 Sep 2018 16:48:14 -0400 Subject: [PATCH 441/546] Avoid extra branches in grpc_error_get_(str|int). Moving the check for "which" inside the for loop, will let the compiler unroll the loop and merge it with the branches grpc_error_is_especial. This is visible in the following godbolts: Before: https://godbolt.org/z/Nqujh1 After: https://godbolt.org/z/fA2PX- --- src/core/lib/iomgr/error.cc | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index 13bc69ffb60..146a539027d 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -454,7 +454,7 @@ typedef struct { grpc_status_code code; const char* msg; } special_error_status_map; -static special_error_status_map error_status_map[] = { +static const special_error_status_map error_status_map[] = { {GRPC_ERROR_NONE, GRPC_STATUS_OK, ""}, {GRPC_ERROR_CANCELLED, GRPC_STATUS_CANCELLED, "Cancelled"}, {GRPC_ERROR_OOM, GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"}, @@ -463,15 +463,13 @@ static special_error_status_map error_status_map[] = { bool grpc_error_get_int(grpc_error* err, grpc_error_ints which, intptr_t* p) { GPR_TIMER_SCOPE("grpc_error_get_int", 0); if (grpc_error_is_special(err)) { - if (which == GRPC_ERROR_INT_GRPC_STATUS) { - for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) { - if (error_status_map[i].error == err) { - if (p != nullptr) *p = error_status_map[i].code; - return true; - } + for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) { + if (error_status_map[i].error == err) { + if (which != GRPC_ERROR_INT_GRPC_STATUS) return false; + if (p != nullptr) *p = error_status_map[i].code; + return true; } } - return false; } uint8_t slot = err->ints[which]; if (slot != UINT8_MAX) { @@ -492,15 +490,13 @@ grpc_error* grpc_error_set_str(grpc_error* src, grpc_error_strs which, bool grpc_error_get_str(grpc_error* err, grpc_error_strs which, grpc_slice* str) { if (grpc_error_is_special(err)) { - if (which == GRPC_ERROR_STR_GRPC_MESSAGE) { - for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) { - if (error_status_map[i].error == err) { - *str = grpc_slice_from_static_string(error_status_map[i].msg); - return true; - } + for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) { + if (error_status_map[i].error == err) { + if (which != GRPC_ERROR_STR_GRPC_MESSAGE) return false; + *str = grpc_slice_from_static_string(error_status_map[i].msg); + return true; } } - return false; } uint8_t slot = err->strs[which]; if (slot != UINT8_MAX) { From c2fd689bad731f30b2ab43a5613e164f7e44be5c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 25 Sep 2018 23:02:42 +0200 Subject: [PATCH 442/546] address comments --- src/csharp/Grpc.Core/Marshaller.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core/Marshaller.cs index 7f010dc4192..0af9aa586bf 100644 --- a/src/csharp/Grpc.Core/Marshaller.cs +++ b/src/csharp/Grpc.Core/Marshaller.cs @@ -57,6 +57,8 @@ namespace Grpc.Core { this.contextualSerializer = GrpcPreconditions.CheckNotNull(serializer, nameof(serializer)); this.contextualDeserializer = GrpcPreconditions.CheckNotNull(deserializer, nameof(deserializer)); + // TODO(jtattermusch): once gRPC C# library switches to using contextual (de)serializer, + // emulating the simple (de)serializer will become unnecessary. this.serializer = EmulateSimpleSerializer; this.deserializer = EmulateSimpleDeserializer; } @@ -87,6 +89,7 @@ namespace Grpc.Core private byte[] EmulateSimpleSerializer(T msg) { // TODO(jtattermusch): avoid the allocation by passing a thread-local instance + // This code will become unnecessary once gRPC C# library switches to using contextual (de)serializer. var context = new EmulatedSerializationContext(); this.contextualSerializer(msg, context); return context.GetPayload(); @@ -96,6 +99,7 @@ namespace Grpc.Core private T EmulateSimpleDeserializer(byte[] payload) { // TODO(jtattermusch): avoid the allocation by passing a thread-local instance + // This code will become unnecessary once gRPC C# library switches to using contextual (de)serializer. var context = new EmulatedDeserializationContext(payload); return this.contextualDeserializer(context); } @@ -134,6 +138,7 @@ namespace Grpc.Core internal class EmulatedDeserializationContext : DeserializationContext { readonly byte[] payload; + bool alreadyCalledPayloadAsNewBuffer; public EmulatedDeserializationContext(byte[] payload) { @@ -144,6 +149,8 @@ namespace Grpc.Core public override byte[] PayloadAsNewBuffer() { + GrpcPreconditions.CheckState(!alreadyCalledPayloadAsNewBuffer); + alreadyCalledPayloadAsNewBuffer = true; return payload; } } From 87592fe9d9c54d6178966f40f4182e0bf6445380 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 14 Sep 2018 11:47:44 -0700 Subject: [PATCH 443/546] support custom logfile name in jobset.py --- tools/run_tests/python_utils/jobset.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/python_utils/jobset.py b/tools/run_tests/python_utils/jobset.py index 561f453da7b..35faed448d9 100755 --- a/tools/run_tests/python_utils/jobset.py +++ b/tools/run_tests/python_utils/jobset.py @@ -176,13 +176,15 @@ class JobSpec(object): timeout_retries=0, kill_handler=None, cpu_cost=1.0, - verbose_success=False): + verbose_success=False, + logfilename=None): """ Arguments: cmdline: a list of arguments to pass as the command line environ: a dictionary of environment variables to set in the child process kill_handler: a handler that will be called whenever job.kill() is invoked cpu_cost: number of cores per second this job needs + logfilename: use given file to store job's output, rather than using a temporary file """ if environ is None: environ = {} @@ -197,6 +199,10 @@ class JobSpec(object): self.kill_handler = kill_handler self.cpu_cost = cpu_cost self.verbose_success = verbose_success + self.logfilename = logfilename + if self.logfilename and self.flake_retries != 0 and self.timeout_retries != 0: + raise Exception( + 'Cannot use custom logfile when retries are enabled') def identity(self): return '%r %r' % (self.cmdline, self.environ) @@ -261,7 +267,15 @@ class Job(object): return self._spec def start(self): - self._tempfile = tempfile.TemporaryFile() + if self._spec.logfilename: + # make sure the log directory exists + logfile_dir = os.path.dirname( + os.path.abspath(self._spec.logfilename)) + if not os.path.exists(logfile_dir): + os.makedirs(logfile_dir) + self._tempfile = open(self._spec.logfilename, 'w+') + else: + self._tempfile = tempfile.TemporaryFile() env = dict(os.environ) env.update(self._spec.environ) env.update(self._add_env) From f952579464cf298bf9d0df3e5c3d4d74c666b903 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 14 Sep 2018 11:48:27 -0700 Subject: [PATCH 444/546] make logs available by run_tests_matrix.py suites --- tools/run_tests/run_tests_matrix.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index 1bbec94ee12..f8fcce45a4f 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -43,9 +43,6 @@ _OBJC_RUNTESTS_TIMEOUT = 90 * 60 # Number of jobs assigned to each run_tests.py instance _DEFAULT_INNER_JOBS = 2 -# report suffix is important for reports to get picked up by internal CI -_REPORT_SUFFIX = 'sponge_log.xml' - def _safe_report_name(name): """Reports with '+' in target name won't show correctly in ResultStore""" @@ -54,7 +51,14 @@ def _safe_report_name(name): def _report_filename(name): """Generates report file name with directory structure that leads to better presentation by internal CI""" - return '%s/%s' % (_safe_report_name(name), _REPORT_SUFFIX) + # 'sponge_log.xml' suffix must be there for results to get recognized by kokoro. + return '%s/%s' % (_safe_report_name(name), 'sponge_log.xml') + + +def _report_logfilename(name): + """Generates report file name with directory structure that leads to better presentation by internal CI""" + # 'sponge_log.log' suffix must be there for test log to get recognized by kokoro. + return '%s/%s' % (_safe_report_name(name), 'sponge_log.log') def _docker_jobspec(name, @@ -75,7 +79,8 @@ def _docker_jobspec(name, ] + runtests_args, environ=runtests_envs, shortname='run_tests_%s' % name, - timeout_seconds=timeout_seconds) + timeout_seconds=timeout_seconds, + logfilename=_report_logfilename(name)) return test_job @@ -102,7 +107,8 @@ def _workspace_jobspec(name, ] + runtests_args, environ=env, shortname='run_tests_%s' % name, - timeout_seconds=timeout_seconds) + timeout_seconds=timeout_seconds, + logfilename=_report_logfilename(name)) return test_job From ef1f8401e104ffc8a4d909985a83ea34a704b554 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 14 Sep 2018 12:02:45 -0700 Subject: [PATCH 445/546] update artifact cleanup script --- tools/internal_ci/helper_scripts/delete_nonartifacts.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/internal_ci/helper_scripts/delete_nonartifacts.sh b/tools/internal_ci/helper_scripts/delete_nonartifacts.sh index c7d6ba6d446..01e9427e1c7 100755 --- a/tools/internal_ci/helper_scripts/delete_nonartifacts.sh +++ b/tools/internal_ci/helper_scripts/delete_nonartifacts.sh @@ -24,4 +24,4 @@ cd "$(dirname "$0")/../../.." # after finishing each build. We only leave files we want to keep: # - reports and artifacts # - directory containing the kokoro scripts to prevent deleting a script while being executed. -time find . -type f -not -iname "*sponge_log.xml" -not -path "./reports/*" -not -path "./artifacts/*" -not -path "./tools/internal_ci/*" -exec rm -f {} + +time find . -type f -not -iname "*sponge_log.*" -not -path "./reports/*" -not -path "./artifacts/*" -not -path "./tools/internal_ci/*" -exec rm -f {} + From 58f167abebdcf8276da52ac295712c1a808ffca7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 14 Sep 2018 12:04:38 -0700 Subject: [PATCH 446/546] upload both sponge_log.xml and sponge_log.log --- tools/internal_ci/linux/grpc_basictests_c_cpp_dbg.cfg | 2 +- tools/internal_ci/linux/grpc_basictests_c_cpp_opt.cfg | 2 +- tools/internal_ci/linux/grpc_basictests_multilang.cfg | 2 +- tools/internal_ci/linux/grpc_build_artifacts.cfg | 2 +- tools/internal_ci/linux/grpc_build_artifacts_extra.cfg | 2 +- tools/internal_ci/linux/grpc_build_artifacts_extra_release.cfg | 2 +- tools/internal_ci/linux/grpc_build_boringssl_at_head.cfg | 2 +- tools/internal_ci/linux/grpc_build_packages.cfg | 2 +- tools/internal_ci/linux/grpc_build_protobuf_at_head.cfg | 2 +- tools/internal_ci/linux/grpc_coverage.cfg | 2 +- tools/internal_ci/linux/grpc_distribtests.cfg | 2 +- tools/internal_ci/linux/grpc_distribtests_standalone.cfg | 2 +- tools/internal_ci/linux/grpc_full_performance_master.cfg | 2 +- tools/internal_ci/linux/grpc_full_performance_release.cfg | 2 +- tools/internal_ci/linux/grpc_interop_alts.cfg | 2 +- tools/internal_ci/linux/grpc_interop_matrix.cfg | 2 +- tools/internal_ci/linux/grpc_interop_tocloud.cfg | 2 +- tools/internal_ci/linux/grpc_interop_toprod.cfg | 2 +- tools/internal_ci/linux/grpc_portability.cfg | 2 +- tools/internal_ci/linux/grpc_portability_build_only.cfg | 2 +- tools/internal_ci/linux/grpc_publish_packages.cfg | 2 +- tools/internal_ci/linux/grpc_pull_request_sanity.cfg | 2 +- tools/internal_ci/linux/grpc_sanity.cfg | 2 +- .../linux/pull_request/grpc_basictests_c_cpp_dbg.cfg | 2 +- .../linux/pull_request/grpc_basictests_c_cpp_opt.cfg | 2 +- tools/internal_ci/linux/pull_request/grpc_basictests_c_dbg.cfg | 2 +- tools/internal_ci/linux/pull_request/grpc_basictests_c_opt.cfg | 2 +- .../internal_ci/linux/pull_request/grpc_basictests_cpp_dbg.cfg | 2 +- .../internal_ci/linux/pull_request/grpc_basictests_cpp_opt.cfg | 2 +- .../linux/pull_request/grpc_basictests_multilang.cfg | 2 +- tools/internal_ci/linux/pull_request/grpc_interop_alts.cfg | 2 +- tools/internal_ci/linux/pull_request/grpc_interop_tocloud.cfg | 2 +- tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg | 2 +- .../internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg | 2 +- tools/internal_ci/linux/pull_request/grpc_sanity.cfg | 2 +- tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg | 2 +- tools/internal_ci/linux/sanitizer/grpc_c_asan.cfg | 2 +- tools/internal_ci/linux/sanitizer/grpc_c_msan.cfg | 2 +- tools/internal_ci/linux/sanitizer/grpc_c_tsan.cfg | 2 +- tools/internal_ci/linux/sanitizer/grpc_c_ubsan.cfg | 2 +- tools/internal_ci/linux/sanitizer/grpc_cpp_asan.cfg | 2 +- tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.cfg | 2 +- tools/internal_ci/linux/sanitizer/pull_request/grpc_c_asan.cfg | 2 +- tools/internal_ci/linux/sanitizer/pull_request/grpc_c_msan.cfg | 2 +- tools/internal_ci/linux/sanitizer/pull_request/grpc_c_tsan.cfg | 2 +- tools/internal_ci/linux/sanitizer/pull_request/grpc_c_ubsan.cfg | 2 +- .../internal_ci/linux/sanitizer/pull_request/grpc_cpp_asan.cfg | 2 +- .../internal_ci/linux/sanitizer/pull_request/grpc_cpp_tsan.cfg | 2 +- tools/internal_ci/macos/grpc_basictests_dbg.cfg | 2 +- tools/internal_ci/macos/grpc_basictests_opt.cfg | 2 +- tools/internal_ci/macos/grpc_build_artifacts.cfg | 2 +- tools/internal_ci/macos/grpc_distribtests.cfg | 2 +- tools/internal_ci/macos/grpc_interop.cfg | 2 +- tools/internal_ci/macos/grpc_interop_toprod.cfg | 2 +- tools/internal_ci/macos/pull_request/grpc_basictests_dbg.cfg | 2 +- tools/internal_ci/macos/pull_request/grpc_basictests_opt.cfg | 2 +- tools/internal_ci/macos/pull_request/grpc_interop.cfg | 2 +- tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg | 2 +- tools/internal_ci/windows/grpc_basictests.cfg | 2 +- tools/internal_ci/windows/grpc_basictests_dbg.cfg | 2 +- tools/internal_ci/windows/grpc_basictests_opt.cfg | 2 +- tools/internal_ci/windows/grpc_build_artifacts.cfg | 2 +- tools/internal_ci/windows/grpc_build_packages.cfg | 2 +- tools/internal_ci/windows/grpc_distribtests.cfg | 2 +- tools/internal_ci/windows/grpc_distribtests_standalone.cfg | 2 +- tools/internal_ci/windows/grpc_portability.cfg | 2 +- tools/internal_ci/windows/grpc_portability_build_only.cfg | 2 +- tools/internal_ci/windows/pull_request/grpc_basictests.cfg | 2 +- tools/internal_ci/windows/pull_request/grpc_basictests_dbg.cfg | 2 +- tools/internal_ci/windows/pull_request/grpc_basictests_opt.cfg | 2 +- tools/internal_ci/windows/pull_request/grpc_portability.cfg | 2 +- 71 files changed, 71 insertions(+), 71 deletions(-) diff --git a/tools/internal_ci/linux/grpc_basictests_c_cpp_dbg.cfg b/tools/internal_ci/linux/grpc_basictests_c_cpp_dbg.cfg index 4a0badf43bc..07f7f0c6591 100644 --- a/tools/internal_ci/linux/grpc_basictests_c_cpp_dbg.cfg +++ b/tools/internal_ci/linux/grpc_basictests_c_cpp_dbg.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_basictests_c_cpp_opt.cfg b/tools/internal_ci/linux/grpc_basictests_c_cpp_opt.cfg index a2cfe021e16..8f2813febf8 100644 --- a/tools/internal_ci/linux/grpc_basictests_c_cpp_opt.cfg +++ b/tools/internal_ci/linux/grpc_basictests_c_cpp_opt.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_basictests_multilang.cfg b/tools/internal_ci/linux/grpc_basictests_multilang.cfg index 4433d14cd72..f8a5a4aea51 100644 --- a/tools/internal_ci/linux/grpc_basictests_multilang.cfg +++ b/tools/internal_ci/linux/grpc_basictests_multilang.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_build_artifacts.cfg b/tools/internal_ci/linux/grpc_build_artifacts.cfg index 88fc6b7b358..1e04a1e7880 100644 --- a/tools/internal_ci/linux/grpc_build_artifacts.cfg +++ b/tools/internal_ci/linux/grpc_build_artifacts.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_build_artifacts.sh" timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/linux/grpc_build_artifacts_extra.cfg b/tools/internal_ci/linux/grpc_build_artifacts_extra.cfg index 619e3ea3a97..2737e2f3453 100644 --- a/tools/internal_ci/linux/grpc_build_artifacts_extra.cfg +++ b/tools/internal_ci/linux/grpc_build_artifacts_extra.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_build_artifacts_extra.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/linux/grpc_build_artifacts_extra_release.cfg b/tools/internal_ci/linux/grpc_build_artifacts_extra_release.cfg index 619e3ea3a97..2737e2f3453 100644 --- a/tools/internal_ci/linux/grpc_build_artifacts_extra_release.cfg +++ b/tools/internal_ci/linux/grpc_build_artifacts_extra_release.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_build_artifacts_extra.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/linux/grpc_build_boringssl_at_head.cfg b/tools/internal_ci/linux/grpc_build_boringssl_at_head.cfg index 11c211fd2b4..9a430db0f9a 100644 --- a/tools/internal_ci/linux/grpc_build_boringssl_at_head.cfg +++ b/tools/internal_ci/linux/grpc_build_boringssl_at_head.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_build_submodule_at_head.sh" timeout_mins: 180 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_build_packages.cfg b/tools/internal_ci/linux/grpc_build_packages.cfg index 6a4a163dfca..23a676cf727 100644 --- a/tools/internal_ci/linux/grpc_build_packages.cfg +++ b/tools/internal_ci/linux/grpc_build_packages.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_build_packages.sh" timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/linux/grpc_build_protobuf_at_head.cfg b/tools/internal_ci/linux/grpc_build_protobuf_at_head.cfg index 2f08e15e638..aef6a7a1dcb 100644 --- a/tools/internal_ci/linux/grpc_build_protobuf_at_head.cfg +++ b/tools/internal_ci/linux/grpc_build_protobuf_at_head.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_build_submodule_at_head.sh" timeout_mins: 180 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_coverage.cfg b/tools/internal_ci/linux/grpc_coverage.cfg index 794a51d3f13..6eb37b7dec3 100644 --- a/tools/internal_ci/linux/grpc_coverage.cfg +++ b/tools/internal_ci/linux/grpc_coverage.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_coverage.sh" timeout_mins: 420 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_distribtests.cfg b/tools/internal_ci/linux/grpc_distribtests.cfg index 0f1d79355a6..848d5713336 100644 --- a/tools/internal_ci/linux/grpc_distribtests.cfg +++ b/tools/internal_ci/linux/grpc_distribtests.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_distribtests.sh" timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/linux/grpc_distribtests_standalone.cfg b/tools/internal_ci/linux/grpc_distribtests_standalone.cfg index bc6c8e8f805..734bdfd78a7 100644 --- a/tools/internal_ci/linux/grpc_distribtests_standalone.cfg +++ b/tools/internal_ci/linux/grpc_distribtests_standalone.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_distribtests_standalone.sh" timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/linux/grpc_full_performance_master.cfg b/tools/internal_ci/linux/grpc_full_performance_master.cfg index 8852130a139..8ad93ee0529 100644 --- a/tools/internal_ci/linux/grpc_full_performance_master.cfg +++ b/tools/internal_ci/linux/grpc_full_performance_master.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_full_performance_master.sh" timeout_mins: 600 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "**/perf_reports/**" } } diff --git a/tools/internal_ci/linux/grpc_full_performance_release.cfg b/tools/internal_ci/linux/grpc_full_performance_release.cfg index e9a4bcdcaf3..11a95e889fa 100644 --- a/tools/internal_ci/linux/grpc_full_performance_release.cfg +++ b/tools/internal_ci/linux/grpc_full_performance_release.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_full_performance_release.sh" timeout_mins: 600 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "**/perf_reports/**" } } diff --git a/tools/internal_ci/linux/grpc_interop_alts.cfg b/tools/internal_ci/linux/grpc_interop_alts.cfg index bda76faf440..4684aba96bf 100644 --- a/tools/internal_ci/linux/grpc_interop_alts.cfg +++ b/tools/internal_ci/linux/grpc_interop_alts.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_interop_tests.sh" timeout_mins: 60 action { define_artifacts { - regex: "**/sponge_log.xml" + regex: "**/sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_interop_matrix.cfg b/tools/internal_ci/linux/grpc_interop_matrix.cfg index ae59e930f77..696a55c0df2 100644 --- a/tools/internal_ci/linux/grpc_interop_matrix.cfg +++ b/tools/internal_ci/linux/grpc_interop_matrix.cfg @@ -20,7 +20,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_interop_matrix.sh" timeout_mins: 300 action { define_artifacts { - regex: "**/sponge_log.xml" + regex: "**/sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_interop_tocloud.cfg b/tools/internal_ci/linux/grpc_interop_tocloud.cfg index 81f2fe9dec6..9b35adcece2 100644 --- a/tools/internal_ci/linux/grpc_interop_tocloud.cfg +++ b/tools/internal_ci/linux/grpc_interop_tocloud.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_interop_tests.sh" timeout_mins: 60 action { define_artifacts { - regex: "**/sponge_log.xml" + regex: "**/sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_interop_toprod.cfg b/tools/internal_ci/linux/grpc_interop_toprod.cfg index 8dfc529947c..de4db81e6ba 100644 --- a/tools/internal_ci/linux/grpc_interop_toprod.cfg +++ b/tools/internal_ci/linux/grpc_interop_toprod.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_interop_tests.sh" timeout_mins: 60 action { define_artifacts { - regex: "**/sponge_log.xml" + regex: "**/sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_portability.cfg b/tools/internal_ci/linux/grpc_portability.cfg index 76e50284777..f417f24bb1c 100644 --- a/tools/internal_ci/linux/grpc_portability.cfg +++ b/tools/internal_ci/linux/grpc_portability.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 1440 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_portability_build_only.cfg b/tools/internal_ci/linux/grpc_portability_build_only.cfg index 4acd9353fb4..fab9dde3e58 100644 --- a/tools/internal_ci/linux/grpc_portability_build_only.cfg +++ b/tools/internal_ci/linux/grpc_portability_build_only.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 180 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_publish_packages.cfg b/tools/internal_ci/linux/grpc_publish_packages.cfg index 82d571d642c..dc9fe7d0a7a 100644 --- a/tools/internal_ci/linux/grpc_publish_packages.cfg +++ b/tools/internal_ci/linux/grpc_publish_packages.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_publish_packages.sh" timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/linux/grpc_pull_request_sanity.cfg b/tools/internal_ci/linux/grpc_pull_request_sanity.cfg index b20d2ffba8e..704d5c6cbc9 100644 --- a/tools/internal_ci/linux/grpc_pull_request_sanity.cfg +++ b/tools/internal_ci/linux/grpc_pull_request_sanity.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 30 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/grpc_sanity.cfg b/tools/internal_ci/linux/grpc_sanity.cfg index 9f65918e23a..341471bbb58 100644 --- a/tools/internal_ci/linux/grpc_sanity.cfg +++ b/tools/internal_ci/linux/grpc_sanity.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 40 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_dbg.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_dbg.cfg index 8124f5c1b3f..8a67d28ce4c 100644 --- a/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_dbg.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_dbg.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_opt.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_opt.cfg index ecedc73e44d..a681978b6e2 100644 --- a/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_opt.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_opt.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_c_dbg.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_c_dbg.cfg index 577cb28ae5f..249ecc99ce2 100644 --- a/tools/internal_ci/linux/pull_request/grpc_basictests_c_dbg.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_c_dbg.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_c_opt.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_c_opt.cfg index 9e0b724b2e1..665d7f3d2c9 100644 --- a/tools/internal_ci/linux/pull_request/grpc_basictests_c_opt.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_c_opt.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_cpp_dbg.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_cpp_dbg.cfg index 0fda74cf44e..163274d4dc3 100644 --- a/tools/internal_ci/linux/pull_request/grpc_basictests_cpp_dbg.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_cpp_dbg.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_cpp_opt.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_cpp_opt.cfg index 199a8905d94..b65cd3e05c2 100644 --- a/tools/internal_ci/linux/pull_request/grpc_basictests_cpp_opt.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_cpp_opt.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_basictests_multilang.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_multilang.cfg index f7e8d8ad33c..59f38f0d1b2 100644 --- a/tools/internal_ci/linux/pull_request/grpc_basictests_multilang.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_basictests_multilang.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_interop_alts.cfg b/tools/internal_ci/linux/pull_request/grpc_interop_alts.cfg index c1253b30f72..e91a6128788 100644 --- a/tools/internal_ci/linux/pull_request/grpc_interop_alts.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_interop_alts.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_interop_tests.sh" timeout_mins: 60 action { define_artifacts { - regex: "**/sponge_log.xml" + regex: "**/sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_interop_tocloud.cfg b/tools/internal_ci/linux/pull_request/grpc_interop_tocloud.cfg index cb18e8e8682..b1eb5756054 100644 --- a/tools/internal_ci/linux/pull_request/grpc_interop_tocloud.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_interop_tocloud.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_interop_tests.sh" timeout_mins: 60 action { define_artifacts { - regex: "**/sponge_log.xml" + regex: "**/sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg b/tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg index d14c79a1f6d..7321effc123 100644 --- a/tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_interop_toprod.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_interop_tests.sh" timeout_mins: 60 action { define_artifacts { - regex: "**/sponge_log.xml" + regex: "**/sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg b/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg index 9269c345f0a..47301d61415 100644 --- a/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_microbenchmark_diff.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_microbenchmark_diff.sh" timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_sanity.cfg b/tools/internal_ci/linux/pull_request/grpc_sanity.cfg index 0f83299aaba..276c34f0cfe 100644 --- a/tools/internal_ci/linux/pull_request/grpc_sanity.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_sanity.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 40 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg b/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg index e86b3ab4758..78358eac28e 100644 --- a/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg +++ b/tools/internal_ci/linux/pull_request/grpc_trickle_diff.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_trickle_diff.sh" timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/sanitizer/grpc_c_asan.cfg b/tools/internal_ci/linux/sanitizer/grpc_c_asan.cfg index 06a4372ce24..d6d70677ddf 100644 --- a/tools/internal_ci/linux/sanitizer/grpc_c_asan.cfg +++ b/tools/internal_ci/linux/sanitizer/grpc_c_asan.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 1440 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/sanitizer/grpc_c_msan.cfg b/tools/internal_ci/linux/sanitizer/grpc_c_msan.cfg index f875327c1b8..7b22c6afef5 100644 --- a/tools/internal_ci/linux/sanitizer/grpc_c_msan.cfg +++ b/tools/internal_ci/linux/sanitizer/grpc_c_msan.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 1440 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/sanitizer/grpc_c_tsan.cfg b/tools/internal_ci/linux/sanitizer/grpc_c_tsan.cfg index 6658a804d89..6c9dd6ef8dc 100644 --- a/tools/internal_ci/linux/sanitizer/grpc_c_tsan.cfg +++ b/tools/internal_ci/linux/sanitizer/grpc_c_tsan.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 1440 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/sanitizer/grpc_c_ubsan.cfg b/tools/internal_ci/linux/sanitizer/grpc_c_ubsan.cfg index 957a91ef2b4..8700c74c8d9 100644 --- a/tools/internal_ci/linux/sanitizer/grpc_c_ubsan.cfg +++ b/tools/internal_ci/linux/sanitizer/grpc_c_ubsan.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 1440 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.cfg b/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.cfg index dbbfce90cb5..02162d860b0 100644 --- a/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.cfg +++ b/tools/internal_ci/linux/sanitizer/grpc_cpp_asan.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 1440 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.cfg b/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.cfg index fb0cefa1606..95582184ed1 100644 --- a/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.cfg +++ b/tools/internal_ci/linux/sanitizer/grpc_cpp_tsan.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 1440 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_asan.cfg b/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_asan.cfg index 1daf7a514e2..d444596a81e 100644 --- a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_asan.cfg +++ b/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_asan.cfg @@ -20,7 +20,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_msan.cfg b/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_msan.cfg index a8503b7bcbe..3891cc37e8e 100644 --- a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_msan.cfg +++ b/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_msan.cfg @@ -20,7 +20,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_tsan.cfg b/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_tsan.cfg index 12af4581eba..91ce1627afc 100644 --- a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_tsan.cfg +++ b/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_tsan.cfg @@ -20,7 +20,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_ubsan.cfg b/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_ubsan.cfg index 0d3803bf236..fcdc2de37bb 100644 --- a/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_ubsan.cfg +++ b/tools/internal_ci/linux/sanitizer/pull_request/grpc_c_ubsan.cfg @@ -20,7 +20,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_asan.cfg b/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_asan.cfg index 557561810bd..de2a74051b6 100644 --- a/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_asan.cfg +++ b/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_asan.cfg @@ -20,7 +20,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_tsan.cfg b/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_tsan.cfg index cb15ca34fd7..51c291f7dff 100644 --- a/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_tsan.cfg +++ b/tools/internal_ci/linux/sanitizer/pull_request/grpc_cpp_tsan.cfg @@ -20,7 +20,7 @@ build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" timeout_mins: 1440 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/macos/grpc_basictests_dbg.cfg b/tools/internal_ci/macos/grpc_basictests_dbg.cfg index 53bda1ff0a6..e6f9c7ec875 100644 --- a/tools/internal_ci/macos/grpc_basictests_dbg.cfg +++ b/tools/internal_ci/macos/grpc_basictests_dbg.cfg @@ -20,7 +20,7 @@ gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0e timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/macos/grpc_basictests_opt.cfg b/tools/internal_ci/macos/grpc_basictests_opt.cfg index d359eb601a0..f2a83fe95a6 100644 --- a/tools/internal_ci/macos/grpc_basictests_opt.cfg +++ b/tools/internal_ci/macos/grpc_basictests_opt.cfg @@ -20,7 +20,7 @@ gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0e timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/macos/grpc_build_artifacts.cfg b/tools/internal_ci/macos/grpc_build_artifacts.cfg index 4da61faed36..c73cf4359f9 100644 --- a/tools/internal_ci/macos/grpc_build_artifacts.cfg +++ b/tools/internal_ci/macos/grpc_build_artifacts.cfg @@ -20,7 +20,7 @@ gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0e timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/macos/grpc_distribtests.cfg b/tools/internal_ci/macos/grpc_distribtests.cfg index ae88f39b903..156ec6fe33f 100644 --- a/tools/internal_ci/macos/grpc_distribtests.cfg +++ b/tools/internal_ci/macos/grpc_distribtests.cfg @@ -20,7 +20,7 @@ gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0e timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/macos/grpc_interop.cfg b/tools/internal_ci/macos/grpc_interop.cfg index b4b1b15cb40..434ecd19c4d 100644 --- a/tools/internal_ci/macos/grpc_interop.cfg +++ b/tools/internal_ci/macos/grpc_interop.cfg @@ -20,7 +20,7 @@ gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0e timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/macos/grpc_interop_toprod.cfg b/tools/internal_ci/macos/grpc_interop_toprod.cfg index c92c397daa7..2cfc8a2d6de 100644 --- a/tools/internal_ci/macos/grpc_interop_toprod.cfg +++ b/tools/internal_ci/macos/grpc_interop_toprod.cfg @@ -21,7 +21,7 @@ gfile_resources: "/bigstore/grpc-testing-secrets/interop/service_account/GrpcTes timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_dbg.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_dbg.cfg index 30c01d3e2f3..c759397b781 100644 --- a/tools/internal_ci/macos/pull_request/grpc_basictests_dbg.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_dbg.cfg @@ -20,7 +20,7 @@ gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0e timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/macos/pull_request/grpc_basictests_opt.cfg b/tools/internal_ci/macos/pull_request/grpc_basictests_opt.cfg index b63ee713bc4..4d68341405b 100644 --- a/tools/internal_ci/macos/pull_request/grpc_basictests_opt.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_basictests_opt.cfg @@ -20,7 +20,7 @@ gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0e timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/macos/pull_request/grpc_interop.cfg b/tools/internal_ci/macos/pull_request/grpc_interop.cfg index b4b1b15cb40..434ecd19c4d 100644 --- a/tools/internal_ci/macos/pull_request/grpc_interop.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_interop.cfg @@ -20,7 +20,7 @@ gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0e timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg index 8942bc7ba71..fb215bdf994 100644 --- a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg +++ b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg @@ -20,7 +20,7 @@ timeout_mins: 60 gfile_resources: "/bigstore/grpc-testing-secrets/github_credentials/oauth_token.txt" action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/windows/grpc_basictests.cfg b/tools/internal_ci/windows/grpc_basictests.cfg index 8e644e4c5e4..fcf5237bf3f 100644 --- a/tools/internal_ci/windows/grpc_basictests.cfg +++ b/tools/internal_ci/windows/grpc_basictests.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/windows/grpc_basictests_dbg.cfg b/tools/internal_ci/windows/grpc_basictests_dbg.cfg index 28d53cdc7bd..4e5e7b65451 100644 --- a/tools/internal_ci/windows/grpc_basictests_dbg.cfg +++ b/tools/internal_ci/windows/grpc_basictests_dbg.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/windows/grpc_basictests_opt.cfg b/tools/internal_ci/windows/grpc_basictests_opt.cfg index 4b7a9659776..f5db6a9897a 100644 --- a/tools/internal_ci/windows/grpc_basictests_opt.cfg +++ b/tools/internal_ci/windows/grpc_basictests_opt.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/windows/grpc_build_artifacts.cfg b/tools/internal_ci/windows/grpc_build_artifacts.cfg index 38b0abd519b..f45cfda1215 100644 --- a/tools/internal_ci/windows/grpc_build_artifacts.cfg +++ b/tools/internal_ci/windows/grpc_build_artifacts.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_build_artifacts.bat" timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/windows/grpc_build_packages.cfg b/tools/internal_ci/windows/grpc_build_packages.cfg index 65a8b1eef33..b351bbb11b3 100644 --- a/tools/internal_ci/windows/grpc_build_packages.cfg +++ b/tools/internal_ci/windows/grpc_build_packages.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_build_packages.bat" timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/windows/grpc_distribtests.cfg b/tools/internal_ci/windows/grpc_distribtests.cfg index 1766e601e51..e12d4bf98dc 100644 --- a/tools/internal_ci/windows/grpc_distribtests.cfg +++ b/tools/internal_ci/windows/grpc_distribtests.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_distribtests.bat" timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/windows/grpc_distribtests_standalone.cfg b/tools/internal_ci/windows/grpc_distribtests_standalone.cfg index 33a50fdc456..7f32ba4c704 100644 --- a/tools/internal_ci/windows/grpc_distribtests_standalone.cfg +++ b/tools/internal_ci/windows/grpc_distribtests_standalone.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_distribtests_standalone.bat" timeout_mins: 120 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" regex: "github/grpc/artifacts/**" } diff --git a/tools/internal_ci/windows/grpc_portability.cfg b/tools/internal_ci/windows/grpc_portability.cfg index 94e71753efd..aa86c06632a 100644 --- a/tools/internal_ci/windows/grpc_portability.cfg +++ b/tools/internal_ci/windows/grpc_portability.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/windows/grpc_portability_build_only.cfg b/tools/internal_ci/windows/grpc_portability_build_only.cfg index 3bc27f1f24a..3dace627eb2 100644 --- a/tools/internal_ci/windows/grpc_portability_build_only.cfg +++ b/tools/internal_ci/windows/grpc_portability_build_only.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/windows/pull_request/grpc_basictests.cfg b/tools/internal_ci/windows/pull_request/grpc_basictests.cfg index 91777cd7cbc..a8e6f0675bd 100644 --- a/tools/internal_ci/windows/pull_request/grpc_basictests.cfg +++ b/tools/internal_ci/windows/pull_request/grpc_basictests.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/windows/pull_request/grpc_basictests_dbg.cfg b/tools/internal_ci/windows/pull_request/grpc_basictests_dbg.cfg index 81a1e9d3c8f..ce957232fdb 100644 --- a/tools/internal_ci/windows/pull_request/grpc_basictests_dbg.cfg +++ b/tools/internal_ci/windows/pull_request/grpc_basictests_dbg.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/windows/pull_request/grpc_basictests_opt.cfg b/tools/internal_ci/windows/pull_request/grpc_basictests_opt.cfg index 3bb6510ca77..7d2abbfb19a 100644 --- a/tools/internal_ci/windows/pull_request/grpc_basictests_opt.cfg +++ b/tools/internal_ci/windows/pull_request/grpc_basictests_opt.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } diff --git a/tools/internal_ci/windows/pull_request/grpc_portability.cfg b/tools/internal_ci/windows/pull_request/grpc_portability.cfg index 2bda4876298..6f332416fe7 100644 --- a/tools/internal_ci/windows/pull_request/grpc_portability.cfg +++ b/tools/internal_ci/windows/pull_request/grpc_portability.cfg @@ -19,7 +19,7 @@ build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" timeout_mins: 240 action { define_artifacts { - regex: "**/*sponge_log.xml" + regex: "**/*sponge_log.*" regex: "github/grpc/reports/**" } } From 2488dff74b808faf2e2a46e0f6b3579499b9983f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 25 Sep 2018 23:36:19 +0200 Subject: [PATCH 447/546] address comments --- tools/run_tests/python_utils/jobset.py | 1 + tools/run_tests/run_tests_matrix.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/python_utils/jobset.py b/tools/run_tests/python_utils/jobset.py index 35faed448d9..a426c6ef9c0 100755 --- a/tools/run_tests/python_utils/jobset.py +++ b/tools/run_tests/python_utils/jobset.py @@ -201,6 +201,7 @@ class JobSpec(object): self.verbose_success = verbose_success self.logfilename = logfilename if self.logfilename and self.flake_retries != 0 and self.timeout_retries != 0: + # Forbidden to avoid overwriting the test log when retrying. raise Exception( 'Cannot use custom logfile when retries are enabled') diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index f8fcce45a4f..00fc68ad171 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -56,8 +56,9 @@ def _report_filename(name): def _report_logfilename(name): - """Generates report file name with directory structure that leads to better presentation by internal CI""" - # 'sponge_log.log' suffix must be there for test log to get recognized by kokoro. + """Generates log file name that corresponds to name generated by _report_filename""" + # 'sponge_log.log' suffix must be there for log to get recognized as "target log" + # for the corresponding 'sponge_log.xml' report. return '%s/%s' % (_safe_report_name(name), 'sponge_log.log') From b772e67c570562222d043d0955c7cc428d7f30aa Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 25 Sep 2018 14:44:04 -0700 Subject: [PATCH 448/546] clang_format --- .../GRPCClient/private/NSError+GRPC.m | 10 +++++----- src/objective-c/tests/UnitTests/UnitTests.m | 20 +++++++++++++------ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/objective-c/GRPCClient/private/NSError+GRPC.m b/src/objective-c/GRPCClient/private/NSError+GRPC.m index c0f7e019a23..3eefed88d63 100644 --- a/src/objective-c/GRPCClient/private/NSError+GRPC.m +++ b/src/objective-c/GRPCClient/private/NSError+GRPC.m @@ -31,13 +31,13 @@ NSString *const kGRPCErrorDomain = @"io.grpc"; } NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; if (details) { - userInfo[NSLocalizedDescriptionKey] = [NSString stringWithCString:details encoding:NSUTF8StringEncoding]; + userInfo[NSLocalizedDescriptionKey] = + [NSString stringWithCString:details encoding:NSUTF8StringEncoding]; } if (errorString) { - userInfo[NSDebugDescriptionErrorKey] = [NSString stringWithCString:errorString encoding:NSUTF8StringEncoding]; + userInfo[NSDebugDescriptionErrorKey] = + [NSString stringWithCString:errorString encoding:NSUTF8StringEncoding]; } - return [NSError errorWithDomain:kGRPCErrorDomain - code:statusCode - userInfo:userInfo]; + return [NSError errorWithDomain:kGRPCErrorDomain code:statusCode userInfo:userInfo]; } @end diff --git a/src/objective-c/tests/UnitTests/UnitTests.m b/src/objective-c/tests/UnitTests/UnitTests.m index 002c4f86594..57e686d1b67 100644 --- a/src/objective-c/tests/UnitTests/UnitTests.m +++ b/src/objective-c/tests/UnitTests/UnitTests.m @@ -32,18 +32,26 @@ const char *kDetails = "test details"; const char *kErrorString = "test errorString"; NSError *error1 = [NSError grpc_errorFromStatusCode:GRPC_STATUS_OK details:nil errorString:nil]; - NSError *error2 = [NSError grpc_errorFromStatusCode:GRPC_STATUS_CANCELLED details:kDetails errorString:kErrorString]; - NSError *error3 = [NSError grpc_errorFromStatusCode:GRPC_STATUS_UNAUTHENTICATED details:kDetails errorString:nil]; - NSError *error4 = [NSError grpc_errorFromStatusCode:GRPC_STATUS_UNAVAILABLE details:nil errorString:nil]; + NSError *error2 = [NSError grpc_errorFromStatusCode:GRPC_STATUS_CANCELLED + details:kDetails + errorString:kErrorString]; + NSError *error3 = [NSError grpc_errorFromStatusCode:GRPC_STATUS_UNAUTHENTICATED + details:kDetails + errorString:nil]; + NSError *error4 = + [NSError grpc_errorFromStatusCode:GRPC_STATUS_UNAVAILABLE details:nil errorString:nil]; XCTAssertNil(error1); XCTAssertEqual(error2.code, 1); XCTAssertEqualObjects(error2.domain, @"io.grpc"); - XCTAssertEqualObjects(error2.userInfo[NSLocalizedDescriptionKey], [NSString stringWithUTF8String:kDetails]); - XCTAssertEqualObjects(error2.userInfo[NSDebugDescriptionErrorKey], [NSString stringWithUTF8String:kErrorString]); + XCTAssertEqualObjects(error2.userInfo[NSLocalizedDescriptionKey], + [NSString stringWithUTF8String:kDetails]); + XCTAssertEqualObjects(error2.userInfo[NSDebugDescriptionErrorKey], + [NSString stringWithUTF8String:kErrorString]); XCTAssertEqual(error3.code, 16); XCTAssertEqualObjects(error3.domain, @"io.grpc"); - XCTAssertEqualObjects(error3.userInfo[NSLocalizedDescriptionKey], [NSString stringWithUTF8String:kDetails]); + XCTAssertEqualObjects(error3.userInfo[NSLocalizedDescriptionKey], + [NSString stringWithUTF8String:kDetails]); XCTAssertNil(error3.userInfo[NSDebugDescriptionErrorKey]); XCTAssertEqual(error4.code, 14); XCTAssertEqualObjects(error4.domain, @"io.grpc"); From c1a1d66864a637f06b409b1768bc05a982b28949 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 25 Sep 2018 17:50:45 -0400 Subject: [PATCH 449/546] Avoid allocating temporary strings in Channel::CreateCall(). Add `SliceFromArray()` which takes a `char*` instead of `const string&`, to save string allocations for copying from a `char *`. Use the new API to eliminate two string allocations and copies per call for method and host names. release-note: no --- include/grpcpp/impl/codegen/slice.h | 4 ++++ src/cpp/client/channel_cc.cc | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/grpcpp/impl/codegen/slice.h b/include/grpcpp/impl/codegen/slice.h index 8966559dc85..9cdca3ab3c9 100644 --- a/include/grpcpp/impl/codegen/slice.h +++ b/include/grpcpp/impl/codegen/slice.h @@ -138,6 +138,10 @@ inline grpc_slice SliceFromCopiedString(const grpc::string& str) { str.length()); } +inline grpc_slice SliceFromArray(const char* arr, size_t len) { + return g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len); +} + } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_SLICE_H diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index c59059f0450..5d1a9f4b961 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -116,10 +117,11 @@ internal::Call Channel::CreateCall(const internal::RpcMethod& method, } else if (!host_.empty()) { host_str = host_.c_str(); } - grpc_slice method_slice = SliceFromCopiedString(method.name()); + grpc_slice method_slice = + SliceFromArray(method.name(), strlen(method.name())); grpc_slice host_slice; if (host_str != nullptr) { - host_slice = SliceFromCopiedString(host_str); + host_slice = SliceFromArray(host_str, strlen(host_str)); } c_call = grpc_channel_create_call( c_channel_, context->propagate_from_call_, From a68ebc7cfde360fc904b99017702e8eedc251277 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 25 Sep 2018 17:59:46 -0400 Subject: [PATCH 450/546] Increase the maximum number of timer shards to 32. Commit 82f9886e accidentally sets the maximum number of timer shards 1, from previously 32. We probably want to increase the max shards further. --- src/core/lib/iomgr/timer_generic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/timer_generic.cc b/src/core/lib/iomgr/timer_generic.cc index 008d37119a9..aeadd10b688 100644 --- a/src/core/lib/iomgr/timer_generic.cc +++ b/src/core/lib/iomgr/timer_generic.cc @@ -256,7 +256,7 @@ static grpc_millis compute_min_deadline(timer_shard* shard) { static void timer_list_init() { uint32_t i; - g_num_shards = GPR_MIN(1, 2 * gpr_cpu_num_cores()); + g_num_shards = GPR_MIN(32, 2 * gpr_cpu_num_cores()); g_shards = static_cast(gpr_zalloc(g_num_shards * sizeof(*g_shards))); g_shard_queue = static_cast( From d8056c5906eb732d8d1f2419f29472d4094d16d3 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 26 Sep 2018 00:11:51 +0200 Subject: [PATCH 451/546] rename _tempfile -> _logfile --- tools/run_tests/python_utils/jobset.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/run_tests/python_utils/jobset.py b/tools/run_tests/python_utils/jobset.py index a426c6ef9c0..b732e1e03e0 100755 --- a/tools/run_tests/python_utils/jobset.py +++ b/tools/run_tests/python_utils/jobset.py @@ -274,9 +274,9 @@ class Job(object): os.path.abspath(self._spec.logfilename)) if not os.path.exists(logfile_dir): os.makedirs(logfile_dir) - self._tempfile = open(self._spec.logfilename, 'w+') + self._logfile = open(self._spec.logfilename, 'w+') else: - self._tempfile = tempfile.TemporaryFile() + self._logfile = tempfile.TemporaryFile() env = dict(os.environ) env.update(self._spec.environ) env.update(self._add_env) @@ -292,7 +292,7 @@ class Job(object): measure_cpu_costs = False try_start = lambda: subprocess.Popen(args=cmdline, stderr=subprocess.STDOUT, - stdout=self._tempfile, + stdout=self._logfile, cwd=self._spec.cwd, shell=self._spec.shell, env=env) @@ -315,7 +315,7 @@ class Job(object): """Poll current state of the job. Prints messages at completion.""" def stdout(self=self): - stdout = read_from_start(self._tempfile) + stdout = read_from_start(self._logfile) self.result.message = stdout[-_MAX_RESULT_SIZE:] return stdout From 8442cc213b2316272764b6a89e5ded5929e35a78 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 25 Sep 2018 18:30:22 -0400 Subject: [PATCH 452/546] Fix styling issue added in c1a1d668 --- include/grpcpp/impl/codegen/slice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/impl/codegen/slice.h b/include/grpcpp/impl/codegen/slice.h index 9cdca3ab3c9..75c093d1da0 100644 --- a/include/grpcpp/impl/codegen/slice.h +++ b/include/grpcpp/impl/codegen/slice.h @@ -139,7 +139,7 @@ inline grpc_slice SliceFromCopiedString(const grpc::string& str) { } inline grpc_slice SliceFromArray(const char* arr, size_t len) { - return g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len); + return g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len); } } // namespace grpc From 369cfe118cbfda61c3fc205a18d1b1924d853700 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 25 Sep 2018 21:59:15 -0400 Subject: [PATCH 453/546] Use SliceFromCopiedString() for host name. This is to address Yang's review comment. --- src/cpp/client/channel_cc.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 5d1a9f4b961..510ae73478e 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -111,17 +111,17 @@ internal::Call Channel::CreateCall(const internal::RpcMethod& method, context->propagation_options_.c_bitmask(), cq->cq(), method.channel_tag(), context->raw_deadline(), nullptr); } else { - const char* host_str = nullptr; + const string* host_str = nullptr; if (!context->authority().empty()) { - host_str = context->authority_.c_str(); + host_str = &context->authority_; } else if (!host_.empty()) { - host_str = host_.c_str(); + host_str = &host_; } grpc_slice method_slice = SliceFromArray(method.name(), strlen(method.name())); grpc_slice host_slice; if (host_str != nullptr) { - host_slice = SliceFromArray(host_str, strlen(host_str)); + host_slice = SliceFromCopiedString(*host_str); } c_call = grpc_channel_create_call( c_channel_, context->propagate_from_call_, From 0535f659f73e6f0073782691b2afa03ca6e6970f Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 25 Sep 2018 22:02:03 -0400 Subject: [PATCH 454/546] Set a minimum bound of 1 for the number of timer shards. --- src/core/lib/iomgr/timer_generic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/timer_generic.cc b/src/core/lib/iomgr/timer_generic.cc index aeadd10b688..aba5539199d 100644 --- a/src/core/lib/iomgr/timer_generic.cc +++ b/src/core/lib/iomgr/timer_generic.cc @@ -256,7 +256,7 @@ static grpc_millis compute_min_deadline(timer_shard* shard) { static void timer_list_init() { uint32_t i; - g_num_shards = GPR_MIN(32, 2 * gpr_cpu_num_cores()); + g_num_shards = GPR_CLAMP(2 * gpr_cpu_num_cores(), 1, 32); g_shards = static_cast(gpr_zalloc(g_num_shards * sizeof(*g_shards))); g_shard_queue = static_cast( From 8bbd1374a5fa7be796997ffbfdbcfabb8814701f Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Tue, 25 Sep 2018 21:05:44 -0700 Subject: [PATCH 455/546] Documentation about grpc polling engines --- doc/grpc-polling-engines.md | 154 ++++++++++++++++++++++++++++++++++ doc/images/grpc-epoll1.png | Bin 0 -> 36205 bytes doc/images/grpc-epollex.png | Bin 0 -> 52651 bytes doc/images/grpc-ps-pss-fd.png | Bin 0 -> 24969 bytes doc/images/grpc-pss.png | Bin 0 -> 31518 bytes 5 files changed, 154 insertions(+) create mode 100644 doc/grpc-polling-engines.md create mode 100644 doc/images/grpc-epoll1.png create mode 100644 doc/images/grpc-epollex.png create mode 100644 doc/images/grpc-ps-pss-fd.png create mode 100644 doc/images/grpc-pss.png diff --git a/doc/grpc-polling-engines.md b/doc/grpc-polling-engines.md new file mode 100644 index 00000000000..65aa5225432 --- /dev/null +++ b/doc/grpc-polling-engines.md @@ -0,0 +1,154 @@ +# Polling Engines + +_Author: Sree Kuchibhotla (@sreecha) - Sep 2018_ + + +## Why do we need a 'polling engine' ? + +Polling engine component was created for the following reasons: + +- gRPC code deals with a bunch of file descriptors on which events like descriptor being readable/writable/error have to be monitored +- gRPC code knows the actions to perform when such events happen + - For example: + - `grpc_endpoint` code calls recvmsg call when the fd is readable and sendmsg call when the fd is writable + - ` tcp_client` connect code issues async connect and finishes creating the client once the fd is writable (i.e when the connect actually finished) +- gRPC needed some component that can "efficiently" to the above operations __using the threads provided by the applications (i.e not create any new threads)__. Also by "efficiently" we mean optimized for latency and throughput + + +## Polling Engine Implementations in gRPC +There are multiple polling engine implementations depending on the OS and the OS version. Fortunately all of them expose the same interface + +- Linux: + + - **epollex** (default but requires kernel version >= 4.5), + - epoll1 (If epollex is not available and glibc version >= 2.9) + - epollsig (if epollex, epoll1 are unavailable AND Kernel has epoll support) + - poll (if kernel NOT have epoll support) +- Mac: **poll** (default), poll-cv +- Windows: (no name) +- One-off polling engines: + - AppEngine platform: poll-cv (default) + - NodeJS : libuv polling engine implementation (requires different compile # defs) + +## Polling Engine Interface + +### Opaque Structures exposed by the polling engine +The following are the **Opaque** structures exposed by Polling Engine interface (NOTE: Different polling engine implementations have different definitions of these structures) + +- **grpc_fd:** Structure representing a file descriptor +- **grpc_pollset:** A set of one or more grpc_fds that are ‘polled’ for readable/writable/error events. One grpc_fd can be in multiple grpc_pollsets +- **grpc_pollset_worker:** Structure representing a ‘polling thread’ - more specifically, the thread that calls grpc_pollset_work() API +- **grpc_pollset_set:** A group of `grpc_fds`, `grpc_pollsets` and `grpc_pollset_sets` (yes, a `grpc_pollset_set` can contain other `grpc_pollset_sets`) + +### Polling engine API + +#### grpc_fd +- **grpc\_fd\_notify\_on\_[read|write|error]** + - Signature: `grpc_fd_notify_on_(grpc_fd* fd, grpc_closure* closure)` + - Register a closure to be called when the fd becomes readable/writable or has an error (In grpc parlance, we refer to this act as “arming the fd”) + - The closure is called exactly once per event. I.e once the fd becomes readable (or writable or error), the closure is fired and the fd is ‘unarmed’. To be notified again, the fd has to be armed again. + +- **grpc_fd_shutdown** + - Signature: `grpc_fd_shutdown(grpc_fd* fd)` + - Any current (or future) closures registered for readable/writable/error events are scheduled immediately with an error + +- **grpc_fd_orphan** + - Signature: `grpc_fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, char* reason)` + - Release the `grpc_fd` structure and call `on_done` closure when the operation is complete + - If `release_fd` is set to `nullptr`, then `close()` the underlying fd as well. If not, put the underlying fd in `release_fd` (and do not call `close()`) + - release_fd set to non-null in cases where the underlying fd is NOT owned by grpc core (like for example the fds used by C-Ares DNS resolver ) + +#### grpc_pollset + +- **grpc_pollset_add_fd ** + - Signature: `grpc_pollset_add_fd(grpc_pollset* ps, grpc_fd *fd)` + - Add fd to pollset + > **NOTE**: There is no `grpc_pollset_remove_fd`. This is because calling `grpc_fd_orphan()` will effectively remove the fd from all the pollsets it’s a part of + +- ** grpc_pollset_work ** + - Signature: `grpc_pollset_work(grpc_pollset* ps, grpc_pollset_worker** worker, grpc_millis deadline)` + > **NOTE**: `grpc_pollset_work()` requires the pollset mutex to be locked before calling it. Shortly after calling `grpc_pollset_work()`, the function populates the `*worker` pointer (among other things) and releases the mutex. Once `grpc_pollset_work()` returns, the `*worker` pointer is **invalid** and should not be used anymore. See the code in `completion_queue.cc` to see how this is used. + - Poll the fds in the pollset for events AND return when ONE of the following is true: + - Deadline expired + - Some fds in the pollset were found to be readable/writable/error and those associated closures were ‘scheduled’ (but not necessarily executed) + - worker is “kicked” (see grpc_pollset_kick for more details) + +- **grpc_pollset_kick** + - Signature: `grpc_pollset_kick(grpc_pollset* ps, grpc_pollset_worker* worker)` + - “Kick the worker” i.e Force the worker to return from grpc_pollset_work() + - If `worker == nullptr`, kick ANY worker active on that pollset + +#### grpc_pollset_set + +- **grpc\_pollset\_set\_[add|del]\_fd** + - Signature: `grpc_pollset_set_[add|del]_fd(grpc_pollset_set* pss, grpc_fd *fd)` +Add/Remove fd to the pollset_set + +- **grpc\_pollset\_set_[add|del]\_pollset** + - Signature: `grpc_pollset_set_[add|del]_pollset(grpc_pollset_set* pss, grpc_pollset* ps)` + - What does adding a pollset to a pollset_set mean ? + - It means that calling `grpc_pollset_work()` on the pollset will also poll all the fds in the pollset_set i.e semantically, it is similar to adding all the fds inside pollset_set to the pollset. + - This guarantee is no longer true once the pollset is removed from the pollset_set + +- **grpc\_pollset\_set_[add|del]\_pollset\_set** + - Signature: `grpc_pollset_set_[add|del]_pollset_set(grpc_pollset_set* bag, grpc_pollset_set* item)` + - Semantically, this is similar to adding all the fds in the ‘bag’ pollset_set to the ‘item’ pollset_set + + +#### Recap: + +__Relation between grpc_pollset_worker, grpc_pollset and grpc_fd:__ + +![image](images/grpc-ps-pss-fd.png) + +__grpc_pollset_set__ + +![image](images/grpc-pss.png) + + +## Polling Engine Implementations + +### epoll1 + +![image](images/grpc-epoll1.png) + +Code at `src/core/lib/iomgr/ev_epoll1_posix.cc` + +- The logic to choose a designated poller is quite complicated. Pollsets are internally sharded into what are called `pollset_neighborhood` (a structure internal to `epoll1` polling engine implementation). `grpc_pollset_workers` that call `grpc_pollset_work` on a given pollset are all queued in a linked-list against the `grpc_pollset`. + +- There are as many neighborhoods as the number of cores. A pollset is put in a neighborhood based on the CPU core, the root worker thread (i.e the head of the linked-list of workers queued against the pollset). The whole idea here is that when choosing the next designated poller, we make a best-effort attempt to pick a worker that is NOT running on the same core. This way, we reduce the probability of the current thread being pre-empted by the CPU scheduler. + +- See `begin_worker()` function in `src/core/lib/iomgr/ev_epoll1_posix.cc` to see how a designated poller is chosen. Similarly `end_worker()` function is called by the worker that was just out of epoll_wait() and will have to choose a new designated poller) + + + +### epollex + +![image](images/grpc-epollex.png) + +Code at `src/core/lib/iomgr/ev_epollex_posix.cc` + +- FDs are added to multiple epollsets with EPOLLEXCLUSIVE flag. This prevents multiple worker threads from waking up from polling whenever the fd is readable/writable + +- A few conclusions: + + - If multiple pollsets are pointing to the same Pollable, then the pollable MUST be either empty or of type PO_FD (i.e single-fd) + - A multi-pollable has one-and-only-one incoming link from a Pollset + - The same FD can be in multiple pollables (even if one of the pollables is of type PO_FD) + - There cannot be two Pollables of type PO_FD for the same fd + +- Why do we need Pollalbe of type PO_FD and Empty pollable ? + - The main reason is the Sync client API + - We create one completion queue per call (therefore one pollset per call). If we didn’t have PO_EMPTY and PO_FD type pollables, then every call on a given channel will effectively have to create a pollable (and hence an epollset). Thats a lot of epoll fd create/delete calls + - With these new types of pollables, all pollsets (corresponding to the new per-call completion queue) will initially point to PO_EMPTY global epollset. Then once the sub-channel fd is added to the pollset, the pollset will point to the Pollable of type PO_FD containing just that fd (i.e + + +### Other polling engine implementations (poll and windows polling engine) +- **poll** polling engine: gRPC's `poll` polling engine is quite complicated. It uses the `poll()` function to do the polling (and hence it is for platforms like osx where epoll is not available) + - The implementation is further complicated by the fact that poll() is level triggered (just keep this in mind in case you wonder why the code at `src/core/lib/iomgr/ev_poll_posix.cc` is written a certain/seemingly complicated way :)) + +- **Polling engine on Windows**: Windows polling engine looks nothing like other polling engines + - Unlike the grpc polling engines for Unix systems (epollex, epoll1 and poll) Windows endpoint implementation and polling engine implementations are very closely tied together + - Windows endpoint read/write API implementations use the Windows IO API which require specifying an [I/O completion port](https://docs.microsoft.com/en-us/windows/desktop/fileio/i-o-completion-ports) + - In Windows polling engine’s grpc_pollset_work() implementation, ONE of the threads is chosen to wait on the I/O completion port while other threads wait on a condition variable (much like the turnstile polling in epollex/epoll1) + diff --git a/doc/images/grpc-epoll1.png b/doc/images/grpc-epoll1.png new file mode 100644 index 0000000000000000000000000000000000000000..3ab9a4c7d11b03eb137d173d841e94d16109d551 GIT binary patch literal 36205 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 PaQ6m!#=7|151##BP3-R2 literal 0 HcmV?d00001 diff --git a/doc/images/grpc-epollex.png b/doc/images/grpc-epollex.png new file mode 100644 index 0000000000000000000000000000000000000000..86dc0005b3e76a4c0edeeb04354e8328b39e568b GIT binary patch literal 52651 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

g03@P*_{%Rr*y14+H`9T0G z@yOWabG@V1jl(rE%^YYY))*p*=ZH~?Zu?yn2^u5=0@oy;&p&aoO+2HnSDOF0Ivv zY3p@BwM$yqr&s4=9UE@}nRIVV%!{M7D?o}U zbL6@q&s+(YWOfb~WEyUFBMCDy@|555Ey=792$QOwwti6kpRylAsLs@S*geqDk3W~b zFSjFZFgdc4mJ{A29=Y7TT~F_eS4&YJEgFd~YBS}SsQbA?P}k2_10?!+QV&jF147P# zbuX<&fLvSAQSB#;i4UuPi9YxwEyMXNs;zHM;ydkgGiv0CmK2z$Z4#NA`KXXW%kzR> z12*Pw^!3hL^^(H~Sa+^1EbD3(V0uRHh#s?g5DQ8YpaosuJd#%}i-_8*6K|rxFjB^>3TTxYqwD z2>$uap<>~zcLxZ~*0z25Hy8r36NzTbPzmq*LrDLK0Xlx_|*#q2F6 zdyb(ChI6!Xnv#1H2#BOE3S{7*Yw zrvytrOcPA9u6LTap-$E#rF**R0_&sh_kGp%=lC}qaQ(IaiQ;QpdT*zKJbL8+|M&mB e75Hqtd2n=@_XDr>Q|zO|>1(L#s-aY^-u_=IgJW+1 literal 0 HcmV?d00001 diff --git a/doc/images/grpc-ps-pss-fd.png b/doc/images/grpc-ps-pss-fd.png new file mode 100644 index 0000000000000000000000000000000000000000..790af7f1bc12d94327bd3297cee296969a6cc1cb GIT binary patch literal 24969 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 literal 0 HcmV?d00001 From 18e8a30a518315fca22c687138d86de36e8cb754 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 26 Sep 2018 06:49:14 -0700 Subject: [PATCH 456/546] Empty implementation of grpc_use_signal since not actually needed anymore --- src/core/lib/iomgr/ev_posix.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc index 8a7dc7b004a..764fb08142a 100644 --- a/src/core/lib/iomgr/ev_posix.cc +++ b/src/core/lib/iomgr/ev_posix.cc @@ -395,4 +395,6 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) { g_event_engine->pollset_set_del_fd(pollset_set, fd); } +void grpc_use_signal(int signum) {} + #endif // GRPC_POSIX_SOCKET_EV From 6f278ca7614e70a425eaded3a9d7da428bef33c5 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 26 Sep 2018 10:53:43 -0700 Subject: [PATCH 457/546] Address review comments --- doc/grpc-polling-engines.md | 58 ++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/doc/grpc-polling-engines.md b/doc/grpc-polling-engines.md index 65aa5225432..bebcb4ccc86 100644 --- a/doc/grpc-polling-engines.md +++ b/doc/grpc-polling-engines.md @@ -10,9 +10,9 @@ Polling engine component was created for the following reasons: - gRPC code deals with a bunch of file descriptors on which events like descriptor being readable/writable/error have to be monitored - gRPC code knows the actions to perform when such events happen - For example: - - `grpc_endpoint` code calls recvmsg call when the fd is readable and sendmsg call when the fd is writable - - ` tcp_client` connect code issues async connect and finishes creating the client once the fd is writable (i.e when the connect actually finished) -- gRPC needed some component that can "efficiently" to the above operations __using the threads provided by the applications (i.e not create any new threads)__. Also by "efficiently" we mean optimized for latency and throughput + - `grpc_endpoint` code calls `recvmsg` call when the fd is readable and `sendmsg` call when the fd is writable + - ` tcp_client` connect code issues async `connect` and finishes creating the client once the fd is writable (i.e when the `connect` actually finished) +- gRPC needed some component that can "efficiently" do the above operations __using the threads provided by the applications (i.e., not create any new threads)__. Also by "efficiently" we mean optimized for latency and throughput ## Polling Engine Implementations in gRPC @@ -20,15 +20,15 @@ There are multiple polling engine implementations depending on the OS and the OS - Linux: - - **epollex** (default but requires kernel version >= 4.5), - - epoll1 (If epollex is not available and glibc version >= 2.9) - - epollsig (if epollex, epoll1 are unavailable AND Kernel has epoll support) - - poll (if kernel NOT have epoll support) -- Mac: **poll** (default), poll-cv + - **`epollex`** (default but requires kernel version >= 4.5), + - `epoll1` (If `epollex` is not available and glibc version >= 2.9) + - `poll` (If kernel does not have epoll support) + - `poll-cv` (If explicitly configured) +- Mac: **`poll`** (default), `poll-cv` (If explicitly configured) - Windows: (no name) - One-off polling engines: - - AppEngine platform: poll-cv (default) - - NodeJS : libuv polling engine implementation (requires different compile # defs) + - AppEngine platform: **`poll-cv`** (default) + - NodeJS : `libuv` polling engine implementation (requires different compile `#define`s) ## Polling Engine Interface @@ -36,8 +36,8 @@ There are multiple polling engine implementations depending on the OS and the OS The following are the **Opaque** structures exposed by Polling Engine interface (NOTE: Different polling engine implementations have different definitions of these structures) - **grpc_fd:** Structure representing a file descriptor -- **grpc_pollset:** A set of one or more grpc_fds that are ‘polled’ for readable/writable/error events. One grpc_fd can be in multiple grpc_pollsets -- **grpc_pollset_worker:** Structure representing a ‘polling thread’ - more specifically, the thread that calls grpc_pollset_work() API +- **grpc_pollset:** A set of one or more grpc_fds that are ‘polled’ for readable/writable/error events. One grpc_fd can be in multiple `grpc_pollset`s +- **grpc_pollset_worker:** Structure representing a ‘polling thread’ - more specifically, the thread that calls `grpc_pollset_work()` API - **grpc_pollset_set:** A group of `grpc_fds`, `grpc_pollsets` and `grpc_pollset_sets` (yes, a `grpc_pollset_set` can contain other `grpc_pollset_sets`) ### Polling engine API @@ -45,7 +45,7 @@ The following are the **Opaque** structures exposed by Polling Engine interface #### grpc_fd - **grpc\_fd\_notify\_on\_[read|write|error]** - Signature: `grpc_fd_notify_on_(grpc_fd* fd, grpc_closure* closure)` - - Register a closure to be called when the fd becomes readable/writable or has an error (In grpc parlance, we refer to this act as “arming the fd”) + - Register a [closure](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/closure.h#L67) to be called when the fd becomes readable/writable or has an error (In grpc parlance, we refer to this act as “arming the fd”) - The closure is called exactly once per event. I.e once the fd becomes readable (or writable or error), the closure is fired and the fd is ‘unarmed’. To be notified again, the fd has to be armed again. - **grpc_fd_shutdown** @@ -56,7 +56,7 @@ The following are the **Opaque** structures exposed by Polling Engine interface - Signature: `grpc_fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, char* reason)` - Release the `grpc_fd` structure and call `on_done` closure when the operation is complete - If `release_fd` is set to `nullptr`, then `close()` the underlying fd as well. If not, put the underlying fd in `release_fd` (and do not call `close()`) - - release_fd set to non-null in cases where the underlying fd is NOT owned by grpc core (like for example the fds used by C-Ares DNS resolver ) + - `release_fd` set to non-null in cases where the underlying fd is NOT owned by grpc core (like for example the fds used by C-Ares DNS resolver ) #### grpc_pollset @@ -68,10 +68,10 @@ The following are the **Opaque** structures exposed by Polling Engine interface - ** grpc_pollset_work ** - Signature: `grpc_pollset_work(grpc_pollset* ps, grpc_pollset_worker** worker, grpc_millis deadline)` > **NOTE**: `grpc_pollset_work()` requires the pollset mutex to be locked before calling it. Shortly after calling `grpc_pollset_work()`, the function populates the `*worker` pointer (among other things) and releases the mutex. Once `grpc_pollset_work()` returns, the `*worker` pointer is **invalid** and should not be used anymore. See the code in `completion_queue.cc` to see how this is used. - - Poll the fds in the pollset for events AND return when ONE of the following is true: + - Poll the fds in the pollset for events AND return when ANY of the following is true: - Deadline expired - Some fds in the pollset were found to be readable/writable/error and those associated closures were ‘scheduled’ (but not necessarily executed) - - worker is “kicked” (see grpc_pollset_kick for more details) + - worker is “kicked” (see `grpc_pollset_kick` for more details) - **grpc_pollset_kick** - Signature: `grpc_pollset_kick(grpc_pollset* ps, grpc_pollset_worker* worker)` @@ -82,7 +82,7 @@ The following are the **Opaque** structures exposed by Polling Engine interface - **grpc\_pollset\_set\_[add|del]\_fd** - Signature: `grpc_pollset_set_[add|del]_fd(grpc_pollset_set* pss, grpc_fd *fd)` -Add/Remove fd to the pollset_set +Add/Remove fd to the `grpc_pollset_set` - **grpc\_pollset\_set_[add|del]\_pollset** - Signature: `grpc_pollset_set_[add|del]_pollset(grpc_pollset_set* pss, grpc_pollset* ps)` @@ -114,12 +114,12 @@ __grpc_pollset_set__ Code at `src/core/lib/iomgr/ev_epoll1_posix.cc` -- The logic to choose a designated poller is quite complicated. Pollsets are internally sharded into what are called `pollset_neighborhood` (a structure internal to `epoll1` polling engine implementation). `grpc_pollset_workers` that call `grpc_pollset_work` on a given pollset are all queued in a linked-list against the `grpc_pollset`. +- The logic to choose a designated poller is quite complicated. Pollsets are internally sharded into what are called `pollset_neighborhood` (a structure internal to `epoll1` polling engine implementation). `grpc_pollset_workers` that call `grpc_pollset_work` on a given pollset are all queued in a linked-list against the `grpc_pollset`. The head of the linked list is called "root worker" -- There are as many neighborhoods as the number of cores. A pollset is put in a neighborhood based on the CPU core, the root worker thread (i.e the head of the linked-list of workers queued against the pollset). The whole idea here is that when choosing the next designated poller, we make a best-effort attempt to pick a worker that is NOT running on the same core. This way, we reduce the probability of the current thread being pre-empted by the CPU scheduler. - -- See `begin_worker()` function in `src/core/lib/iomgr/ev_epoll1_posix.cc` to see how a designated poller is chosen. Similarly `end_worker()` function is called by the worker that was just out of epoll_wait() and will have to choose a new designated poller) +- There are as many neighborhoods as the number of cores. A pollset is put in a neighborhood based on the CPU core of the root worker thread. When picking the next designated poller, we always try to find another worker on the current pollset. If there are no more workers in the current pollset, a `pollset_neighborhood` listed is scanned to pick the next pollset and worker that could be the new designated poller. + - NOTE: There is room to tune this implementation. All we really need is good way to maintain a list of `grpc_pollset_workers` with a way to group them per-pollset (needed to implement `grpc_pollset_kick` semantics) and a way randomly select a new designated poller +- See [`begin_worker()`](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/ev_epoll1_linux.cc#L729) function to see how a designated poller is chosen. Similarly [`end_worker()`](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/ev_epoll1_linux.cc#L916) function is called by the worker that was just out of `epoll_wait()` and will have to choose a new designated poller) ### epollex @@ -130,17 +130,17 @@ Code at `src/core/lib/iomgr/ev_epollex_posix.cc` - FDs are added to multiple epollsets with EPOLLEXCLUSIVE flag. This prevents multiple worker threads from waking up from polling whenever the fd is readable/writable -- A few conclusions: +- A few observations: - - If multiple pollsets are pointing to the same Pollable, then the pollable MUST be either empty or of type PO_FD (i.e single-fd) - - A multi-pollable has one-and-only-one incoming link from a Pollset - - The same FD can be in multiple pollables (even if one of the pollables is of type PO_FD) - - There cannot be two Pollables of type PO_FD for the same fd + - If multiple pollsets are pointing to the same `Pollable`, then the `pollable` MUST be either empty or of type `PO_FD` (i.e single-fd) + - A multi-pollable has one-and-only-one incoming link from a pollset + - The same FD can be in multiple `Pollable`s (even if one of the `Pollable`s is of type PO_FD) + - There cannot be two `Pollable`s of type PO_FD for the same fd -- Why do we need Pollalbe of type PO_FD and Empty pollable ? +- Why do we need `Pollable` of type PO_FD and PO_EMTPY ? - The main reason is the Sync client API - - We create one completion queue per call (therefore one pollset per call). If we didn’t have PO_EMPTY and PO_FD type pollables, then every call on a given channel will effectively have to create a pollable (and hence an epollset). Thats a lot of epoll fd create/delete calls - - With these new types of pollables, all pollsets (corresponding to the new per-call completion queue) will initially point to PO_EMPTY global epollset. Then once the sub-channel fd is added to the pollset, the pollset will point to the Pollable of type PO_FD containing just that fd (i.e + - We create one new completion queue per call. If we didn’t have PO_EMPTY and PO_FD type pollables, then every call on a given channel will effectively have to create a `Pollable` and hence an epollset. This is because every completion queue automatically creates a pollset and the channel fd will have to be put in that pollset. This clearly requires an epollset to put that fd. Creating an epollset per call (even if we delete the epollset once the call is completed) would mean a lot of sys calls to create/delete epoll fds. This is clearly not a good idea. + - With these new types of `Pollable`s, all pollsets (corresponding to the new per-call completion queue) will initially point to PO_EMPTY global epollset. Then once the channel fd is added to the pollset, the pollset will point to the `Pollable` of type PO_FD containing just that fd (i.e it will reuse the existing `Pollable`). This way, the epoll fd creation/deletion churn is avoided. ### Other polling engine implementations (poll and windows polling engine) From 3c2c28e3fc3010e9fd5d6ac2ea257358463abe89 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 26 Sep 2018 10:57:20 -0700 Subject: [PATCH 458/546] Moved to under core --- doc/{ => core}/grpc-polling-engines.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename doc/{ => core}/grpc-polling-engines.md (98%) diff --git a/doc/grpc-polling-engines.md b/doc/core/grpc-polling-engines.md similarity index 98% rename from doc/grpc-polling-engines.md rename to doc/core/grpc-polling-engines.md index bebcb4ccc86..f273913b1e4 100644 --- a/doc/grpc-polling-engines.md +++ b/doc/core/grpc-polling-engines.md @@ -99,18 +99,18 @@ Add/Remove fd to the `grpc_pollset_set` __Relation between grpc_pollset_worker, grpc_pollset and grpc_fd:__ -![image](images/grpc-ps-pss-fd.png) +![image](../images/grpc-ps-pss-fd.png) __grpc_pollset_set__ -![image](images/grpc-pss.png) +![image](../images/grpc-pss.png) ## Polling Engine Implementations ### epoll1 -![image](images/grpc-epoll1.png) +![image](../images/grpc-epoll1.png) Code at `src/core/lib/iomgr/ev_epoll1_posix.cc` @@ -124,7 +124,7 @@ Code at `src/core/lib/iomgr/ev_epoll1_posix.cc` ### epollex -![image](images/grpc-epollex.png) +![image](../images/grpc-epollex.png) Code at `src/core/lib/iomgr/ev_epollex_posix.cc` From 31d3134d5b525e2483d023d5e8efe461b7eab171 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 26 Sep 2018 12:36:11 -0700 Subject: [PATCH 459/546] Cq documentation --- doc/core/grpc-cq.md | 64 +++++++++++++++++++++++++++++++++++++++++ doc/images/grpc-cq.png | Bin 0 -> 41659 bytes 2 files changed, 64 insertions(+) create mode 100644 doc/core/grpc-cq.md create mode 100644 doc/images/grpc-cq.png diff --git a/doc/core/grpc-cq.md b/doc/core/grpc-cq.md new file mode 100644 index 00000000000..b485c354566 --- /dev/null +++ b/doc/core/grpc-cq.md @@ -0,0 +1,64 @@ +# gRPC Completion Queue + +_Author: Sree Kuchibhotla (@sreecha) - Sep 2018_ + +Code: [completion_queue.cc](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/surface/completion_queue.cc) + +This document gives an overview of completion queue architecture and focuses mainly on the interaction between completion queue and the Polling engine layer. + +## Completion queue attributes +Completion queue has two attributes + + - Completion_type: + - GRPC_CQ_NEXT: grpc_completion_queue_next() can be called (but not grpc_completion_queue_pluck()) + - GRPC_CQ_PLUCK: grpc_completion_queue_pluck() can be called (but not grpc_completion_queue_next()) + - GRPC_CQ_CALLBACK: The tags in the queue are function pointers to callbacks. Also, neither next() nor pluck() can be called on this + + - Polling_type: + - GRPC_CQ_NON_POLLING: Threads calling completion_queue_next/pluck do not do any polling + - GRPC_CQ_DEFAULT_POLLING: Threads calling completion_queue_next/pluck do polling + - GRPC_CQ_NON_LISTENING: Functionally similar to default polling except for a boolean attribute that states that the cq is non-listening. This is used by the grpc-server code to not associate any listening sockets with this completion-queue’s pollset + + +## Details + +![image](../images/grpc-cq.png) + + +### **grpc\_completion\_queue\_next()** & **grpc_completion_queue_pluck()** APIS + + +``` C++ +grpc_completion_queue_next(cq, deadline)/pluck(cq, deadline, tag) { + while(true) { + \\ 1. If an event is queued in the completion queue, dequeue and return + \\ (in case of pluck() dequeue only if the tag is the one we are interested in) + + \\ 2. If completion queue shutdown return + + \\ 3. In case of pluck, add (tag, worker) pair to the tag<->worker map on the cq + + \\ 4. Call grpc_pollset_work(cq’s-pollset, deadline) to do polling + \\ Note that if this function found some fds to be readable/writable/error, + \\ it would have scheduled those closures (which may queue completion events + \\ on SOME completion queue - not necessarily this one) + } +} +``` + +### Queuing a completion event (i.e., "tag") + +``` C++ +grpc_cq_end_op(cq, tag) { + \\ 1. Queue the tag in the event queue + + \\ 2. Find the pollset corresponding to the completion queue + \\ (i) If the cq is of type GRPC_CQ_NEXT, then KICK ANY worker + \\ i.e., call grpc_pollset_kick(pollset, nullptr) + \\ (ii) If the cq is of type GRPC_CQ_PLUCK, then search the tag<->worker + \\ map on the completion queue to find the worker. Then specifically + \\ kick that worker i.e call grpc_pollset_kick(pollset, worker) +} + +``` + diff --git a/doc/images/grpc-cq.png b/doc/images/grpc-cq.png new file mode 100644 index 0000000000000000000000000000000000000000..2d9e0958623c8aa4080f6c799b5bc1d2cf0d5923 GIT binary patch literal 41659 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 literal 0 HcmV?d00001 From f13a74312672aaf7c72e984f59dbd351dcda4e8a Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 26 Sep 2018 17:19:39 -0700 Subject: [PATCH 460/546] Implement child socket support --- .../client_channel/client_channel_channelz.cc | 19 +++++++++++++++++++ .../client_channel/client_channel_channelz.h | 8 +++----- .../ext/filters/client_channel/subchannel.cc | 10 ++++++++++ .../ext/filters/client_channel/subchannel.h | 3 +++ .../chttp2/transport/chttp2_transport.cc | 12 +++++++++++- .../cronet/transport/cronet_transport.cc | 6 +++++- .../ext/transport/inproc/inproc_transport.cc | 5 ++++- src/core/lib/transport/transport.cc | 5 +++++ src/core/lib/transport/transport.h | 10 ++++++++++ src/core/lib/transport/transport_impl.h | 3 +++ 10 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 7e8f59bcd33..4fedcbcbb6c 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -136,6 +136,23 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) { false); } +void SubchannelNode::PopulateChildSockets(grpc_json* json) { + ChildRefsList child_sockets; + grpc_json* json_iterator = nullptr; + grpc_subchannel_populate_child_sockets(subchannel_, &child_sockets); + if (!child_sockets.empty()) { + grpc_json* array_parent = grpc_json_create_child( + nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); + for (size_t i = 0; i < child_sockets.size(); ++i) { + json_iterator = + grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, + GRPC_JSON_OBJECT, false); + grpc_json_add_number_string_child(json_iterator, nullptr, "socketId", + child_sockets[i]); + } + } +} + grpc_json* SubchannelNode::RenderJson() { grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; @@ -166,6 +183,8 @@ grpc_json* SubchannelNode::RenderJson() { } // ask CallCountingHelper to populate trace and call count data. call_counter_.PopulateCallCounts(json); + json = top_level_json; + PopulateChildSockets(json); return top_level_json; } diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index 8ce331e529d..a63df00f9f2 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -31,11 +31,6 @@ typedef struct grpc_subchannel grpc_subchannel; namespace grpc_core { -// TODO(ncteisen), this only contains the uuids of the children for now, -// since that is all that is strictly needed. In a future enhancement we will -// add human readable names as in the channelz.proto -typedef InlinedVector ChildRefsList; - namespace channelz { // Subtype of ChannelNode that overrides and provides client_channel specific @@ -76,6 +71,9 @@ class SubchannelNode : public BaseNode { grpc_json* RenderJson() override; + // helper to populate the socket(s) that this subchannel owns. + void PopulateChildSockets(grpc_json* json); + // proxy methods to composed classes. void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { trace_.AddTraceEvent(severity, data); diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 57d0b3759f2..29aeb06e7bc 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -97,6 +97,8 @@ struct grpc_subchannel { /** set during connection */ grpc_connect_out_args connecting_result; + grpc_transport* transport; + /** callback for connection finishing */ grpc_closure on_connected; @@ -411,6 +413,13 @@ grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( return subchannel->channelz_subchannel.get(); } +void grpc_subchannel_populate_child_sockets( + grpc_subchannel* subchannel, grpc_core::ChildRefsList* child_sockets) { + if (subchannel->transport != nullptr) { + grpc_transport_populate_sockets(subchannel->transport, child_sockets); + } +} + static void continue_connect_locked(grpc_subchannel* c) { grpc_connect_in_args args; args.interested_parties = c->pollset_set; @@ -621,6 +630,7 @@ static bool publish_transport_locked(grpc_subchannel* c) { GRPC_ERROR_UNREF(error); return false; } + c->transport = c->connecting_result.transport; memset(&c->connecting_result, 0, sizeof(c->connecting_result)); /* initialize state watcher */ diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 84febb52040..2cf5067fc26 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -126,6 +126,9 @@ void grpc_subchannel_call_unref( grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( grpc_subchannel* subchannel); +void grpc_subchannel_populate_child_sockets( + grpc_subchannel* subchannel, grpc_core::ChildRefsList* child_sockets); + /** 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(). */ diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index d3232f4d268..202da652de7 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -3157,6 +3157,15 @@ static grpc_endpoint* chttp2_get_endpoint(grpc_transport* t) { return (reinterpret_cast(t))->ep; } +static void populate_sockets(grpc_transport* transport, + grpc_core::ChildRefsList* child_sockets) { + grpc_chttp2_transport* t = + reinterpret_cast(transport); + if (t->channelz_socket != nullptr) { + child_sockets->push_back(t->channelz_socket->uuid()); + } +} + static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), "chttp2", init_stream, @@ -3166,7 +3175,8 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), perform_transport_op, destroy_stream, destroy_transport, - chttp2_get_endpoint}; + chttp2_get_endpoint, + populate_sockets}; static const grpc_transport_vtable* get_vtable(void) { return &vtable; } diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index 81e2634e3a7..f3826a78de0 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -1439,6 +1439,9 @@ static grpc_endpoint* get_endpoint(grpc_transport* gt) { return nullptr; } static void perform_op(grpc_transport* gt, grpc_transport_op* op) {} +static void populate_sockets(grpc_transport* t, + grpc_core::ChildRefsList* child_sockets) {} + static const grpc_transport_vtable grpc_cronet_vtable = { sizeof(stream_obj), "cronet_http", @@ -1449,7 +1452,8 @@ static const grpc_transport_vtable grpc_cronet_vtable = { perform_op, destroy_stream, destroy_transport, - get_endpoint}; + get_endpoint, + populate_sockets}; grpc_transport* grpc_create_cronet_transport(void* engine, const char* target, const grpc_channel_args* args, diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index b0ca7f8207e..2deaacb2e06 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -1170,6 +1170,9 @@ static void set_pollset_set(grpc_transport* gt, grpc_stream* gs, static grpc_endpoint* get_endpoint(grpc_transport* t) { return nullptr; } +static void populate_sockets(grpc_transport* t, + grpc_core::ChildRefsList* child_sockets) {} + /******************************************************************************* * GLOBAL INIT AND DESTROY */ @@ -1194,7 +1197,7 @@ static const grpc_transport_vtable inproc_vtable = { sizeof(inproc_stream), "inproc", init_stream, set_pollset, set_pollset_set, perform_stream_op, perform_transport_op, destroy_stream, destroy_transport, - get_endpoint}; + get_endpoint, populate_sockets}; /******************************************************************************* * Main inproc transport functions diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index cbdb77c8441..2e7c40dda45 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -199,6 +199,11 @@ grpc_endpoint* grpc_transport_get_endpoint(grpc_transport* transport) { return transport->vtable->get_endpoint(transport); } +void grpc_transport_populate_sockets(grpc_transport* transport, + grpc_core::ChildRefsList* child_sockets) { + return transport->vtable->populate_sockets(transport, child_sockets); +} + // This comment should be sung to the tune of // "Supercalifragilisticexpialidocious": // diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 9e784635c69..93445ebd051 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -39,6 +39,13 @@ #define GRPC_PROTOCOL_VERSION_MIN_MAJOR 2 #define GRPC_PROTOCOL_VERSION_MIN_MINOR 1 +namespace grpc_core { +// TODO(ncteisen), this only contains the uuids of the children for now, +// since that is all that is strictly needed. In a future enhancement we will +// add human readable names as in the channelz.proto +typedef InlinedVector ChildRefsList; +} // namespace grpc_core + /* forward declarations */ typedef struct grpc_transport grpc_transport; @@ -366,6 +373,9 @@ void grpc_transport_destroy(grpc_transport* transport); /* Get the endpoint used by \a transport */ grpc_endpoint* grpc_transport_get_endpoint(grpc_transport* transport); +void grpc_transport_populate_sockets(grpc_transport* transport, + grpc_core::ChildRefsList* child_sockets); + /* Allocate a grpc_transport_op, and preconfigure the on_consumed closure to \a on_consumed and then delete the returned transport op */ grpc_transport_op* grpc_make_transport_op(grpc_closure* on_consumed); diff --git a/src/core/lib/transport/transport_impl.h b/src/core/lib/transport/transport_impl.h index ba5e05df0af..7ae59a1d17f 100644 --- a/src/core/lib/transport/transport_impl.h +++ b/src/core/lib/transport/transport_impl.h @@ -60,6 +60,9 @@ typedef struct grpc_transport_vtable { /* implementation of grpc_transport_get_endpoint */ grpc_endpoint* (*get_endpoint)(grpc_transport* self); + + void (*populate_sockets)(grpc_transport* self, + grpc_core::ChildRefsList* child_sockets); } grpc_transport_vtable; /* an instance of a grpc transport */ From a1598c5abfadf9e622d21a5cc0f754b412378314 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 12 Sep 2018 16:58:44 -0700 Subject: [PATCH 461/546] Create interfaces and initial plumbing for interception API --- include/grpcpp/channel.h | 14 +++- include/grpcpp/create_channel.h | 21 ++++++ .../grpcpp/impl/codegen/client_interceptor.h | 44 ++++++++++++ include/grpcpp/impl/codegen/interceptor.h | 67 +++++++++++++++++++ include/grpcpp/security/credentials.h | 28 ++++++++ src/cpp/client/channel_cc.cc | 8 ++- src/cpp/client/create_channel.cc | 42 ++++++++++-- src/cpp/client/create_channel_internal.cc | 10 ++- src/cpp/client/create_channel_internal.h | 8 ++- src/cpp/client/create_channel_posix.cc | 9 ++- src/cpp/client/cronet_credentials.cc | 19 ++++-- src/cpp/client/insecure_credentials.cc | 11 ++- src/cpp/client/secure_credentials.cc | 12 +++- src/cpp/client/secure_credentials.h | 6 ++ src/cpp/server/server_cc.cc | 3 +- test/cpp/microbenchmarks/bm_call_create.cc | 6 +- test/cpp/microbenchmarks/fullstack_fixtures.h | 2 +- test/cpp/performance/writes_per_rpc_test.cc | 2 +- 18 files changed, 284 insertions(+), 28 deletions(-) create mode 100644 include/grpcpp/impl/codegen/client_interceptor.h create mode 100644 include/grpcpp/impl/codegen/interceptor.h diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h index f1dba5b8ad1..b7c9e354de1 100644 --- a/include/grpcpp/channel.h +++ b/include/grpcpp/channel.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -62,8 +63,14 @@ class Channel final : public ChannelInterface, friend class internal::BlockingUnaryCallImpl; friend void experimental::ChannelResetConnectionBackoff(Channel* channel); friend std::shared_ptr CreateChannelInternal( - const grpc::string& host, grpc_channel* c_channel); - Channel(const grpc::string& host, grpc_channel* c_channel); + const grpc::string& host, grpc_channel* c_channel, + std::unique_ptr>> + interceptor_creators); + Channel(const grpc::string& host, grpc_channel* c_channel, + std::unique_ptr>> + interceptor_creators); internal::Call CreateCall(const internal::RpcMethod& method, ClientContext* context, @@ -91,6 +98,9 @@ class Channel final : public ChannelInterface, // It is _not owned_ by the channel; ownership belongs with its internal // shutdown callback tag (invoked when the CQ is fully shutdown). CompletionQueue* callback_cq_ = nullptr; + + std::vector> + interceptor_creators_; }; } // namespace grpc diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index 7a505a71271..43188d09e70 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -53,6 +54,26 @@ std::shared_ptr CreateCustomChannel( const std::shared_ptr& creds, const ChannelArguments& args); +namespace experimental { +/// Create a new \em custom \a Channel pointing to \a target with \a +/// interceptors being invoked per call. +/// +/// \warning For advanced use and testing ONLY. Override default channel +/// arguments only if necessary. +/// +/// \param target The URI of the endpoint to connect to. +/// \param creds Credentials to use for the created channel. If it does not +/// hold an object or is invalid, a lame channel (one on which all operations +/// fail) is returned. +/// \param args Options for channel creation. +std::shared_ptr CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const ChannelArguments& args, + std::unique_ptr>> + interceptor_creators); +} // namespace experimental } // namespace grpc #endif // GRPCPP_CREATE_CHANNEL_H diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h new file mode 100644 index 00000000000..23111b2c4ba --- /dev/null +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -0,0 +1,44 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_IMPL_CODEGEN_CLIENT_INTERCEPTOR_H +#define GRPCPP_IMPL_CODEGEN_CLIENT_INTERCEPTOR_H + +#include +#include + +namespace grpc { +namespace experimental { +class ClientInterceptor { + public: + virtual ~ClientInterceptor() {} + + virtual void Intercept(InterceptorBatchMethods* methods) = 0; +}; + +class ClientRpcInfo {}; + +class ClientInterceptorFactoryInterface { + public: + virtual ~ClientInterceptorFactoryInterface() {} + virtual ClientInterceptor* CreateClientInterceptor(ClientRpcInfo* info) = 0; +}; + +} // namespace experimental +} // namespace grpc +#endif /* GRPCPP_IMPL_CODEGEN_CLIENT_INTERCEPTOR_H */ diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h new file mode 100644 index 00000000000..930183e9810 --- /dev/null +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -0,0 +1,67 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_IMPL_CODEGEN_INTERCEPTOR_H +#define GRPCPP_IMPL_CODEGEN_INTERCEPTOR_H + +namespace grpc { +namespace experimental { +class InterceptedMessage { + public: + template + bool Extract(M* msg); // returns false if definitely invalid extraction + template + M* MutableExtract(); + uint64_t length(); // length on wire +}; + +enum class InterceptionHookPoints { + /* The first two in this list are for clients and servers */ + PRE_SEND_INITIAL_METADATA, + PRE_SEND_MESSAGE, + PRE_SEND_STATUS /* server only */, + /* The following three are for hijacked clients only and can only be + registered by the global interceptor */ + PRE_RECV_INITIAL_METADATA, + PRE_RECV_MESSAGE, + PRE_RECV_STATUS, + /* The following two are for all clients and servers */ + POST_RECV_INITIAL_METADATA, + POST_RECV_MESSAGE, + POST_RECV_STATUS /* client only */, + POST_RECV_CLOSE /* server only */, + NUM_INTERCEPTION_HOOKS +}; + +class InterceptorBatchMethods { + public: + virtual ~InterceptorBatchMethods(); + // Queries to check whether the current batch has an interception hook point + // of type \a type + virtual bool QueryInterceptionHookPoint(InterceptionHookPoints type) = 0; + // Calling this will signal that the interceptor is done intercepting the + // current batch of the RPC + virtual void Proceed() = 0; + // Calling this indicates that the interceptor has hijacked the RPC (only + // valid if the batch contains send_initial_metadata on the client side) + virtual void Hijack() = 0; +}; +} // namespace experimental +} // namespace grpc + +#endif /* GRPCPP_IMPL_CODEGEN_INTERCEPTOR_H */ diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index bfadc15df57..53f0131c002 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -38,6 +39,18 @@ class SecureChannelCredentials; class CallCredentials; class SecureCallCredentials; +class ChannelCredentials; + +namespace experimental { +std::shared_ptr CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const ChannelArguments& args, + std::unique_ptr>> + interceptor_creators); +} // namespace experimental + /// A channel credentials object encapsulates all the state needed by a client /// to authenticate with a server for a given channel. /// It can make various assertions, e.g., about the client’s identity, role @@ -62,8 +75,23 @@ class ChannelCredentials : private GrpcLibraryCodegen { const std::shared_ptr& creds, const ChannelArguments& args); + friend std::shared_ptr + experimental::CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const ChannelArguments& args, + std::unique_ptr>> + interceptor_creators); + virtual std::shared_ptr CreateChannel( const grpc::string& target, const ChannelArguments& args) = 0; + + virtual std::shared_ptr CreateChannelWithInterceptors( + const grpc::string& target, const ChannelArguments& args, + std::unique_ptr>> + interceptor_creators) = 0; }; /// A call credentials object encapsulates the state needed by a client to diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index c59059f0450..00430d07db2 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -50,8 +50,14 @@ namespace grpc { static internal::GrpcLibraryInitializer g_gli_initializer; -Channel::Channel(const grpc::string& host, grpc_channel* channel) +Channel::Channel( + const grpc::string& host, grpc_channel* channel, + std::unique_ptr>> + interceptor_creators) : host_(host), c_channel_(channel) { + auto vector = interceptor_creators.release(); + interceptor_creators_ = std::move(*vector); g_gli_initializer.summon(); } diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 67a46ce0e1b..efdff6c2652 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -39,11 +39,43 @@ std::shared_ptr CreateCustomChannel( const std::shared_ptr& creds, const ChannelArguments& args) { GrpcLibraryCodegen init_lib; // We need to call init in case of a bad creds. - return creds ? creds->CreateChannel(target, args) - : CreateChannelInternal( - "", grpc_lame_client_channel_create( - nullptr, GRPC_STATUS_INVALID_ARGUMENT, - "Invalid credentials.")); + return creds + ? creds->CreateChannel(target, args) + : CreateChannelInternal("", + grpc_lame_client_channel_create( + nullptr, GRPC_STATUS_INVALID_ARGUMENT, + "Invalid credentials."), + nullptr); } +namespace experimental { +/// Create a new \em custom \a Channel pointing to \a target with \a +/// interceptors being invoked per call. +/// +/// \warning For advanced use and testing ONLY. Override default channel +/// arguments only if necessary. +/// +/// \param target The URI of the endpoint to connect to. +/// \param creds Credentials to use for the created channel. If it does not +/// hold an object or is invalid, a lame channel (one on which all operations +/// fail) is returned. +/// \param args Options for channel creation. +std::shared_ptr CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const ChannelArguments& args, + std::unique_ptr>> + interceptor_creators) { + return creds + ? creds->CreateChannelWithInterceptors( + target, args, std::move(interceptor_creators)) + : CreateChannelInternal("", + grpc_lame_client_channel_create( + nullptr, GRPC_STATUS_INVALID_ARGUMENT, + "Invalid credentials."), + nullptr); +} +} // namespace experimental + } // namespace grpc diff --git a/src/cpp/client/create_channel_internal.cc b/src/cpp/client/create_channel_internal.cc index aa96edfcff2..313d682aae5 100644 --- a/src/cpp/client/create_channel_internal.cc +++ b/src/cpp/client/create_channel_internal.cc @@ -24,8 +24,12 @@ struct grpc_channel; namespace grpc { -std::shared_ptr CreateChannelInternal(const grpc::string& host, - grpc_channel* c_channel) { - return std::shared_ptr(new Channel(host, c_channel)); +std::shared_ptr CreateChannelInternal( + const grpc::string& host, grpc_channel* c_channel, + std::unique_ptr>> + interceptor_creators) { + return std::shared_ptr( + new Channel(host, c_channel, std::move(interceptor_creators))); } } // namespace grpc diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h index 86e81672776..512fc228669 100644 --- a/src/cpp/client/create_channel_internal.h +++ b/src/cpp/client/create_channel_internal.h @@ -21,6 +21,7 @@ #include +#include #include struct grpc_channel; @@ -28,8 +29,11 @@ struct grpc_channel; namespace grpc { class Channel; -std::shared_ptr CreateChannelInternal(const grpc::string& host, - grpc_channel* c_channel); +std::shared_ptr CreateChannelInternal( + const grpc::string& host, grpc_channel* c_channel, + std::unique_ptr>> + interceptor_creators); } // namespace grpc diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index f9285c9b287..b9e5887bccb 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -33,7 +33,8 @@ std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, internal::GrpcLibrary init_lib; init_lib.init(); return CreateChannelInternal( - "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr)); + "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr), + nullptr); } std::shared_ptr CreateCustomInsecureChannelFromFd( @@ -42,8 +43,10 @@ std::shared_ptr CreateCustomInsecureChannelFromFd( init_lib.init(); grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal("", grpc_insecure_channel_create_from_fd( - target.c_str(), fd, &channel_args)); + return CreateChannelInternal( + "", + grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), + nullptr); } #endif // GPR_SUPPORT_CHANNELS_FROM_FD diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc index 5c65ad05ead..09a76b428cc 100644 --- a/src/cpp/client/cronet_credentials.cc +++ b/src/cpp/client/cronet_credentials.cc @@ -31,16 +31,25 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { std::shared_ptr CreateChannel( const string& target, const grpc::ChannelArguments& args) override { - grpc_channel_args channel_args; - args.SetChannelArgs(&channel_args); - return CreateChannelInternal( - "", grpc_cronet_secure_channel_create(engine_, target.c_str(), - &channel_args, nullptr)); + return CreateChannelWithInterceptors(target, args, nullptr); } SecureChannelCredentials* AsSecureCredentials() override { return nullptr; } private: + std::shared_ptr CreateChannelWithInterceptors( + const string& target, const grpc::ChannelArguments& args, + std::unique_ptr>> + interceptor_creators) override { + grpc_channel_args channel_args; + args.SetChannelArgs(&channel_args); + return CreateChannelInternal( + "", + grpc_cronet_secure_channel_create(engine_, target.c_str(), + &channel_args, nullptr), + std::move(interceptor_creators)); + } void* engine_; }; diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 04dc5c0bcc2..b816e0c59af 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -32,11 +32,20 @@ class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: std::shared_ptr CreateChannel( const string& target, const grpc::ChannelArguments& args) override { + return CreateChannelWithInterceptors(target, args, nullptr); + } + + std::shared_ptr CreateChannelWithInterceptors( + const string& target, const grpc::ChannelArguments& args, + std::unique_ptr>> + interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); return CreateChannelInternal( "", - grpc_insecure_channel_create(target.c_str(), &channel_args, nullptr)); + grpc_insecure_channel_create(target.c_str(), &channel_args, nullptr), + std::move(interceptor_creators)); } SecureChannelCredentials* AsSecureCredentials() override { return nullptr; } diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index e48fbeb86d7..d1cd78e755c 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -36,12 +36,22 @@ SecureChannelCredentials::SecureChannelCredentials( std::shared_ptr SecureChannelCredentials::CreateChannel( const string& target, const grpc::ChannelArguments& args) { + return CreateChannelWithInterceptors(target, args, nullptr); +} + +std::shared_ptr +SecureChannelCredentials::CreateChannelWithInterceptors( + const string& target, const grpc::ChannelArguments& args, + std::unique_ptr>> + interceptor_creators) { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); return CreateChannelInternal( args.GetSslTargetNameOverride(), grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args, - nullptr)); + nullptr), + std::move(interceptor_creators)); } SecureCallCredentials::SecureCallCredentials(grpc_call_credentials* c_creds) diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 85cb54227c8..bfb6e17ee9d 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -36,9 +36,15 @@ class SecureChannelCredentials final : public ChannelCredentials { std::shared_ptr CreateChannel( const string& target, const grpc::ChannelArguments& args) override; + SecureChannelCredentials* AsSecureCredentials() override { return this; } private: + std::shared_ptr CreateChannelWithInterceptors( + const string& target, const grpc::ChannelArguments& args, + std::unique_ptr>> + interceptor_creators) override; grpc_channel_credentials* const c_creds_; }; diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 36f7eb81f96..72371e53841 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -473,7 +473,8 @@ std::shared_ptr Server::InProcessChannel( const ChannelArguments& args) { grpc_channel_args channel_args = args.c_channel_args(); return CreateChannelInternal( - "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr)); + "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr), + nullptr); } static grpc_server_register_method_payload_handling PayloadHandlingForMethod( diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 9516b2e3e25..389b888084f 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -133,8 +133,10 @@ static void BM_LameChannelCallCreateCpp(benchmark::State& state) { TrackCounters track_counters; auto stub = grpc::testing::EchoTestService::NewStub(grpc::CreateChannelInternal( - "", grpc_lame_client_channel_create( - "localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah"))); + "", + grpc_lame_client_channel_create("localhost:1234", + GRPC_STATUS_UNAUTHENTICATED, "blah"), + nullptr)); grpc::CompletionQueue cq; grpc::testing::EchoRequest send_request; grpc::testing::EchoResponse recv_response; diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index d390ae08f61..7188a2a28a3 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -218,7 +218,7 @@ class EndpointPairFixture : public BaseFixture { "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport_); grpc_chttp2_transport_start_reading(client_transport_, nullptr, nullptr); - channel_ = CreateChannelInternal("", channel); + channel_ = CreateChannelInternal("", channel, nullptr); } } diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc index 0ea3181f7ed..7b51260e5be 100644 --- a/test/cpp/performance/writes_per_rpc_test.cc +++ b/test/cpp/performance/writes_per_rpc_test.cc @@ -118,7 +118,7 @@ class EndpointPairFixture { "target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); grpc_chttp2_transport_start_reading(transport, nullptr, nullptr); - channel_ = CreateChannelInternal("", channel); + channel_ = CreateChannelInternal("", channel, nullptr); } } From 4cc16f951c0909196a9ed62774adcbbaf9cc88c1 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 27 Sep 2018 09:45:59 -0500 Subject: [PATCH 462/546] Simplifiy transport querying function --- .../client_channel/client_channel_channelz.cc | 29 +++++++------------ .../client_channel/client_channel_channelz.h | 5 ++++ .../ext/filters/client_channel/subchannel.cc | 16 +++++----- .../ext/filters/client_channel/subchannel.h | 4 +-- .../chttp2/transport/chttp2_transport.cc | 9 +++--- .../cronet/transport/cronet_transport.cc | 5 ++-- .../ext/transport/inproc/inproc_transport.cc | 5 ++-- src/core/lib/transport/transport.cc | 5 ++-- src/core/lib/transport/transport.h | 10 +------ src/core/lib/transport/transport_impl.h | 3 +- test/cpp/microbenchmarks/bm_call_create.cc | 10 ++++--- 11 files changed, 46 insertions(+), 55 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 4fedcbcbb6c..8d02304d19f 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -136,23 +136,6 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) { false); } -void SubchannelNode::PopulateChildSockets(grpc_json* json) { - ChildRefsList child_sockets; - grpc_json* json_iterator = nullptr; - grpc_subchannel_populate_child_sockets(subchannel_, &child_sockets); - if (!child_sockets.empty()) { - grpc_json* array_parent = grpc_json_create_child( - nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); - for (size_t i = 0; i < child_sockets.size(); ++i) { - json_iterator = - grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, - GRPC_JSON_OBJECT, false); - grpc_json_add_number_string_child(json_iterator, nullptr, "socketId", - child_sockets[i]); - } - } -} - grpc_json* SubchannelNode::RenderJson() { grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; @@ -184,7 +167,17 @@ grpc_json* SubchannelNode::RenderJson() { // ask CallCountingHelper to populate trace and call count data. call_counter_.PopulateCallCounts(json); json = top_level_json; - PopulateChildSockets(json); + // populate the child socket. + intptr_t socket_uuid = grpc_subchannel_get_child_socket_uuid(subchannel_); + if (socket_uuid != 0) { + grpc_json* array_parent = grpc_json_create_child( + nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); + json_iterator = + grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, + GRPC_JSON_OBJECT, false); + grpc_json_add_number_string_child(json_iterator, nullptr, "socketId", + socket_uuid); + } return top_level_json; } diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index a63df00f9f2..a6dae165223 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -31,6 +31,11 @@ typedef struct grpc_subchannel grpc_subchannel; namespace grpc_core { +// TODO(ncteisen), this only contains the uuids of the children for now, +// since that is all that is strictly needed. In a future enhancement we will +// add human readable names as in the channelz.proto +typedef InlinedVector ChildRefsList; + namespace channelz { // Subtype of ChannelNode that overrides and provides client_channel specific diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 29aeb06e7bc..4c33636646c 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -97,7 +97,9 @@ struct grpc_subchannel { /** set during connection */ grpc_connect_out_args connecting_result; - grpc_transport* transport; + /** uuid of this subchannel's socket. 0 if this subchannel is not + connected */ + intptr_t socket_uuid; /** callback for connection finishing */ grpc_closure on_connected; @@ -256,6 +258,7 @@ static void disconnect(grpc_subchannel* c) { c->disconnected = true; grpc_connector_shutdown(c->connector, GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Subchannel disconnected")); + c->socket_uuid = 0; c->connected_subchannel.reset(); gpr_mu_unlock(&c->mu); } @@ -413,11 +416,9 @@ grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( return subchannel->channelz_subchannel.get(); } -void grpc_subchannel_populate_child_sockets( - grpc_subchannel* subchannel, grpc_core::ChildRefsList* child_sockets) { - if (subchannel->transport != nullptr) { - grpc_transport_populate_sockets(subchannel->transport, child_sockets); - } +intptr_t grpc_subchannel_get_child_socket_uuid( + grpc_subchannel* subchannel) { + return subchannel->socket_uuid; } static void continue_connect_locked(grpc_subchannel* c) { @@ -578,6 +579,7 @@ static void on_connected_subchannel_connectivity_changed(void* p, grpc_connectivity_state_name( connected_subchannel_watcher->connectivity_state)); } + c->socket_uuid = 0; c->connected_subchannel.reset(); grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE, @@ -630,7 +632,7 @@ static bool publish_transport_locked(grpc_subchannel* c) { GRPC_ERROR_UNREF(error); return false; } - c->transport = c->connecting_result.transport; + c->socket_uuid = grpc_transport_get_socket_uuid(c->connecting_result.transport); memset(&c->connecting_result, 0, sizeof(c->connecting_result)); /* initialize state watcher */ diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 2cf5067fc26..67a2d497111 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -126,8 +126,8 @@ void grpc_subchannel_call_unref( grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( grpc_subchannel* subchannel); -void grpc_subchannel_populate_child_sockets( - grpc_subchannel* subchannel, grpc_core::ChildRefsList* child_sockets); +intptr_t grpc_subchannel_get_child_socket_uuid( + grpc_subchannel* subchannel); /** 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 diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 202da652de7..45ef4161f78 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -3157,12 +3157,13 @@ static grpc_endpoint* chttp2_get_endpoint(grpc_transport* t) { return (reinterpret_cast(t))->ep; } -static void populate_sockets(grpc_transport* transport, - grpc_core::ChildRefsList* child_sockets) { +static intptr_t get_socket_uuid(grpc_transport* transport) { grpc_chttp2_transport* t = reinterpret_cast(transport); if (t->channelz_socket != nullptr) { - child_sockets->push_back(t->channelz_socket->uuid()); + return t->channelz_socket->uuid(); + } else { + return 0; } } @@ -3176,7 +3177,7 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), destroy_stream, destroy_transport, chttp2_get_endpoint, - populate_sockets}; + get_socket_uuid}; static const grpc_transport_vtable* get_vtable(void) { return &vtable; } diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index f3826a78de0..bb20d9db084 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -1439,8 +1439,7 @@ static grpc_endpoint* get_endpoint(grpc_transport* gt) { return nullptr; } static void perform_op(grpc_transport* gt, grpc_transport_op* op) {} -static void populate_sockets(grpc_transport* t, - grpc_core::ChildRefsList* child_sockets) {} +static intptr_t get_socket_uuid(grpc_transport* t) { return 0; } static const grpc_transport_vtable grpc_cronet_vtable = { sizeof(stream_obj), @@ -1453,7 +1452,7 @@ static const grpc_transport_vtable grpc_cronet_vtable = { destroy_stream, destroy_transport, get_endpoint, - populate_sockets}; + get_socket_uuid}; grpc_transport* grpc_create_cronet_transport(void* engine, const char* target, const grpc_channel_args* args, diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 2deaacb2e06..56951f83386 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -1170,8 +1170,7 @@ static void set_pollset_set(grpc_transport* gt, grpc_stream* gs, static grpc_endpoint* get_endpoint(grpc_transport* t) { return nullptr; } -static void populate_sockets(grpc_transport* t, - grpc_core::ChildRefsList* child_sockets) {} +static intptr_t get_socket_uuid(grpc_transport* t) { return 0; } /******************************************************************************* * GLOBAL INIT AND DESTROY @@ -1197,7 +1196,7 @@ static const grpc_transport_vtable inproc_vtable = { sizeof(inproc_stream), "inproc", init_stream, set_pollset, set_pollset_set, perform_stream_op, perform_transport_op, destroy_stream, destroy_transport, - get_endpoint, populate_sockets}; + get_endpoint, get_socket_uuid}; /******************************************************************************* * Main inproc transport functions diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index 2e7c40dda45..c8fdbb4de26 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -199,9 +199,8 @@ grpc_endpoint* grpc_transport_get_endpoint(grpc_transport* transport) { return transport->vtable->get_endpoint(transport); } -void grpc_transport_populate_sockets(grpc_transport* transport, - grpc_core::ChildRefsList* child_sockets) { - return transport->vtable->populate_sockets(transport, child_sockets); +intptr_t grpc_transport_get_socket_uuid(grpc_transport* transport) { + return transport->vtable->get_socket_uuid(transport); } // This comment should be sung to the tune of diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 93445ebd051..aad133f6c3d 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -39,13 +39,6 @@ #define GRPC_PROTOCOL_VERSION_MIN_MAJOR 2 #define GRPC_PROTOCOL_VERSION_MIN_MINOR 1 -namespace grpc_core { -// TODO(ncteisen), this only contains the uuids of the children for now, -// since that is all that is strictly needed. In a future enhancement we will -// add human readable names as in the channelz.proto -typedef InlinedVector ChildRefsList; -} // namespace grpc_core - /* forward declarations */ typedef struct grpc_transport grpc_transport; @@ -373,8 +366,7 @@ void grpc_transport_destroy(grpc_transport* transport); /* Get the endpoint used by \a transport */ grpc_endpoint* grpc_transport_get_endpoint(grpc_transport* transport); -void grpc_transport_populate_sockets(grpc_transport* transport, - grpc_core::ChildRefsList* child_sockets); +intptr_t grpc_transport_get_socket_uuid(grpc_transport* transport); /* Allocate a grpc_transport_op, and preconfigure the on_consumed closure to \a on_consumed and then delete the returned transport op */ diff --git a/src/core/lib/transport/transport_impl.h b/src/core/lib/transport/transport_impl.h index 7ae59a1d17f..d609470ef01 100644 --- a/src/core/lib/transport/transport_impl.h +++ b/src/core/lib/transport/transport_impl.h @@ -61,8 +61,7 @@ typedef struct grpc_transport_vtable { /* implementation of grpc_transport_get_endpoint */ grpc_endpoint* (*get_endpoint)(grpc_transport* self); - void (*populate_sockets)(grpc_transport* self, - grpc_core::ChildRefsList* child_sockets); + intptr_t (*get_socket_uuid)(grpc_transport* self); } grpc_transport_vtable; /* an instance of a grpc transport */ diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 9516b2e3e25..b0cccafcf82 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -446,11 +446,13 @@ void Destroy(grpc_transport* self) {} /* implementation of grpc_transport_get_endpoint */ grpc_endpoint* GetEndpoint(grpc_transport* self) { return nullptr; } +intptr_t GetSocketUuid(grpc_transport* t) { return 0; } + static const grpc_transport_vtable dummy_transport_vtable = { - 0, "dummy_http2", InitStream, - SetPollset, SetPollsetSet, PerformStreamOp, - PerformOp, DestroyStream, Destroy, - GetEndpoint}; + 0, "dummy_http2", InitStream, + SetPollset, SetPollsetSet, PerformStreamOp, + PerformOp, DestroyStream, Destroy, + GetEndpoint, GetSocketUuid}; static grpc_transport dummy_transport = {&dummy_transport_vtable}; From 80ce1865d765f3a3623a8d6420b8e82e3f4b5cca Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Thu, 27 Sep 2018 11:26:05 -0400 Subject: [PATCH 463/546] Make SliceFromArray() static in channel_cc.cc. Also, use `context->authority_` instead of `context->authority()` for consistency. --- include/grpcpp/impl/codegen/slice.h | 4 ---- src/cpp/client/channel_cc.cc | 6 +++++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/grpcpp/impl/codegen/slice.h b/include/grpcpp/impl/codegen/slice.h index 75c093d1da0..8966559dc85 100644 --- a/include/grpcpp/impl/codegen/slice.h +++ b/include/grpcpp/impl/codegen/slice.h @@ -138,10 +138,6 @@ inline grpc_slice SliceFromCopiedString(const grpc::string& str) { str.length()); } -inline grpc_slice SliceFromArray(const char* arr, size_t len) { - return g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len); -} - } // namespace grpc #endif // GRPCPP_IMPL_CODEGEN_SLICE_H diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 510ae73478e..31c02893b11 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -65,6 +65,10 @@ Channel::~Channel() { namespace { +inline grpc_slice SliceFromArray(const char* arr, size_t len) { + return g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len); +} + grpc::string GetChannelInfoField(grpc_channel* channel, grpc_channel_info* channel_info, char*** channel_info_field) { @@ -112,7 +116,7 @@ internal::Call Channel::CreateCall(const internal::RpcMethod& method, method.channel_tag(), context->raw_deadline(), nullptr); } else { const string* host_str = nullptr; - if (!context->authority().empty()) { + if (!context->authority_.empty()) { host_str = &context->authority_; } else if (!host_.empty()) { host_str = &host_; From f2b493e3697211552a28dba582313174f2a932f2 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 27 Sep 2018 10:38:37 -0500 Subject: [PATCH 464/546] reviewer feedback --- .../client_channel/client_channel_channelz.cc | 5 ++-- .../client_channel/client_channel_channelz.h | 3 --- .../ext/filters/client_channel/subchannel.cc | 25 +++++++++---------- .../ext/filters/client_channel/subchannel.h | 9 ++++--- test/cpp/microbenchmarks/bm_call_create.cc | 6 ++--- 5 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index 8d02304d19f..b66c920b909 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -172,9 +172,8 @@ grpc_json* SubchannelNode::RenderJson() { if (socket_uuid != 0) { grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); - json_iterator = - grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, - GRPC_JSON_OBJECT, false); + json_iterator = grpc_json_create_child(json_iterator, array_parent, nullptr, + nullptr, GRPC_JSON_OBJECT, false); grpc_json_add_number_string_child(json_iterator, nullptr, "socketId", socket_uuid); } diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h index a6dae165223..8ce331e529d 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.h +++ b/src/core/ext/filters/client_channel/client_channel_channelz.h @@ -76,9 +76,6 @@ class SubchannelNode : public BaseNode { grpc_json* RenderJson() override; - // helper to populate the socket(s) that this subchannel owns. - void PopulateChildSockets(grpc_json* json); - // proxy methods to composed classes. void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { trace_.AddTraceEvent(severity, data); diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 4c33636646c..4756733f1f8 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -97,10 +97,6 @@ struct grpc_subchannel { /** set during connection */ grpc_connect_out_args connecting_result; - /** uuid of this subchannel's socket. 0 if this subchannel is not - connected */ - intptr_t socket_uuid; - /** callback for connection finishing */ grpc_closure on_connected; @@ -258,7 +254,6 @@ static void disconnect(grpc_subchannel* c) { c->disconnected = true; grpc_connector_shutdown(c->connector, GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Subchannel disconnected")); - c->socket_uuid = 0; c->connected_subchannel.reset(); gpr_mu_unlock(&c->mu); } @@ -416,9 +411,12 @@ grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( return subchannel->channelz_subchannel.get(); } -intptr_t grpc_subchannel_get_child_socket_uuid( - grpc_subchannel* subchannel) { - return subchannel->socket_uuid; +intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel) { + if (subchannel->connected_subchannel != nullptr) { + return subchannel->connected_subchannel->socket_uuid(); + } else { + return 0; + } } static void continue_connect_locked(grpc_subchannel* c) { @@ -579,7 +577,6 @@ static void on_connected_subchannel_connectivity_changed(void* p, grpc_connectivity_state_name( connected_subchannel_watcher->connectivity_state)); } - c->socket_uuid = 0; c->connected_subchannel.reset(); grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE, @@ -632,7 +629,8 @@ static bool publish_transport_locked(grpc_subchannel* c) { GRPC_ERROR_UNREF(error); return false; } - c->socket_uuid = grpc_transport_get_socket_uuid(c->connecting_result.transport); + intptr_t socket_uuid = + grpc_transport_get_socket_uuid(c->connecting_result.transport); memset(&c->connecting_result, 0, sizeof(c->connecting_result)); /* initialize state watcher */ @@ -653,7 +651,7 @@ static bool publish_transport_locked(grpc_subchannel* c) { /* publish */ c->connected_subchannel.reset(grpc_core::New( - stk, c->channelz_subchannel.get())); + stk, c->channelz_subchannel.get(), socket_uuid)); gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", c->connected_subchannel.get(), c); @@ -823,10 +821,11 @@ namespace grpc_core { ConnectedSubchannel::ConnectedSubchannel( grpc_channel_stack* channel_stack, - channelz::SubchannelNode* channelz_subchannel) + channelz::SubchannelNode* channelz_subchannel, intptr_t socket_uuid) : RefCountedWithTracing(&grpc_trace_stream_refcount), channel_stack_(channel_stack), - channelz_subchannel_(channelz_subchannel) {} + channelz_subchannel_(channelz_subchannel), + socket_uuid_(socket_uuid) {} ConnectedSubchannel::~ConnectedSubchannel() { GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 67a2d497111..5d95a720853 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -86,7 +86,8 @@ class ConnectedSubchannel : public RefCountedWithTracing { }; explicit ConnectedSubchannel(grpc_channel_stack* channel_stack, - channelz::SubchannelNode* channelz_subchannel); + channelz::SubchannelNode* channelz_subchannel, + intptr_t socket_uuid); ~ConnectedSubchannel(); grpc_channel_stack* channel_stack() { return channel_stack_; } @@ -98,12 +99,15 @@ class ConnectedSubchannel : public RefCountedWithTracing { channelz::SubchannelNode* channelz_subchannel() { return channelz_subchannel_; } + intptr_t socket_uuid() { return socket_uuid_; } private: grpc_channel_stack* channel_stack_; // backpointer to the channelz node in this connected subchannel's // owning subchannel. channelz::SubchannelNode* channelz_subchannel_; + // uuid of this subchannel's socket. 0 if this subchannel is not connected. + intptr_t socket_uuid_; }; } // namespace grpc_core @@ -126,8 +130,7 @@ void grpc_subchannel_call_unref( grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node( grpc_subchannel* subchannel); -intptr_t grpc_subchannel_get_child_socket_uuid( - grpc_subchannel* subchannel); +intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel); /** 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 diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index b0cccafcf82..45ac782a0e1 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -449,9 +449,9 @@ grpc_endpoint* GetEndpoint(grpc_transport* self) { return nullptr; } intptr_t GetSocketUuid(grpc_transport* t) { return 0; } static const grpc_transport_vtable dummy_transport_vtable = { - 0, "dummy_http2", InitStream, - SetPollset, SetPollsetSet, PerformStreamOp, - PerformOp, DestroyStream, Destroy, + 0, "dummy_http2", InitStream, + SetPollset, SetPollsetSet, PerformStreamOp, + PerformOp, DestroyStream, Destroy, GetEndpoint, GetSocketUuid}; static grpc_transport dummy_transport = {&dummy_transport_vtable}; From 404b2515af9c4dcc29440dea8b955ba341521b68 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 27 Sep 2018 11:18:42 -0500 Subject: [PATCH 465/546] reviewer feedback --- .../ext/filters/client_channel/connector.h | 3 +++ .../ext/filters/client_channel/subchannel.cc | 3 +-- .../ext/filters/client_channel/subchannel.h | 2 +- .../chttp2/client/chttp2_connector.cc | 2 ++ .../chttp2/transport/chttp2_transport.cc | 23 +++++++++---------- .../chttp2/transport/chttp2_transport.h | 2 ++ .../cronet/transport/cronet_transport.cc | 5 +--- .../ext/transport/inproc/inproc_transport.cc | 4 +--- src/core/lib/transport/transport.cc | 4 ---- src/core/lib/transport/transport.h | 2 -- src/core/lib/transport/transport_impl.h | 2 -- test/cpp/microbenchmarks/bm_call_create.cc | 10 ++++---- 12 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/core/ext/filters/client_channel/connector.h b/src/core/ext/filters/client_channel/connector.h index 556594929c1..ea34dcdab57 100644 --- a/src/core/ext/filters/client_channel/connector.h +++ b/src/core/ext/filters/client_channel/connector.h @@ -47,6 +47,9 @@ typedef struct { /** channel arguments (to be passed to the filters) */ grpc_channel_args* channel_args; + + /** socket uuid of the connected transport. 0 if not available */ + intptr_t socket_uuid; } grpc_connect_out_args; struct grpc_connector_vtable { diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 4756733f1f8..2847f4bdc18 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -629,8 +629,7 @@ static bool publish_transport_locked(grpc_subchannel* c) { GRPC_ERROR_UNREF(error); return false; } - intptr_t socket_uuid = - grpc_transport_get_socket_uuid(c->connecting_result.transport); + intptr_t socket_uuid = c->connecting_result.socket_uuid; memset(&c->connecting_result, 0, sizeof(c->connecting_result)); /* initialize state watcher */ diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 5d95a720853..699f93a8e77 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -107,7 +107,7 @@ class ConnectedSubchannel : public RefCountedWithTracing { // owning subchannel. channelz::SubchannelNode* channelz_subchannel_; // uuid of this subchannel's socket. 0 if this subchannel is not connected. - intptr_t socket_uuid_; + const intptr_t socket_uuid_; }; } // namespace grpc_core diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index e7522ffba87..0ac84032fd4 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -117,6 +117,8 @@ static void on_handshake_done(void* arg, grpc_error* error) { c->args.interested_parties); c->result->transport = grpc_create_chttp2_transport(args->args, args->endpoint, true); + c->result->socket_uuid = + grpc_chttp2_transport_get_socket_uuid(c->result->transport); GPR_ASSERT(c->result->transport); // TODO(roth): We ideally want to wait until we receive HTTP/2 // settings from the server before we consider the connection diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 45ef4161f78..776c15138b8 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -3157,16 +3157,6 @@ static grpc_endpoint* chttp2_get_endpoint(grpc_transport* t) { return (reinterpret_cast(t))->ep; } -static intptr_t get_socket_uuid(grpc_transport* transport) { - grpc_chttp2_transport* t = - reinterpret_cast(transport); - if (t->channelz_socket != nullptr) { - return t->channelz_socket->uuid(); - } else { - return 0; - } -} - static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), "chttp2", init_stream, @@ -3176,11 +3166,20 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream), perform_transport_op, destroy_stream, destroy_transport, - chttp2_get_endpoint, - get_socket_uuid}; + chttp2_get_endpoint}; static const grpc_transport_vtable* get_vtable(void) { return &vtable; } +intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport) { + grpc_chttp2_transport* t = + reinterpret_cast(transport); + if (t->channelz_socket != nullptr) { + return t->channelz_socket->uuid(); + } else { + return 0; + } +} + grpc_transport* grpc_create_chttp2_transport( const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client) { grpc_chttp2_transport* t = static_cast( diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h index 9d55b3f4b0d..e5872fee436 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h @@ -34,6 +34,8 @@ extern bool g_flow_control_enabled; grpc_transport* grpc_create_chttp2_transport( const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client); +intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport); + /// Takes ownership of \a read_buffer, which (if non-NULL) contains /// leftover bytes previously read from the endpoint (e.g., by handshakers). /// If non-null, \a notify_on_receive_settings will be scheduled when diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc index bb20d9db084..81e2634e3a7 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.cc +++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc @@ -1439,8 +1439,6 @@ static grpc_endpoint* get_endpoint(grpc_transport* gt) { return nullptr; } static void perform_op(grpc_transport* gt, grpc_transport_op* op) {} -static intptr_t get_socket_uuid(grpc_transport* t) { return 0; } - static const grpc_transport_vtable grpc_cronet_vtable = { sizeof(stream_obj), "cronet_http", @@ -1451,8 +1449,7 @@ static const grpc_transport_vtable grpc_cronet_vtable = { perform_op, destroy_stream, destroy_transport, - get_endpoint, - get_socket_uuid}; + get_endpoint}; grpc_transport* grpc_create_cronet_transport(void* engine, const char* target, const grpc_channel_args* args, diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 56951f83386..b0ca7f8207e 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -1170,8 +1170,6 @@ static void set_pollset_set(grpc_transport* gt, grpc_stream* gs, static grpc_endpoint* get_endpoint(grpc_transport* t) { return nullptr; } -static intptr_t get_socket_uuid(grpc_transport* t) { return 0; } - /******************************************************************************* * GLOBAL INIT AND DESTROY */ @@ -1196,7 +1194,7 @@ static const grpc_transport_vtable inproc_vtable = { sizeof(inproc_stream), "inproc", init_stream, set_pollset, set_pollset_set, perform_stream_op, perform_transport_op, destroy_stream, destroy_transport, - get_endpoint, get_socket_uuid}; + get_endpoint}; /******************************************************************************* * Main inproc transport functions diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index c8fdbb4de26..cbdb77c8441 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -199,10 +199,6 @@ grpc_endpoint* grpc_transport_get_endpoint(grpc_transport* transport) { return transport->vtable->get_endpoint(transport); } -intptr_t grpc_transport_get_socket_uuid(grpc_transport* transport) { - return transport->vtable->get_socket_uuid(transport); -} - // This comment should be sung to the tune of // "Supercalifragilisticexpialidocious": // diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index aad133f6c3d..9e784635c69 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -366,8 +366,6 @@ void grpc_transport_destroy(grpc_transport* transport); /* Get the endpoint used by \a transport */ grpc_endpoint* grpc_transport_get_endpoint(grpc_transport* transport); -intptr_t grpc_transport_get_socket_uuid(grpc_transport* transport); - /* Allocate a grpc_transport_op, and preconfigure the on_consumed closure to \a on_consumed and then delete the returned transport op */ grpc_transport_op* grpc_make_transport_op(grpc_closure* on_consumed); diff --git a/src/core/lib/transport/transport_impl.h b/src/core/lib/transport/transport_impl.h index d609470ef01..ba5e05df0af 100644 --- a/src/core/lib/transport/transport_impl.h +++ b/src/core/lib/transport/transport_impl.h @@ -60,8 +60,6 @@ typedef struct grpc_transport_vtable { /* implementation of grpc_transport_get_endpoint */ grpc_endpoint* (*get_endpoint)(grpc_transport* self); - - intptr_t (*get_socket_uuid)(grpc_transport* self); } grpc_transport_vtable; /* an instance of a grpc transport */ diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 45ac782a0e1..9516b2e3e25 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -446,13 +446,11 @@ void Destroy(grpc_transport* self) {} /* implementation of grpc_transport_get_endpoint */ grpc_endpoint* GetEndpoint(grpc_transport* self) { return nullptr; } -intptr_t GetSocketUuid(grpc_transport* t) { return 0; } - static const grpc_transport_vtable dummy_transport_vtable = { - 0, "dummy_http2", InitStream, - SetPollset, SetPollsetSet, PerformStreamOp, - PerformOp, DestroyStream, Destroy, - GetEndpoint, GetSocketUuid}; + 0, "dummy_http2", InitStream, + SetPollset, SetPollsetSet, PerformStreamOp, + PerformOp, DestroyStream, Destroy, + GetEndpoint}; static grpc_transport dummy_transport = {&dummy_transport_vtable}; From d5d881ae9f30dd91c820a97254f56ed36c116454 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 26 Sep 2018 17:43:14 -0700 Subject: [PATCH 466/546] Core infrastructure for timer manager debug --- src/core/lib/gpr/sync_posix.cc | 22 +++++++++++++++++++++- src/core/lib/iomgr/timer_manager.cc | 12 ++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 848d23730c2..ce2a5ca31a8 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -27,6 +27,15 @@ #include #include "src/core/lib/profiling/timers.h" +// For debug only. Forward statistics to another module. +void (*g_grpc_debug_timer_manager_stats)(int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, int64_t fork_count, int64_t timer_wait_err, int64_t timer_wait_cv) = nullptr; +// For debug only. Variables storing the counters being logged. +int64_t g_timer_manager_init_count = 0; +int64_t g_timer_manager_shutdown_count = 0; +int64_t g_fork_count = 0; +int64_t g_timer_wait_err = 0; +int64_t g_timer_wait_cv = 0; + #ifdef GPR_LOW_LEVEL_COUNTERS gpr_atm gpr_mu_locks = 0; gpr_atm gpr_counter_atm_cas = 0; @@ -88,7 +97,18 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts); } - GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); + if (!(err == 0 || err == ETIMEDOUT || err == EAGAIN)) { + if (g_grpc_debug_timer_manager_stats) { + g_timer_wait_err = err; + g_timer_wait_cv = (int64_t)cv; + g_grpc_debug_timer_manager_stats(g_timer_manager_init_count, + g_timer_manager_shutdown_count, + g_fork_count, + g_timer_wait_err, + g_timer_wait_cv); + } + GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); + } return err == ETIMEDOUT; } diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index 26de2166718..8c9158922df 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -61,6 +61,15 @@ static uint64_t g_timed_waiter_generation; static void timer_thread(void* completed_thread_ptr); +// For debug only. Forward statistics to another module. +extern void (*g_grpc_debug_timer_manager_stats)(int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, int64_t fork_count, int64_t timer_wait_err, int64_t timer_wait_cv); +// For debug only. Variables storing the counters being logged. +extern int64_t g_timer_manager_init_count; +extern int64_t g_timer_manager_shutdown_count; +extern int64_t g_fork_count; +extern int64_t g_timer_wait_err; +extern int64_t g_timer_wait_cv; + static void gc_completed_threads(void) { if (g_completed_threads != nullptr) { completed_thread* to_gc = g_completed_threads; @@ -285,6 +294,7 @@ void grpc_timer_manager_init(void) { gpr_mu_init(&g_mu); gpr_cv_init(&g_cv_wait); gpr_cv_init(&g_cv_shutdown); + g_timer_manager_init_count++; g_threaded = false; g_thread_count = 0; g_waiter_count = 0; @@ -319,6 +329,7 @@ static void stop_threads(void) { } void grpc_timer_manager_shutdown(void) { + g_timer_manager_shutdown_count++; stop_threads(); gpr_mu_destroy(&g_mu); @@ -327,6 +338,7 @@ void grpc_timer_manager_shutdown(void) { } void grpc_timer_manager_set_threading(bool threaded) { + g_fork_count++; if (threaded) { start_threads(); } else { From c74e7fc668cd7ac30746b4848dcf19510fe4185b Mon Sep 17 00:00:00 2001 From: Menghan Li Date: Tue, 25 Sep 2018 15:42:00 -0700 Subject: [PATCH 467/546] add google default creds go tests cloud_to_prod_auth google_default_creds tests are for c++ --- tools/run_tests/run_interop_tests.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 9bbc2e3e0ed..e8d6b59687c 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -777,12 +777,14 @@ def cloud_to_prod_jobspec(language, ] if transport_security == 'tls': transport_security_options = ['--use_tls=true'] - elif transport_security == 'google_default_credentials' and language == 'c++': + elif transport_security == 'google_default_credentials' and str( + language) in ['c++', 'go']: transport_security_options = [ '--custom_credentials_type=google_default_credentials' ] else: - print('Invalid transport security option.') + print('Invalid transport security option %s in cloud_to_prod_jobspec.' % + transport_security) sys.exit(1) cmdargs = cmdargs + transport_security_options environ = dict(language.cloud_to_prod_env(), **language.global_env()) @@ -817,8 +819,9 @@ def cloud_to_prod_jobspec(language, cmdline=cmdline, cwd=cwd, environ=environ, - shortname='%s:%s:%s:%s' % (suite_name, language, server_host_nickname, - test_case), + shortname='%s:%s:%s:%s:%s' % + (suite_name, language, server_host_nickname, test_case, + transport_security), timeout_seconds=_TEST_TIMEOUT, flake_retries=4 if args.allow_flakes else 0, timeout_retries=2 if args.allow_flakes else 0, @@ -848,7 +851,8 @@ def cloud_to_cloud_jobspec(language, elif transport_security == 'insecure': interop_only_options += ['--use_tls=false'] else: - print('Invalid transport security option.') + print('Invalid transport security option %s in cloud_to_cloud_jobspec.' + % transport_security) sys.exit(1) client_test_case = test_case @@ -903,8 +907,8 @@ def cloud_to_cloud_jobspec(language, cmdline=cmdline, cwd=cwd, environ=environ, - shortname='cloud_to_cloud:%s:%s_server:%s' % (language, server_name, - test_case), + shortname='cloud_to_cloud:%s:%s_server:%s:%s' % + (language, server_name, test_case, transport_security), timeout_seconds=_TEST_TIMEOUT, flake_retries=4 if args.allow_flakes else 0, timeout_retries=2 if args.allow_flakes else 0, @@ -929,7 +933,8 @@ def server_jobspec(language, elif transport_security == 'insecure': server_cmd += ['--use_tls=false'] else: - print('Invalid transport security option.') + print('Invalid transport security option %s in server_jobspec.' % + transport_security) sys.exit(1) cmdline = bash_cmdline(language.server_cmd(server_cmd)) environ = language.global_env() @@ -1318,7 +1323,7 @@ try: service_account_key_file, transport_security='tls') jobs.append(tls_test_job) - if language == 'c++': + if str(language) in ['c++', 'go']: google_default_creds_test_job = cloud_to_prod_jobspec( language, test_case, @@ -1370,7 +1375,9 @@ try: service_account_key_file, transport_security='tls') jobs.append(tls_test_job) - if language == 'c++': + if str(language) in [ + 'go' + ]: # Add more languages to the list to turn on tests. google_default_creds_test_job = cloud_to_prod_jobspec( language, test_case, @@ -1378,6 +1385,7 @@ try: prod_servers[server_host_nickname], docker_image=docker_images.get( str(language)), + auth=True, manual_cmd_log=client_manual_cmd_log, service_account_key_file=args. service_account_key_file, From a74492e8a41a086f82d73f640d0e69d187c38be6 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 27 Sep 2018 11:11:01 -0700 Subject: [PATCH 468/546] Polling engine usage in client server --- ...grpc-client-server-polling-engine-usage.md | 32 ++++++++++++++++++ doc/images/grpc-call-channel-cq.png | Bin 0 -> 46078 bytes doc/images/grpc-client-lb-pss.png | Bin 0 -> 56397 bytes doc/images/grpc-server-cq-fds.png | Bin 0 -> 42096 bytes tools/doxygen/Doxyfile.core | 1 + tools/doxygen/Doxyfile.core.internal | 1 + 6 files changed, 34 insertions(+) create mode 100644 doc/core/grpc-client-server-polling-engine-usage.md create mode 100644 doc/images/grpc-call-channel-cq.png create mode 100644 doc/images/grpc-client-lb-pss.png create mode 100644 doc/images/grpc-server-cq-fds.png diff --git a/doc/core/grpc-client-server-polling-engine-usage.md b/doc/core/grpc-client-server-polling-engine-usage.md new file mode 100644 index 00000000000..8de3979a56a --- /dev/null +++ b/doc/core/grpc-client-server-polling-engine-usage.md @@ -0,0 +1,32 @@ +# Polling Engine Usage on gRPC client and Server + +_Author: Sree Kuchibhotla (@sreecha) - Sep 2018_ + + +This document talks about how polling engine is used in gRPC core (both on client and server code paths). + +## gRPC client + +### Relation between Call, Channel (sub-channels), Completion queue, `grpc_pollset` +- A gRPC Call is tied to a channel (more specifically a sub-channel) and a completion queue for the lifetime of the call. +- Once a _sub-channel_ is picked for the call, the file-descriptor (socket fd in case of TCP channels) is added to the pollset corresponding to call's completion queue. (Recall that as per [grpc-cq](grpc-cq.md), a completion queue has a pollset by default) + +![image](../images/grpc-call-channel-cq.png) + + +### Making progress on Async `connect()` on sub-channels (`grpc_pollset_set` usecase) +- A gRPC channel is created between a client and a 'target'. The 'target' may resolve in to one or more backend servers. +- A sub-channel is the 'connection' from a client to the backend server +- While establishing sub-cannels (i.e connections) to the backends, gRPC issues async [`connect()`](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/tcp_client_posix.cc#L296) calls which may not complete right away. When the `connect()` eventually succeeds, the socket fd is makde 'writable' + - This means that the polling engine must be monitoring all these sub-channel `fd`s for writable events and we need to make sure there is a polling thread that monitors all these fds + - To accomplish this, the `grpc_pollset_set` is used the following way (see picture below) + +![image](../images/grpc-client-lb-pss.png) + +## gRPC server + +- The listening fd (i.e., the socket fd corresponding to the server listening port) is added to each of the server completion queues. Note that in gRPC we use SO_REUSEPORT option and create multiple listening fds but all of them map to the same listening port +- A new incoming channel is randomly assigned to some server completion queue (see picture below) + +![image](../images/grpc-server-cq-fds.png) + diff --git a/doc/images/grpc-call-channel-cq.png b/doc/images/grpc-call-channel-cq.png new file mode 100644 index 0000000000000000000000000000000000000000..d73b987ee927277b4ecff934db115e4859487165 GIT binary patch literal 46078 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

sDJ#JwJ|>T3zhjB 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%0DBkKNx| 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

I2#LFsz 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 Nc~_6KH0NN_e*jnh;79-f literal 0 HcmV?d00001 diff --git a/doc/images/grpc-server-cq-fds.png b/doc/images/grpc-server-cq-fds.png new file mode 100644 index 0000000000000000000000000000000000000000..e52bfac81c7064dbb601a89f8bd9cb915c527e55 GIT binary patch literal 42096 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 a0So4-!>_Fs2c5%{(AP21uDSQ%*?$3Bmsnc> literal 0 HcmV?d00001 diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index aa75bc68283..43a9b846a2b 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -771,6 +771,7 @@ doc/compression_cookbook.md \ doc/connection-backoff-interop-test-description.md \ doc/connection-backoff.md \ doc/connectivity-semantics-and-api.md \ +doc/core/grpc-client-server-polling-engine-usage.md \ doc/core/grpc-error.md \ doc/core/moving-to-c++.md \ doc/core/pending_api_cleanups.md \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 91860567339..6b08d49346d 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -771,6 +771,7 @@ doc/compression_cookbook.md \ doc/connection-backoff-interop-test-description.md \ doc/connection-backoff.md \ doc/connectivity-semantics-and-api.md \ +doc/core/grpc-client-server-polling-engine-usage.md \ doc/core/grpc-error.md \ doc/core/moving-to-c++.md \ doc/core/pending_api_cleanups.md \ From 82b2e2977d5cd144c6e2350d55b6f928fd8f6ce7 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 27 Sep 2018 11:17:27 -0700 Subject: [PATCH 469/546] generate_projects.sh --- tools/doxygen/Doxyfile.core | 1 + tools/doxygen/Doxyfile.core.internal | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index aa75bc68283..9f7c2c9140a 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -772,6 +772,7 @@ doc/connection-backoff-interop-test-description.md \ doc/connection-backoff.md \ doc/connectivity-semantics-and-api.md \ doc/core/grpc-error.md \ +doc/core/grpc-polling-engines.md \ doc/core/moving-to-c++.md \ doc/core/pending_api_cleanups.md \ doc/core/transport_explainer.md \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 91860567339..2ce6412d2cf 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -772,6 +772,7 @@ doc/connection-backoff-interop-test-description.md \ doc/connection-backoff.md \ doc/connectivity-semantics-and-api.md \ doc/core/grpc-error.md \ +doc/core/grpc-polling-engines.md \ doc/core/moving-to-c++.md \ doc/core/pending_api_cleanups.md \ doc/core/transport_explainer.md \ From 018a14bdec298275ed0b560be55f783092defb85 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 27 Sep 2018 11:18:18 -0700 Subject: [PATCH 470/546] generate_projects.sh --- tools/doxygen/Doxyfile.core | 1 + tools/doxygen/Doxyfile.core.internal | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index aa75bc68283..8562dfff3a9 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -771,6 +771,7 @@ doc/compression_cookbook.md \ doc/connection-backoff-interop-test-description.md \ doc/connection-backoff.md \ doc/connectivity-semantics-and-api.md \ +doc/core/grpc-cq.md \ doc/core/grpc-error.md \ doc/core/moving-to-c++.md \ doc/core/pending_api_cleanups.md \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 91860567339..aa7b11fd547 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -771,6 +771,7 @@ doc/compression_cookbook.md \ doc/connection-backoff-interop-test-description.md \ doc/connection-backoff.md \ doc/connectivity-semantics-and-api.md \ +doc/core/grpc-cq.md \ doc/core/grpc-error.md \ doc/core/moving-to-c++.md \ doc/core/pending_api_cleanups.md \ From 038e760a7da9098dd1e0b76db0342b1eb1a6351d Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 27 Sep 2018 10:26:08 -0500 Subject: [PATCH 471/546] Channelz C++ Socket support --- src/cpp/server/channelz/channelz_service.cc | 17 +++ src/cpp/server/channelz/channelz_service.h | 4 + test/cpp/end2end/channelz_service_test.cc | 152 ++++++++++++++++++++ 3 files changed, 173 insertions(+) diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc index e096c1f421d..4e3fe8c1c94 100644 --- a/src/cpp/server/channelz/channelz_service.cc +++ b/src/cpp/server/channelz/channelz_service.cc @@ -92,4 +92,21 @@ Status ChannelzService::GetSubchannel( return Status::OK; } +Status ChannelzService::GetSocket(ServerContext* unused, + const channelz::v1::GetSocketRequest* request, + channelz::v1::GetSocketResponse* response) { + char* json_str = grpc_channelz_get_socket(request->socket_id()); + gpr_log(GPR_ERROR, "%s", json_str); + if (json_str == nullptr) { + return Status(NOT_FOUND, "No object found for that SocketId"); + } + google::protobuf::util::Status s = + google::protobuf::util::JsonStringToMessage(json_str, response); + gpr_free(json_str); + if (s != google::protobuf::util::Status::OK) { + return Status(INTERNAL, s.ToString()); + } + return Status::OK; +} + } // namespace grpc diff --git a/src/cpp/server/channelz/channelz_service.h b/src/cpp/server/channelz/channelz_service.h index 9e0b5b6eadb..1be4e01c73c 100644 --- a/src/cpp/server/channelz/channelz_service.h +++ b/src/cpp/server/channelz/channelz_service.h @@ -44,6 +44,10 @@ class ChannelzService final : public channelz::v1::Channelz::Service { Status GetSubchannel(ServerContext* unused, const channelz::v1::GetSubchannelRequest* request, channelz::v1::GetSubchannelResponse* response) override; + // implementation of GetSocket rpc + Status GetSocket(ServerContext* unused, + const channelz::v1::GetSocketRequest* request, + channelz::v1::GetSocketResponse* response) override; }; } // namespace grpc diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index e96d68f93b0..a597fd9c4b4 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -43,6 +43,8 @@ using grpc::channelz::v1::GetChannelRequest; using grpc::channelz::v1::GetChannelResponse; using grpc::channelz::v1::GetServersRequest; using grpc::channelz::v1::GetServersResponse; +using grpc::channelz::v1::GetSocketRequest; +using grpc::channelz::v1::GetSocketResponse; using grpc::channelz::v1::GetSubchannelRequest; using grpc::channelz::v1::GetSubchannelResponse; using grpc::channelz::v1::GetTopChannelsRequest; @@ -71,6 +73,26 @@ class Proxy : public ::grpc::testing::EchoTestService::Service { return stubs_[idx]->Echo(client_context.get(), *request, response); } + Status BidiStream(ServerContext* server_context, + ServerReaderWriter* + stream_from_client) override { + EchoRequest request; + EchoResponse response; + std::unique_ptr client_context = + ClientContext::FromServerContext(*server_context); + + // always use the first proxy for streaming + auto stream_to_backend = stubs_[0]->BidiStream(client_context.get()); + while (stream_from_client->Read(&request)) { + stream_to_backend->Write(request); + stream_to_backend->Read(&response); + stream_from_client->Write(response); + } + + stream_to_backend->WritesDone(); + return stream_to_backend->Finish(); + } + private: std::vector> stubs_; }; @@ -149,6 +171,21 @@ class ChannelzServerTest : public ::testing::Test { EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); } + void SendSuccessfulStream(int num_messages) { + EchoRequest request; + EchoResponse response; + request.set_message("Hello channelz"); + ClientContext context; + auto stream_to_proxy = echo_stub_->BidiStream(&context); + for (int i = 0; i < num_messages; ++i) { + EXPECT_TRUE(stream_to_proxy->Write(request)); + EXPECT_TRUE(stream_to_proxy->Read(&response)); + } + stream_to_proxy->WritesDone(); + Status s = stream_to_proxy->Finish(); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + } + void SendFailedEcho(int channel_idx) { EchoRequest request; EchoResponse response; @@ -448,6 +485,121 @@ TEST_F(ChannelzServerTest, ServerCallTest) { kNumSuccess + kNumFailed + 1); } +TEST_F(ChannelzServerTest, ManySubchannelsAndSockets) { + ResetStubs(); + const int kNumChannels = 4; + ConfigureProxy(kNumChannels); + const int kNumSuccess = 10; + const int kNumFailed = 11; + for (int i = 0; i < kNumSuccess; ++i) { + SendSuccessfulEcho(0); + SendSuccessfulEcho(2); + } + for (int i = 0; i < kNumFailed; ++i) { + SendFailedEcho(1); + SendFailedEcho(2); + } + GetTopChannelsRequest gtc_request; + GetTopChannelsResponse gtc_response; + gtc_request.set_start_channel_id(0); + ClientContext context; + Status s = + channelz_stub_->GetTopChannels(&context, gtc_request, >c_response); + EXPECT_TRUE(s.ok()) << s.error_message(); + EXPECT_EQ(gtc_response.channel_size(), kNumChannels); + for (int i = 0; i < gtc_response.channel_size(); ++i) { + // if the channel sent no RPCs, then expect no subchannels to have been + // created. + if (gtc_response.channel(i).data().calls_started() == 0) { + EXPECT_EQ(gtc_response.channel(i).subchannel_ref_size(), 0); + continue; + } + // The resolver must return at least one address. + ASSERT_GT(gtc_response.channel(i).subchannel_ref_size(), 0); + // First grab the subchannel + GetSubchannelRequest get_subchannel_req; + GetSubchannelResponse get_subchannel_resp; + get_subchannel_req.set_subchannel_id( + gtc_response.channel(i).subchannel_ref(0).subchannel_id()); + ClientContext get_subchannel_ctx; + Status s = channelz_stub_->GetSubchannel( + &get_subchannel_ctx, get_subchannel_req, &get_subchannel_resp); + EXPECT_TRUE(s.ok()) << s.error_message(); + EXPECT_EQ(get_subchannel_resp.subchannel().socket_ref_size(), 1); + // Now grab the socket. + GetSocketRequest get_socket_req; + GetSocketResponse get_socket_resp; + ClientContext get_socket_ctx; + get_socket_req.set_socket_id( + get_subchannel_resp.subchannel().socket_ref(0).socket_id()); + s = channelz_stub_->GetSocket(&get_socket_ctx, get_socket_req, + &get_socket_resp); + EXPECT_TRUE(s.ok()) << s.error_message(); + // calls started == streams started AND stream succeeded. Since none of + // these RPCs were canceled, all of the streams will succeeded even though + // the RPCs they represent might have failed. + EXPECT_EQ(get_subchannel_resp.subchannel().data().calls_started(), + get_socket_resp.socket().data().streams_started()); + EXPECT_EQ(get_subchannel_resp.subchannel().data().calls_started(), + get_socket_resp.socket().data().streams_succeeded()); + // All of the calls were unary, so calls started == messages sent. + EXPECT_EQ(get_subchannel_resp.subchannel().data().calls_started(), + get_socket_resp.socket().data().messages_sent()); + // We only get responses when the RPC was successful, so + // calls succeeded == messages received. + EXPECT_EQ(get_subchannel_resp.subchannel().data().calls_succeeded(), + get_socket_resp.socket().data().messages_received()); + } +} + +TEST_F(ChannelzServerTest, StreamingRPC) { + ResetStubs(); + ConfigureProxy(1); + const int kNumMessages = 5; + SendSuccessfulStream(kNumMessages); + // Get the channel + GetChannelRequest get_channel_request; + GetChannelResponse get_channel_response; + get_channel_request.set_channel_id(GetChannelId(0)); + ClientContext get_channel_context; + Status s = channelz_stub_->GetChannel( + &get_channel_context, get_channel_request, &get_channel_response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + EXPECT_EQ(get_channel_response.channel().data().calls_started(), 1); + EXPECT_EQ(get_channel_response.channel().data().calls_succeeded(), 1); + EXPECT_EQ(get_channel_response.channel().data().calls_failed(), 0); + // Get the subchannel + ASSERT_GT(get_channel_response.channel().subchannel_ref_size(), 0); + GetSubchannelRequest get_subchannel_request; + GetSubchannelResponse get_subchannel_response; + ClientContext get_subchannel_context; + get_subchannel_request.set_subchannel_id( + get_channel_response.channel().subchannel_ref(0).subchannel_id()); + s = channelz_stub_->GetSubchannel(&get_subchannel_context, + get_subchannel_request, + &get_subchannel_response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + EXPECT_EQ(get_subchannel_response.subchannel().data().calls_started(), 1); + EXPECT_EQ(get_subchannel_response.subchannel().data().calls_succeeded(), 1); + EXPECT_EQ(get_subchannel_response.subchannel().data().calls_failed(), 0); + // Get the socket + ASSERT_GT(get_subchannel_response.subchannel().socket_ref_size(), 0); + GetSocketRequest get_socket_request; + GetSocketResponse get_socket_response; + ClientContext get_socket_context; + get_socket_request.set_socket_id( + get_subchannel_response.subchannel().socket_ref(0).socket_id()); + s = channelz_stub_->GetSocket(&get_socket_context, get_socket_request, + &get_socket_response); + EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message(); + EXPECT_EQ(get_socket_response.socket().data().streams_started(), 1); + EXPECT_EQ(get_socket_response.socket().data().streams_succeeded(), 1); + EXPECT_EQ(get_socket_response.socket().data().streams_failed(), 0); + EXPECT_EQ(get_socket_response.socket().data().messages_sent(), kNumMessages); + EXPECT_EQ(get_socket_response.socket().data().messages_received(), + kNumMessages); +} + } // namespace testing } // namespace grpc From c1f880d9fe0e0ce810fb50f7ac6ebe5bedee3922 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 27 Sep 2018 12:28:21 -0700 Subject: [PATCH 472/546] Minor change --- doc/core/grpc-client-server-polling-engine-usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/core/grpc-client-server-polling-engine-usage.md b/doc/core/grpc-client-server-polling-engine-usage.md index 8de3979a56a..fa54f946213 100644 --- a/doc/core/grpc-client-server-polling-engine-usage.md +++ b/doc/core/grpc-client-server-polling-engine-usage.md @@ -26,7 +26,7 @@ This document talks about how polling engine is used in gRPC core (both on clien ## gRPC server - The listening fd (i.e., the socket fd corresponding to the server listening port) is added to each of the server completion queues. Note that in gRPC we use SO_REUSEPORT option and create multiple listening fds but all of them map to the same listening port -- A new incoming channel is randomly assigned to some server completion queue (see picture below) +- A new incoming channel is assigned to some server completion queue picked randomly (note that we currently [round-robin](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/tcp_server_posix.cc#L231) over the server completion queues) ![image](../images/grpc-server-cq-fds.png) From 635e0bd1e5149aee941d6b6064bb7cef738e7537 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 27 Sep 2018 12:30:51 -0700 Subject: [PATCH 473/546] fix typo --- doc/core/grpc-client-server-polling-engine-usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/core/grpc-client-server-polling-engine-usage.md b/doc/core/grpc-client-server-polling-engine-usage.md index fa54f946213..3a560e71a81 100644 --- a/doc/core/grpc-client-server-polling-engine-usage.md +++ b/doc/core/grpc-client-server-polling-engine-usage.md @@ -17,7 +17,7 @@ This document talks about how polling engine is used in gRPC core (both on clien ### Making progress on Async `connect()` on sub-channels (`grpc_pollset_set` usecase) - A gRPC channel is created between a client and a 'target'. The 'target' may resolve in to one or more backend servers. - A sub-channel is the 'connection' from a client to the backend server -- While establishing sub-cannels (i.e connections) to the backends, gRPC issues async [`connect()`](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/tcp_client_posix.cc#L296) calls which may not complete right away. When the `connect()` eventually succeeds, the socket fd is makde 'writable' +- While establishing sub-cannels (i.e connections) to the backends, gRPC issues async [`connect()`](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/tcp_client_posix.cc#L296) calls which may not complete right away. When the `connect()` eventually succeeds, the socket fd is make 'writable' - This means that the polling engine must be monitoring all these sub-channel `fd`s for writable events and we need to make sure there is a polling thread that monitors all these fds - To accomplish this, the `grpc_pollset_set` is used the following way (see picture below) From c33b593c8863ccc496e913bd82744ecc991c89f8 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 27 Sep 2018 14:23:29 -0700 Subject: [PATCH 474/546] Add comments on what 'covering' a write means --- src/core/lib/iomgr/tcp_posix.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index ac1e919acb1..4aad83915f4 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -204,6 +204,15 @@ static void drop_uncovered(grpc_tcp* tcp) { GPR_ASSERT(old_count != 1); } +/* gRPC API considers a Write operation to be done the moment it clears ‘flow + control’ i.e., and not necessarily sent on the wire. This means that the + application MAY NOT call `grpc_completion_queue_next/pluck` in a timely + manner when its `Write()` API is acked. + + We need to ensure that the fd is 'covered' (i.e being monitored by some + polling thread and progress is made) and hence add it to a backup poller + here */ + static void cover_self(grpc_tcp* tcp) { backup_poller* p; gpr_atm old_count = From 57d1bae72be3deb63230dd7967a9aab458e56f6d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 27 Sep 2018 14:48:22 -0700 Subject: [PATCH 475/546] Wrap everything with macro --- src/core/lib/gpr/sync_posix.cc | 27 +++++++++++++++++++-------- src/core/lib/iomgr/timer_manager.cc | 21 +++++++++++++++++---- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index ce2a5ca31a8..cd7ec90c578 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -27,14 +27,20 @@ #include #include "src/core/lib/profiling/timers.h" -// For debug only. Forward statistics to another module. -void (*g_grpc_debug_timer_manager_stats)(int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, int64_t fork_count, int64_t timer_wait_err, int64_t timer_wait_cv) = nullptr; -// For debug only. Variables storing the counters being logged. +// For debug of the timer manager crash only. +// TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER +void (*g_grpc_debug_timer_manager_stats)(int64_t timer_manager_init_count, + int64_t timer_manager_shutdown_count, + int64_t fork_count, + int64_t timer_wait_err, + int64_t timer_wait_cv) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; int64_t g_timer_wait_err = 0; int64_t g_timer_wait_cv = 0; +#endif // GRPC_DEBUG_TIMER_MANAGER #ifdef GPR_LOW_LEVEL_COUNTERS gpr_atm gpr_mu_locks = 0; @@ -97,18 +103,23 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts); } + +#ifdef GRPC_DEBUG_TIMER_MANAGER + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. if (!(err == 0 || err == ETIMEDOUT || err == EAGAIN)) { if (g_grpc_debug_timer_manager_stats) { g_timer_wait_err = err; g_timer_wait_cv = (int64_t)cv; - g_grpc_debug_timer_manager_stats(g_timer_manager_init_count, - g_timer_manager_shutdown_count, - g_fork_count, - g_timer_wait_err, - g_timer_wait_cv); + g_grpc_debug_timer_manager_stats( + g_timer_manager_init_count, g_timer_manager_shutdown_count, + g_fork_count, g_timer_wait_err, g_timer_wait_cv); } GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); } +#else + GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); +#endif return err == ETIMEDOUT; } diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index 8c9158922df..3be1209228b 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -61,14 +61,15 @@ static uint64_t g_timed_waiter_generation; static void timer_thread(void* completed_thread_ptr); -// For debug only. Forward statistics to another module. -extern void (*g_grpc_debug_timer_manager_stats)(int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, int64_t fork_count, int64_t timer_wait_err, int64_t timer_wait_cv); -// For debug only. Variables storing the counters being logged. +// For debug of the timer manager crash only. +// TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER extern int64_t g_timer_manager_init_count; extern int64_t g_timer_manager_shutdown_count; extern int64_t g_fork_count; extern int64_t g_timer_wait_err; extern int64_t g_timer_wait_cv; +#endif // GRPC_DEBUG_TIMER_MANAGER static void gc_completed_threads(void) { if (g_completed_threads != nullptr) { @@ -291,10 +292,14 @@ static void start_threads(void) { } void grpc_timer_manager_init(void) { +#ifdef GRPC_DEBUG_TIMER_MANAGER + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. + g_timer_manager_init_count++; +#endif gpr_mu_init(&g_mu); gpr_cv_init(&g_cv_wait); gpr_cv_init(&g_cv_shutdown); - g_timer_manager_init_count++; g_threaded = false; g_thread_count = 0; g_waiter_count = 0; @@ -329,7 +334,11 @@ static void stop_threads(void) { } void grpc_timer_manager_shutdown(void) { +// For debug of the timer manager crash only. +// TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER g_timer_manager_shutdown_count++; +#endif stop_threads(); gpr_mu_destroy(&g_mu); @@ -338,7 +347,11 @@ void grpc_timer_manager_shutdown(void) { } void grpc_timer_manager_set_threading(bool threaded) { +// For debug of the timer manager crash only. +// TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER g_fork_count++; +#endif if (threaded) { start_threads(); } else { From 74c729ce45ad8bc365e94def3e9ab167e016b0ed Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 27 Sep 2018 15:25:21 -0700 Subject: [PATCH 476/546] Remove another cv --- src/core/lib/gpr/sync_posix.cc | 11 ++++------- src/core/lib/iomgr/timer_manager.cc | 9 ++++----- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index cd7ec90c578..87356e99699 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -33,13 +33,11 @@ void (*g_grpc_debug_timer_manager_stats)(int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, int64_t fork_count, - int64_t timer_wait_err, - int64_t timer_wait_cv) = nullptr; + int64_t timer_wait_err) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; int64_t g_timer_wait_err = 0; -int64_t g_timer_wait_cv = 0; #endif // GRPC_DEBUG_TIMER_MANAGER #ifdef GPR_LOW_LEVEL_COUNTERS @@ -110,10 +108,9 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { if (!(err == 0 || err == ETIMEDOUT || err == EAGAIN)) { if (g_grpc_debug_timer_manager_stats) { g_timer_wait_err = err; - g_timer_wait_cv = (int64_t)cv; - g_grpc_debug_timer_manager_stats( - g_timer_manager_init_count, g_timer_manager_shutdown_count, - g_fork_count, g_timer_wait_err, g_timer_wait_cv); + g_grpc_debug_timer_manager_stats(g_timer_manager_init_count, + g_timer_manager_shutdown_count, + g_fork_count, g_timer_wait_err); } GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); } diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index 3be1209228b..ba4d50ac426 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -68,7 +68,6 @@ extern int64_t g_timer_manager_init_count; extern int64_t g_timer_manager_shutdown_count; extern int64_t g_fork_count; extern int64_t g_timer_wait_err; -extern int64_t g_timer_wait_cv; #endif // GRPC_DEBUG_TIMER_MANAGER static void gc_completed_threads(void) { @@ -334,9 +333,9 @@ static void stop_threads(void) { } void grpc_timer_manager_shutdown(void) { -// For debug of the timer manager crash only. -// TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. g_timer_manager_shutdown_count++; #endif stop_threads(); @@ -347,9 +346,9 @@ void grpc_timer_manager_shutdown(void) { } void grpc_timer_manager_set_threading(bool threaded) { -// For debug of the timer manager crash only. -// TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. g_fork_count++; #endif if (threaded) { From 1097ae5e50c7ea8d8d459fcc25b1aad82f11546c Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 27 Sep 2018 15:32:07 -0700 Subject: [PATCH 477/546] Add TODO in fd_global_shutdown() --- src/core/lib/iomgr/ev_epoll1_linux.cc | 4 ++++ src/core/lib/iomgr/ev_epollex_linux.cc | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index aa5016bd8fd..6ef889b0feb 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -273,6 +273,10 @@ static gpr_mu fork_fd_list_mu; static void fd_global_init(void) { gpr_mu_init(&fd_freelist_mu); } static void fd_global_shutdown(void) { + // TODO(guantaol): We don't have a reasonable explanation about this + // lock()/unlock() pattern. It can be a valid barrier if there is at most one + // pending lock() at this point. Otherwise, there is still a possibility of + // use-after-free race. Need to reason about the code and/or clean it up. gpr_mu_lock(&fd_freelist_mu); gpr_mu_unlock(&fd_freelist_mu); while (fd_freelist != nullptr) { diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index b082634af11..06a382c5560 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -403,6 +403,10 @@ static void unref_by(grpc_fd* fd, int n) { static void fd_global_init(void) { gpr_mu_init(&fd_freelist_mu); } static void fd_global_shutdown(void) { + // TODO(guantaol): We don't have a reasonable explanation about this + // lock()/unlock() pattern. It can be a valid barrier if there is at most one + // pending lock() at this point. Otherwise, there is still a possibility of + // use-after-free race. Need to reason about the code and/or clean it up. gpr_mu_lock(&fd_freelist_mu); gpr_mu_unlock(&fd_freelist_mu); while (fd_freelist != nullptr) { From ec09960e21722571f0638465c29b434b1bd38199 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 27 Sep 2018 15:33:34 -0700 Subject: [PATCH 478/546] Log init counter after the cv is initialized --- src/core/lib/iomgr/timer_manager.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index ba4d50ac426..eaba05a5ceb 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -291,13 +291,13 @@ static void start_threads(void) { } void grpc_timer_manager_init(void) { + gpr_mu_init(&g_mu); + gpr_cv_init(&g_cv_wait); #ifdef GRPC_DEBUG_TIMER_MANAGER // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. g_timer_manager_init_count++; #endif - gpr_mu_init(&g_mu); - gpr_cv_init(&g_cv_wait); gpr_cv_init(&g_cv_shutdown); g_threaded = false; g_thread_count = 0; From b741edf37e2a50aa044b6b044f4f76d960dbf19a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 27 Sep 2018 17:34:19 -0700 Subject: [PATCH 479/546] Error fixes --- include/grpcpp/impl/codegen/client_interceptor.h | 4 ++-- include/grpcpp/impl/codegen/interceptor.h | 2 +- src/cpp/client/channel_cc.cc | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h index 23111b2c4ba..f460c5ac0c0 100644 --- a/include/grpcpp/impl/codegen/client_interceptor.h +++ b/include/grpcpp/impl/codegen/client_interceptor.h @@ -20,7 +20,6 @@ #define GRPCPP_IMPL_CODEGEN_CLIENT_INTERCEPTOR_H #include -#include namespace grpc { namespace experimental { @@ -41,4 +40,5 @@ class ClientInterceptorFactoryInterface { } // namespace experimental } // namespace grpc -#endif /* GRPCPP_IMPL_CODEGEN_CLIENT_INTERCEPTOR_H */ + +#endif // GRPCPP_IMPL_CODEGEN_CLIENT_INTERCEPTOR_H diff --git a/include/grpcpp/impl/codegen/interceptor.h b/include/grpcpp/impl/codegen/interceptor.h index 930183e9810..6402a3a9466 100644 --- a/include/grpcpp/impl/codegen/interceptor.h +++ b/include/grpcpp/impl/codegen/interceptor.h @@ -64,4 +64,4 @@ class InterceptorBatchMethods { } // namespace experimental } // namespace grpc -#endif /* GRPCPP_IMPL_CODEGEN_INTERCEPTOR_H */ +#endif // GRPCPP_IMPL_CODEGEN_INTERCEPTOR_H diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 00430d07db2..7c7ecc8cb76 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -57,7 +57,9 @@ Channel::Channel( interceptor_creators) : host_(host), c_channel_(channel) { auto vector = interceptor_creators.release(); - interceptor_creators_ = std::move(*vector); + if (vector != nullptr) { + interceptor_creators_ = std::move(*vector); + } g_gli_initializer.summon(); } From 5525521456e8a5f18b829e90ba47319ff0feb5e2 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 27 Sep 2018 17:45:37 -0700 Subject: [PATCH 480/546] Build changes --- BUILD | 2 ++ CMakeLists.txt | 5 +++++ Makefile | 5 +++++ build.yaml | 1 + gRPC-C++.podspec | 1 + tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/run_tests/generated/sources_and_headers.json | 2 ++ 8 files changed, 18 insertions(+) diff --git a/BUILD b/BUILD index 6348c4e6ff2..9739d6b3659 100644 --- a/BUILD +++ b/BUILD @@ -1984,6 +1984,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", @@ -1991,6 +1992,7 @@ grpc_cc_library( "include/grpcpp/impl/codegen/core_codegen_interface.h", "include/grpcpp/impl/codegen/create_auth_context.h", "include/grpcpp/impl/codegen/grpc_library.h", + "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/rpc_method.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 51788be1086..62862003581 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3015,6 +3015,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h include/grpcpp/impl/codegen/completion_queue_tag.h @@ -3587,6 +3588,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h include/grpcpp/impl/codegen/completion_queue_tag.h @@ -3999,6 +4001,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h include/grpcpp/impl/codegen/completion_queue_tag.h @@ -4179,6 +4182,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h include/grpcpp/impl/codegen/completion_queue_tag.h @@ -4500,6 +4504,7 @@ foreach(_hdr include/grpcpp/impl/codegen/channel_interface.h include/grpcpp/impl/codegen/client_callback.h include/grpcpp/impl/codegen/client_context.h + include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/completion_queue.h include/grpcpp/impl/codegen/completion_queue_tag.h diff --git a/Makefile b/Makefile index baaebd1803c..2e0a9d689c0 100644 --- a/Makefile +++ b/Makefile @@ -5433,6 +5433,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ @@ -6012,6 +6013,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ @@ -6404,6 +6406,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ @@ -6560,6 +6563,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ @@ -6885,6 +6889,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ + include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ diff --git a/build.yaml b/build.yaml index f3895bb7026..d3cdcd7098c 100644 --- a/build.yaml +++ b/build.yaml @@ -1173,6 +1173,7 @@ filegroups: - include/grpcpp/impl/codegen/channel_interface.h - include/grpcpp/impl/codegen/client_callback.h - include/grpcpp/impl/codegen/client_context.h + - include/grpcpp/impl/codegen/client_interceptor.h - include/grpcpp/impl/codegen/client_unary_call.h - include/grpcpp/impl/codegen/completion_queue.h - include/grpcpp/impl/codegen/completion_queue_tag.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 3ca132f7c38..ce89fedca21 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -132,6 +132,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/channel_interface.h', 'include/grpcpp/impl/codegen/client_callback.h', 'include/grpcpp/impl/codegen/client_context.h', + 'include/grpcpp/impl/codegen/client_interceptor.h', 'include/grpcpp/impl/codegen/client_unary_call.h', 'include/grpcpp/impl/codegen/completion_queue.h', 'include/grpcpp/impl/codegen/completion_queue_tag.h', diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 3b7fd1fa8e0..1fa827885fe 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -949,6 +949,7 @@ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ +include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c1bcdfd3d09..6bd83f03c34 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -950,6 +950,7 @@ include/grpcpp/impl/codegen/callback_common.h \ include/grpcpp/impl/codegen/channel_interface.h \ include/grpcpp/impl/codegen/client_callback.h \ include/grpcpp/impl/codegen/client_context.h \ +include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 29b72dca43f..7f064b39eee 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11087,6 +11087,7 @@ "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", @@ -11155,6 +11156,7 @@ "include/grpcpp/impl/codegen/channel_interface.h", "include/grpcpp/impl/codegen/client_callback.h", "include/grpcpp/impl/codegen/client_context.h", + "include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/completion_queue.h", "include/grpcpp/impl/codegen/completion_queue_tag.h", From e70d0d3ed41ee4fc3165c11de9237d64c8cacba1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 28 Sep 2018 09:56:47 +0200 Subject: [PATCH 481/546] remove no-longer-useful properties from build.yaml --- build.yaml | 48 --------------------------------------------- templates/README.md | 12 ------------ 2 files changed, 60 deletions(-) diff --git a/build.yaml b/build.yaml index f3895bb7026..7f63cf1da08 100644 --- a/build.yaml +++ b/build.yaml @@ -1437,7 +1437,6 @@ libs: filegroups: - gpr_base secure: false - vs_project_guid: '{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}' - name: gpr_test_util build: private language: c @@ -1448,7 +1447,6 @@ libs: deps: - gpr secure: false - vs_project_guid: '{EAB0A629-17A9-44DB-B5FF-E91A721FE037}' - name: grpc build: all language: c @@ -1481,10 +1479,6 @@ libs: - grpc_server_backward_compatibility generate_plugin_registry: true secure: true - vs_packages: - - grpc.dependencies.openssl - - grpc.dependencies.zlib - vs_project_guid: '{29D16885-7228-4C31-81ED-5F9187C7F2A9}' - name: grpc_cronet build: all language: c @@ -1511,17 +1505,6 @@ libs: build_system: - visual_studio deps_linkage: static - dll_def: grpc.def - vs_config_type: DynamicLibrary - vs_packages: - - grpc.dependencies.openssl - - grpc.dependencies.zlib - vs_project_guid: '{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}' - vs_props: - - zlib - - openssl - - winsock - - global - name: grpc_test_util build: private language: c @@ -1540,7 +1523,6 @@ libs: - grpc filegroups: - grpc_test_util_base - vs_project_guid: '{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}' - name: grpc_test_util_unsecure build: private language: c @@ -1551,7 +1533,6 @@ libs: filegroups: - grpc_test_util_base secure: false - vs_project_guid: '{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}' - name: grpc_unsecure build: all language: c @@ -1582,7 +1563,6 @@ libs: - grpc_server_backward_compatibility generate_plugin_registry: true secure: false - vs_project_guid: '{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}' - name: reconnect_server build: private language: c @@ -1636,7 +1616,6 @@ libs: - grpc++_codegen_proto - grpc++_codegen_base_src secure: check - vs_project_guid: '{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}' - name: grpc++_core_stats build: private language: c++ @@ -1682,7 +1661,6 @@ libs: deps: - grpc++ baselib: true - vs_project_guid: '{9F58AD72-49E1-4D10-B826-9E190AB0AAC0}' - name: grpc++_proto_reflection_desc_db build: private language: c++ @@ -1795,7 +1773,6 @@ libs: - grpc++_codegen_base - grpc++_codegen_base_src secure: false - vs_project_guid: '{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}' - name: grpc_benchmark build: test language: c++ @@ -1870,9 +1847,6 @@ libs: filegroups: - grpc++_config_proto secure: false - vs_project_guid: '{B6E81D84-2ACB-41B8-8781-493A944C7817}' - vs_props: - - protoc - name: grpcpp_channelz build: all language: c++ @@ -2027,16 +2001,6 @@ libs: LDFLAGS: $(if $(subst Linux,,$(SYSTEM)),,-Wl$(comma)-wrap$(comma)memcpy) deps_linkage: static dll: only - vs_config_type: DynamicLibrary - vs_packages: - - grpc.dependencies.openssl - - grpc.dependencies.zlib - vs_project_guid: '{D64C6D63-4458-4A88-AB38-35678384A7E4}' - vs_props: - - zlib - - openssl - - winsock - - global targets: - name: algorithm_test build: test @@ -4732,8 +4696,6 @@ targets: deps: - grpc_plugin_support secure: false - vs_config_type: Application - vs_project_guid: '{7E51A25F-AC59-488F-906C-C60FAAE706AA}' - name: grpc_csharp_plugin build: protoc language: c++ @@ -4742,8 +4704,6 @@ targets: deps: - grpc_plugin_support secure: false - vs_config_type: Application - vs_project_guid: '{3C813052-A49A-4662-B90A-1ADBEC7EE453}' - name: grpc_linux_system_roots_test gtest: true build: test @@ -4763,7 +4723,6 @@ targets: deps: - grpc_plugin_support secure: false - vs_config_type: Application - name: grpc_objective_c_plugin build: protoc language: c++ @@ -4772,8 +4731,6 @@ targets: deps: - grpc_plugin_support secure: false - vs_config_type: Application - vs_project_guid: '{19564640-CEE6-4921-ABA5-676ED79A36F6}' - name: grpc_php_plugin build: protoc language: c++ @@ -4782,7 +4739,6 @@ targets: deps: - grpc_plugin_support secure: false - vs_config_type: Application - name: grpc_python_plugin build: protoc language: c++ @@ -4791,8 +4747,6 @@ targets: deps: - grpc_plugin_support secure: false - vs_config_type: Application - vs_project_guid: '{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}' - name: grpc_ruby_plugin build: protoc language: c++ @@ -4801,8 +4755,6 @@ targets: deps: - grpc_plugin_support secure: false - vs_config_type: Application - vs_project_guid: '{069E9D05-B78B-4751-9252-D21EBAE7DE8E}' - name: grpc_tool_test gtest: true build: test diff --git a/templates/README.md b/templates/README.md index c837b5b260c..bf6aab80df9 100644 --- a/templates/README.md +++ b/templates/README.md @@ -87,7 +87,6 @@ src: # list of files to compile secure: boolean, # see below baselib: boolean, # this is a low level library that has system # dependencies -vs_project_guid: '{...}', # Visual Studio's unique guid for that project filegroups: # list of filegroups to merge to that project # note that this will be expanded automatically deps: # list of libraries this target depends on @@ -95,12 +94,6 @@ deps_linkage: "..." # "static" or "dynamic". Used by the Makefile only to # determine the way dependencies are linkned. Defaults # to "dynamic". dll: "..." # see below. -dll_def: "..." # Visual Studio's dll definition file. -vs_props: # List of property sheets to attach to that project. -vs_config_type: "..." # DynamicLibrary/StaticLibrary. Used only when - # creating a library. Specifies if we're building a - # static library or a dll. Use in conjunction with `dll_def`. -vs_packages: # List of nuget packages this project depends on. ``` ## The `"build"` tag @@ -141,11 +134,6 @@ Used only by Visual Studio's project files. "true" means the project will be built with both static and dynamic runtimes. "false" means it'll only be built with static runtime. "only" means it'll only be built with the dll runtime. -## The `"dll_def"` tag - -Specifies the visual studio's dll definition file. When creating a DLL, you -sometimes (not always) need a def file (see grpc.def). - # The template system From c542aa0c50f7c784b609ba20273f430498d2ebe9 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 28 Sep 2018 09:57:25 +0200 Subject: [PATCH 482/546] remove more --- build.yaml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/build.yaml b/build.yaml index 7f63cf1da08..e9290927f20 100644 --- a/build.yaml +++ b/build.yaml @@ -1495,16 +1495,6 @@ libs: platforms: - linux secure: true -- name: grpc_dll - build: private - language: c - src: [] - deps: - - gpr - - grpc - build_system: - - visual_studio - deps_linkage: static - name: grpc_test_util build: private language: c From d9f1aea9e3ca4d5fdc01d79cc1d8b276d72e0600 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 28 Sep 2018 10:12:37 +0200 Subject: [PATCH 483/546] regenerate projects --- grpc.gyp | 10 ---------- tools/run_tests/generated/sources_and_headers.json | 13 ------------- 2 files changed, 23 deletions(-) diff --git a/grpc.gyp b/grpc.gyp index 1ef44eb4ad2..fb1f7a8530a 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -592,16 +592,6 @@ 'src/core/plugin_registry/grpc_plugin_registry.cc', ], }, - { - 'target_name': 'grpc_dll', - 'type': 'static_library', - 'dependencies': [ - 'gpr', - 'grpc', - ], - 'sources': [ - ], - }, { 'target_name': 'grpc_test_util', 'type': 'static_library', diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 29b72dca43f..faffe7ec777 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -7089,19 +7089,6 @@ "third_party": false, "type": "lib" }, - { - "deps": [ - "gpr", - "grpc" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "grpc_dll", - "src": [], - "third_party": false, - "type": "lib" - }, { "deps": [ "gpr", From 0442a99fc0073d42954e4bf8e47ef516290cacb4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 28 Sep 2018 10:25:41 +0200 Subject: [PATCH 484/546] updates to templates/README.md --- templates/README.md | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/templates/README.md b/templates/README.md index bf6aab80df9..a7aeec26c7c 100644 --- a/templates/README.md +++ b/templates/README.md @@ -1,9 +1,13 @@ # Regenerating project files -Prerequisites: `python`, `pip install mako`, `go` +Prerequisites +- `python` +- `pip install mako` (the template processor) +- `pip install pyyaml` (to read the yaml files) +- `go` (required by boringssl dependency) ``` -# Regenerate the projects files using templates +# Regenerate the projects files (and other generated files) using templates tools/buildgen/generate_projects.sh ``` @@ -19,25 +23,13 @@ So instead we decided to work the following way: targets and files needed to build grpc and its tests, as well as a basic system for dependency description. -* Each project file (Makefile, Visual Studio project files, Bazel's BUILD) is -a [YAML](http://yaml.org) file used by the `build.yaml` file to generate the -final output file. +* Most of the build systems supported by gRPC (e.g. Makefile, cmake, XCode) have a template defined in this directory. The templates use the information from the `build.yaml` file to generate the project files specific to a given build system. This way we can maintain as many project system as we see fit, without having to manually maintain them when we add or remove new code to the repository. Only the structure of the project file is relevant to the template. The actual list of source code and targets isn't. -We currently have template files for GNU Make, Visual Studio 2013, -[Bazel](http://bazel.io) and [gyp](https://gyp.gsrc.io/) (albeit only for -Node.js). In the future, we -would like to expand to also generate [cmake](https://cmake.org) -project files, XCode project files, and an Android.mk file allowing to compile -gRPC using Android's NDK. - -We'll gladly accept contribution that'd create additional project files -using that system. - # Structure of `build.yaml` The `build.yaml` file has the following structure: @@ -130,7 +122,7 @@ protobuf is for `"c++"` ones. ## The `"dll"` tag -Used only by Visual Studio's project files. "true" means the project will be +Currently only used by cmake. "true" means the project will be built with both static and dynamic runtimes. "false" means it'll only be built with static runtime. "only" means it'll only be built with the dll runtime. @@ -140,8 +132,7 @@ with static runtime. "only" means it'll only be built with the dll runtime. We're currently using the [mako templates](http://www.makotemplates.org/) renderer. That choice enables us to simply render text files without dragging with us a lot of other features. Feel free to explore the current templates -in that directory. The simplest one is probably [BUILD.template](BUILD.template) -which is used to create the [Bazel](http://bazel.io/) project file. +in that directory. ## The renderer engine From ea5aa4a34af3f605d641d805889f005133512cec Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 28 Sep 2018 11:39:32 +0200 Subject: [PATCH 485/546] addressing a few nits --- src/csharp/Grpc.Core.Tests/MetadataTest.cs | 17 +++++++++++++++++ src/csharp/Grpc.Core/Internal/MarshalUtils.cs | 4 ++++ src/csharp/Grpc.Core/Metadata.cs | 3 +++ 3 files changed, 24 insertions(+) diff --git a/src/csharp/Grpc.Core.Tests/MetadataTest.cs b/src/csharp/Grpc.Core.Tests/MetadataTest.cs index 171c5c470e5..d85d7572a63 100644 --- a/src/csharp/Grpc.Core.Tests/MetadataTest.cs +++ b/src/csharp/Grpc.Core.Tests/MetadataTest.cs @@ -72,6 +72,23 @@ namespace Grpc.Core.Tests Assert.Throws(typeof(ArgumentException), () => new Metadata.Entry("abc/", "xyz")); } + [Test] + public void KeysAreNormalized_UppercaseKey() + { + var uppercaseKey = "ABC"; + var entry = new Metadata.Entry(uppercaseKey, "XYZ"); + Assert.AreEqual("abc", entry.Key); + } + + [Test] + public void KeysAreNormalized_LowercaseKey() + { + var lowercaseKey = "abc"; + var entry = new Metadata.Entry(lowercaseKey, "XYZ"); + // no allocation if key already lowercase + Assert.AreSame(lowercaseKey, entry.Key); + } + [Test] public void Entry_ConstructionPreconditions() { diff --git a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs index 73b7a2ef95f..09ded1a0363 100644 --- a/src/csharp/Grpc.Core/Internal/MarshalUtils.cs +++ b/src/csharp/Grpc.Core/Internal/MarshalUtils.cs @@ -36,8 +36,12 @@ namespace Grpc.Core.Internal public static string PtrToStringUTF8(IntPtr ptr, int len) { if (len == 0) + { return ""; + } + // TODO(jtattermusch): once Span dependency is added, + // use Span-based API to decode the string without copying the buffer. var bytes = new byte[len]; Marshal.Copy(ptr, bytes, 0, len); return EncodingUTF8.GetString(bytes); diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs index 122c1e88830..a9aa2cbbfc8 100644 --- a/src/csharp/Grpc.Core/Metadata.cs +++ b/src/csharp/Grpc.Core/Metadata.cs @@ -361,7 +361,10 @@ namespace Grpc.Core GrpcPreconditions.CheckArgument(IsValidKey(key, out bool isLowercase), "Metadata entry key not valid. Keys can only contain lowercase alphanumeric characters, underscores, hyphens and dots."); if (isLowercase) + { + // save allocation of a new string if already lowercase return key; + } return key.ToLowerInvariant(); } From 98bce85cacc8a17a6f6b0d96df3ae2c1d07f5b13 Mon Sep 17 00:00:00 2001 From: Alex Villarreal Date: Fri, 27 Apr 2018 19:34:25 -0500 Subject: [PATCH 486/546] Improve documentation to use Metadata.Entry Add notes about the parameters in public constructors of `Metadata.Entry`, and `Metadata`s `Add` methods (which call the aforementioned constructors), to clearly indicate what a valid key should be, **and the fact that it is converted to lowercase**. Seems like an important enough side effect that it should be explicit in the documentation. --- src/csharp/Grpc.Core/Metadata.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs index a9aa2cbbfc8..b59aee7d803 100644 --- a/src/csharp/Grpc.Core/Metadata.cs +++ b/src/csharp/Grpc.Core/Metadata.cs @@ -137,6 +137,8 @@ namespace Grpc.Core ///

/// /// + /// Metadata key. Gets converted to lowercase. Must not use suffix indicating a binary valued metadata entry. Can only contain lowercase alphanumeric characters, underscores and hyphens. + /// Value string. Only ASCII characters are allowed. public void Add(string key, string value) { Add(new Entry(key, value)); @@ -145,6 +147,8 @@ namespace Grpc.Core /// /// /// + /// Metadata key. Gets converted to lowercase. Needs to have suffix indicating a binary valued metadata entry. Can only contain lowercase alphanumeric characters, underscores and hyphens. + /// Value bytes. public void Add(string key, byte[] valueBytes) { Add(new Entry(key, valueBytes)); @@ -239,7 +243,7 @@ namespace Grpc.Core /// /// Initializes a new instance of the struct with a binary value. /// - /// Metadata key, needs to have suffix indicating a binary valued metadata entry. + /// Metadata key. Gets converted to lowercase. Needs to have suffix indicating a binary valued metadata entry. Can only contain lowercase alphanumeric characters, underscores and hyphens. /// Value bytes. public Entry(string key, byte[] valueBytes) { @@ -255,7 +259,7 @@ namespace Grpc.Core /// /// Initializes a new instance of the struct holding an ASCII value. /// - /// Metadata key, must not use suffix indicating a binary valued metadata entry. + /// Metadata key. Gets converted to lowercase. Must not use suffix indicating a binary valued metadata entry. Can only contain lowercase alphanumeric characters, underscores and hyphens. /// Value string. Only ASCII characters are allowed. public Entry(string key, string value) { From bc75644385af5df2db437c370ed3931e0df66fb4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 28 Sep 2018 12:07:08 +0200 Subject: [PATCH 487/546] review comments --- src/csharp/Grpc.Core/Metadata.cs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs index b59aee7d803..bc263c34696 100644 --- a/src/csharp/Grpc.Core/Metadata.cs +++ b/src/csharp/Grpc.Core/Metadata.cs @@ -135,20 +135,16 @@ namespace Grpc.Core } /// - /// + /// Adds a new ASCII-valued metadata entry. See Metadata.Entry constructor for params. /// - /// Metadata key. Gets converted to lowercase. Must not use suffix indicating a binary valued metadata entry. Can only contain lowercase alphanumeric characters, underscores and hyphens. - /// Value string. Only ASCII characters are allowed. public void Add(string key, string value) { Add(new Entry(key, value)); } /// - /// + /// Adds a new binary-valued metadata entry. See Metadata.Entry constructor for params. /// - /// Metadata key. Gets converted to lowercase. Needs to have suffix indicating a binary valued metadata entry. Can only contain lowercase alphanumeric characters, underscores and hyphens. - /// Value bytes. public void Add(string key, byte[] valueBytes) { Add(new Entry(key, valueBytes)); @@ -243,7 +239,7 @@ namespace Grpc.Core /// /// Initializes a new instance of the struct with a binary value. /// - /// Metadata key. Gets converted to lowercase. Needs to have suffix indicating a binary valued metadata entry. Can only contain lowercase alphanumeric characters, underscores and hyphens. + /// Metadata key. Gets converted to lowercase. Needs to have suffix indicating a binary valued metadata entry. Can only contain lowercase alphanumeric characters, underscores, hyphens and dots. /// Value bytes. public Entry(string key, byte[] valueBytes) { @@ -257,9 +253,9 @@ namespace Grpc.Core } /// - /// Initializes a new instance of the struct holding an ASCII value. + /// Initializes a new instance of the struct with an ASCII value. /// - /// Metadata key. Gets converted to lowercase. Must not use suffix indicating a binary valued metadata entry. Can only contain lowercase alphanumeric characters, underscores and hyphens. + /// Metadata key. Gets converted to lowercase. Must not use suffix indicating a binary valued metadata entry. Can only contain lowercase alphanumeric characters, underscores, hyphens and dots. /// Value string. Only ASCII characters are allowed. public Entry(string key, string value) { From bcaf46ea1801f5d6b328bef69102643f8beb742d Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Fri, 28 Sep 2018 10:51:39 -0700 Subject: [PATCH 488/546] Log cv, mu pointers and deadline values --- src/core/lib/gpr/sync_posix.cc | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 87356e99699..b6eb0b68ce0 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -30,14 +30,19 @@ // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER -void (*g_grpc_debug_timer_manager_stats)(int64_t timer_manager_init_count, - int64_t timer_manager_shutdown_count, - int64_t fork_count, - int64_t timer_wait_err) = nullptr; +void (*g_grpc_debug_timer_manager_stats)( + int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, + int64_t fork_count, int64_t timer_wait_err, int64_t timer_cv_value, + int64_t timer_mu_value, int64_t abstime_sec_value, + int64_t abstime_nsec_value) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; int64_t g_timer_wait_err = 0; +int64_t g_timer_cv_value = 0; +int64_t g_timer_mu_value = 0; +int64_t g_abstime_sec_value = -1; +int64_t g_abstime_nsec_value = -1; #endif // GRPC_DEBUG_TIMER_MANAGER #ifdef GPR_LOW_LEVEL_COUNTERS @@ -100,17 +105,28 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { abs_deadline_ts.tv_sec = static_cast(abs_deadline.tv_sec); abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts); +#ifdef GRPC_DEBUG_TIMER_MANAGER + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. + if (GPR_UNLIKELY(!(err == 0 || err == ETIMEDOUT || err == EAGAIN))) { + g_abstime_sec_value = abs_deadline_ts.tv_sec; + g_abstime_nsec_value = abs_deadline_ts.tv_nsec; + } +#endif } #ifdef GRPC_DEBUG_TIMER_MANAGER // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. - if (!(err == 0 || err == ETIMEDOUT || err == EAGAIN)) { + if (GPR_UNLIKELY(!(err == 0 || err == ETIMEDOUT || err == EAGAIN))) { if (g_grpc_debug_timer_manager_stats) { g_timer_wait_err = err; - g_grpc_debug_timer_manager_stats(g_timer_manager_init_count, - g_timer_manager_shutdown_count, - g_fork_count, g_timer_wait_err); + g_timer_cv_value = (int64_t)cv; + g_timer_mu_value = (int64_t)mu; + g_grpc_debug_timer_manager_stats( + g_timer_manager_init_count, g_timer_manager_shutdown_count, + g_fork_count, g_timer_wait_err, g_timer_cv_value, g_timer_mu_value, + g_abstime_sec_value, g_abstime_nsec_value); } GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); } From 4772a743e829070d2098d2f06a35b326b7687b6f Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Fri, 28 Sep 2018 10:27:53 -0700 Subject: [PATCH 489/546] Delete hpack lookup table --- BUILD | 2 - CMakeLists.txt | 6 - Makefile | 6 - build.yaml | 2 - config.m4 | 1 - config.w32 | 1 - gRPC-C++.podspec | 1 - gRPC-Core.podspec | 3 - grpc.gemspec | 2 - grpc.gyp | 4 - package.xml | 2 - .../chttp2/transport/hpack_mapping.cc | 39 -- .../chttp2/transport/hpack_mapping.h | 38 -- .../transport/chttp2/transport/hpack_table.cc | 10 +- src/core/lib/transport/static_metadata.cc | 442 +++++++++--------- src/core/lib/transport/static_metadata.h | 378 +++++++-------- src/python/grpcio/grpc_core_dependencies.py | 1 - test/core/end2end/fuzzers/hpack.dictionary | 64 +-- tools/codegen/core/gen_static_metadata.py | 200 +++----- tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 3 - 21 files changed, 517 insertions(+), 690 deletions(-) delete mode 100644 src/core/ext/transport/chttp2/transport/hpack_mapping.cc delete mode 100644 src/core/ext/transport/chttp2/transport/hpack_mapping.h diff --git a/BUILD b/BUILD index 71980bdbf4a..271e57e36cf 100644 --- a/BUILD +++ b/BUILD @@ -1575,7 +1575,6 @@ grpc_cc_library( "src/core/ext/transport/chttp2/transport/frame_window_update.cc", "src/core/ext/transport/chttp2/transport/hpack_encoder.cc", "src/core/ext/transport/chttp2/transport/hpack_parser.cc", - "src/core/ext/transport/chttp2/transport/hpack_mapping.cc", "src/core/ext/transport/chttp2/transport/hpack_table.cc", "src/core/ext/transport/chttp2/transport/http2_settings.cc", "src/core/ext/transport/chttp2/transport/huffsyms.cc", @@ -1600,7 +1599,6 @@ grpc_cc_library( "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_mapping.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", diff --git a/CMakeLists.txt b/CMakeLists.txt index 9517883916d..c358e9bd43b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1105,7 +1105,6 @@ add_library(grpc src/core/ext/transport/chttp2/transport/frame_settings.cc src/core/ext/transport/chttp2/transport/frame_window_update.cc src/core/ext/transport/chttp2/transport/hpack_encoder.cc - src/core/ext/transport/chttp2/transport/hpack_mapping.cc src/core/ext/transport/chttp2/transport/hpack_parser.cc src/core/ext/transport/chttp2/transport/hpack_table.cc src/core/ext/transport/chttp2/transport/http2_settings.cc @@ -1517,7 +1516,6 @@ add_library(grpc_cronet src/core/ext/transport/chttp2/transport/frame_settings.cc src/core/ext/transport/chttp2/transport/frame_window_update.cc src/core/ext/transport/chttp2/transport/hpack_encoder.cc - src/core/ext/transport/chttp2/transport/hpack_mapping.cc src/core/ext/transport/chttp2/transport/hpack_parser.cc src/core/ext/transport/chttp2/transport/hpack_table.cc src/core/ext/transport/chttp2/transport/http2_settings.cc @@ -1931,7 +1929,6 @@ add_library(grpc_test_util src/core/ext/transport/chttp2/transport/frame_settings.cc src/core/ext/transport/chttp2/transport/frame_window_update.cc src/core/ext/transport/chttp2/transport/hpack_encoder.cc - src/core/ext/transport/chttp2/transport/hpack_mapping.cc src/core/ext/transport/chttp2/transport/hpack_parser.cc src/core/ext/transport/chttp2/transport/hpack_table.cc src/core/ext/transport/chttp2/transport/http2_settings.cc @@ -2242,7 +2239,6 @@ add_library(grpc_test_util_unsecure src/core/ext/transport/chttp2/transport/frame_settings.cc src/core/ext/transport/chttp2/transport/frame_window_update.cc src/core/ext/transport/chttp2/transport/hpack_encoder.cc - src/core/ext/transport/chttp2/transport/hpack_mapping.cc src/core/ext/transport/chttp2/transport/hpack_parser.cc src/core/ext/transport/chttp2/transport/hpack_table.cc src/core/ext/transport/chttp2/transport/http2_settings.cc @@ -2511,7 +2507,6 @@ add_library(grpc_unsecure src/core/ext/transport/chttp2/transport/frame_settings.cc src/core/ext/transport/chttp2/transport/frame_window_update.cc src/core/ext/transport/chttp2/transport/hpack_encoder.cc - src/core/ext/transport/chttp2/transport/hpack_mapping.cc src/core/ext/transport/chttp2/transport/hpack_parser.cc src/core/ext/transport/chttp2/transport/hpack_table.cc src/core/ext/transport/chttp2/transport/http2_settings.cc @@ -3183,7 +3178,6 @@ add_library(grpc++_cronet src/core/ext/transport/chttp2/transport/frame_settings.cc src/core/ext/transport/chttp2/transport/frame_window_update.cc src/core/ext/transport/chttp2/transport/hpack_encoder.cc - src/core/ext/transport/chttp2/transport/hpack_mapping.cc src/core/ext/transport/chttp2/transport/hpack_parser.cc src/core/ext/transport/chttp2/transport/hpack_table.cc src/core/ext/transport/chttp2/transport/http2_settings.cc diff --git a/Makefile b/Makefile index 9634fa807f8..2f2537228cf 100644 --- a/Makefile +++ b/Makefile @@ -3614,7 +3614,6 @@ LIBGRPC_SRC = \ src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ - src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ @@ -4025,7 +4024,6 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ - src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ @@ -4437,7 +4435,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ - src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ @@ -4739,7 +4736,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ - src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ @@ -4986,7 +4982,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ - src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ @@ -5646,7 +5641,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ - src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ diff --git a/build.yaml b/build.yaml index a39050336da..d6e67aa7ee3 100644 --- a/build.yaml +++ b/build.yaml @@ -936,7 +936,6 @@ filegroups: - 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_mapping.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 @@ -958,7 +957,6 @@ filegroups: - src/core/ext/transport/chttp2/transport/frame_settings.cc - src/core/ext/transport/chttp2/transport/frame_window_update.cc - src/core/ext/transport/chttp2/transport/hpack_encoder.cc - - src/core/ext/transport/chttp2/transport/hpack_mapping.cc - src/core/ext/transport/chttp2/transport/hpack_parser.cc - src/core/ext/transport/chttp2/transport/hpack_table.cc - src/core/ext/transport/chttp2/transport/http2_settings.cc diff --git a/config.m4 b/config.m4 index a6ce55e0a9d..af3624cdd1b 100644 --- a/config.m4 +++ b/config.m4 @@ -249,7 +249,6 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/transport/chttp2/transport/frame_settings.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ - src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ src/core/ext/transport/chttp2/transport/http2_settings.cc \ diff --git a/config.w32 b/config.w32 index 333986c50a5..ad91ee40bd7 100644 --- a/config.w32 +++ b/config.w32 @@ -224,7 +224,6 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\transport\\chttp2\\transport\\frame_settings.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\frame_window_update.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\hpack_encoder.cc " + - "src\\core\\ext\\transport\\chttp2\\transport\\hpack_mapping.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\hpack_parser.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\hpack_table.cc " + "src\\core\\ext\\transport\\chttp2\\transport\\http2_settings.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 0dcea02f1ee..03ec223279e 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -255,7 +255,6 @@ Pod::Spec.new do |s| '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_mapping.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', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 1efa71a19e0..5a82a4200a2 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -263,7 +263,6 @@ Pod::Spec.new do |s| '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_mapping.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', @@ -682,7 +681,6 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/frame_settings.cc', 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', - 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_table.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', @@ -868,7 +866,6 @@ Pod::Spec.new do |s| '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_mapping.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', diff --git a/grpc.gemspec b/grpc.gemspec index f5cbf796240..c8e58faec9e 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -195,7 +195,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/frame_settings.h ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_window_update.h ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder.h ) - s.files += %w( src/core/ext/transport/chttp2/transport/hpack_mapping.h ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser.h ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_table.h ) s.files += %w( src/core/ext/transport/chttp2/transport/http2_settings.h ) @@ -618,7 +617,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/frame_settings.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_window_update.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder.cc ) - s.files += %w( src/core/ext/transport/chttp2/transport/hpack_mapping.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/hpack_table.cc ) s.files += %w( src/core/ext/transport/chttp2/transport/http2_settings.cc ) diff --git a/grpc.gyp b/grpc.gyp index a3adc3f0b95..b8aae44de30 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -441,7 +441,6 @@ 'src/core/ext/transport/chttp2/transport/frame_settings.cc', 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', - 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_table.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', @@ -826,7 +825,6 @@ 'src/core/ext/transport/chttp2/transport/frame_settings.cc', 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', - 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_table.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', @@ -1062,7 +1060,6 @@ 'src/core/ext/transport/chttp2/transport/frame_settings.cc', 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', - 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_table.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', @@ -1255,7 +1252,6 @@ 'src/core/ext/transport/chttp2/transport/frame_settings.cc', 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', - 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_table.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', diff --git a/package.xml b/package.xml index 1e8ae8bb6a9..9c0e078e92c 100644 --- a/package.xml +++ b/package.xml @@ -200,7 +200,6 @@ - @@ -623,7 +622,6 @@ - diff --git a/src/core/ext/transport/chttp2/transport/hpack_mapping.cc b/src/core/ext/transport/chttp2/transport/hpack_mapping.cc deleted file mode 100644 index fd529f0fd4d..00000000000 --- a/src/core/ext/transport/chttp2/transport/hpack_mapping.cc +++ /dev/null @@ -1,39 +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. - */ - -/* - * WARNING: Auto-generated code. - * - * To make changes to this file, change - * tools/codegen/core/gen_static_metadata.py, and then re-run it. - * - * This file contains the mapping from the index of each metadata element in the - * grpc static metadata table to the index of that element in the hpack static - * metadata table. If the element is not contained in the static hpack table, - * then the returned index is 0. - */ - -#include - -#include "src/core/ext/transport/chttp2/transport/hpack_mapping.h" - -const uint8_t grpc_hpack_static_mdelem_indices[GRPC_STATIC_MDELEM_COUNT] = { - 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 13, 6, 7, 0, 1, 2, 0, 4, - 5, 9, 10, 11, 12, 14, 15, 0, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 0, 0, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; diff --git a/src/core/ext/transport/chttp2/transport/hpack_mapping.h b/src/core/ext/transport/chttp2/transport/hpack_mapping.h deleted file mode 100644 index ebcd65bd9fe..00000000000 --- a/src/core/ext/transport/chttp2/transport/hpack_mapping.h +++ /dev/null @@ -1,38 +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. - */ - -/* - * WARNING: Auto-generated code. - * - * To make changes to this file, change - * tools/codegen/core/gen_static_metadata.py, and then re-run it. - * - * This file contains the mapping from the index of each metadata element in the - * grpc static metadata table to the index of that element in the hpack static - * metadata table. If the element is not contained in the static hpack table, - * then the returned index is 0. - */ - -#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_MAPPING_H -#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_MAPPING_H - -#include - -#include "src/core/lib/transport/static_metadata.h" - -extern const uint8_t grpc_hpack_static_mdelem_indices[GRPC_STATIC_MDELEM_COUNT]; - -#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_MAPPING_H */ diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc index 117679ab751..fcfb01872bf 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_table.cc +++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc @@ -27,7 +27,6 @@ #include #include -#include "src/core/ext/transport/chttp2/transport/hpack_mapping.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/murmur_hash.h" #include "src/core/lib/transport/static_metadata.h" @@ -389,9 +388,10 @@ size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem, uint8_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md) { if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) { - return grpc_hpack_static_mdelem_indices[GRPC_MDELEM_DATA(md) - - grpc_static_mdelem_table]; - } else { - return 0; + uint8_t index = GRPC_MDELEM_DATA(md) - grpc_static_mdelem_table; + if (index < GRPC_CHTTP2_LAST_STATIC_ENTRY) { + return index + 1; // Hpack static metadata element indices start at 1 + } } + return 0; } diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index ed88aa3f289..cdcb9a11d23 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -64,46 +64,46 @@ static uint8_t g_bytes[] = { 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, + 114, 101, 97, 109, 47, 103, 122, 105, 112, 71, 69, 84, 80, 79, 83, + 84, 47, 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 104, 116, + 116, 112, 104, 116, 116, 112, 115, 50, 48, 48, 50, 48, 52, 50, 48, + 54, 51, 48, 52, 52, 48, 48, 52, 48, 52, 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, 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, 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, 103, 114, 112, 99, 80, 85, 84, 108, 98, 45, 99, 111, 115, + 116, 45, 98, 105, 110, 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, @@ -265,69 +265,69 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { {&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[38], {{g_bytes + 504, 3}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 507, 4}}}, + {&grpc_static_metadata_refcounts[40], {{g_bytes + 511, 1}}}, + {&grpc_static_metadata_refcounts[41], {{g_bytes + 512, 11}}}, + {&grpc_static_metadata_refcounts[42], {{g_bytes + 523, 4}}}, + {&grpc_static_metadata_refcounts[43], {{g_bytes + 527, 5}}}, + {&grpc_static_metadata_refcounts[44], {{g_bytes + 532, 3}}}, + {&grpc_static_metadata_refcounts[45], {{g_bytes + 535, 3}}}, + {&grpc_static_metadata_refcounts[46], {{g_bytes + 538, 3}}}, + {&grpc_static_metadata_refcounts[47], {{g_bytes + 541, 3}}}, + {&grpc_static_metadata_refcounts[48], {{g_bytes + 544, 3}}}, + {&grpc_static_metadata_refcounts[49], {{g_bytes + 547, 3}}}, + {&grpc_static_metadata_refcounts[50], {{g_bytes + 550, 3}}}, + {&grpc_static_metadata_refcounts[51], {{g_bytes + 553, 14}}}, + {&grpc_static_metadata_refcounts[52], {{g_bytes + 567, 13}}}, + {&grpc_static_metadata_refcounts[53], {{g_bytes + 580, 15}}}, + {&grpc_static_metadata_refcounts[54], {{g_bytes + 595, 13}}}, + {&grpc_static_metadata_refcounts[55], {{g_bytes + 608, 6}}}, + {&grpc_static_metadata_refcounts[56], {{g_bytes + 614, 27}}}, + {&grpc_static_metadata_refcounts[57], {{g_bytes + 641, 3}}}, + {&grpc_static_metadata_refcounts[58], {{g_bytes + 644, 5}}}, + {&grpc_static_metadata_refcounts[59], {{g_bytes + 649, 13}}}, + {&grpc_static_metadata_refcounts[60], {{g_bytes + 662, 13}}}, + {&grpc_static_metadata_refcounts[61], {{g_bytes + 675, 19}}}, + {&grpc_static_metadata_refcounts[62], {{g_bytes + 694, 16}}}, + {&grpc_static_metadata_refcounts[63], {{g_bytes + 710, 14}}}, + {&grpc_static_metadata_refcounts[64], {{g_bytes + 724, 16}}}, + {&grpc_static_metadata_refcounts[65], {{g_bytes + 740, 13}}}, + {&grpc_static_metadata_refcounts[66], {{g_bytes + 753, 6}}}, + {&grpc_static_metadata_refcounts[67], {{g_bytes + 759, 4}}}, + {&grpc_static_metadata_refcounts[68], {{g_bytes + 763, 4}}}, + {&grpc_static_metadata_refcounts[69], {{g_bytes + 767, 6}}}, + {&grpc_static_metadata_refcounts[70], {{g_bytes + 773, 7}}}, + {&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 4}}}, + {&grpc_static_metadata_refcounts[72], {{g_bytes + 784, 8}}}, + {&grpc_static_metadata_refcounts[73], {{g_bytes + 792, 17}}}, + {&grpc_static_metadata_refcounts[74], {{g_bytes + 809, 13}}}, + {&grpc_static_metadata_refcounts[75], {{g_bytes + 822, 8}}}, + {&grpc_static_metadata_refcounts[76], {{g_bytes + 830, 19}}}, + {&grpc_static_metadata_refcounts[77], {{g_bytes + 849, 13}}}, + {&grpc_static_metadata_refcounts[78], {{g_bytes + 862, 4}}}, + {&grpc_static_metadata_refcounts[79], {{g_bytes + 866, 8}}}, + {&grpc_static_metadata_refcounts[80], {{g_bytes + 874, 12}}}, + {&grpc_static_metadata_refcounts[81], {{g_bytes + 886, 18}}}, + {&grpc_static_metadata_refcounts[82], {{g_bytes + 904, 19}}}, + {&grpc_static_metadata_refcounts[83], {{g_bytes + 923, 5}}}, + {&grpc_static_metadata_refcounts[84], {{g_bytes + 928, 7}}}, + {&grpc_static_metadata_refcounts[85], {{g_bytes + 935, 7}}}, + {&grpc_static_metadata_refcounts[86], {{g_bytes + 942, 11}}}, + {&grpc_static_metadata_refcounts[87], {{g_bytes + 953, 6}}}, + {&grpc_static_metadata_refcounts[88], {{g_bytes + 959, 10}}}, + {&grpc_static_metadata_refcounts[89], {{g_bytes + 969, 25}}}, + {&grpc_static_metadata_refcounts[90], {{g_bytes + 994, 17}}}, + {&grpc_static_metadata_refcounts[91], {{g_bytes + 1011, 4}}}, + {&grpc_static_metadata_refcounts[92], {{g_bytes + 1015, 3}}}, + {&grpc_static_metadata_refcounts[93], {{g_bytes + 1018, 16}}}, + {&grpc_static_metadata_refcounts[94], {{g_bytes + 1034, 1}}}, + {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1043, 8}}}, + {&grpc_static_metadata_refcounts[97], {{g_bytes + 1051, 16}}}, + {&grpc_static_metadata_refcounts[98], {{g_bytes + 1067, 4}}}, + {&grpc_static_metadata_refcounts[99], {{g_bytes + 1071, 3}}}, + {&grpc_static_metadata_refcounts[100], {{g_bytes + 1074, 11}}}, {&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}}}, @@ -341,14 +341,15 @@ 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[] = { - 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}; + 15, 9, -8, 0, 2, -44, -78, 17, 0, 6, -8, 0, 0, 0, 6, + -5, -10, 0, 0, -2, -3, -4, 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, -63, 0, -46, -68, -69, -53, 0, 31, 30, + 29, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 18, + 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, + 2, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, -5, 0}; static uint32_t elems_phash(uint32_t i) { - i -= 50; + i -= 40; uint32_t x = i % 103; uint32_t y = i / 103; uint32_t h = x; @@ -360,28 +361,25 @@ static uint32_t elems_phash(uint32_t i) { } static const uint16_t elem_keys[] = { - 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}; + 254, 255, 256, 257, 258, 259, 260, 1085, 1086, 143, 144, 1709, + 462, 463, 1604, 40, 41, 761, 1716, 980, 981, 1611, 621, 1499, + 760, 2024, 2129, 2234, 5384, 5699, 5804, 6014, 6119, 6224, 1732, 6329, + 6434, 6539, 6644, 6749, 6854, 6959, 7064, 7169, 7274, 7379, 7484, 7589, + 5909, 5594, 7694, 7799, 7904, 8009, 8114, 8219, 8324, 8429, 8534, 8639, + 8744, 8849, 8954, 9059, 9164, 9269, 9374, 1145, 518, 9479, 204, 9584, + 9689, 1151, 1152, 1153, 1154, 1775, 9794, 1040, 1670, 10529, 0, 0, + 1782, 829, 0, 0, 0, 0, 344, 1567, 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, 0, 0, 0, 0, 0, + 0}; static const uint8_t elem_idxs[] = { - 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}; + 7, 8, 9, 10, 11, 12, 13, 77, 79, 1, 2, 71, 5, 6, 25, 3, + 4, 63, 84, 66, 65, 73, 67, 30, 62, 57, 37, 74, 14, 17, 18, 20, + 21, 22, 15, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 35, 36, 38, + 19, 16, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 76, 69, 56, 70, 58, 59, 78, 80, 81, 82, 83, 60, 64, + 72, 75, 255, 255, 85, 61, 255, 255, 255, 255, 0, 68}; grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) { if (a == -1 || b == -1) return GRPC_MDNULL; @@ -395,160 +393,160 @@ 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[38], {{g_bytes + 504, 1}}}}, - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}}, - {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, - {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, - {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 513, 8}}}}, - {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 521, 16}}}}, - {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 537, 4}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 541, 3}}}}, - {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 544, 3}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 547, 4}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 551, 5}}}}, - {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 556, 4}}}}, {{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 560, 3}}}}, + {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 3}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 563, 3}}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 507, 4}}}}, {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 566, 1}}}}, + {&grpc_static_metadata_refcounts[40], {{g_bytes + 511, 1}}}}, {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 567, 11}}}}, + {&grpc_static_metadata_refcounts[41], {{g_bytes + 512, 11}}}}, + {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, + {&grpc_static_metadata_refcounts[42], {{g_bytes + 523, 4}}}}, + {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, + {&grpc_static_metadata_refcounts[43], {{g_bytes + 527, 5}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 578, 3}}}}, + {&grpc_static_metadata_refcounts[44], {{g_bytes + 532, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[53], {{g_bytes + 581, 3}}}}, + {&grpc_static_metadata_refcounts[45], {{g_bytes + 535, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[54], {{g_bytes + 584, 3}}}}, + {&grpc_static_metadata_refcounts[46], {{g_bytes + 538, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[55], {{g_bytes + 587, 3}}}}, + {&grpc_static_metadata_refcounts[47], {{g_bytes + 541, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&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[48], {{g_bytes + 544, 3}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[49], {{g_bytes + 547, 3}}}}, + {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, + {&grpc_static_metadata_refcounts[50], {{g_bytes + 550, 3}}}}, + {{&grpc_static_metadata_refcounts[51], {{g_bytes + 553, 14}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[58], {{g_bytes + 607, 13}}}}, - {{&grpc_static_metadata_refcounts[59], {{g_bytes + 620, 15}}}, + {&grpc_static_metadata_refcounts[52], {{g_bytes + 567, 13}}}}, + {{&grpc_static_metadata_refcounts[53], {{g_bytes + 580, 15}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[60], {{g_bytes + 635, 13}}}, + {{&grpc_static_metadata_refcounts[54], {{g_bytes + 595, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[61], {{g_bytes + 648, 6}}}, + {{&grpc_static_metadata_refcounts[55], {{g_bytes + 608, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[62], {{g_bytes + 654, 27}}}, + {{&grpc_static_metadata_refcounts[56], {{g_bytes + 614, 27}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[63], {{g_bytes + 681, 3}}}, + {{&grpc_static_metadata_refcounts[57], {{g_bytes + 641, 3}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[64], {{g_bytes + 684, 5}}}, + {{&grpc_static_metadata_refcounts[58], {{g_bytes + 644, 5}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[65], {{g_bytes + 689, 13}}}, + {{&grpc_static_metadata_refcounts[59], {{g_bytes + 649, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[66], {{g_bytes + 702, 13}}}, + {{&grpc_static_metadata_refcounts[60], {{g_bytes + 662, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[67], {{g_bytes + 715, 19}}}, + {{&grpc_static_metadata_refcounts[61], {{g_bytes + 675, 19}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, - {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[68], {{g_bytes + 734, 16}}}, + {{&grpc_static_metadata_refcounts[62], {{g_bytes + 694, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[69], {{g_bytes + 750, 14}}}, + {{&grpc_static_metadata_refcounts[63], {{g_bytes + 710, 14}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[70], {{g_bytes + 764, 16}}}, + {{&grpc_static_metadata_refcounts[64], {{g_bytes + 724, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 13}}}, + {{&grpc_static_metadata_refcounts[65], {{g_bytes + 740, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[72], {{g_bytes + 793, 6}}}, + {{&grpc_static_metadata_refcounts[66], {{g_bytes + 753, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[73], {{g_bytes + 799, 4}}}, + {{&grpc_static_metadata_refcounts[67], {{g_bytes + 759, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[74], {{g_bytes + 803, 4}}}, + {{&grpc_static_metadata_refcounts[68], {{g_bytes + 763, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[75], {{g_bytes + 807, 6}}}, + {{&grpc_static_metadata_refcounts[69], {{g_bytes + 767, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[76], {{g_bytes + 813, 7}}}, + {{&grpc_static_metadata_refcounts[70], {{g_bytes + 773, 7}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[77], {{g_bytes + 820, 4}}}, + {{&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[78], {{g_bytes + 824, 8}}}, + {{&grpc_static_metadata_refcounts[72], {{g_bytes + 784, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[79], {{g_bytes + 832, 17}}}, + {{&grpc_static_metadata_refcounts[73], {{g_bytes + 792, 17}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[80], {{g_bytes + 849, 13}}}, + {{&grpc_static_metadata_refcounts[74], {{g_bytes + 809, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[81], {{g_bytes + 862, 8}}}, + {{&grpc_static_metadata_refcounts[75], {{g_bytes + 822, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[82], {{g_bytes + 870, 19}}}, + {{&grpc_static_metadata_refcounts[76], {{g_bytes + 830, 19}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[83], {{g_bytes + 889, 13}}}, + {{&grpc_static_metadata_refcounts[77], {{g_bytes + 849, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}}, + {{&grpc_static_metadata_refcounts[78], {{g_bytes + 862, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[84], {{g_bytes + 902, 11}}}, + {{&grpc_static_metadata_refcounts[79], {{g_bytes + 866, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[85], {{g_bytes + 913, 4}}}, + {{&grpc_static_metadata_refcounts[80], {{g_bytes + 874, 12}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[86], {{g_bytes + 917, 8}}}, + {{&grpc_static_metadata_refcounts[81], {{g_bytes + 886, 18}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[87], {{g_bytes + 925, 12}}}, + {{&grpc_static_metadata_refcounts[82], {{g_bytes + 904, 19}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[88], {{g_bytes + 937, 18}}}, + {{&grpc_static_metadata_refcounts[83], {{g_bytes + 923, 5}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[89], {{g_bytes + 955, 19}}}, + {{&grpc_static_metadata_refcounts[84], {{g_bytes + 928, 7}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[90], {{g_bytes + 974, 5}}}, + {{&grpc_static_metadata_refcounts[85], {{g_bytes + 935, 7}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[91], {{g_bytes + 979, 7}}}, + {{&grpc_static_metadata_refcounts[86], {{g_bytes + 942, 11}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[92], {{g_bytes + 986, 7}}}, + {{&grpc_static_metadata_refcounts[87], {{g_bytes + 953, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[93], {{g_bytes + 993, 11}}}, + {{&grpc_static_metadata_refcounts[88], {{g_bytes + 959, 10}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1004, 6}}}, + {{&grpc_static_metadata_refcounts[89], {{g_bytes + 969, 25}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[95], {{g_bytes + 1010, 10}}}, + {{&grpc_static_metadata_refcounts[90], {{g_bytes + 994, 17}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[96], {{g_bytes + 1020, 25}}}, + {{&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[97], {{g_bytes + 1045, 17}}}, + {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1011, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}}, + {{&grpc_static_metadata_refcounts[92], {{g_bytes + 1015, 3}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[98], {{g_bytes + 1062, 4}}}, + {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1018, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[99], {{g_bytes + 1066, 3}}}, + {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, + {&grpc_static_metadata_refcounts[94], {{g_bytes + 1034, 1}}}}, + {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, + {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}}, + {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, + {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}}, + {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, + {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}}, + {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, + {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, + {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1043, 8}}}}, + {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, + {&grpc_static_metadata_refcounts[97], {{g_bytes + 1051, 16}}}}, + {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, + {&grpc_static_metadata_refcounts[98], {{g_bytes + 1067, 4}}}}, + {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, + {&grpc_static_metadata_refcounts[99], {{g_bytes + 1071, 3}}}}, + {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, + {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, + {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, + {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}}, + {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[100], {{g_bytes + 1069, 16}}}, + {{&grpc_static_metadata_refcounts[100], {{g_bytes + 1074, 11}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, + {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, @@ -562,7 +560,7 @@ grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}}, + {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 1e95f4e5bb7..5e57ea57412 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -113,132 +113,132 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; #define GRPC_MDSTR_GZIP (grpc_static_slice_table[36]) /* "stream/gzip" */ #define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[37]) -/* "0" */ -#define GRPC_MDSTR_0 (grpc_static_slice_table[38]) -/* "identity" */ -#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[39]) -/* "trailers" */ -#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[40]) -/* "application/grpc" */ -#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[41]) -/* "POST" */ -#define GRPC_MDSTR_POST (grpc_static_slice_table[42]) -/* "200" */ -#define GRPC_MDSTR_200 (grpc_static_slice_table[43]) -/* "404" */ -#define GRPC_MDSTR_404 (grpc_static_slice_table[44]) -/* "http" */ -#define GRPC_MDSTR_HTTP (grpc_static_slice_table[45]) -/* "https" */ -#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[46]) -/* "grpc" */ -#define GRPC_MDSTR_GRPC (grpc_static_slice_table[47]) /* "GET" */ -#define GRPC_MDSTR_GET (grpc_static_slice_table[48]) -/* "PUT" */ -#define GRPC_MDSTR_PUT (grpc_static_slice_table[49]) +#define GRPC_MDSTR_GET (grpc_static_slice_table[38]) +/* "POST" */ +#define GRPC_MDSTR_POST (grpc_static_slice_table[39]) /* "/" */ -#define GRPC_MDSTR_SLASH (grpc_static_slice_table[50]) +#define GRPC_MDSTR_SLASH (grpc_static_slice_table[40]) /* "/index.html" */ -#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[51]) +#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[41]) +/* "http" */ +#define GRPC_MDSTR_HTTP (grpc_static_slice_table[42]) +/* "https" */ +#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[43]) +/* "200" */ +#define GRPC_MDSTR_200 (grpc_static_slice_table[44]) /* "204" */ -#define GRPC_MDSTR_204 (grpc_static_slice_table[52]) +#define GRPC_MDSTR_204 (grpc_static_slice_table[45]) /* "206" */ -#define GRPC_MDSTR_206 (grpc_static_slice_table[53]) +#define GRPC_MDSTR_206 (grpc_static_slice_table[46]) /* "304" */ -#define GRPC_MDSTR_304 (grpc_static_slice_table[54]) +#define GRPC_MDSTR_304 (grpc_static_slice_table[47]) /* "400" */ -#define GRPC_MDSTR_400 (grpc_static_slice_table[55]) +#define GRPC_MDSTR_400 (grpc_static_slice_table[48]) +/* "404" */ +#define GRPC_MDSTR_404 (grpc_static_slice_table[49]) /* "500" */ -#define GRPC_MDSTR_500 (grpc_static_slice_table[56]) +#define GRPC_MDSTR_500 (grpc_static_slice_table[50]) /* "accept-charset" */ -#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[57]) +#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[51]) /* "gzip, deflate" */ -#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[58]) +#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[52]) /* "accept-language" */ -#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[59]) +#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[53]) /* "accept-ranges" */ -#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[60]) +#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[54]) /* "accept" */ -#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[61]) +#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[55]) /* "access-control-allow-origin" */ -#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[62]) +#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[56]) /* "age" */ -#define GRPC_MDSTR_AGE (grpc_static_slice_table[63]) +#define GRPC_MDSTR_AGE (grpc_static_slice_table[57]) /* "allow" */ -#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[64]) +#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[58]) /* "authorization" */ -#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[65]) +#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[59]) /* "cache-control" */ -#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[66]) +#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[60]) /* "content-disposition" */ -#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[67]) +#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[61]) /* "content-language" */ -#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[68]) +#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[62]) /* "content-length" */ -#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[69]) +#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[63]) /* "content-location" */ -#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[70]) +#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[64]) /* "content-range" */ -#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[71]) +#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[65]) /* "cookie" */ -#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[72]) +#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[66]) /* "date" */ -#define GRPC_MDSTR_DATE (grpc_static_slice_table[73]) +#define GRPC_MDSTR_DATE (grpc_static_slice_table[67]) /* "etag" */ -#define GRPC_MDSTR_ETAG (grpc_static_slice_table[74]) +#define GRPC_MDSTR_ETAG (grpc_static_slice_table[68]) /* "expect" */ -#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[75]) +#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[69]) /* "expires" */ -#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[76]) +#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[70]) /* "from" */ -#define GRPC_MDSTR_FROM (grpc_static_slice_table[77]) +#define GRPC_MDSTR_FROM (grpc_static_slice_table[71]) /* "if-match" */ -#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[78]) +#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[72]) /* "if-modified-since" */ -#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[79]) +#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[73]) /* "if-none-match" */ -#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[80]) +#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[74]) /* "if-range" */ -#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[81]) +#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[75]) /* "if-unmodified-since" */ -#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[82]) +#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[76]) /* "last-modified" */ -#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[83]) -/* "lb-cost-bin" */ -#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[84]) +#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[77]) /* "link" */ -#define GRPC_MDSTR_LINK (grpc_static_slice_table[85]) +#define GRPC_MDSTR_LINK (grpc_static_slice_table[78]) /* "location" */ -#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[86]) +#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[79]) /* "max-forwards" */ -#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[87]) +#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[80]) /* "proxy-authenticate" */ -#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[88]) +#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[81]) /* "proxy-authorization" */ -#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[89]) +#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[82]) /* "range" */ -#define GRPC_MDSTR_RANGE (grpc_static_slice_table[90]) +#define GRPC_MDSTR_RANGE (grpc_static_slice_table[83]) /* "referer" */ -#define GRPC_MDSTR_REFERER (grpc_static_slice_table[91]) +#define GRPC_MDSTR_REFERER (grpc_static_slice_table[84]) /* "refresh" */ -#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[92]) +#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[85]) /* "retry-after" */ -#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[93]) +#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[86]) /* "server" */ -#define GRPC_MDSTR_SERVER (grpc_static_slice_table[94]) +#define GRPC_MDSTR_SERVER (grpc_static_slice_table[87]) /* "set-cookie" */ -#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[95]) +#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[88]) /* "strict-transport-security" */ -#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[96]) +#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[89]) /* "transfer-encoding" */ -#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[97]) +#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[90]) /* "vary" */ -#define GRPC_MDSTR_VARY (grpc_static_slice_table[98]) +#define GRPC_MDSTR_VARY (grpc_static_slice_table[91]) /* "via" */ -#define GRPC_MDSTR_VIA (grpc_static_slice_table[99]) +#define GRPC_MDSTR_VIA (grpc_static_slice_table[92]) /* "www-authenticate" */ -#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[100]) +#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[93]) +/* "0" */ +#define GRPC_MDSTR_0 (grpc_static_slice_table[94]) +/* "identity" */ +#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[95]) +/* "trailers" */ +#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[96]) +/* "application/grpc" */ +#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[97]) +/* "grpc" */ +#define GRPC_MDSTR_GRPC (grpc_static_slice_table[98]) +/* "PUT" */ +#define GRPC_MDSTR_PUT (grpc_static_slice_table[99]) +/* "lb-cost-bin" */ +#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[100]) /* "identity,deflate" */ #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[101]) /* "identity,gzip" */ @@ -262,233 +262,233 @@ extern grpc_slice_refcount #define GRPC_STATIC_MDELEM_COUNT 86 extern grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; -/* "grpc-status": "0" */ -#define GRPC_MDELEM_GRPC_STATUS_0 \ +/* ":authority": "" */ +#define GRPC_MDELEM_AUTHORITY_EMPTY \ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[0], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-status": "1" */ -#define GRPC_MDELEM_GRPC_STATUS_1 \ +/* ":method": "GET" */ +#define GRPC_MDELEM_METHOD_GET \ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[1], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-status": "2" */ -#define GRPC_MDELEM_GRPC_STATUS_2 \ +/* ":method": "POST" */ +#define GRPC_MDELEM_METHOD_POST \ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[2], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-encoding": "identity" */ -#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY \ +/* ":path": "/" */ +#define GRPC_MDELEM_PATH_SLASH \ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[3], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-encoding": "gzip" */ -#define GRPC_MDELEM_GRPC_ENCODING_GZIP \ +/* ":path": "/index.html" */ +#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML \ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[4], GRPC_MDELEM_STORAGE_STATIC)) -/* "grpc-encoding": "deflate" */ -#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC)) -/* "te": "trailers" */ -#define GRPC_MDELEM_TE_TRAILERS \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-type": "application/grpc" */ -#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC)) -/* ":method": "POST" */ -#define GRPC_MDELEM_METHOD_POST \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC)) -/* ":status": "200" */ -#define GRPC_MDELEM_STATUS_200 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC)) -/* ":status": "404" */ -#define GRPC_MDELEM_STATUS_404 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC)) /* ":scheme": "http" */ #define GRPC_MDELEM_SCHEME_HTTP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[5], GRPC_MDELEM_STORAGE_STATIC)) /* ":scheme": "https" */ #define GRPC_MDELEM_SCHEME_HTTPS \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC)) -/* ":scheme": "grpc" */ -#define GRPC_MDELEM_SCHEME_GRPC \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC)) -/* ":authority": "" */ -#define GRPC_MDELEM_AUTHORITY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC)) -/* ":method": "GET" */ -#define GRPC_MDELEM_METHOD_GET \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC)) -/* ":method": "PUT" */ -#define GRPC_MDELEM_METHOD_PUT \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC)) -/* ":path": "/" */ -#define GRPC_MDELEM_PATH_SLASH \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC)) -/* ":path": "/index.html" */ -#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[6], GRPC_MDELEM_STORAGE_STATIC)) +/* ":status": "200" */ +#define GRPC_MDELEM_STATUS_200 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[7], GRPC_MDELEM_STORAGE_STATIC)) /* ":status": "204" */ #define GRPC_MDELEM_STATUS_204 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[8], GRPC_MDELEM_STORAGE_STATIC)) /* ":status": "206" */ #define GRPC_MDELEM_STATUS_206 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[9], GRPC_MDELEM_STORAGE_STATIC)) /* ":status": "304" */ #define GRPC_MDELEM_STATUS_304 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[10], GRPC_MDELEM_STORAGE_STATIC)) /* ":status": "400" */ #define GRPC_MDELEM_STATUS_400 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[11], GRPC_MDELEM_STORAGE_STATIC)) +/* ":status": "404" */ +#define GRPC_MDELEM_STATUS_404 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[12], GRPC_MDELEM_STORAGE_STATIC)) /* ":status": "500" */ #define GRPC_MDELEM_STATUS_500 \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[13], GRPC_MDELEM_STORAGE_STATIC)) /* "accept-charset": "" */ #define GRPC_MDELEM_ACCEPT_CHARSET_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC)) -/* "accept-encoding": "" */ -#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[14], GRPC_MDELEM_STORAGE_STATIC)) /* "accept-encoding": "gzip, deflate" */ #define GRPC_MDELEM_ACCEPT_ENCODING_GZIP_COMMA_DEFLATE \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[15], GRPC_MDELEM_STORAGE_STATIC)) /* "accept-language": "" */ #define GRPC_MDELEM_ACCEPT_LANGUAGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[16], GRPC_MDELEM_STORAGE_STATIC)) /* "accept-ranges": "" */ #define GRPC_MDELEM_ACCEPT_RANGES_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[17], GRPC_MDELEM_STORAGE_STATIC)) /* "accept": "" */ #define GRPC_MDELEM_ACCEPT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[18], GRPC_MDELEM_STORAGE_STATIC)) /* "access-control-allow-origin": "" */ #define GRPC_MDELEM_ACCESS_CONTROL_ALLOW_ORIGIN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[19], GRPC_MDELEM_STORAGE_STATIC)) /* "age": "" */ #define GRPC_MDELEM_AGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[20], GRPC_MDELEM_STORAGE_STATIC)) /* "allow": "" */ #define GRPC_MDELEM_ALLOW_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[21], GRPC_MDELEM_STORAGE_STATIC)) /* "authorization": "" */ #define GRPC_MDELEM_AUTHORIZATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[22], GRPC_MDELEM_STORAGE_STATIC)) /* "cache-control": "" */ #define GRPC_MDELEM_CACHE_CONTROL_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[23], GRPC_MDELEM_STORAGE_STATIC)) /* "content-disposition": "" */ #define GRPC_MDELEM_CONTENT_DISPOSITION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-encoding": "identity" */ -#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC)) -/* "content-encoding": "gzip" */ -#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[24], GRPC_MDELEM_STORAGE_STATIC)) /* "content-encoding": "" */ #define GRPC_MDELEM_CONTENT_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[25], GRPC_MDELEM_STORAGE_STATIC)) /* "content-language": "" */ #define GRPC_MDELEM_CONTENT_LANGUAGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[26], GRPC_MDELEM_STORAGE_STATIC)) /* "content-length": "" */ #define GRPC_MDELEM_CONTENT_LENGTH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[27], GRPC_MDELEM_STORAGE_STATIC)) /* "content-location": "" */ #define GRPC_MDELEM_CONTENT_LOCATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[28], GRPC_MDELEM_STORAGE_STATIC)) /* "content-range": "" */ #define GRPC_MDELEM_CONTENT_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[29], GRPC_MDELEM_STORAGE_STATIC)) /* "content-type": "" */ #define GRPC_MDELEM_CONTENT_TYPE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[30], GRPC_MDELEM_STORAGE_STATIC)) /* "cookie": "" */ #define GRPC_MDELEM_COOKIE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[31], GRPC_MDELEM_STORAGE_STATIC)) /* "date": "" */ #define GRPC_MDELEM_DATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[32], GRPC_MDELEM_STORAGE_STATIC)) /* "etag": "" */ #define GRPC_MDELEM_ETAG_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[33], GRPC_MDELEM_STORAGE_STATIC)) /* "expect": "" */ #define GRPC_MDELEM_EXPECT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[34], GRPC_MDELEM_STORAGE_STATIC)) /* "expires": "" */ #define GRPC_MDELEM_EXPIRES_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[35], GRPC_MDELEM_STORAGE_STATIC)) /* "from": "" */ #define GRPC_MDELEM_FROM_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[36], GRPC_MDELEM_STORAGE_STATIC)) /* "host": "" */ #define GRPC_MDELEM_HOST_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[37], GRPC_MDELEM_STORAGE_STATIC)) /* "if-match": "" */ #define GRPC_MDELEM_IF_MATCH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[38], GRPC_MDELEM_STORAGE_STATIC)) /* "if-modified-since": "" */ #define GRPC_MDELEM_IF_MODIFIED_SINCE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[39], GRPC_MDELEM_STORAGE_STATIC)) /* "if-none-match": "" */ #define GRPC_MDELEM_IF_NONE_MATCH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[40], GRPC_MDELEM_STORAGE_STATIC)) /* "if-range": "" */ #define GRPC_MDELEM_IF_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[41], GRPC_MDELEM_STORAGE_STATIC)) /* "if-unmodified-since": "" */ #define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[42], GRPC_MDELEM_STORAGE_STATIC)) /* "last-modified": "" */ #define GRPC_MDELEM_LAST_MODIFIED_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC)) -/* "lb-token": "" */ -#define GRPC_MDELEM_LB_TOKEN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC)) -/* "lb-cost-bin": "" */ -#define GRPC_MDELEM_LB_COST_BIN_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[43], GRPC_MDELEM_STORAGE_STATIC)) /* "link": "" */ #define GRPC_MDELEM_LINK_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[44], GRPC_MDELEM_STORAGE_STATIC)) /* "location": "" */ #define GRPC_MDELEM_LOCATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[45], GRPC_MDELEM_STORAGE_STATIC)) /* "max-forwards": "" */ #define GRPC_MDELEM_MAX_FORWARDS_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[46], GRPC_MDELEM_STORAGE_STATIC)) /* "proxy-authenticate": "" */ #define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[47], GRPC_MDELEM_STORAGE_STATIC)) /* "proxy-authorization": "" */ #define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[48], GRPC_MDELEM_STORAGE_STATIC)) /* "range": "" */ #define GRPC_MDELEM_RANGE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[49], GRPC_MDELEM_STORAGE_STATIC)) /* "referer": "" */ #define GRPC_MDELEM_REFERER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[50], GRPC_MDELEM_STORAGE_STATIC)) /* "refresh": "" */ #define GRPC_MDELEM_REFRESH_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[51], GRPC_MDELEM_STORAGE_STATIC)) /* "retry-after": "" */ #define GRPC_MDELEM_RETRY_AFTER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[52], GRPC_MDELEM_STORAGE_STATIC)) /* "server": "" */ #define GRPC_MDELEM_SERVER_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[53], GRPC_MDELEM_STORAGE_STATIC)) /* "set-cookie": "" */ #define GRPC_MDELEM_SET_COOKIE_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[54], GRPC_MDELEM_STORAGE_STATIC)) /* "strict-transport-security": "" */ #define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[55], GRPC_MDELEM_STORAGE_STATIC)) /* "transfer-encoding": "" */ #define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC)) /* "user-agent": "" */ #define GRPC_MDELEM_USER_AGENT_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC)) /* "vary": "" */ #define GRPC_MDELEM_VARY_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC)) /* "via": "" */ #define GRPC_MDELEM_VIA_EMPTY \ - (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC)) + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC)) /* "www-authenticate": "" */ #define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-status": "0" */ +#define GRPC_MDELEM_GRPC_STATUS_0 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-status": "1" */ +#define GRPC_MDELEM_GRPC_STATUS_1 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-status": "2" */ +#define GRPC_MDELEM_GRPC_STATUS_2 \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-encoding": "identity" */ +#define GRPC_MDELEM_GRPC_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-encoding": "gzip" */ +#define GRPC_MDELEM_GRPC_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC)) +/* "grpc-encoding": "deflate" */ +#define GRPC_MDELEM_GRPC_ENCODING_DEFLATE \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC)) +/* "te": "trailers" */ +#define GRPC_MDELEM_TE_TRAILERS \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-type": "application/grpc" */ +#define GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC)) +/* ":scheme": "grpc" */ +#define GRPC_MDELEM_SCHEME_GRPC \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC)) +/* ":method": "PUT" */ +#define GRPC_MDELEM_METHOD_PUT \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC)) +/* "accept-encoding": "" */ +#define GRPC_MDELEM_ACCEPT_ENCODING_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-encoding": "identity" */ +#define GRPC_MDELEM_CONTENT_ENCODING_IDENTITY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC)) +/* "content-encoding": "gzip" */ +#define GRPC_MDELEM_CONTENT_ENCODING_GZIP \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC)) +/* "lb-token": "" */ +#define GRPC_MDELEM_LB_TOKEN_EMPTY \ + (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC)) +/* "lb-cost-bin": "" */ +#define GRPC_MDELEM_LB_COST_BIN_EMPTY \ (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC)) /* "grpc-accept-encoding": "identity" */ #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index ceacc83e626..0f68e823d79 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -223,7 +223,6 @@ CORE_SOURCE_FILES = [ 'src/core/ext/transport/chttp2/transport/frame_settings.cc', 'src/core/ext/transport/chttp2/transport/frame_window_update.cc', 'src/core/ext/transport/chttp2/transport/hpack_encoder.cc', - 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc', 'src/core/ext/transport/chttp2/transport/hpack_parser.cc', 'src/core/ext/transport/chttp2/transport/hpack_table.cc', 'src/core/ext/transport/chttp2/transport/http2_settings.cc', diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary index c719d0fa84e..569e744a6b9 100644 --- a/test/core/end2end/fuzzers/hpack.dictionary +++ b/test/core/end2end/fuzzers/hpack.dictionary @@ -37,24 +37,18 @@ "\x07deflate" "\x04gzip" "\x0Bstream/gzip" -"\x010" -"\x08identity" -"\x08trailers" -"\x10application/grpc" -"\x04POST" -"\x03200" -"\x03404" -"\x04http" -"\x05https" -"\x04grpc" "\x03GET" -"\x03PUT" +"\x04POST" "\x01/" "\x0B/index.html" +"\x04http" +"\x05https" +"\x03200" "\x03204" "\x03206" "\x03304" "\x03400" +"\x03404" "\x03500" "\x0Eaccept-charset" "\x0Dgzip, deflate" @@ -83,7 +77,6 @@ "\x08if-range" "\x13if-unmodified-since" "\x0Dlast-modified" -"\x0Blb-cost-bin" "\x04link" "\x08location" "\x0Cmax-forwards" @@ -100,36 +93,32 @@ "\x04vary" "\x03via" "\x10www-authenticate" +"\x010" +"\x08identity" +"\x08trailers" +"\x10application/grpc" +"\x04grpc" +"\x03PUT" +"\x0Blb-cost-bin" "\x10identity,deflate" "\x0Didentity,gzip" "\x0Cdeflate,gzip" "\x15identity,deflate,gzip" -"\x00\x0Bgrpc-status\x010" -"\x00\x0Bgrpc-status\x011" -"\x00\x0Bgrpc-status\x012" -"\x00\x0Dgrpc-encoding\x08identity" -"\x00\x0Dgrpc-encoding\x04gzip" -"\x00\x0Dgrpc-encoding\x07deflate" -"\x00\x02te\x08trailers" -"\x00\x0Ccontent-type\x10application/grpc" -"\x00\x07:method\x04POST" -"\x00\x07:status\x03200" -"\x00\x07:status\x03404" -"\x00\x07:scheme\x04http" -"\x00\x07:scheme\x05https" -"\x00\x07:scheme\x04grpc" "\x00\x0A:authority\x00" "\x00\x07:method\x03GET" -"\x00\x07:method\x03PUT" +"\x00\x07:method\x04POST" "\x00\x05:path\x01/" "\x00\x05:path\x0B/index.html" +"\x00\x07:scheme\x04http" +"\x00\x07:scheme\x05https" +"\x00\x07:status\x03200" "\x00\x07:status\x03204" "\x00\x07:status\x03206" "\x00\x07:status\x03304" "\x00\x07:status\x03400" +"\x00\x07:status\x03404" "\x00\x07:status\x03500" "\x00\x0Eaccept-charset\x00" -"\x00\x0Faccept-encoding\x00" "\x00\x0Faccept-encoding\x0Dgzip, deflate" "\x00\x0Faccept-language\x00" "\x00\x0Daccept-ranges\x00" @@ -140,8 +129,6 @@ "\x00\x0Dauthorization\x00" "\x00\x0Dcache-control\x00" "\x00\x13content-disposition\x00" -"\x00\x10content-encoding\x08identity" -"\x00\x10content-encoding\x04gzip" "\x00\x10content-encoding\x00" "\x00\x10content-language\x00" "\x00\x0Econtent-length\x00" @@ -161,8 +148,6 @@ "\x00\x08if-range\x00" "\x00\x13if-unmodified-since\x00" "\x00\x0Dlast-modified\x00" -"\x00\x08lb-token\x00" -"\x00\x0Blb-cost-bin\x00" "\x00\x04link\x00" "\x00\x08location\x00" "\x00\x0Cmax-forwards\x00" @@ -180,6 +165,21 @@ "\x00\x04vary\x00" "\x00\x03via\x00" "\x00\x10www-authenticate\x00" +"\x00\x0Bgrpc-status\x010" +"\x00\x0Bgrpc-status\x011" +"\x00\x0Bgrpc-status\x012" +"\x00\x0Dgrpc-encoding\x08identity" +"\x00\x0Dgrpc-encoding\x04gzip" +"\x00\x0Dgrpc-encoding\x07deflate" +"\x00\x02te\x08trailers" +"\x00\x0Ccontent-type\x10application/grpc" +"\x00\x07:scheme\x04grpc" +"\x00\x07:method\x03PUT" +"\x00\x0Faccept-encoding\x00" +"\x00\x10content-encoding\x08identity" +"\x00\x10content-encoding\x04gzip" +"\x00\x08lb-token\x00" +"\x00\x0Blb-cost-bin\x00" "\x00\x14grpc-accept-encoding\x08identity" "\x00\x14grpc-accept-encoding\x07deflate" "\x00\x14grpc-accept-encoding\x10identity,deflate" diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index ab2e5a671a3..c7f80c12666 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -23,14 +23,14 @@ import subprocess import re import perfection -# Configuration: a list of either strings or 2-tuples of strings or 3-tuples of -# strings. +# Configuration: a list of either strings or 2-tuples of strings. # A single string represents a static grpc_mdstr. # A 2-tuple represents a static grpc_mdelem (and appropriate grpc_mdstrs will # also be created). -# A 3-tuple represents a static grpc_mdelem (and appropriate grpc_mdstrs will -# also be created), with the last value equivalent to the mdelem's static hpack -# table index as defined by RFC 7541 +# The list of 2-tuples must begin with the static hpack table elements as +# defined by RFC 7541 and be in the same order because of an hpack encoding +# performance optimization that relies on this. If you want to change this, then +# you must change the implementation of the encoding optimization as well. CONFIG = [ # metadata strings @@ -68,6 +68,67 @@ CONFIG = [ 'gzip', 'stream/gzip', # metadata elements + (':authority', ''), + (':method', 'GET'), + (':method', 'POST'), + (':path', '/'), + (':path', '/index.html'), + (':scheme', 'http'), + (':scheme', 'https'), + (':status', '200'), + (':status', '204'), + (':status', '206'), + (':status', '304'), + (':status', '400'), + (':status', '404'), + (':status', '500'), + ('accept-charset', ''), + ('accept-encoding', 'gzip, deflate'), + ('accept-language', ''), + ('accept-ranges', ''), + ('accept', ''), + ('access-control-allow-origin', ''), + ('age', ''), + ('allow', ''), + ('authorization', ''), + ('cache-control', ''), + ('content-disposition', ''), + ('content-encoding', ''), + ('content-language', ''), + ('content-length', ''), + ('content-location', ''), + ('content-range', ''), + ('content-type', ''), + ('cookie', ''), + ('date', ''), + ('etag', ''), + ('expect', ''), + ('expires', ''), + ('from', ''), + ('host', ''), + ('if-match', ''), + ('if-modified-since', ''), + ('if-none-match', ''), + ('if-range', ''), + ('if-unmodified-since', ''), + ('last-modified', ''), + ('link', ''), + ('location', ''), + ('max-forwards', ''), + ('proxy-authenticate', ''), + ('proxy-authorization', ''), + ('range', ''), + ('referer', ''), + ('refresh', ''), + ('retry-after', ''), + ('server', ''), + ('set-cookie', ''), + ('strict-transport-security', ''), + ('transfer-encoding', ''), + ('user-agent', ''), + ('vary', ''), + ('via', ''), + ('www-authenticate', ''), ('grpc-status', '0'), ('grpc-status', '1'), ('grpc-status', '2'), @@ -76,74 +137,13 @@ CONFIG = [ ('grpc-encoding', 'deflate'), ('te', 'trailers'), ('content-type', 'application/grpc'), - (':method', 'POST', 3), - (':status', '200', 8), - (':status', '404', 13), - (':scheme', 'http', 6), - (':scheme', 'https', 7), - (':scheme', 'grpc', 0), - (':authority', '', 1), - (':method', 'GET', 2), + (':scheme', 'grpc'), (':method', 'PUT'), - (':path', '/', 4), - (':path', '/index.html', 5), - (':status', '204', 9), - (':status', '206', 10), - (':status', '304', 11), - (':status', '400', 12), - (':status', '500', 14), - ('accept-charset', '', 15), ('accept-encoding', ''), - ('accept-encoding', 'gzip, deflate', 16), - ('accept-language', '', 17), - ('accept-ranges', '', 18), - ('accept', '', 19), - ('access-control-allow-origin', '', 20), - ('age', '', 21), - ('allow', '', 22), - ('authorization', '', 23), - ('cache-control', '', 24), - ('content-disposition', '', 25), ('content-encoding', 'identity'), ('content-encoding', 'gzip'), - ('content-encoding', '', 26), - ('content-language', '', 27), - ('content-length', '', 28), - ('content-location', '', 29), - ('content-range', '', 30), - ('content-type', '', 31), - ('cookie', '', 32), - ('date', '', 33), - ('etag', '', 34), - ('expect', '', 35), - ('expires', '', 36), - ('from', '', 37), - ('host', '', 38), - ('if-match', '', 39), - ('if-modified-since', '', 40), - ('if-none-match', '', 41), - ('if-range', '', 42), - ('if-unmodified-since', '', 43), - ('last-modified', '', 44), ('lb-token', ''), ('lb-cost-bin', ''), - ('link', '', 45), - ('location', '', 46), - ('max-forwards', '', 47), - ('proxy-authenticate', '', 48), - ('proxy-authorization', '', 49), - ('range', '', 50), - ('referer', '', 51), - ('refresh', '', 52), - ('retry-after', '', 53), - ('server', '', 54), - ('set-cookie', '', 55), - ('strict-transport-security', '', 56), - ('transfer-encoding', '', 57), - ('user-agent', '', 58), - ('vary', '', 59), - ('via', '', 60), - ('www-authenticate', '', 61), ] # All entries here are ignored when counting non-default initial metadata that @@ -326,17 +326,6 @@ else: os.path.dirname(sys.argv[0]), '../../../test/core/end2end/fuzzers/hpack.dictionary'), 'w') -HPACK_H = open( - os.path.join( - os.path.dirname(sys.argv[0]), - '../../../src/core/ext/transport/chttp2/transport/hpack_mapping.h'), - 'w') -HPACK_C = open( - os.path.join( - os.path.dirname(sys.argv[0]), - '../../../src/core/ext/transport/chttp2/transport/hpack_mapping.cc'), - 'w') - # copy-paste copyright notice from this file with open(sys.argv[0]) as my_source: copyright = [] @@ -351,8 +340,7 @@ with open(sys.argv[0]) as my_source: if line[0] != '#': break copyright.append(line) - put_banner([H, C, HPACK_H, HPACK_C], - [line[2:].rstrip() for line in copyright]) + put_banner([H, C], [line[2:].rstrip() for line in copyright]) hex_bytes = [ord(c) for c in 'abcdefABCDEF0123456789'] @@ -379,17 +367,6 @@ See metadata.h for an explanation of the interface here, and metadata.cc for an explanation of what's going on. """.splitlines()) -put_banner([HPACK_H, HPACK_C], """WARNING: Auto-generated code. - -To make changes to this file, change -tools/codegen/core/gen_static_metadata.py, and then re-run it. - -This file contains the mapping from the index of each metadata element in the -grpc static metadata table to the index of that element in the hpack static -metadata table. If the element is not contained in the static hpack table, then -the returned index is 0. -""".splitlines()) - print >> H, '#ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H' print >> H, '#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H' print >> H @@ -403,20 +380,6 @@ print >> C, '#include "src/core/lib/transport/static_metadata.h"' print >> C print >> C, '#include "src/core/lib/slice/slice_internal.h"' print >> C -print >> HPACK_H, ('#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_' - 'MAPPING_H') -print >> HPACK_H, ('#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_' - 'MAPPING_H') -print >> HPACK_H -print >> HPACK_H, '#include ' -print >> HPACK_H -print >> HPACK_H, '#include "src/core/lib/transport/static_metadata.h"' -print >> HPACK_H -print >> HPACK_C, '#include ' -print >> HPACK_C -print >> HPACK_C, ('#include ' - '"src/core/ext/transport/chttp2/transport/hpack_mapping.h"') -print >> HPACK_C str_ofs = 0 id2strofs = {} @@ -493,28 +456,11 @@ print >> H, ('extern grpc_mdelem_data ' print >> H, ('extern uintptr_t ' 'grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];') for i, elem in enumerate(all_elems): - print >> H, '/* "%s": "%s" */' % (elem[0], elem[1]) + print >> H, '/* "%s": "%s" */' % elem print >> H, ('#define %s (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[%d], ' 'GRPC_MDELEM_STORAGE_STATIC))') % (mangle(elem).upper(), i) print >> H -# Print out the chttp2 mapping between static mdelem index and the hpack static -# table index -print >> HPACK_H, ('extern const uint8_t grpc_hpack_static_mdelem_indices[' - 'GRPC_STATIC_MDELEM_COUNT];') -print >> HPACK_H -print >> HPACK_C, ('const uint8_t grpc_hpack_static_mdelem_indices[' - 'GRPC_STATIC_MDELEM_COUNT] = {') -indices = '' -for elem in all_elems: - index = 0 - if len(elem) == 3: - index = elem[2] - indices += '%d,' % index -print >> HPACK_C, ' %s' % indices -print >> HPACK_C, '};' -print >> HPACK_C - print >> C, ('uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] ' '= {') print >> C, ' %s' % ','.join( @@ -607,9 +553,8 @@ print >> C, '}' print >> C print >> C, 'grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {' -for elem in all_elems: - print >> C, '{%s,%s},' % (slice_def(str_idx(elem[0])), - slice_def(str_idx(elem[1]))) +for a, b in all_elems: + print >> C, '{%s,%s},' % (slice_def(str_idx(a)), slice_def(str_idx(b))) print >> C, '};' print >> H, 'typedef enum {' @@ -653,8 +598,5 @@ print >> H, '#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GR print >> H, '#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */' -print >> HPACK_H, ('#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_' - 'MAPPING_H */') - H.close() C.close() diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index ed0e17a99ef..7cd1dc7bf37 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1013,8 +1013,6 @@ src/core/ext/transport/chttp2/transport/frame_window_update.cc \ src/core/ext/transport/chttp2/transport/frame_window_update.h \ src/core/ext/transport/chttp2/transport/hpack_encoder.cc \ src/core/ext/transport/chttp2/transport/hpack_encoder.h \ -src/core/ext/transport/chttp2/transport/hpack_mapping.cc \ -src/core/ext/transport/chttp2/transport/hpack_mapping.h \ src/core/ext/transport/chttp2/transport/hpack_parser.cc \ src/core/ext/transport/chttp2/transport/hpack_parser.h \ src/core/ext/transport/chttp2/transport/hpack_table.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 96645d0bbfe..f3e93a08746 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10697,7 +10697,6 @@ "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_mapping.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", @@ -10735,8 +10734,6 @@ "src/core/ext/transport/chttp2/transport/frame_window_update.h", "src/core/ext/transport/chttp2/transport/hpack_encoder.cc", "src/core/ext/transport/chttp2/transport/hpack_encoder.h", - "src/core/ext/transport/chttp2/transport/hpack_mapping.cc", - "src/core/ext/transport/chttp2/transport/hpack_mapping.h", "src/core/ext/transport/chttp2/transport/hpack_parser.cc", "src/core/ext/transport/chttp2/transport/hpack_parser.h", "src/core/ext/transport/chttp2/transport/hpack_table.cc", From 55bb0cfb90bb9430c8abb827d39568a19ac10520 Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Fri, 28 Sep 2018 13:49:09 -0700 Subject: [PATCH 490/546] Create lock.yml --- .github/lock.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/lock.yml diff --git a/.github/lock.yml b/.github/lock.yml new file mode 100644 index 00000000000..119e4840bee --- /dev/null +++ b/.github/lock.yml @@ -0,0 +1,2 @@ +daysUntilLock: 90 +lockComment: false From d568fba51ac5558241836eb80bc0d6b4ca7edfdc Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Fri, 28 Sep 2018 14:36:13 -0700 Subject: [PATCH 491/546] Add documentation for running microbenchmarks with other tooling --- test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc index 5a7a8d5bafe..d4bd58b9838 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc @@ -31,6 +31,8 @@ auto& force_library_initialization = Library::get(); * CONFIGURATIONS */ +// Replace "benchmark::internal::Benchmark" with "::testing::Benchmark" to use +// internal microbenchmarking tooling static void SweepSizesArgs(benchmark::internal::Benchmark* b) { b->Args({0, 0}); for (int i = 1; i <= 128 * 1024 * 1024; i *= 8) { From f443f185b3dd4b694e9719d7e730e98396416ce8 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Fri, 28 Sep 2018 19:48:38 -0700 Subject: [PATCH 492/546] Address feedback comment --- src/core/lib/iomgr/tcp_posix.cc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 4aad83915f4..e40bf81c90e 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -204,15 +204,13 @@ static void drop_uncovered(grpc_tcp* tcp) { GPR_ASSERT(old_count != 1); } -/* gRPC API considers a Write operation to be done the moment it clears ‘flow - control’ i.e., and not necessarily sent on the wire. This means that the - application MAY NOT call `grpc_completion_queue_next/pluck` in a timely - manner when its `Write()` API is acked. - - We need to ensure that the fd is 'covered' (i.e being monitored by some - polling thread and progress is made) and hence add it to a backup poller - here */ - +// gRPC API considers a Write operation to be done the moment it clears ‘flow +// control’ i.e., not necessarily sent on the wire. This means that the +// application MIGHT not call `grpc_completion_queue_next/pluck` in a timely +// manner when its `Write()` API is acked. +// +// We need to ensure that the fd is 'covered' (i.e being monitored by some +// polling thread and progress is made) and hence add it to a backup poller here static void cover_self(grpc_tcp* tcp) { backup_poller* p; gpr_atm old_count = From 1d999617e2ef67686d6f6d8be8e2dc62976380eb Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Sun, 30 Sep 2018 22:13:44 -0700 Subject: [PATCH 493/546] Add experimental versions with interceptors for create channel from fd and inproc channel --- CMakeLists.txt | 5 ++++ Makefile | 5 ++++ build.yaml | 1 + gRPC-C++.podspec | 1 + include/grpcpp/create_channel_posix.h | 17 +++++++++++++ include/grpcpp/security/credentials.h | 6 ++++- include/grpcpp/server.h | 25 +++++++++++++++++++ src/cpp/client/channel_cc.cc | 2 +- src/cpp/client/create_channel_posix.cc | 19 ++++++++++++++ src/cpp/server/server_cc.cc | 13 ++++++++++ tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + .../generated/sources_and_headers.json | 2 ++ 13 files changed, 96 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 62862003581..2bd0a92c6bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3023,6 +3023,7 @@ foreach(_hdr include/grpcpp/impl/codegen/core_codegen_interface.h include/grpcpp/impl/codegen/create_auth_context.h include/grpcpp/impl/codegen/grpc_library.h + include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -3596,6 +3597,7 @@ foreach(_hdr include/grpcpp/impl/codegen/core_codegen_interface.h include/grpcpp/impl/codegen/create_auth_context.h include/grpcpp/impl/codegen/grpc_library.h + include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -4009,6 +4011,7 @@ foreach(_hdr include/grpcpp/impl/codegen/core_codegen_interface.h include/grpcpp/impl/codegen/create_auth_context.h include/grpcpp/impl/codegen/grpc_library.h + include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -4190,6 +4193,7 @@ foreach(_hdr include/grpcpp/impl/codegen/core_codegen_interface.h include/grpcpp/impl/codegen/create_auth_context.h include/grpcpp/impl/codegen/grpc_library.h + include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h @@ -4512,6 +4516,7 @@ foreach(_hdr include/grpcpp/impl/codegen/core_codegen_interface.h include/grpcpp/impl/codegen/create_auth_context.h include/grpcpp/impl/codegen/grpc_library.h + include/grpcpp/impl/codegen/interceptor.h include/grpcpp/impl/codegen/metadata_map.h include/grpcpp/impl/codegen/method_handler_impl.h include/grpcpp/impl/codegen/rpc_method.h diff --git a/Makefile b/Makefile index 2e0a9d689c0..bcf7c69da72 100644 --- a/Makefile +++ b/Makefile @@ -5441,6 +5441,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ + include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6021,6 +6022,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ + include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6414,6 +6416,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ + include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6571,6 +6574,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ + include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ @@ -6897,6 +6901,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ + include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/rpc_method.h \ diff --git a/build.yaml b/build.yaml index d3cdcd7098c..8cd72dd7978 100644 --- a/build.yaml +++ b/build.yaml @@ -1181,6 +1181,7 @@ filegroups: - include/grpcpp/impl/codegen/core_codegen_interface.h - include/grpcpp/impl/codegen/create_auth_context.h - include/grpcpp/impl/codegen/grpc_library.h + - include/grpcpp/impl/codegen/interceptor.h - include/grpcpp/impl/codegen/metadata_map.h - include/grpcpp/impl/codegen/method_handler_impl.h - include/grpcpp/impl/codegen/rpc_method.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index ce89fedca21..490c8e23eaf 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -140,6 +140,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/codegen/core_codegen_interface.h', 'include/grpcpp/impl/codegen/create_auth_context.h', 'include/grpcpp/impl/codegen/grpc_library.h', + 'include/grpcpp/impl/codegen/interceptor.h', 'include/grpcpp/impl/codegen/metadata_map.h', 'include/grpcpp/impl/codegen/method_handler_impl.h', 'include/grpcpp/impl/codegen/rpc_method.h', diff --git a/include/grpcpp/create_channel_posix.h b/include/grpcpp/create_channel_posix.h index 9bf5acc45c0..808514041b8 100644 --- a/include/grpcpp/create_channel_posix.h +++ b/include/grpcpp/create_channel_posix.h @@ -45,6 +45,23 @@ std::shared_ptr CreateInsecureChannelFromFd(const grpc::string& target, std::shared_ptr CreateCustomInsecureChannelFromFd( const grpc::string& target, int fd, const ChannelArguments& args); +namespace experimental { + +/// Create a new \a Channel communicating over given file descriptor with custom +/// channel arguments. +/// +/// \param target The name of the target. +/// \param fd The file descriptor representing a socket. +/// \param args Options for channel creation. +/// \param interceptor_creators Vector of interceptor factory objects. +std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( + const grpc::string& target, int fd, const ChannelArguments& args, + std::unique_ptr>> + interceptor_creators); + +} // namespace experimental + #endif // GPR_SUPPORT_CHANNELS_FROM_FD } // namespace grpc diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 53f0131c002..8dfbdec3e64 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -87,11 +87,15 @@ class ChannelCredentials : private GrpcLibraryCodegen { virtual std::shared_ptr CreateChannel( const grpc::string& target, const ChannelArguments& args) = 0; + // This function should have been a pure virtual function, but it is + // implemented as a virtual function so that it does not break API. virtual std::shared_ptr CreateChannelWithInterceptors( const grpc::string& target, const ChannelArguments& args, std::unique_ptr>> - interceptor_creators) = 0; + interceptor_creators) { + return nullptr; + }; }; /// A call credentials object encapsulates the state needed by a client to diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 72544c0f0bc..8d3e856502c 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -99,6 +100,30 @@ class Server : public ServerInterface, private GrpcLibraryCodegen { /// Establish a channel for in-process communication std::shared_ptr InProcessChannel(const ChannelArguments& args); + /// NOTE: class experimental_type is not part of the public API of this class. + /// TODO(yashykt): Integrate into public API when this is no longer + /// experimental. + class experimental_type { + public: + explicit experimental_type(Server* server) : server_(server) {} + + /// Establish a channel for in-process communication with client + /// interceptors + std::shared_ptr InProcessChannelWithInterceptors( + const ChannelArguments& args, + std::unique_ptr>> + interceptor_creators); + + private: + Server* server_; + }; + + /// NOTE: The function experimental() is not stable public API. It is a view + /// to the experimental components of this class. It may be changed or removed + /// at any time. + experimental_type experimental() { return experimental_type(this); } + protected: /// Register a service. This call does not take ownership of the service. /// The service must exist for the lifetime of the Server instance. diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 7c7ecc8cb76..c9f70b186fe 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -56,7 +56,7 @@ Channel::Channel( std::unique_ptr>> interceptor_creators) : host_(host), c_channel_(channel) { - auto vector = interceptor_creators.release(); + auto* vector = interceptor_creators.release(); if (vector != nullptr) { interceptor_creators_ = std::move(*vector); } diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index b9e5887bccb..8d775e7a87f 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -49,6 +49,25 @@ std::shared_ptr CreateCustomInsecureChannelFromFd( nullptr); } +namespace experimental { + +std::shared_ptr CreateCustomInsecureChannelWithInterceptorsFromFd( + const grpc::string& target, int fd, const ChannelArguments& args, + std::unique_ptr>> + interceptor_creators) { + internal::GrpcLibrary init_lib; + init_lib.init(); + grpc_channel_args channel_args; + args.SetChannelArgs(&channel_args); + return CreateChannelInternal( + "", + grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args), + std::move(interceptor_creators)); +} + +} // namespace experimental + #endif // GPR_SUPPORT_CHANNELS_FROM_FD } // namespace grpc diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 72371e53841..7c764f4bce8 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -477,6 +477,19 @@ std::shared_ptr Server::InProcessChannel( nullptr); } +std::shared_ptr +Server::experimental_type::InProcessChannelWithInterceptors( + const ChannelArguments& args, + std::unique_ptr>> + interceptor_creators) { + grpc_channel_args channel_args = args.c_channel_args(); + return CreateChannelInternal( + "inproc", + grpc_inproc_channel_create(server_->server_, &channel_args, nullptr), + std::move(interceptor_creators)); +} + static grpc_server_register_method_payload_handling PayloadHandlingForMethod( internal::RpcServiceMethod* method) { switch (method->method_type()) { diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 1fa827885fe..97599be443f 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -959,6 +959,7 @@ include/grpcpp/impl/codegen/core_codegen.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ +include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 6bd83f03c34..c852b29fced 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -961,6 +961,7 @@ include/grpcpp/impl/codegen/core_codegen.h \ include/grpcpp/impl/codegen/core_codegen_interface.h \ include/grpcpp/impl/codegen/create_auth_context.h \ include/grpcpp/impl/codegen/grpc_library.h \ +include/grpcpp/impl/codegen/interceptor.h \ include/grpcpp/impl/codegen/metadata_map.h \ include/grpcpp/impl/codegen/method_handler_impl.h \ include/grpcpp/impl/codegen/proto_buffer_reader.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 7f064b39eee..8d88e5b9fa9 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -11095,6 +11095,7 @@ "include/grpcpp/impl/codegen/core_codegen_interface.h", "include/grpcpp/impl/codegen/create_auth_context.h", "include/grpcpp/impl/codegen/grpc_library.h", + "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/rpc_method.h", @@ -11164,6 +11165,7 @@ "include/grpcpp/impl/codegen/core_codegen_interface.h", "include/grpcpp/impl/codegen/create_auth_context.h", "include/grpcpp/impl/codegen/grpc_library.h", + "include/grpcpp/impl/codegen/interceptor.h", "include/grpcpp/impl/codegen/metadata_map.h", "include/grpcpp/impl/codegen/method_handler_impl.h", "include/grpcpp/impl/codegen/rpc_method.h", From d55ef6cc03eb9c5460618167d51de7fe1f99dba3 Mon Sep 17 00:00:00 2001 From: Nathan Herring Date: Mon, 1 Oct 2018 10:13:04 +0200 Subject: [PATCH 494/546] Fix inverted logic for --call_creds=none. Fixes #16622. Follow up to change 6e3938c. Thanks to @bluecmd for pointing it out. --- test/cpp/util/cli_credentials.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/util/cli_credentials.cc b/test/cpp/util/cli_credentials.cc index 1125b2d945e..91acc904aac 100644 --- a/test/cpp/util/cli_credentials.cc +++ b/test/cpp/util/cli_credentials.cc @@ -151,7 +151,7 @@ std::shared_ptr CliCredentials::GetCallCredentials() if (IsAccessToken(FLAGS_call_creds)) { return grpc::AccessTokenCredentials(AccessToken(FLAGS_call_creds)); } - if (FLAGS_call_creds.compare("none") != 0) { + if (FLAGS_call_creds.compare("none") == 0) { // Nothing to do; creds, if any, are baked into the channel. return std::shared_ptr(); } From 8722714ae4a53f5f8db82e566f6567746439cbab Mon Sep 17 00:00:00 2001 From: ganmacs Date: Mon, 1 Oct 2018 17:32:12 +0900 Subject: [PATCH 495/546] change var name to be consistent with others --- src/ruby/pb/test/client.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb index 7710d346574..b2303c6e142 100755 --- a/src/ruby/pb/test/client.rb +++ b/src/ruby/pb/test/client.rb @@ -112,7 +112,7 @@ def create_stub(opts) creds = ssl_creds(opts.use_test_ca) stub_opts = { channel_args: { - GRPC::Core::Channel::SSL_TARGET => opts.host_override + GRPC::Core::Channel::SSL_TARGET => opts.server_host_override } } @@ -703,14 +703,14 @@ class NamedTests end # Args is used to hold the command line info. -Args = Struct.new(:default_service_account, :server_host, :host_override, +Args = Struct.new(:default_service_account, :server_host, :server_host_override, :oauth_scope, :server_port, :secure, :test_case, :use_test_ca) # validates the command line options, returning them as a Hash. def parse_args args = Args.new - args.host_override = 'foo.test.google.fr' + args.server_host_override = 'foo.test.google.fr' OptionParser.new do |opts| opts.on('--oauth_scope scope', 'Scope for OAuth tokens') { |v| args['oauth_scope'] = v } @@ -723,7 +723,7 @@ def parse_args end opts.on('--server_host_override HOST_OVERRIDE', 'override host via a HTTP header') do |v| - args['host_override'] = v + args['server_host_override'] = v end opts.on('--server_port SERVER_PORT', 'server port') do |v| args['server_port'] = v From ee1f49b252a6510e26fbfb3c0889afe877217d57 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 1 Oct 2018 17:20:10 +0200 Subject: [PATCH 496/546] upgrade CommandLineParser to 2.3.0 --- .../Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj | 2 +- src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index ad7033b7829..8daf3fa98bb 100755 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -18,7 +18,7 @@ - + diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index 8a629f9748b..d39d46cf1b0 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -16,7 +16,7 @@ - + From b23cfa2f3e80cea9bd1a3dcc35607f455347976f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 1 Oct 2018 17:04:52 +0200 Subject: [PATCH 497/546] fix and polish artifact dockerfiles --- .../grpc_artifact_linux_x64/Dockerfile | 18 +----- .../grpc_artifact_linux_x86/Dockerfile | 9 +-- .../grpc_artifact_node_linux_x64/Dockerfile | 63 +++++++++++++++++++ .../grpc_artifact_node_linux_x86/Dockerfile | 55 ++++++++++++++++ 4 files changed, 121 insertions(+), 24 deletions(-) create mode 100644 tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile create mode 100644 tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile index 0251b2b3929..228efef698e 100644 --- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile @@ -16,10 +16,8 @@ FROM debian:jessie -RUN apt-get update && apt-get install debian-keyring && apt-key update - # Install Git and basic packages. -RUN apt-get update && apt-key update && apt-get install -y \ +RUN apt-get update && apt-get install -y \ autoconf \ autotools-dev \ build-essential \ @@ -46,11 +44,6 @@ RUN apt-get update && apt-key update && apt-get install -y \ wget \ zip && apt-get clean -# Install Node dependencies -RUN touch .profile -RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash -RUN /bin/bash -l -c "nvm install 8 && npm install -g node-pre-gyp" - ################## # Ruby dependencies @@ -72,15 +65,8 @@ RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" # PHP dependencies RUN apt-get update && apt-get install -y \ - php5 php5-dev php-pear phpunit - -################## -# Install cross compiler for ARM - -RUN echo 'deb http://emdebian.org/tools/debian/ jessie main' | tee -a /etc/apt/sources.list.d/crosstools.list && \ - curl http://emdebian.org/tools/debian/emdebian-toolchain-archive.key | apt-key add - + php5 php5-dev php-pear phpunit && apt-get clean -RUN dpkg --add-architecture armhf && apt-get update && apt-get install -y crossbuild-essential-armhf RUN mkdir /var/local/jenkins diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile index 2d179c8c459..d33e0f83ea1 100644 --- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile @@ -16,10 +16,8 @@ FROM 32bit/debian:jessie -RUN apt-get update && apt-get install debian-keyring && apt-key update - # Install Git and basic packages. -RUN apt-get update && apt-key update && apt-get install -y \ +RUN apt-get update && apt-get install -y \ autoconf \ autotools-dev \ build-essential \ @@ -46,11 +44,6 @@ RUN apt-get update && apt-key update && apt-get install -y \ wget \ zip && apt-get clean -# Install Node dependencies -RUN touch .profile -RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash -RUN /bin/bash -l -c "nvm install 8 && npm install -g node-pre-gyp" - ################## # Ruby dependencies diff --git a/tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile new file mode 100644 index 00000000000..5c531a776cb --- /dev/null +++ b/tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile @@ -0,0 +1,63 @@ +# 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. + +# Docker file for building gRPC artifacts. + +FROM debian:stretch + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + clang \ + curl \ + gcc \ + gcc-multilib \ + git \ + golang \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + perl \ + strace \ + python-dev \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +# Install Node dependencies +RUN touch .profile +RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash +RUN /bin/bash -l -c "nvm install 8 && npm install -g node-pre-gyp" + +################## +# Install cross compiler for ARM + +RUN echo 'deb http://emdebian.org/tools/debian/ jessie main' | tee -a /etc/apt/sources.list.d/crosstools.list && \ + curl http://emdebian.org/tools/debian/emdebian-toolchain-archive.key | apt-key add - + +RUN dpkg --add-architecture armhf && apt-get update && apt-get install -y crossbuild-essential-armhf && apt-get clean + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile new file mode 100644 index 00000000000..400fef4379c --- /dev/null +++ b/tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile @@ -0,0 +1,55 @@ +# Copyright 2016 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Docker file for building gRPC artifacts. + +FROM i386/debian:stretch + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + clang \ + curl \ + gcc \ + gcc-multilib \ + git \ + golang \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + perl \ + strace \ + python-dev \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +# Install Node dependencies +RUN touch .profile +RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash +RUN /bin/bash -l -c "nvm install 8 && npm install -g node-pre-gyp" + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] From 2b89be31c8708471edcee3b6e48d17ffb91fbee1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 1 Oct 2018 18:03:51 +0200 Subject: [PATCH 498/546] fix copyright --- tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile | 2 +- tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile index 5c531a776cb..edabacd027f 100644 --- a/tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2016 gRPC authors. +# Copyright 2018 The gRPC Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile index 400fef4379c..2c030ef60ef 100644 --- a/tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2016 gRPC authors. +# Copyright 2018 The gRPC Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 67d219a88434d98bda1d284f9147290e75324519 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 1 Oct 2018 18:13:06 +0200 Subject: [PATCH 499/546] node artifact docker images not needed anymore --- .../grpc_artifact_node_linux_x64/Dockerfile | 63 ------------------- .../grpc_artifact_node_linux_x86/Dockerfile | 55 ---------------- 2 files changed, 118 deletions(-) delete mode 100644 tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile delete mode 100644 tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile diff --git a/tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile deleted file mode 100644 index edabacd027f..00000000000 --- a/tools/dockerfile/grpc_artifact_node_linux_x64/Dockerfile +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright 2018 The 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. - -# Docker file for building gRPC artifacts. - -FROM debian:stretch - -# Install Git and basic packages. -RUN apt-get update && apt-get install -y \ - autoconf \ - autotools-dev \ - build-essential \ - bzip2 \ - clang \ - curl \ - gcc \ - gcc-multilib \ - git \ - golang \ - libc6 \ - libc6-dbg \ - libc6-dev \ - libgtest-dev \ - libtool \ - make \ - perl \ - strace \ - python-dev \ - python-setuptools \ - python-yaml \ - telnet \ - unzip \ - wget \ - zip && apt-get clean - -# Install Node dependencies -RUN touch .profile -RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash -RUN /bin/bash -l -c "nvm install 8 && npm install -g node-pre-gyp" - -################## -# Install cross compiler for ARM - -RUN echo 'deb http://emdebian.org/tools/debian/ jessie main' | tee -a /etc/apt/sources.list.d/crosstools.list && \ - curl http://emdebian.org/tools/debian/emdebian-toolchain-archive.key | apt-key add - - -RUN dpkg --add-architecture armhf && apt-get update && apt-get install -y crossbuild-essential-armhf && apt-get clean - -RUN mkdir /var/local/jenkins - -# Define the default command. -CMD ["bash"] diff --git a/tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile deleted file mode 100644 index 2c030ef60ef..00000000000 --- a/tools/dockerfile/grpc_artifact_node_linux_x86/Dockerfile +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 2018 The 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. - -# Docker file for building gRPC artifacts. - -FROM i386/debian:stretch - -# Install Git and basic packages. -RUN apt-get update && apt-get install -y \ - autoconf \ - autotools-dev \ - build-essential \ - bzip2 \ - clang \ - curl \ - gcc \ - gcc-multilib \ - git \ - golang \ - libc6 \ - libc6-dbg \ - libc6-dev \ - libgtest-dev \ - libtool \ - make \ - perl \ - strace \ - python-dev \ - python-setuptools \ - python-yaml \ - telnet \ - unzip \ - wget \ - zip && apt-get clean - -# Install Node dependencies -RUN touch .profile -RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash -RUN /bin/bash -l -c "nvm install 8 && npm install -g node-pre-gyp" - -RUN mkdir /var/local/jenkins - -# Define the default command. -CMD ["bash"] From bf4432b67e82d6183e7bf2eec510aaf9aa6fd1e5 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Mon, 1 Oct 2018 10:08:50 -0700 Subject: [PATCH 500/546] Add comment to specify hpack elements --- tools/codegen/core/gen_static_metadata.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index c7f80c12666..f705a9bd41c 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -68,6 +68,7 @@ CONFIG = [ 'gzip', 'stream/gzip', # metadata elements + # begin hpack static elements (':authority', ''), (':method', 'GET'), (':method', 'POST'), @@ -129,6 +130,7 @@ CONFIG = [ ('vary', ''), ('via', ''), ('www-authenticate', ''), + # end hpack static elements ('grpc-status', '0'), ('grpc-status', '1'), ('grpc-status', '2'), From beec2c6ba3f5f789b92a684ff823790f1d63762a Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 1 Oct 2018 13:11:29 -0700 Subject: [PATCH 501/546] Add alias for macro for internal app --- src/core/lib/gpr/sync_posix.cc | 8 ++++++++ src/core/lib/iomgr/timer_manager.cc | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index b6eb0b68ce0..6d0a4279390 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -27,6 +27,14 @@ #include #include "src/core/lib/profiling/timers.h" +// For debug of the timer manager crash only. +#ifndef kGMS_BuildConfig_EnableGRPCTimerCrashDebug +#define kGMS_BuildConfig_EnableGRPCTimerCrashDebug() GRPC_DEBUG_TIMER_MANAGER +#endif +#ifndef kBuildConfig_EnableGRPCTimerCrashDebug +#define kBuildConfig_EnableGRPCTimerCrashDebug() GRPC_DEBUG_TIMER_MANAGER +#endif + // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index eaba05a5ceb..4a06790b3d0 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -61,6 +61,14 @@ static uint64_t g_timed_waiter_generation; static void timer_thread(void* completed_thread_ptr); +// For debug of the timer manager crash only. +#ifndef kGMS_BuildConfig_EnableGRPCTimerCrashDebug +#define kGMS_BuildConfig_EnableGRPCTimerCrashDebug() GRPC_DEBUG_TIMER_MANAGER +#endif +#ifndef kBuildConfig_EnableGRPCTimerCrashDebug +#define kBuildConfig_EnableGRPCTimerCrashDebug() GRPC_DEBUG_TIMER_MANAGER +#endif + // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER From 385a1f1643243c0e873d0423d4a2a337faa46c00 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 1 Oct 2018 14:11:48 -0700 Subject: [PATCH 502/546] polish assert --- src/core/lib/gpr/sync_posix.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 6d0a4279390..1a1de597d05 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -136,11 +136,9 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { g_fork_count, g_timer_wait_err, g_timer_cv_value, g_timer_mu_value, g_abstime_sec_value, g_abstime_nsec_value); } - GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); } -#else - GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); #endif + GPR_ASSERT(err == 0 || err == ETIMEDOUT || err == EAGAIN); return err == ETIMEDOUT; } From 516150062129b5d8f0e2302eef780ed1d977ecac Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Mon, 1 Oct 2018 14:50:20 -0700 Subject: [PATCH 503/546] polish macro --- src/core/lib/gpr/sync_posix.cc | 8 ++------ src/core/lib/iomgr/timer_manager.cc | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 1a1de597d05..012d85d78c6 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -28,13 +28,9 @@ #include "src/core/lib/profiling/timers.h" // For debug of the timer manager crash only. -#ifndef kGMS_BuildConfig_EnableGRPCTimerCrashDebug -#define kGMS_BuildConfig_EnableGRPCTimerCrashDebug() GRPC_DEBUG_TIMER_MANAGER +#ifndef kGMS_BuildConfig_EnableGRPC +#define kGMS_BuildConfig_EnableGRPC() GRPC_DEBUG_TIMER_MANAGER #endif -#ifndef kBuildConfig_EnableGRPCTimerCrashDebug -#define kBuildConfig_EnableGRPCTimerCrashDebug() GRPC_DEBUG_TIMER_MANAGER -#endif - // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index 4a06790b3d0..e2e25ff188a 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -62,13 +62,9 @@ static uint64_t g_timed_waiter_generation; static void timer_thread(void* completed_thread_ptr); // For debug of the timer manager crash only. -#ifndef kGMS_BuildConfig_EnableGRPCTimerCrashDebug -#define kGMS_BuildConfig_EnableGRPCTimerCrashDebug() GRPC_DEBUG_TIMER_MANAGER +#ifndef kGMS_BuildConfig_EnableGRPC +#define kGMS_BuildConfig_EnableGRPC() GRPC_DEBUG_TIMER_MANAGER #endif -#ifndef kBuildConfig_EnableGRPCTimerCrashDebug -#define kBuildConfig_EnableGRPCTimerCrashDebug() GRPC_DEBUG_TIMER_MANAGER -#endif - // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER From 18ba787392a9c860710650c0e01eacaed0716991 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Mon, 1 Oct 2018 18:17:10 -0700 Subject: [PATCH 504/546] Fix the unused result error in client_channel_stress_test.cc. --- test/cpp/client/client_channel_stress_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index 826907ae4e5..976eeb6aeab 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -245,7 +245,7 @@ class ClientChannelStressTest { EchoResponse response; { std::lock_guard lock(stub_mutex_); - stub_->Echo(&context, request, &response); + Status status = stub_->Echo(&context, request, &response); } } gpr_log(GPR_INFO, "Finish sending requests."); From 08125f7af0da0e3b45bc9212b09b0dff23fd499c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 2 Oct 2018 11:18:54 +0200 Subject: [PATCH 505/546] cmake: prevent C core from depending on libstdc++ --- CMakeLists.txt | 1434 ++++++++++++++++++++++++++++- templates/CMakeLists.txt.template | 28 +- 2 files changed, 1424 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0e2244e75a..9c91dd3664f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,6 +115,17 @@ else() set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf") endif() +if (_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC) + # C core has C++ source code, but should not depend on libstc++ (for better portability). + # We need to use a few tricks to convince cmake to do that. + # https://stackoverflow.com/questions/15058403/how-to-stop-cmake-from-linking-against-libstdc + set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") + # Exceptions and RTTI must be off to avoid dependency on libstdc++ + set(_gRPC_CORE_NOSTDCXX_FLAGS -fno-exceptions -fno-rtti) +else() + set(_gRPC_CORE_NOSTDCXX_FLAGS "") +endif() + include(cmake/zlib.cmake) include(cmake/cares.cmake) include(cmake/protobuf.cmake) @@ -710,7 +721,12 @@ target_include_directories(address_sorting PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(address_sorting PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(address_sorting PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(address_sorting ${_gRPC_BASELIB_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -757,7 +773,12 @@ target_include_directories(alts_test_util PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(alts_test_util PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(alts_test_util PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(alts_test_util ${_gRPC_SSL_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -833,7 +854,12 @@ target_include_directories(gpr PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(gpr PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(gpr ${_gRPC_ALLTARGETS_LIBRARIES} ) @@ -923,7 +949,12 @@ target_include_directories(gpr_test_util PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_test_util PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(gpr_test_util PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(gpr_test_util ${_gRPC_ALLTARGETS_LIBRARIES} gpr @@ -1273,7 +1304,12 @@ target_include_directories(grpc PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(grpc PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(grpc ${_gRPC_BASELIB_LIBRARIES} ${_gRPC_SSL_LIBRARIES} @@ -1650,7 +1686,12 @@ target_include_directories(grpc_cronet PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_cronet PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(grpc_cronet PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(grpc_cronet ${_gRPC_BASELIB_LIBRARIES} ${_gRPC_SSL_LIBRARIES} @@ -1961,7 +2002,12 @@ target_include_directories(grpc_test_util PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_test_util PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(grpc_test_util PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(grpc_test_util ${_gRPC_ALLTARGETS_LIBRARIES} gpr_test_util @@ -2270,7 +2316,12 @@ target_include_directories(grpc_test_util_unsecure PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_test_util_unsecure PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(grpc_test_util_unsecure PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(grpc_test_util_unsecure ${_gRPC_ALLTARGETS_LIBRARIES} gpr @@ -2598,7 +2649,12 @@ target_include_directories(grpc_unsecure PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_unsecure PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(grpc_unsecure PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(grpc_unsecure ${_gRPC_BASELIB_LIBRARIES} ${_gRPC_ZLIB_LIBRARIES} @@ -2691,7 +2747,12 @@ target_include_directories(reconnect_server PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(reconnect_server PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(reconnect_server PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(reconnect_server ${_gRPC_ALLTARGETS_LIBRARIES} test_tcp_server @@ -2733,7 +2794,12 @@ target_include_directories(test_tcp_server PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(test_tcp_server PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(test_tcp_server PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(test_tcp_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util @@ -2815,7 +2881,6 @@ target_include_directories(grpc++ PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc++ ${_gRPC_BASELIB_LIBRARIES} ${_gRPC_SSL_LIBRARIES} @@ -3099,7 +3164,6 @@ target_include_directories(grpc++_core_stats PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc++_core_stats ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -3385,7 +3449,6 @@ target_include_directories(grpc++_cronet PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc++_cronet ${_gRPC_BASELIB_LIBRARIES} ${_gRPC_SSL_LIBRARIES} @@ -3660,7 +3723,6 @@ target_include_directories(grpc++_error_details PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc++_error_details ${_gRPC_BASELIB_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES} @@ -3732,7 +3794,6 @@ target_include_directories(grpc++_proto_reflection_desc_db PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc++_proto_reflection_desc_db ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -3792,7 +3853,6 @@ target_include_directories(grpc++_reflection PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc++_reflection ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -3856,7 +3916,6 @@ target_include_directories(grpc++_test_config PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc++_test_config ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -3943,7 +4002,6 @@ target_include_directories(grpc++_test_util PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc++_test_util ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -4123,7 +4181,6 @@ target_include_directories(grpc++_test_util_unsecure PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc++_test_util_unsecure ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -4300,7 +4357,6 @@ target_include_directories(grpc++_unsecure PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc++_unsecure ${_gRPC_BASELIB_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES} @@ -4569,7 +4625,6 @@ target_include_directories(grpc_benchmark PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc_benchmark ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -4629,7 +4684,6 @@ target_include_directories(grpc_cli_libs PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc_cli_libs ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -4687,7 +4741,6 @@ target_include_directories(grpc_plugin_support PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpc_plugin_support ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES} @@ -4753,7 +4806,6 @@ target_include_directories(grpcpp_channelz PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(grpcpp_channelz ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -4838,7 +4890,6 @@ target_include_directories(http2_client_main PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(http2_client_main ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -4895,7 +4946,6 @@ target_include_directories(interop_client_helper PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(interop_client_helper ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -4967,7 +5017,6 @@ target_include_directories(interop_client_main PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(interop_client_main ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -5019,7 +5068,6 @@ target_include_directories(interop_server_helper PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(interop_server_helper ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -5089,7 +5137,6 @@ target_include_directories(interop_server_lib PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(interop_server_lib ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -5141,7 +5188,6 @@ target_include_directories(interop_server_main PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(interop_server_main ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -5245,7 +5291,6 @@ target_include_directories(qps PRIVATE third_party/googletest/googlemock PRIVATE ${_gRPC_PROTO_GENS_DIR} ) - target_link_libraries(qps ${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -5289,7 +5334,12 @@ target_include_directories(grpc_csharp_ext PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_csharp_ext PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(grpc_csharp_ext PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(grpc_csharp_ext ${_gRPC_ALLTARGETS_LIBRARIES} grpc @@ -5337,7 +5387,12 @@ target_include_directories(bad_client_test PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(bad_client_test PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(bad_client_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util_unsecure @@ -5378,7 +5433,12 @@ target_include_directories(bad_ssl_test_server PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(bad_ssl_test_server PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(bad_ssl_test_server PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(bad_ssl_test_server ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util @@ -5498,7 +5558,12 @@ target_include_directories(end2end_tests PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(end2end_tests PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(end2end_tests PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(end2end_tests ${_gRPC_SSL_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES} @@ -5618,7 +5683,12 @@ target_include_directories(end2end_nosec_tests PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} ) - + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(end2end_nosec_tests PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(end2end_nosec_tests PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() target_link_libraries(end2end_nosec_tests ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util_unsecure @@ -5658,6 +5728,12 @@ target_link_libraries(algorithm_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(algorithm_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(algorithm_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -5685,6 +5761,12 @@ target_link_libraries(alloc_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(alloc_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(alloc_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -5714,6 +5796,12 @@ target_link_libraries(alpn_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(alpn_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(alpn_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -5741,6 +5829,12 @@ target_link_libraries(arena_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(arena_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(arena_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -5769,6 +5863,12 @@ target_link_libraries(avl_test grpc ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(avl_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(avl_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -5799,6 +5899,12 @@ target_link_libraries(bad_server_response_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(bad_server_response_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(bad_server_response_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -5826,6 +5932,12 @@ target_link_libraries(bin_decoder_test grpc ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(bin_decoder_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(bin_decoder_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -5853,6 +5965,12 @@ target_link_libraries(bin_encoder_test grpc ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(bin_encoder_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(bin_encoder_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX) @@ -5883,6 +6001,12 @@ target_link_libraries(buffer_list_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(buffer_list_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(buffer_list_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -5913,6 +6037,12 @@ target_link_libraries(channel_create_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(channel_create_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(channel_create_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) add_executable(check_epollexclusive @@ -5939,6 +6069,12 @@ target_link_libraries(check_epollexclusive gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(check_epollexclusive PROPERTIES LINKER_LANGUAGE C) + target_compile_options(check_epollexclusive PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + if (gRPC_BUILD_TESTS) add_executable(chttp2_hpack_encoder_test @@ -5967,6 +6103,12 @@ target_link_libraries(chttp2_hpack_encoder_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(chttp2_hpack_encoder_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(chttp2_hpack_encoder_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -5996,6 +6138,12 @@ target_link_libraries(chttp2_stream_map_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(chttp2_stream_map_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(chttp2_stream_map_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6025,6 +6173,12 @@ target_link_libraries(chttp2_varint_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(chttp2_varint_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(chttp2_varint_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6053,6 +6207,12 @@ target_link_libraries(cmdline_test grpc_test_util ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(cmdline_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(cmdline_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6082,6 +6242,12 @@ target_link_libraries(combiner_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(combiner_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(combiner_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6111,6 +6277,12 @@ target_link_libraries(compression_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(compression_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(compression_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6140,6 +6312,12 @@ target_link_libraries(concurrent_connectivity_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(concurrent_connectivity_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(concurrent_connectivity_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6169,6 +6347,12 @@ target_link_libraries(connection_refused_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(connection_refused_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(connection_refused_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6198,6 +6382,12 @@ target_link_libraries(dns_resolver_connectivity_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(dns_resolver_connectivity_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(dns_resolver_connectivity_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6227,6 +6417,12 @@ target_link_libraries(dns_resolver_cooldown_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(dns_resolver_cooldown_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(dns_resolver_cooldown_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6256,6 +6452,12 @@ target_link_libraries(dns_resolver_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(dns_resolver_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(dns_resolver_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -6286,6 +6488,12 @@ target_link_libraries(dualstack_socket_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(dualstack_socket_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(dualstack_socket_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6316,6 +6524,12 @@ target_link_libraries(endpoint_pair_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(endpoint_pair_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(endpoint_pair_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6345,6 +6559,12 @@ target_link_libraries(error_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(error_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(error_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX) @@ -6375,6 +6595,12 @@ target_link_libraries(ev_epollex_linux_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(ev_epollex_linux_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(ev_epollex_linux_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6405,6 +6631,12 @@ target_link_libraries(fake_resolver_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(fake_resolver_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(fake_resolver_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -6435,6 +6667,12 @@ target_link_libraries(fake_transport_security_test grpc ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(fake_transport_security_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(fake_transport_security_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6466,6 +6704,12 @@ target_link_libraries(fd_conservation_posix_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(fd_conservation_posix_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(fd_conservation_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6497,6 +6741,12 @@ target_link_libraries(fd_posix_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(fd_posix_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(fd_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6527,6 +6777,12 @@ target_link_libraries(fling_client gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(fling_client PROPERTIES LINKER_LANGUAGE C) + target_compile_options(fling_client PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6556,6 +6812,12 @@ target_link_libraries(fling_server gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(fling_server PROPERTIES LINKER_LANGUAGE C) + target_compile_options(fling_server PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -6586,6 +6848,12 @@ target_link_libraries(fling_stream_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(fling_stream_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(fling_stream_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6617,6 +6885,12 @@ target_link_libraries(fling_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(fling_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(fling_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6646,6 +6920,12 @@ target_link_libraries(fork_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(fork_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(fork_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6677,6 +6957,12 @@ target_link_libraries(goaway_server_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(goaway_server_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(goaway_server_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6705,6 +6991,12 @@ target_link_libraries(gpr_cpu_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_cpu_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_cpu_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6732,6 +7024,12 @@ target_link_libraries(gpr_env_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_env_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_env_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6759,6 +7057,12 @@ target_link_libraries(gpr_host_port_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_host_port_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_host_port_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6786,6 +7090,12 @@ target_link_libraries(gpr_log_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_log_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_log_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6813,6 +7123,12 @@ target_link_libraries(gpr_manual_constructor_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_manual_constructor_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_manual_constructor_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6840,6 +7156,12 @@ target_link_libraries(gpr_mpscq_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_mpscq_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_mpscq_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6867,6 +7189,12 @@ target_link_libraries(gpr_spinlock_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_spinlock_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_spinlock_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6894,6 +7222,12 @@ target_link_libraries(gpr_string_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_string_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_string_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6921,6 +7255,12 @@ target_link_libraries(gpr_sync_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_sync_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_sync_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6948,6 +7288,12 @@ target_link_libraries(gpr_thd_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_thd_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_thd_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -6975,6 +7321,12 @@ target_link_libraries(gpr_time_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_time_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_time_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7002,6 +7354,12 @@ target_link_libraries(gpr_tls_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_tls_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_tls_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7029,6 +7387,12 @@ target_link_libraries(gpr_useful_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(gpr_useful_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(gpr_useful_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7058,6 +7422,12 @@ target_link_libraries(grpc_auth_context_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_auth_context_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_auth_context_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7087,6 +7457,12 @@ target_link_libraries(grpc_b64_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_b64_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_b64_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7116,6 +7492,12 @@ target_link_libraries(grpc_byte_buffer_reader_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_byte_buffer_reader_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_byte_buffer_reader_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7145,6 +7527,12 @@ target_link_libraries(grpc_channel_args_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_channel_args_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_channel_args_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7174,6 +7562,12 @@ target_link_libraries(grpc_channel_stack_builder_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_channel_stack_builder_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_channel_stack_builder_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7203,6 +7597,12 @@ target_link_libraries(grpc_channel_stack_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_channel_stack_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_channel_stack_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7232,6 +7632,12 @@ target_link_libraries(grpc_completion_queue_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_completion_queue_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_completion_queue_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7261,6 +7667,12 @@ target_link_libraries(grpc_completion_queue_threading_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_completion_queue_threading_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_completion_queue_threading_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) add_executable(grpc_create_jwt @@ -7289,6 +7701,12 @@ target_link_libraries(grpc_create_jwt gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_create_jwt PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_create_jwt PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + if (gRPC_BUILD_TESTS) add_executable(grpc_credentials_test @@ -7317,6 +7735,12 @@ target_link_libraries(grpc_credentials_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_credentials_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_credentials_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7346,6 +7770,12 @@ target_link_libraries(grpc_fetch_oauth2 gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_fetch_oauth2 PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_fetch_oauth2 PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7375,6 +7805,12 @@ target_link_libraries(grpc_ipv6_loopback_available_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_ipv6_loopback_available_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_ipv6_loopback_available_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -7405,6 +7841,12 @@ target_link_libraries(grpc_json_token_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_json_token_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_json_token_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7435,6 +7877,12 @@ target_link_libraries(grpc_jwt_verifier_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_jwt_verifier_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_jwt_verifier_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) add_executable(grpc_print_google_default_creds_token @@ -7462,6 +7910,12 @@ target_link_libraries(grpc_print_google_default_creds_token gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_print_google_default_creds_token PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_print_google_default_creds_token PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + if (gRPC_BUILD_TESTS) add_executable(grpc_security_connector_test @@ -7490,6 +7944,12 @@ target_link_libraries(grpc_security_connector_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_security_connector_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_security_connector_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7519,6 +7979,12 @@ target_link_libraries(grpc_ssl_credentials_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_ssl_credentials_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_ssl_credentials_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) add_executable(grpc_verify_jwt @@ -7546,6 +8012,12 @@ target_link_libraries(grpc_verify_jwt gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(grpc_verify_jwt PROPERTIES LINKER_LANGUAGE C) + target_compile_options(grpc_verify_jwt PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX) @@ -7576,6 +8048,12 @@ target_link_libraries(handshake_client gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(handshake_client PROPERTIES LINKER_LANGUAGE C) + target_compile_options(handshake_client PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7609,6 +8087,12 @@ target_link_libraries(handshake_server gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(handshake_server PROPERTIES LINKER_LANGUAGE C) + target_compile_options(handshake_server PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7642,6 +8126,12 @@ target_link_libraries(handshake_server_with_readahead_handshaker gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(handshake_server_with_readahead_handshaker PROPERTIES LINKER_LANGUAGE C) + target_compile_options(handshake_server_with_readahead_handshaker PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7674,6 +8164,12 @@ target_link_libraries(handshake_verify_peer_options gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(handshake_verify_peer_options PROPERTIES LINKER_LANGUAGE C) + target_compile_options(handshake_verify_peer_options PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7702,6 +8198,12 @@ target_link_libraries(histogram_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(histogram_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(histogram_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7731,6 +8233,12 @@ target_link_libraries(hpack_parser_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(hpack_parser_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(hpack_parser_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7760,6 +8268,12 @@ target_link_libraries(hpack_table_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(hpack_table_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(hpack_table_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7789,6 +8303,12 @@ target_link_libraries(http_parser_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(http_parser_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(http_parser_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7818,6 +8338,12 @@ target_link_libraries(httpcli_format_request_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(httpcli_format_request_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(httpcli_format_request_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -7848,6 +8374,12 @@ target_link_libraries(httpcli_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(httpcli_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(httpcli_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7879,6 +8411,12 @@ target_link_libraries(httpscli_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(httpscli_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(httpscli_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7909,6 +8447,12 @@ target_link_libraries(init_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(init_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(init_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7938,6 +8482,12 @@ target_link_libraries(inproc_callback_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(inproc_callback_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(inproc_callback_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7967,6 +8517,12 @@ target_link_libraries(invalid_call_argument_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(invalid_call_argument_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(invalid_call_argument_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -7996,6 +8552,12 @@ target_link_libraries(json_rewrite gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(json_rewrite PROPERTIES LINKER_LANGUAGE C) + target_compile_options(json_rewrite PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8025,6 +8587,12 @@ target_link_libraries(json_rewrite_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(json_rewrite_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(json_rewrite_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8054,6 +8622,12 @@ target_link_libraries(json_stream_error_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(json_stream_error_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(json_stream_error_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8083,6 +8657,12 @@ target_link_libraries(json_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(json_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(json_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8112,6 +8692,12 @@ target_link_libraries(lame_client_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(lame_client_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(lame_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8141,6 +8727,12 @@ target_link_libraries(load_file_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(load_file_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(load_file_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8170,6 +8762,12 @@ target_link_libraries(memory_profile_client gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(memory_profile_client PROPERTIES LINKER_LANGUAGE C) + target_compile_options(memory_profile_client PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8199,6 +8797,12 @@ target_link_libraries(memory_profile_server gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(memory_profile_server PROPERTIES LINKER_LANGUAGE C) + target_compile_options(memory_profile_server PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -8229,6 +8833,12 @@ target_link_libraries(memory_profile_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(memory_profile_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(memory_profile_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8259,6 +8869,12 @@ target_link_libraries(message_compress_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(message_compress_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(message_compress_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8288,6 +8904,12 @@ target_link_libraries(minimal_stack_is_minimal_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(minimal_stack_is_minimal_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(minimal_stack_is_minimal_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8317,6 +8939,12 @@ target_link_libraries(multiple_server_queues_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(multiple_server_queues_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(multiple_server_queues_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8344,6 +8972,12 @@ target_link_libraries(murmur_hash_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(murmur_hash_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(murmur_hash_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8373,6 +9007,12 @@ target_link_libraries(no_server_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(no_server_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(no_server_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8402,6 +9042,12 @@ target_link_libraries(num_external_connectivity_watchers_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(num_external_connectivity_watchers_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(num_external_connectivity_watchers_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8431,6 +9077,12 @@ target_link_libraries(parse_address_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(parse_address_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(parse_address_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8460,6 +9112,12 @@ target_link_libraries(percent_encoding_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(percent_encoding_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(percent_encoding_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -8490,6 +9148,12 @@ target_link_libraries(resolve_address_posix_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(resolve_address_posix_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(resolve_address_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8520,6 +9184,12 @@ target_link_libraries(resolve_address_using_ares_resolver_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(resolve_address_using_ares_resolver_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(resolve_address_using_ares_resolver_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8549,6 +9219,12 @@ target_link_libraries(resolve_address_using_native_resolver_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(resolve_address_using_native_resolver_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(resolve_address_using_native_resolver_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8578,6 +9254,12 @@ target_link_libraries(resource_quota_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(resource_quota_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(resource_quota_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8607,6 +9289,12 @@ target_link_libraries(secure_channel_create_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(secure_channel_create_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(secure_channel_create_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8636,6 +9324,12 @@ target_link_libraries(secure_endpoint_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(secure_endpoint_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(secure_endpoint_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8665,6 +9359,12 @@ target_link_libraries(sequential_connectivity_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(sequential_connectivity_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(sequential_connectivity_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8694,6 +9394,12 @@ target_link_libraries(server_chttp2_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(server_chttp2_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(server_chttp2_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8723,6 +9429,12 @@ target_link_libraries(server_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(server_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(server_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8752,6 +9464,12 @@ target_link_libraries(slice_buffer_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(slice_buffer_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(slice_buffer_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8781,6 +9499,12 @@ target_link_libraries(slice_string_helpers_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(slice_string_helpers_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(slice_string_helpers_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8810,6 +9534,12 @@ target_link_libraries(slice_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(slice_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(slice_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8839,6 +9569,12 @@ target_link_libraries(sockaddr_resolver_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(sockaddr_resolver_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(sockaddr_resolver_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8868,6 +9604,12 @@ target_link_libraries(sockaddr_utils_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(sockaddr_utils_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(sockaddr_utils_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -8898,6 +9640,12 @@ target_link_libraries(socket_utils_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(socket_utils_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(socket_utils_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8929,6 +9677,12 @@ target_link_libraries(ssl_transport_security_test grpc ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(ssl_transport_security_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(ssl_transport_security_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8959,6 +9713,12 @@ target_link_libraries(status_conversion_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(status_conversion_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(status_conversion_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -8988,6 +9748,12 @@ target_link_libraries(stream_compression_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(stream_compression_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(stream_compression_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9017,6 +9783,12 @@ target_link_libraries(stream_owned_slice_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(stream_owned_slice_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(stream_owned_slice_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -9047,6 +9819,12 @@ target_link_libraries(tcp_client_posix_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(tcp_client_posix_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(tcp_client_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9077,6 +9855,12 @@ target_link_libraries(tcp_client_uv_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(tcp_client_uv_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(tcp_client_uv_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -9107,6 +9891,12 @@ target_link_libraries(tcp_posix_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(tcp_posix_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(tcp_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9138,6 +9928,12 @@ target_link_libraries(tcp_server_posix_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(tcp_server_posix_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(tcp_server_posix_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9168,6 +9964,12 @@ target_link_libraries(tcp_server_uv_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(tcp_server_uv_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(tcp_server_uv_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9197,6 +9999,12 @@ target_link_libraries(time_averaged_stats_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(time_averaged_stats_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(time_averaged_stats_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9226,6 +10034,12 @@ target_link_libraries(timeout_encoding_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(timeout_encoding_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(timeout_encoding_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9255,6 +10069,12 @@ target_link_libraries(timer_heap_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(timer_heap_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(timer_heap_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9284,6 +10104,12 @@ target_link_libraries(timer_list_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(timer_list_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(timer_list_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9313,6 +10139,12 @@ target_link_libraries(transport_connectivity_state_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(transport_connectivity_state_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(transport_connectivity_state_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9342,6 +10174,12 @@ target_link_libraries(transport_metadata_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(transport_metadata_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(transport_metadata_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -9372,6 +10210,12 @@ target_link_libraries(transport_security_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(transport_security_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(transport_security_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9403,6 +10247,12 @@ target_link_libraries(udp_server_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(udp_server_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(udp_server_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9433,6 +10283,12 @@ target_link_libraries(uri_parser_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(uri_parser_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(uri_parser_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -9463,6 +10319,12 @@ target_link_libraries(wakeup_fd_cv_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(wakeup_fd_cv_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(wakeup_fd_cv_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9504,6 +10366,7 @@ target_link_libraries(alarm_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9541,6 +10404,7 @@ target_link_libraries(alts_counter_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9579,6 +10443,7 @@ target_link_libraries(alts_crypt_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9616,6 +10481,7 @@ target_link_libraries(alts_crypter_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9653,6 +10519,7 @@ target_link_libraries(alts_frame_handler_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9691,6 +10558,7 @@ target_link_libraries(alts_frame_protector_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9728,6 +10596,7 @@ target_link_libraries(alts_grpc_record_protocol_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9765,6 +10634,7 @@ target_link_libraries(alts_handshaker_client_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9802,6 +10672,7 @@ target_link_libraries(alts_handshaker_service_api_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9839,6 +10710,7 @@ target_link_libraries(alts_iovec_record_protocol_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9875,6 +10747,7 @@ target_link_libraries(alts_security_connector_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9912,6 +10785,7 @@ target_link_libraries(alts_tsi_handshaker_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9949,6 +10823,7 @@ target_link_libraries(alts_tsi_utils_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -9986,6 +10861,7 @@ target_link_libraries(alts_zero_copy_grpc_protector_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10026,6 +10902,7 @@ target_link_libraries(async_end2end_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10066,6 +10943,7 @@ target_link_libraries(auth_property_iterator_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10104,6 +10982,7 @@ target_link_libraries(backoff_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10144,6 +11023,7 @@ target_link_libraries(bdp_estimator_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -10188,6 +11068,7 @@ target_link_libraries(bm_arena ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10233,6 +11114,7 @@ target_link_libraries(bm_call_create ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10278,6 +11160,7 @@ target_link_libraries(bm_channel ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10323,6 +11206,7 @@ target_link_libraries(bm_chttp2_hpack ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10368,6 +11252,7 @@ target_link_libraries(bm_chttp2_transport ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10413,6 +11298,7 @@ target_link_libraries(bm_closure ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10458,6 +11344,7 @@ target_link_libraries(bm_cq ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10503,6 +11390,7 @@ target_link_libraries(bm_cq_multiple_threads ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10548,6 +11436,7 @@ target_link_libraries(bm_error ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10593,6 +11482,7 @@ target_link_libraries(bm_fullstack_streaming_ping_pong ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10638,6 +11528,7 @@ target_link_libraries(bm_fullstack_streaming_pump ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10683,6 +11574,7 @@ target_link_libraries(bm_fullstack_trickle ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10728,6 +11620,7 @@ target_link_libraries(bm_fullstack_unary_ping_pong ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10773,6 +11666,7 @@ target_link_libraries(bm_metadata ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10818,6 +11712,7 @@ target_link_libraries(bm_pollset ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10857,6 +11752,7 @@ target_link_libraries(byte_stream_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10894,6 +11790,7 @@ target_link_libraries(channel_arguments_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10931,6 +11828,7 @@ target_link_libraries(channel_filter_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -10978,6 +11876,7 @@ target_link_libraries(channel_trace_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11018,6 +11917,7 @@ target_link_libraries(channelz_registry_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11066,6 +11966,7 @@ target_link_libraries(channelz_service_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11113,6 +12014,7 @@ target_link_libraries(channelz_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11149,6 +12051,7 @@ target_link_libraries(check_gcp_environment_linux_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11185,6 +12088,7 @@ target_link_libraries(check_gcp_environment_windows_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11223,6 +12127,7 @@ target_link_libraries(chttp2_settings_timeout_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11264,6 +12169,7 @@ target_link_libraries(cli_call_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11304,6 +12210,7 @@ target_link_libraries(client_callback_end2end_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11351,6 +12258,7 @@ target_link_libraries(client_channel_stress_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -11392,6 +12300,7 @@ target_link_libraries(client_crash_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11433,6 +12342,7 @@ target_link_libraries(client_crash_test_server ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11473,6 +12383,7 @@ target_link_libraries(client_lb_end2end_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11560,6 +12471,7 @@ target_link_libraries(codegen_test_full ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11647,6 +12559,7 @@ target_link_libraries(codegen_test_minimal ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11684,6 +12597,7 @@ target_link_libraries(credentials_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11723,6 +12637,7 @@ target_link_libraries(cxx_byte_buffer_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11762,6 +12677,7 @@ target_link_libraries(cxx_slice_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11798,6 +12714,7 @@ target_link_libraries(cxx_string_ref_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11837,6 +12754,7 @@ target_link_libraries(cxx_time_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11877,6 +12795,7 @@ target_link_libraries(end2end_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11920,6 +12839,7 @@ target_link_libraries(error_details_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -11960,6 +12880,7 @@ target_link_libraries(exception_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12000,6 +12921,7 @@ target_link_libraries(filter_end2end_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12040,6 +12962,7 @@ target_link_libraries(generic_end2end_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12084,6 +13007,7 @@ target_link_libraries(golden_file_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12120,6 +13044,7 @@ target_link_libraries(grpc_alts_credentials_options_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12160,6 +13085,7 @@ target_link_libraries(grpc_cli ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_CODEGEN) @@ -12190,6 +13116,7 @@ target_link_libraries(grpc_cpp_plugin ) + if (gRPC_INSTALL) install(TARGETS grpc_cpp_plugin EXPORT gRPCTargets RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} @@ -12228,6 +13155,7 @@ target_link_libraries(grpc_csharp_plugin ) + if (gRPC_INSTALL) install(TARGETS grpc_csharp_plugin EXPORT gRPCTargets RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} @@ -12274,6 +13202,7 @@ target_link_libraries(grpc_linux_system_roots_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_CODEGEN) @@ -12304,6 +13233,7 @@ target_link_libraries(grpc_node_plugin ) + if (gRPC_INSTALL) install(TARGETS grpc_node_plugin EXPORT gRPCTargets RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} @@ -12342,6 +13272,7 @@ target_link_libraries(grpc_objective_c_plugin ) + if (gRPC_INSTALL) install(TARGETS grpc_objective_c_plugin EXPORT gRPCTargets RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} @@ -12380,6 +13311,7 @@ target_link_libraries(grpc_php_plugin ) + if (gRPC_INSTALL) install(TARGETS grpc_php_plugin EXPORT gRPCTargets RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} @@ -12418,6 +13350,7 @@ target_link_libraries(grpc_python_plugin ) + if (gRPC_INSTALL) install(TARGETS grpc_python_plugin EXPORT gRPCTargets RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} @@ -12456,6 +13389,7 @@ target_link_libraries(grpc_ruby_plugin ) + if (gRPC_INSTALL) install(TARGETS grpc_ruby_plugin EXPORT gRPCTargets RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR} @@ -12521,6 +13455,7 @@ target_link_libraries(grpc_tool_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12566,6 +13501,7 @@ target_link_libraries(grpclb_api_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12613,6 +13549,7 @@ target_link_libraries(grpclb_end2end_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12652,6 +13589,7 @@ target_link_libraries(h2_ssl_cert_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12691,6 +13629,7 @@ target_link_libraries(h2_ssl_session_reuse_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12731,6 +13670,7 @@ target_link_libraries(health_service_end2end_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -12771,6 +13711,7 @@ target_link_libraries(http2_client ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12812,6 +13753,7 @@ target_link_libraries(hybrid_end2end_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12851,6 +13793,7 @@ target_link_libraries(inlined_vector_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -12895,6 +13838,7 @@ target_link_libraries(inproc_sync_unary_ping_pong_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12939,6 +13883,7 @@ target_link_libraries(interop_client ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -12984,6 +13929,7 @@ target_link_libraries(interop_server ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13025,6 +13971,7 @@ target_link_libraries(interop_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13068,6 +14015,7 @@ target_link_libraries(json_run_localhost ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13108,6 +14056,7 @@ target_link_libraries(memory_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13153,6 +14102,7 @@ target_link_libraries(metrics_client ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13193,6 +14143,7 @@ target_link_libraries(mock_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13233,6 +14184,7 @@ target_link_libraries(nonblocking_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13268,6 +14220,7 @@ target_link_libraries(noop-benchmark ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13307,6 +14260,7 @@ target_link_libraries(orphanable_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13349,6 +14303,7 @@ target_link_libraries(proto_server_reflection_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13385,6 +14340,7 @@ target_link_libraries(proto_utils_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -13428,6 +14384,7 @@ target_link_libraries(qps_interarrival_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13472,6 +14429,7 @@ target_link_libraries(qps_json_driver ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -13516,6 +14474,7 @@ target_link_libraries(qps_openloop_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13560,6 +14519,7 @@ target_link_libraries(qps_worker ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13600,6 +14560,7 @@ target_link_libraries(raw_end2end_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13662,6 +14623,7 @@ target_link_libraries(reconnect_interop_client ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13726,6 +14688,7 @@ target_link_libraries(reconnect_interop_server ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13765,6 +14728,7 @@ target_link_libraries(ref_counted_ptr_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13804,6 +14768,7 @@ target_link_libraries(ref_counted_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13842,6 +14807,7 @@ target_link_libraries(retry_throttle_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13882,6 +14848,7 @@ target_link_libraries(secure_auth_context_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -13926,6 +14893,7 @@ target_link_libraries(secure_sync_unary_ping_pong_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -13967,6 +14935,7 @@ target_link_libraries(server_builder_plugin_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14021,6 +14990,7 @@ target_link_libraries(server_builder_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_POSIX) @@ -14076,6 +15046,7 @@ target_link_libraries(server_builder_with_socket_mutator_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14116,6 +15087,7 @@ target_link_libraries(server_context_test_spouse_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -14157,6 +15129,7 @@ target_link_libraries(server_crash_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14198,6 +15171,7 @@ target_link_libraries(server_crash_test_client ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14238,6 +15212,7 @@ target_link_libraries(server_early_return_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14292,6 +15267,7 @@ target_link_libraries(server_request_call_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14332,6 +15308,7 @@ target_link_libraries(shutdown_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14370,6 +15347,7 @@ target_link_libraries(slice_hash_table_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14408,6 +15386,7 @@ target_link_libraries(slice_weak_hash_table_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14447,6 +15426,7 @@ target_link_libraries(stats_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14482,6 +15462,7 @@ target_link_libraries(status_metadata_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14517,6 +15498,7 @@ target_link_libraries(status_util_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -14558,6 +15540,7 @@ target_link_libraries(streaming_throughput_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14631,6 +15614,7 @@ target_link_libraries(stress_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14669,6 +15653,7 @@ target_link_libraries(thread_manager_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14709,6 +15694,7 @@ target_link_libraries(thread_stress_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14749,6 +15735,7 @@ target_link_libraries(transport_pid_controller_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14786,6 +15773,7 @@ target_link_libraries(transport_security_common_api_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -14827,6 +15815,7 @@ target_link_libraries(writes_per_rpc_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14855,6 +15844,7 @@ target_link_libraries(public_headers_must_be_c89 gpr ) + endif (gRPC_BUILD_TESTS) add_executable(gen_hpack_tables @@ -14882,6 +15872,7 @@ target_link_libraries(gen_hpack_tables ) + add_executable(gen_legal_metadata_characters tools/codegen/core/gen_legal_metadata_characters.cc ) @@ -14905,6 +15896,7 @@ target_link_libraries(gen_legal_metadata_characters ) + add_executable(gen_percent_encoding_tables tools/codegen/core/gen_percent_encoding_tables.cc ) @@ -14927,6 +15919,7 @@ target_link_libraries(gen_percent_encoding_tables ${_gRPC_ALLTARGETS_LIBRARIES} ) + if (gRPC_BUILD_TESTS) add_executable(badreq_bad_client_test @@ -14957,6 +15950,12 @@ target_link_libraries(badreq_bad_client_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(badreq_bad_client_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(badreq_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -14988,6 +15987,12 @@ target_link_libraries(connection_prefix_bad_client_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(connection_prefix_bad_client_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(connection_prefix_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15019,6 +16024,12 @@ target_link_libraries(duplicate_header_bad_client_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(duplicate_header_bad_client_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(duplicate_header_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15050,6 +16061,12 @@ target_link_libraries(head_of_line_blocking_bad_client_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(head_of_line_blocking_bad_client_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(head_of_line_blocking_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15081,6 +16098,12 @@ target_link_libraries(headers_bad_client_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(headers_bad_client_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(headers_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15112,6 +16135,12 @@ target_link_libraries(initial_settings_frame_bad_client_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(initial_settings_frame_bad_client_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(initial_settings_frame_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15143,6 +16172,12 @@ target_link_libraries(large_metadata_bad_client_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(large_metadata_bad_client_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(large_metadata_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15174,6 +16209,12 @@ target_link_libraries(server_registered_method_bad_client_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(server_registered_method_bad_client_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(server_registered_method_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15205,6 +16246,12 @@ target_link_libraries(simple_request_bad_client_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(simple_request_bad_client_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(simple_request_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15236,6 +16283,12 @@ target_link_libraries(unknown_frame_bad_client_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(unknown_frame_bad_client_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(unknown_frame_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15267,6 +16320,12 @@ target_link_libraries(window_overflow_bad_client_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(window_overflow_bad_client_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(window_overflow_bad_client_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -15298,6 +16357,12 @@ target_link_libraries(bad_ssl_cert_server gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(bad_ssl_cert_server PROPERTIES LINKER_LANGUAGE C) + target_compile_options(bad_ssl_cert_server PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15329,6 +16394,12 @@ target_link_libraries(bad_ssl_cert_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(bad_ssl_cert_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(bad_ssl_cert_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15360,6 +16431,12 @@ target_link_libraries(h2_census_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_census_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_census_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15390,6 +16467,12 @@ target_link_libraries(h2_compress_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_compress_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_compress_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15420,6 +16503,12 @@ target_link_libraries(h2_fakesec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_fakesec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_fakesec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -15451,6 +16540,12 @@ target_link_libraries(h2_fd_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_fd_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_fd_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15482,6 +16577,12 @@ target_link_libraries(h2_full_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_full_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_full_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX) @@ -15513,6 +16614,12 @@ target_link_libraries(h2_full+pipe_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_full+pipe_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_full+pipe_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15544,6 +16651,12 @@ target_link_libraries(h2_full+trace_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_full+trace_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_full+trace_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15574,6 +16687,12 @@ target_link_libraries(h2_full+workarounds_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_full+workarounds_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_full+workarounds_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15604,6 +16723,12 @@ target_link_libraries(h2_http_proxy_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_http_proxy_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_http_proxy_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -15635,6 +16760,12 @@ target_link_libraries(h2_local_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_local_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_local_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15666,6 +16797,12 @@ target_link_libraries(h2_oauth2_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_oauth2_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_oauth2_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15696,6 +16833,12 @@ target_link_libraries(h2_proxy_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_proxy_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_proxy_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15726,6 +16869,12 @@ target_link_libraries(h2_sockpair_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_sockpair_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_sockpair_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15756,6 +16905,12 @@ target_link_libraries(h2_sockpair+trace_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_sockpair+trace_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_sockpair+trace_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15786,6 +16941,12 @@ target_link_libraries(h2_sockpair_1byte_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_sockpair_1byte_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_sockpair_1byte_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15816,6 +16977,12 @@ target_link_libraries(h2_ssl_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_ssl_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_ssl_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15846,6 +17013,12 @@ target_link_libraries(h2_ssl_proxy_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_ssl_proxy_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_ssl_proxy_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -15877,6 +17050,12 @@ target_link_libraries(h2_uds_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_uds_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_uds_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15908,6 +17087,12 @@ target_link_libraries(inproc_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(inproc_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(inproc_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15938,6 +17123,12 @@ target_link_libraries(h2_census_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_census_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_census_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -15968,6 +17159,12 @@ target_link_libraries(h2_compress_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_compress_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_compress_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -15999,6 +17196,12 @@ target_link_libraries(h2_fd_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_fd_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_fd_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16030,6 +17233,12 @@ target_link_libraries(h2_full_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_full_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_full_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX) @@ -16061,6 +17270,12 @@ target_link_libraries(h2_full+pipe_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_full+pipe_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_full+pipe_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16092,6 +17307,12 @@ target_link_libraries(h2_full+trace_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_full+trace_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_full+trace_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16122,6 +17343,12 @@ target_link_libraries(h2_full+workarounds_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_full+workarounds_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_full+workarounds_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16152,6 +17379,12 @@ target_link_libraries(h2_http_proxy_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_http_proxy_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_http_proxy_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16182,6 +17415,12 @@ target_link_libraries(h2_proxy_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_proxy_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_proxy_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16212,6 +17451,12 @@ target_link_libraries(h2_sockpair_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_sockpair_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_sockpair_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16242,6 +17487,12 @@ target_link_libraries(h2_sockpair+trace_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_sockpair+trace_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_sockpair+trace_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16272,6 +17523,12 @@ target_link_libraries(h2_sockpair_1byte_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_sockpair_1byte_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_sockpair_1byte_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -16303,6 +17560,12 @@ target_link_libraries(h2_uds_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(h2_uds_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(h2_uds_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16334,6 +17597,12 @@ target_link_libraries(inproc_nosec_test gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(inproc_nosec_test PROPERTIES LINKER_LANGUAGE C) + target_compile_options(inproc_nosec_test PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16375,6 +17644,7 @@ target_link_libraries(resolver_component_test_unsecure ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16416,6 +17686,7 @@ target_link_libraries(resolver_component_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -16458,6 +17729,7 @@ target_link_libraries(resolver_component_tests_runner_invoker_unsecure ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16501,6 +17773,7 @@ target_link_libraries(resolver_component_tests_runner_invoker ${_gRPC_GFLAGS_LIBRARIES} ) + endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16543,6 +17816,7 @@ target_link_libraries(address_sorting_test_unsecure ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16584,6 +17858,7 @@ target_link_libraries(address_sorting_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16625,6 +17900,7 @@ target_link_libraries(cancel_ares_query_test ${_gRPC_GFLAGS_LIBRARIES} ) + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16655,6 +17931,12 @@ target_link_libraries(alts_credentials_fuzzer_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(alts_credentials_fuzzer_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(alts_credentials_fuzzer_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16685,6 +17967,12 @@ target_link_libraries(api_fuzzer_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(api_fuzzer_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(api_fuzzer_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16715,6 +18003,12 @@ target_link_libraries(client_fuzzer_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(client_fuzzer_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(client_fuzzer_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16745,6 +18039,12 @@ target_link_libraries(hpack_parser_fuzzer_test_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(hpack_parser_fuzzer_test_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(hpack_parser_fuzzer_test_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16775,6 +18075,12 @@ target_link_libraries(http_request_fuzzer_test_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(http_request_fuzzer_test_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(http_request_fuzzer_test_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16805,6 +18111,12 @@ target_link_libraries(http_response_fuzzer_test_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(http_response_fuzzer_test_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(http_response_fuzzer_test_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16835,6 +18147,12 @@ target_link_libraries(json_fuzzer_test_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(json_fuzzer_test_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(json_fuzzer_test_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16865,6 +18183,12 @@ target_link_libraries(nanopb_fuzzer_response_test_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(nanopb_fuzzer_response_test_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(nanopb_fuzzer_response_test_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16895,6 +18219,12 @@ target_link_libraries(nanopb_fuzzer_serverlist_test_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(nanopb_fuzzer_serverlist_test_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(nanopb_fuzzer_serverlist_test_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16925,6 +18255,12 @@ target_link_libraries(percent_decode_fuzzer_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(percent_decode_fuzzer_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(percent_decode_fuzzer_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16955,6 +18291,12 @@ target_link_libraries(percent_encode_fuzzer_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(percent_encode_fuzzer_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(percent_encode_fuzzer_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -16985,6 +18327,12 @@ target_link_libraries(server_fuzzer_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(server_fuzzer_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(server_fuzzer_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -17015,6 +18363,12 @@ target_link_libraries(ssl_server_fuzzer_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(ssl_server_fuzzer_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(ssl_server_fuzzer_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) @@ -17045,6 +18399,12 @@ target_link_libraries(uri_fuzzer_test_one_entry gpr ) + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(uri_fuzzer_test_one_entry PROPERTIES LINKER_LANGUAGE C) + target_compile_options(uri_fuzzer_test_one_entry PRIVATE $<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + endif (gRPC_BUILD_TESTS) diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 2a514ed7b68..aec1624acdb 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -164,6 +164,17 @@ set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf") endif() + if (_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC) + # C core has C++ source code, but should not depend on libstc++ (for better portability). + # We need to use a few tricks to convince cmake to do that. + # https://stackoverflow.com/questions/15058403/how-to-stop-cmake-from-linking-against-libstdc + set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") + # Exceptions and RTTI must be off to avoid dependency on libstdc++ + set(_gRPC_CORE_NOSTDCXX_FLAGS -fno-exceptions -fno-rtti) + else() + set(_gRPC_CORE_NOSTDCXX_FLAGS "") + endif() + include(cmake/zlib.cmake) include(cmake/cares.cmake) include(cmake/protobuf.cmake) @@ -403,7 +414,14 @@ PRIVATE <%text>${_gRPC_PROTO_GENS_DIR} % endif ) - + % if lib.language in ['c', 'csharp']: + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(${lib.name} PROPERTIES LINKER_LANGUAGE C) + # only use the flags for C++ source files + target_compile_options(${lib.name} PRIVATE <%text>$<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + % endif % if len(get_deps(lib)) > 0: target_link_libraries(${lib.name} % for dep in get_deps(lib): @@ -492,6 +510,14 @@ ${dep} % endfor ) + + % if tgt.language in ['c', 'csharp']: + # avoid dependency on libstdc++ + if (_gRPC_CORE_NOSTDCXX_FLAGS) + set_target_properties(${tgt.name} PROPERTIES LINKER_LANGUAGE C) + target_compile_options(${tgt.name} PRIVATE <%text>$<$:${_gRPC_CORE_NOSTDCXX_FLAGS}>) + endif() + % endif % endif From 0d2bc2f1dffee4eef947b8e1a3f9c56bc03d0da6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 2 Oct 2018 13:17:59 +0200 Subject: [PATCH 506/546] server-reflection.md: fix markdown --- doc/server-reflection.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/server-reflection.md b/doc/server-reflection.md index 3716dc5a21d..0cc30a4eb09 100644 --- a/doc/server-reflection.md +++ b/doc/server-reflection.md @@ -161,6 +161,7 @@ which FileDescriptorProtos have been sent on a given stream, for a given value of valid_host, and avoid sending them repeatedly for overlapping requests. | message_request message | Result | +| --------------------------- | ----------------------------------------------- | | files_for_file_name | transitive closure of file name | | files_for_symbol_name | transitive closure file containing symbol | | file_containing_extension | transitive closure of file containing a given extension number of a given symbol | From c288d1a89482b0d3d8284d522bb87e6d15dd572d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 2 Oct 2018 13:55:38 +0200 Subject: [PATCH 507/546] improve doc comments for ChannelOptions --- src/csharp/Grpc.Core/ChannelOptions.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core/ChannelOptions.cs b/src/csharp/Grpc.Core/ChannelOptions.cs index 6ad5d56cad6..6fd66bf129c 100644 --- a/src/csharp/Grpc.Core/ChannelOptions.cs +++ b/src/csharp/Grpc.Core/ChannelOptions.cs @@ -26,6 +26,8 @@ namespace Grpc.Core /// /// Channel option specified when creating a channel. /// Corresponds to grpc_channel_args from grpc/grpc.h. + /// Commonly used channel option names are defined in ChannelOptions, + /// but any of the GRPC_ARG_* channel options names defined in grpc_types.h can be used. /// public sealed class ChannelOption { @@ -122,7 +124,8 @@ namespace Grpc.Core } /// - /// Defines names of supported channel options. + /// Defines names of most commonly used channel options. + /// Other supported options names can be found in grpc_types.h (GRPC_ARG_* definitions) /// public static class ChannelOptions { From 8eb6daddd9312d000db4f7b33dd35a509adea2a2 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 2 Oct 2018 14:08:06 +0200 Subject: [PATCH 508/546] ChannelOption: implement hashcode and equals --- src/csharp/Grpc.Core/ChannelOptions.cs | 36 +++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core/ChannelOptions.cs b/src/csharp/Grpc.Core/ChannelOptions.cs index 6fd66bf129c..3ea05120c10 100644 --- a/src/csharp/Grpc.Core/ChannelOptions.cs +++ b/src/csharp/Grpc.Core/ChannelOptions.cs @@ -29,7 +29,7 @@ namespace Grpc.Core /// Commonly used channel option names are defined in ChannelOptions, /// but any of the GRPC_ARG_* channel options names defined in grpc_types.h can be used. /// - public sealed class ChannelOption + public sealed class ChannelOption : IEquatable { /// /// Type of ChannelOption. @@ -121,6 +121,40 @@ namespace Grpc.Core return stringValue; } } + + public override bool Equals(object obj) + { + return Equals(obj as ChannelOption); + } + + public bool Equals(ChannelOption other) + { + return other != null && + type == other.type && + name == other.name && + intValue == other.intValue && + stringValue == other.stringValue; + } + + public override int GetHashCode() + { + var hashCode = 1412678443; + hashCode = hashCode * -1521134295 + type.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(name); + hashCode = hashCode * -1521134295 + intValue.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(stringValue); + return hashCode; + } + + public static bool operator ==(ChannelOption option1, ChannelOption option2) + { + return EqualityComparer.Default.Equals(option1, option2); + } + + public static bool operator !=(ChannelOption option1, ChannelOption option2) + { + return !(option1 == option2); + } } /// From e88a40ae265ee82073ef9238a0289e6e952557a8 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 2 Oct 2018 14:34:20 +0200 Subject: [PATCH 509/546] add xmldoc comments --- src/csharp/Grpc.Core/ChannelOptions.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/csharp/Grpc.Core/ChannelOptions.cs b/src/csharp/Grpc.Core/ChannelOptions.cs index 3ea05120c10..880f2bef5f9 100644 --- a/src/csharp/Grpc.Core/ChannelOptions.cs +++ b/src/csharp/Grpc.Core/ChannelOptions.cs @@ -122,11 +122,17 @@ namespace Grpc.Core } } + /// + /// Determines whether the specified object is equal to the current object. + /// public override bool Equals(object obj) { return Equals(obj as ChannelOption); } + /// + /// Determines whether the specified object is equal to the current object. + /// public bool Equals(ChannelOption other) { return other != null && @@ -136,6 +142,9 @@ namespace Grpc.Core stringValue == other.stringValue; } + /// + /// A hash code for the current object. + /// public override int GetHashCode() { var hashCode = 1412678443; @@ -146,11 +155,17 @@ namespace Grpc.Core return hashCode; } + /// + /// Equality operator. + /// public static bool operator ==(ChannelOption option1, ChannelOption option2) { return EqualityComparer.Default.Equals(option1, option2); } + /// + /// Inequality operator. + /// public static bool operator !=(ChannelOption option1, ChannelOption option2) { return !(option1 == option2); From 8b6719a1d708b8703e755bc89bf287a9b506c6fa Mon Sep 17 00:00:00 2001 From: Kevin Damm Date: Tue, 2 Oct 2018 15:11:48 -0400 Subject: [PATCH 510/546] Update README.md ordered list spacing Certain markdown interpreters do not recognize ordered lists if there isn't a blank line between the numbered lines. This change corrects the spacing between the steps for getting gRPC into a Unity project. --- src/csharp/experimental/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/csharp/experimental/README.md b/src/csharp/experimental/README.md index bd53cbcd357..64515075ce0 100644 --- a/src/csharp/experimental/README.md +++ b/src/csharp/experimental/README.md @@ -22,10 +22,14 @@ gRPC C# now has experimental support for Unity. Please try using gRPC with Unity and provide feedback! How to test gRPC in a Unity project + 1. Create a Unity project that targets .NET 4.x (Edit -> Project Settings -> Editor -> Scripting Runtime Version). gRPC uses APIs that are only available in .NET4.5+ so this is a requirement. + 2. Download the latest development build of `grpc_unity_package.VERSION.zip` from [daily builds](https://packages.grpc.io/) + 3. Extract the `.zip` file in the `Assets` directory in your Unity project + 4. Unity IDE will pick up all the bundled files and add them to project automatically. You should be able to use gRPC and Protobuf in your scripts from now on. From 40a75213e4914a601743830fd98991214206f0bd Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 2 Oct 2018 14:38:00 -0700 Subject: [PATCH 511/546] Keepalive should return unavailable instead of internal status --- .../ext/transport/chttp2/transport/chttp2_transport.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 776c15138b8..dc79cee0456 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -2757,10 +2757,10 @@ static void keepalive_watchdog_fired_locked(void* arg, grpc_error* error) { if (error == GRPC_ERROR_NONE) { t->keepalive_state = GRPC_CHTTP2_KEEPALIVE_STATE_DYING; close_transport_locked( - t, - grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "keepalive watchdog timeout"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL)); + t, grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "keepalive watchdog timeout"), + GRPC_ERROR_INT_GRPC_STATUS, + GRPC_STATUS_UNAVAILABLE)); } } else { /* The watchdog timer should have been cancelled by From bb872692b7c0acb6263842f6e6e9549f5642aa09 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 2 Oct 2018 14:41:20 -0700 Subject: [PATCH 512/546] Make changes to doc --- doc/statuscodes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/statuscodes.md b/doc/statuscodes.md index 06fbe5c8fe8..547da054951 100644 --- a/doc/statuscodes.md +++ b/doc/statuscodes.md @@ -38,7 +38,7 @@ situations in which they are generated. | Error parsing response proto | INTERNAL | Client| | Error parsing request proto | INTERNAL | Server| | Sent or received message was larger than configured limit | RESOURCE_EXHAUSTED | Both | -| Keepalive watchdog times out | INTERNAL | Both | +| Keepalive watchdog times out | UNAVAILABLE | Both | The following status codes are never generated by the library: - INVALID_ARGUMENT From a64cb54de152017d6c3c968ec9c22a98c405a8ba Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 2 Oct 2018 17:33:07 -0700 Subject: [PATCH 513/546] Channel trace is limited by memory --- include/grpc/impl/codegen/grpc_types.h | 8 +- .../ext/filters/client_channel/subchannel.cc | 8 +- src/core/lib/channel/channel_trace.cc | 40 ++-- src/core/lib/channel/channel_trace.h | 9 +- src/core/lib/slice/slice.cc | 8 + src/core/lib/slice/slice_internal.h | 5 + src/core/lib/surface/channel.cc | 10 +- src/core/lib/surface/server.cc | 8 +- test/core/channel/channel_trace_test.cc | 178 +++++++++++++----- test/core/channel/channelz_test.cc | 16 +- test/core/end2end/tests/channelz.cc | 5 +- test/cpp/end2end/channelz_service_test.cc | 6 +- 12 files changed, 207 insertions(+), 94 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 9ed5b3c1d4b..672f130babd 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -285,9 +285,11 @@ typedef struct { #define GRPC_ARG_SOCKET_MUTATOR "grpc.socket_mutator" /** The grpc_socket_factory instance to create and bind sockets. A pointer. */ #define GRPC_ARG_SOCKET_FACTORY "grpc.socket_factory" -/** The maximum number of trace events to keep in the tracer for each channel or - * subchannel. The default is 10. If set to 0, channel tracing is disabled. */ -#define GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE \ +/** The maximum ammount of memory that the trace event can use per channel + * trace node. Once the maximum is reached, subsequent events will evict the + * oldest events from the buffer. The unit for this knob is bytes. Setting + * it to zero causes channel tracing to be disabled. */ +#define GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE \ "grpc.max_channel_trace_events_per_node" /** If non-zero, gRPC library will track stats and information at at per channel * level. Disabling channelz naturally disables channel tracing. The default diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 2847f4bdc18..53954ea2d0b 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -389,15 +389,15 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, const grpc_arg* arg = grpc_channel_args_find(c->args, GRPC_ARG_ENABLE_CHANNELZ); bool channelz_enabled = grpc_channel_arg_get_bool(arg, false); - arg = grpc_channel_args_find(c->args, - GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); + arg = grpc_channel_args_find( + c->args, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); const grpc_integer_options options = {0, 0, INT_MAX}; - size_t channel_tracer_max_nodes = + size_t channel_tracer_max_memory = (size_t)grpc_channel_arg_get_integer(arg, options); if (channelz_enabled) { c->channelz_subchannel = grpc_core::MakeRefCounted( - c, channel_tracer_max_nodes); + c, channel_tracer_max_memory); c->channelz_subchannel->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Subchannel created")); diff --git a/src/core/lib/channel/channel_trace.cc b/src/core/lib/channel/channel_trace.cc index cfb2faba517..3227fe53a12 100644 --- a/src/core/lib/channel/channel_trace.cc +++ b/src/core/lib/channel/channel_trace.cc @@ -48,31 +48,37 @@ ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data, timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(), GPR_CLOCK_REALTIME)), next_(nullptr), - referenced_entity_(std::move(referenced_entity)) {} + referenced_entity_(std::move(referenced_entity)) { + memory_usage_ = sizeof(TraceEvent) + grpc_slice_memory_usage(data); +} ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data) : severity_(severity), data_(data), timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(), GPR_CLOCK_REALTIME)), - next_(nullptr) {} + next_(nullptr) { + memory_usage_ = sizeof(TraceEvent) + grpc_slice_memory_usage(data); +} ChannelTrace::TraceEvent::~TraceEvent() { grpc_slice_unref_internal(data_); } -ChannelTrace::ChannelTrace(size_t max_events) +ChannelTrace::ChannelTrace(size_t max_event_memory) : num_events_logged_(0), - list_size_(0), - max_list_size_(max_events), + event_list_memory_usage_(0), + max_event_memory_(max_event_memory), head_trace_(nullptr), tail_trace_(nullptr) { - if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0 + if (max_event_memory_ == 0) + return; // tracing is disabled if max_event_memory_ == 0 gpr_mu_init(&tracer_mu_); time_created_ = grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(), GPR_CLOCK_REALTIME); } ChannelTrace::~ChannelTrace() { - if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0 + if (max_event_memory_ == 0) + return; // tracing is disabled if max_event_memory_ == 0 TraceEvent* it = head_trace_; while (it != nullptr) { TraceEvent* to_free = it; @@ -93,25 +99,27 @@ void ChannelTrace::AddTraceEventHelper(TraceEvent* new_trace_event) { tail_trace_->set_next(new_trace_event); tail_trace_ = tail_trace_->next(); } - ++list_size_; - // maybe garbage collect the end - if (list_size_ > max_list_size_) { + event_list_memory_usage_ += new_trace_event->memory_usage(); + // maybe garbage collect the tail until we are under the memory limit. + while (event_list_memory_usage_ > max_event_memory_) { TraceEvent* to_free = head_trace_; + event_list_memory_usage_ -= to_free->memory_usage(); head_trace_ = head_trace_->next(); Delete(to_free); - --list_size_; } } void ChannelTrace::AddTraceEvent(Severity severity, grpc_slice data) { - if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0 + if (max_event_memory_ == 0) + return; // tracing is disabled if max_event_memory_ == 0 AddTraceEventHelper(New(severity, data)); } void ChannelTrace::AddTraceEventWithReference( Severity severity, grpc_slice data, RefCountedPtr referenced_entity) { - if (max_list_size_ == 0) return; // tracing is disabled if max_events == 0 + if (max_event_memory_ == 0) + return; // tracing is disabled if max_event_memory_ == 0 // create and fill up the new event AddTraceEventHelper( New(severity, data, std::move(referenced_entity))); @@ -162,8 +170,8 @@ void ChannelTrace::TraceEvent::RenderTraceEvent(grpc_json* json) const { } grpc_json* ChannelTrace::RenderJson() const { - if (!max_list_size_) - return nullptr; // tracing is disabled if max_events == 0 + if (max_event_memory_ == 0) + return nullptr; // tracing is disabled if max_event_memory_ == 0 grpc_json* json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json_iterator = nullptr; if (num_events_logged_ > 0) { @@ -174,7 +182,7 @@ grpc_json* ChannelTrace::RenderJson() const { json_iterator, json, "creationTimestamp", gpr_format_timespec(time_created_), GRPC_JSON_STRING, true); // only add in the event list if it is non-empty. - if (num_events_logged_ > 0) { + if (head_trace_ != nullptr) { grpc_json* events = grpc_json_create_child(json_iterator, json, "events", nullptr, GRPC_JSON_ARRAY, false); json_iterator = nullptr; diff --git a/src/core/lib/channel/channel_trace.h b/src/core/lib/channel/channel_trace.h index 94fea20b451..0e9ce5f6488 100644 --- a/src/core/lib/channel/channel_trace.h +++ b/src/core/lib/channel/channel_trace.h @@ -37,7 +37,7 @@ class BaseNode; // https://github.com/grpc/proposal/blob/master/A14-channelz.md class ChannelTrace { public: - ChannelTrace(size_t max_events); + ChannelTrace(size_t max_event_memory); ~ChannelTrace(); enum Severity { @@ -92,6 +92,8 @@ class ChannelTrace { TraceEvent* next() const { return next_; } void set_next(TraceEvent* next) { next_ = next; } + size_t memory_usage() { return memory_usage_; } + private: Severity severity_; grpc_slice data_; @@ -99,6 +101,7 @@ class ChannelTrace { TraceEvent* next_; // the tracer object for the (sub)channel that this trace event refers to. RefCountedPtr referenced_entity_; + size_t memory_usage_; }; // TraceEvent // Internal helper to add and link in a trace event @@ -106,8 +109,8 @@ class ChannelTrace { gpr_mu tracer_mu_; uint64_t num_events_logged_; - size_t list_size_; - size_t max_list_size_; + size_t event_list_memory_usage_; + size_t max_event_memory_; TraceEvent* head_trace_; TraceEvent* tail_trace_; gpr_timespec time_created_; diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index 419474129b6..e842d84f11f 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -88,6 +88,14 @@ static const grpc_slice_refcount_vtable noop_refcount_vtable = { static grpc_slice_refcount noop_refcount = {&noop_refcount_vtable, &noop_refcount}; +size_t grpc_slice_memory_usage(grpc_slice s) { + if (s.refcount == nullptr || s.refcount == &noop_refcount) { + return 0; + } else { + return s.data.refcounted.length; + } +} + grpc_slice grpc_slice_from_static_buffer(const void* s, size_t len) { grpc_slice slice; slice.refcount = &noop_refcount; diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index 5d3d26b67b3..5b05951522f 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -46,4 +46,9 @@ grpc_slice grpc_slice_maybe_static_intern(grpc_slice slice, uint32_t grpc_static_slice_hash(grpc_slice s); int grpc_static_slice_eq(grpc_slice a, grpc_slice b); +// Returns the memory used by this slice, not counting the slice structure +// itself. This means that inlined and slices from static strings will return +// 0. All other slices will return the size of the allocated chars. +size_t grpc_slice_memory_usage(grpc_slice s); + #endif /* GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H */ diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index 054fe105c3c..6ca3af1aeda 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -102,7 +102,7 @@ grpc_channel* grpc_channel_create_with_builder( channel->target = target; channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type); - size_t channel_tracer_max_nodes = 0; // default to off + size_t channel_tracer_max_memory = 0; // default to off bool channelz_enabled = false; bool internal_channel = false; // this creates the default ChannelNode. Different types of channels may @@ -141,11 +141,11 @@ grpc_channel* grpc_channel_create_with_builder( static_cast(args->args[i].value.integer) | 0x1; /* always support no compression */ } else if (0 == strcmp(args->args[i].key, - GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE)) { - GPR_ASSERT(channel_tracer_max_nodes == 0); + GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE)) { + GPR_ASSERT(channel_tracer_max_memory == 0); // max_nodes defaults to 0 (which is off), clamped between 0 and INT_MAX const grpc_integer_options options = {0, 0, INT_MAX}; - channel_tracer_max_nodes = + channel_tracer_max_memory = (size_t)grpc_channel_arg_get_integer(&args->args[i], options); } else if (0 == strcmp(args->args[i].key, GRPC_ARG_ENABLE_CHANNELZ)) { // channelz will not be enabled by default until all concerns in @@ -169,7 +169,7 @@ grpc_channel* grpc_channel_create_with_builder( // bookkeeping for server channels occurs in src/core/lib/surface/server.cc if (channelz_enabled && channel->is_client) { channel->channelz_channel = channel_node_create_func( - channel, channel_tracer_max_nodes, !internal_channel); + channel, channel_tracer_max_memory, !internal_channel); channel->channelz_channel->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Channel created")); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 72ddc2648d9..b9e86784f31 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -1009,13 +1009,13 @@ grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) { const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_ENABLE_CHANNELZ); if (grpc_channel_arg_get_bool(arg, false)) { - arg = grpc_channel_args_find(args, - GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); - size_t trace_events_per_node = + arg = grpc_channel_args_find( + args, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); + size_t channel_tracer_max_memory = grpc_channel_arg_get_integer(arg, {0, 0, INT_MAX}); server->channelz_server = grpc_core::MakeRefCounted( - trace_events_per_node); + channel_tracer_max_memory); server->channelz_server->AddTraceEvent( grpc_core::channelz::ChannelTrace::Severity::Info, grpc_slice_from_static_string("Server created")); diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index d594445bfb9..8385475e7dd 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -65,6 +65,11 @@ grpc_json* GetJsonChild(grpc_json* parent, const char* key) { void ValidateJsonArraySize(grpc_json* json, const char* key, size_t expected_size) { grpc_json* arr = GetJsonChild(json, key); + // the events array should not be present if there are no events. + if (expected_size == 0) { + EXPECT_EQ(arr, nullptr); + return; + } ASSERT_NE(arr, nullptr); ASSERT_EQ(arr->type, GRPC_JSON_ARRAY); size_t count = 0; @@ -94,29 +99,31 @@ void AddSimpleTrace(ChannelTrace* tracer) { } // checks for the existence of all the required members of the tracer. -void ValidateChannelTrace(ChannelTrace* tracer, - size_t expected_num_event_logged, size_t max_nodes) { - if (!max_nodes) return; +void ValidateChannelTraceCustom(ChannelTrace* tracer, size_t num_events_logged, + size_t num_events_expected) { grpc_json* json = tracer->RenderJson(); EXPECT_NE(json, nullptr); char* json_str = grpc_json_dump_to_string(json, 0); grpc_json_destroy(json); grpc::testing::ValidateChannelTraceProtoJsonTranslation(json_str); grpc_json* parsed_json = grpc_json_parse_string(json_str); - ValidateChannelTraceData(parsed_json, expected_num_event_logged, - GPR_MIN(expected_num_event_logged, max_nodes)); + ValidateChannelTraceData(parsed_json, num_events_logged, num_events_expected); grpc_json_destroy(parsed_json); gpr_free(json_str); } +void ValidateChannelTrace(ChannelTrace* tracer, size_t num_events_logged) { + ValidateChannelTraceCustom(tracer, num_events_logged, num_events_logged); +} + class ChannelFixture { public: - ChannelFixture(int max_trace_nodes) { + ChannelFixture(int max_tracer_event_memory) { grpc_arg client_a; client_a.type = GRPC_ARG_INTEGER; client_a.key = - const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); - client_a.value.integer = max_trace_nodes; + const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); + client_a.value.integer = max_tracer_event_memory; grpc_channel_args client_args = {1, &client_a}; channel_ = grpc_insecure_channel_create("fake_target", &client_args, nullptr); @@ -132,67 +139,67 @@ class ChannelFixture { } // anonymous namespace -class ChannelTracerTest : public ::testing::TestWithParam {}; +const int kEventListMemoryLimit = 1024 * 1024; // Tests basic ChannelTrace functionality like construction, adding trace, and // lookups by uuid. -TEST_P(ChannelTracerTest, BasicTest) { +TEST(ChannelTracerTest, BasicTest) { grpc_core::ExecCtx exec_ctx; - ChannelTrace tracer(GetParam()); + ChannelTrace tracer(kEventListMemoryLimit); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); tracer.AddTraceEvent(ChannelTrace::Severity::Info, grpc_slice_from_static_string("trace three")); tracer.AddTraceEvent(ChannelTrace::Severity::Error, grpc_slice_from_static_string("trace four error")); - ValidateChannelTrace(&tracer, 4, GetParam()); + ValidateChannelTrace(&tracer, 4); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); - ValidateChannelTrace(&tracer, 6, GetParam()); + ValidateChannelTrace(&tracer, 6); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); - ValidateChannelTrace(&tracer, 10, GetParam()); + ValidateChannelTrace(&tracer, 10); } // Tests more complex functionality, like a parent channel tracking // subchannles. This exercises the ref/unref patterns since the parent tracer // and this function will both hold refs to the subchannel. -TEST_P(ChannelTracerTest, ComplexTest) { +TEST(ChannelTracerTest, ComplexTest) { grpc_core::ExecCtx exec_ctx; - ChannelTrace tracer(GetParam()); + ChannelTrace tracer(kEventListMemoryLimit); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); - ChannelFixture channel1(GetParam()); - RefCountedPtr sc1 = - MakeRefCounted(channel1.channel(), GetParam(), true); + ChannelFixture channel1(kEventListMemoryLimit); + RefCountedPtr sc1 = MakeRefCounted( + channel1.channel(), kEventListMemoryLimit, true); ChannelNodePeer sc1_peer(sc1.get()); tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel one created"), sc1); - ValidateChannelTrace(&tracer, 3, GetParam()); + ValidateChannelTrace(&tracer, 3); AddSimpleTrace(sc1_peer.trace()); AddSimpleTrace(sc1_peer.trace()); AddSimpleTrace(sc1_peer.trace()); - ValidateChannelTrace(sc1_peer.trace(), 3, GetParam()); + ValidateChannelTrace(sc1_peer.trace(), 3); AddSimpleTrace(sc1_peer.trace()); AddSimpleTrace(sc1_peer.trace()); AddSimpleTrace(sc1_peer.trace()); - ValidateChannelTrace(sc1_peer.trace(), 6, GetParam()); + ValidateChannelTrace(sc1_peer.trace(), 6); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); - ValidateChannelTrace(&tracer, 5, GetParam()); - ChannelFixture channel2(GetParam()); - RefCountedPtr sc2 = - MakeRefCounted(channel2.channel(), GetParam(), true); + ValidateChannelTrace(&tracer, 5); + ChannelFixture channel2(kEventListMemoryLimit); + RefCountedPtr sc2 = MakeRefCounted( + channel2.channel(), kEventListMemoryLimit, true); tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("LB channel two created"), sc2); tracer.AddTraceEventWithReference( ChannelTrace::Severity::Warning, grpc_slice_from_static_string("subchannel one inactive"), sc1); - ValidateChannelTrace(&tracer, 7, GetParam()); + ValidateChannelTrace(&tracer, 7); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); @@ -206,38 +213,38 @@ TEST_P(ChannelTracerTest, ComplexTest) { // Test a case in which the parent channel has subchannels and the subchannels // have connections. Ensures that everything lives as long as it should then // gets deleted. -TEST_P(ChannelTracerTest, TestNesting) { +TEST(ChannelTracerTest, TestNesting) { grpc_core::ExecCtx exec_ctx; - ChannelTrace tracer(GetParam()); + ChannelTrace tracer(kEventListMemoryLimit); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); - ValidateChannelTrace(&tracer, 2, GetParam()); - ChannelFixture channel1(GetParam()); - RefCountedPtr sc1 = - MakeRefCounted(channel1.channel(), GetParam(), true); + ValidateChannelTrace(&tracer, 2); + ChannelFixture channel1(kEventListMemoryLimit); + RefCountedPtr sc1 = MakeRefCounted( + channel1.channel(), kEventListMemoryLimit, true); ChannelNodePeer sc1_peer(sc1.get()); tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel one created"), sc1); - ValidateChannelTrace(&tracer, 3, GetParam()); + ValidateChannelTrace(&tracer, 3); AddSimpleTrace(sc1_peer.trace()); - ChannelFixture channel2(GetParam()); - RefCountedPtr conn1 = - MakeRefCounted(channel2.channel(), GetParam(), true); + ChannelFixture channel2(kEventListMemoryLimit); + RefCountedPtr conn1 = MakeRefCounted( + channel2.channel(), kEventListMemoryLimit, true); ChannelNodePeer conn1_peer(conn1.get()); // nesting one level deeper. sc1_peer.trace()->AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("connection one created"), conn1); - ValidateChannelTrace(&tracer, 3, GetParam()); + ValidateChannelTrace(&tracer, 3); AddSimpleTrace(conn1_peer.trace()); AddSimpleTrace(&tracer); AddSimpleTrace(&tracer); - ValidateChannelTrace(&tracer, 5, GetParam()); - ValidateChannelTrace(conn1_peer.trace(), 1, GetParam()); - ChannelFixture channel3(GetParam()); - RefCountedPtr sc2 = - MakeRefCounted(channel3.channel(), GetParam(), true); + ValidateChannelTrace(&tracer, 5); + ValidateChannelTrace(conn1_peer.trace(), 1); + ChannelFixture channel3(kEventListMemoryLimit); + RefCountedPtr sc2 = MakeRefCounted( + channel3.channel(), kEventListMemoryLimit, true); tracer.AddTraceEventWithReference( ChannelTrace::Severity::Info, grpc_slice_from_static_string("subchannel two created"), sc2); @@ -247,14 +254,93 @@ TEST_P(ChannelTracerTest, TestNesting) { ChannelTrace::Severity::Warning, grpc_slice_from_static_string("subchannel one inactive"), sc1); AddSimpleTrace(&tracer); - ValidateChannelTrace(&tracer, 8, GetParam()); + ValidateChannelTrace(&tracer, 8); sc1.reset(); sc2.reset(); conn1.reset(); } -INSTANTIATE_TEST_CASE_P(ChannelTracerTestSweep, ChannelTracerTest, - ::testing::Values(0, 1, 2, 6, 10, 15)); +TEST(ChannelTracerTest, TestSmallMemoryLimit) { + grpc_core::ExecCtx exec_ctx; + // doesn't make sense, but serves a testing purpose for the channel tracing + // bookkeeping. All tracing events added should will get immediately garbage + // collected. + const int kSmallMemoryLimit = 1; + ChannelTrace tracer(kSmallMemoryLimit); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + tracer.AddTraceEvent(ChannelTrace::Severity::Info, + grpc_slice_from_static_string("trace three")); + tracer.AddTraceEvent(ChannelTrace::Severity::Error, + grpc_slice_from_static_string("trace four error")); + ValidateChannelTraceCustom(&tracer, 4, 0); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + ValidateChannelTraceCustom(&tracer, 6, 0); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + AddSimpleTrace(&tracer); + ValidateChannelTraceCustom(&tracer, 10, 0); +} + +TEST(ChannelTracerTest, TestEviction) { + grpc_core::ExecCtx exec_ctx; + // This depends on sizeof(ChannelTrace). If that struct has been updated, + // this will too. + const int kTraceEventSize = 80; + const int kNumEvents = 5; + ChannelTrace tracer(kTraceEventSize * kNumEvents); + for (int i = 1; i <= kNumEvents; ++i) { + AddSimpleTrace(&tracer); + ValidateChannelTrace(&tracer, i); + } + // at this point the list is full, and each subsequent enntry will cause an + // eviction. + for (int i = 1; i <= kNumEvents; ++i) { + AddSimpleTrace(&tracer); + ValidateChannelTraceCustom(&tracer, kNumEvents + i, kNumEvents); + } +} + +TEST(ChannelTracerTest, TestMultipleEviction) { + grpc_core::ExecCtx exec_ctx; + // This depends on sizeof(ChannelTrace). If that struct has been updated, + // this will too. + const int kTraceEventSize = 80; + const int kNumEvents = 5; + ChannelTrace tracer(kTraceEventSize * kNumEvents); + for (int i = 1; i <= kNumEvents; ++i) { + AddSimpleTrace(&tracer); + ValidateChannelTrace(&tracer, i); + } + // at this point the list is full, and each subsequent enntry will cause an + // eviction. We will now add in a trace event that has a copied string. This + // uses more memory, so it will cause a double eviciction + tracer.AddTraceEvent( + ChannelTrace::Severity::Info, + grpc_slice_from_copied_string( + "long enough string to trigger a multiple eviction")); + ValidateChannelTraceCustom(&tracer, kNumEvents + 1, kNumEvents - 1); +} + +TEST(ChannelTracerTest, TestTotalEviction) { + grpc_core::ExecCtx exec_ctx; + // This depends on sizeof(ChannelTrace). If that struct has been updated, + // this will too. + const int kTraceEventSize = 80; + const int kNumEvents = 5; + ChannelTrace tracer(kTraceEventSize * kNumEvents); + for (int i = 1; i <= kNumEvents; ++i) { + AddSimpleTrace(&tracer); + ValidateChannelTrace(&tracer, i); + } + // at this point the list is full. Now we add such a big slice that + // everything gets evicted. + grpc_slice huge_slice = grpc_slice_malloc(kTraceEventSize * (kNumEvents + 1)); + tracer.AddTraceEvent(ChannelTrace::Severity::Info, huge_slice); + ValidateChannelTraceCustom(&tracer, kNumEvents + 1, 0); +} } // namespace testing } // namespace channelz diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index bcda30d9f29..745a2bff09d 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -124,11 +124,11 @@ void ValidateGetServers(size_t expected_servers) { class ChannelFixture { public: - ChannelFixture(int max_trace_nodes = 0) { + ChannelFixture(int max_tracer_event_memory = 0) { grpc_arg client_a[2]; client_a[0] = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE), - max_trace_nodes); + const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE), + max_tracer_event_memory); client_a[1] = grpc_channel_arg_integer_create( const_cast(GRPC_ARG_ENABLE_CHANNELZ), true); grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a}; @@ -146,11 +146,11 @@ class ChannelFixture { class ServerFixture { public: - explicit ServerFixture(int max_trace_nodes = 0) { + explicit ServerFixture(int max_tracer_event_memory = 0) { grpc_arg server_a[] = { grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE), - max_trace_nodes), + const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE), + max_tracer_event_memory), grpc_channel_arg_integer_create( const_cast(GRPC_ARG_ENABLE_CHANNELZ), true), }; @@ -360,10 +360,10 @@ TEST(ChannelzGetServersTest, ManyServersTest) { } INSTANTIATE_TEST_CASE_P(ChannelzChannelTestSweep, ChannelzChannelTest, - ::testing::Values(0, 1, 2, 6, 10, 15)); + ::testing::Values(0, 8, 64, 1024, 1024 * 1024)); INSTANTIATE_TEST_CASE_P(ChannelzServerTestSweep, ChannelzServerTest, - ::testing::Values(0, 1, 2, 6, 10, 15)); + ::testing::Values(0, 8, 64, 1024, 1024 * 1024)); } // namespace testing } // namespace channelz diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 40a0370f0ea..58ffdc18daf 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -267,8 +267,9 @@ static void test_channelz_with_channel_trace(grpc_end2end_test_config config) { grpc_arg arg[2]; arg[0].type = GRPC_ARG_INTEGER; - arg[0].key = const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); - arg[0].value.integer = 5; + arg[0].key = + const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); + arg[0].value.integer = 1024; arg[1].type = GRPC_ARG_INTEGER; arg[1].key = const_cast(GRPC_ARG_ENABLE_CHANNELZ); arg[1].value.integer = true; diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index a597fd9c4b4..df9e23d50cb 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -115,8 +115,8 @@ class ChannelzServerTest : public ::testing::Test { InsecureServerCredentials()); // forces channelz and channel tracing to be enabled. proxy_builder.AddChannelArgument(GRPC_ARG_ENABLE_CHANNELZ, 1); - proxy_builder.AddChannelArgument(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE, - 10); + proxy_builder.AddChannelArgument( + GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 1024); proxy_builder.RegisterService(&proxy_service_); proxy_server_ = proxy_builder.BuildAndStart(); } @@ -142,7 +142,7 @@ class ChannelzServerTest : public ::testing::Test { // are the ones that our test will actually be validating. ChannelArguments args; args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 1); - args.SetInt(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE, 10); + args.SetInt(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 1024); std::shared_ptr channel_to_backend = CreateCustomChannel( backend_server_address, InsecureChannelCredentials(), args); proxy_service_.AddChannelToBackend(channel_to_backend); From f9061852007cdef4b5e71dbe8f0b7ccc0874d3f9 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 2 Oct 2018 16:00:53 -0700 Subject: [PATCH 514/546] Shard channelz stats by CPU --- src/core/lib/channel/channelz.cc | 73 ++++++++++++++++++++++++------ src/core/lib/channel/channelz.h | 24 ++++++---- src/core/lib/iomgr/exec_ctx.h | 7 --- test/core/channel/channelz_test.cc | 3 +- 4 files changed, 74 insertions(+), 33 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 339c827525c..e9c29489a2d 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -34,6 +34,7 @@ #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/memory.h" #include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/transport/error_utils.h" @@ -55,35 +56,77 @@ char* BaseNode::RenderJsonString() { } CallCountingHelper::CallCountingHelper() { - gpr_atm_no_barrier_store(&last_call_started_millis_, - (gpr_atm)ExecCtx::Get()->Now()); + num_cores_ = GPR_MAX(1, gpr_cpu_num_cores()); + per_cpu_counter_data_storage_ = + static_cast(gpr_zalloc(sizeof(CounterData) * num_cores_)); } -CallCountingHelper::~CallCountingHelper() {} +CallCountingHelper::~CallCountingHelper() { + gpr_free(per_cpu_counter_data_storage_); +} void CallCountingHelper::RecordCallStarted() { - gpr_atm_no_barrier_fetch_add(&calls_started_, static_cast(1)); - gpr_atm_no_barrier_store(&last_call_started_millis_, - (gpr_atm)ExecCtx::Get()->Now()); + gpr_atm_no_barrier_fetch_add( + &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()] + .calls_started_, + static_cast(1)); + gpr_atm_no_barrier_store( + &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()] + .last_call_started_millis_, + (gpr_atm)ExecCtx::Get()->Now()); +} + +void CallCountingHelper::RecordCallFailed() { + gpr_atm_no_barrier_fetch_add( + &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()] + .calls_failed_, + static_cast(1)); +} + +void CallCountingHelper::RecordCallSucceeded() { + gpr_atm_no_barrier_fetch_add( + &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()] + .calls_succeeded_, + static_cast(1)); +} + +CallCountingHelper::CounterData CallCountingHelper::Collect() { + CounterData out; + memset(&out, 0, sizeof(out)); + for (size_t core = 0; core < num_cores_; ++core) { + out.calls_started_ += gpr_atm_no_barrier_load( + &per_cpu_counter_data_storage_[core].calls_started_); + out.calls_succeeded_ += gpr_atm_no_barrier_load( + &per_cpu_counter_data_storage_[core].calls_succeeded_); + out.calls_failed_ += gpr_atm_no_barrier_load( + &per_cpu_counter_data_storage_[core].calls_failed_); + gpr_atm last_call = gpr_atm_no_barrier_load( + &per_cpu_counter_data_storage_[core].last_call_started_millis_); + if (last_call > out.last_call_started_millis_) { + out.last_call_started_millis_ = last_call; + } + } + return out; } void CallCountingHelper::PopulateCallCounts(grpc_json* json) { grpc_json* json_iterator = nullptr; - if (calls_started_ != 0) { + CounterData data = Collect(); + if (data.calls_started_ != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "callsStarted", calls_started_); + json, json_iterator, "callsStarted", data.calls_started_); } - if (calls_succeeded_ != 0) { + if (data.calls_succeeded_ != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "callsSucceeded", calls_succeeded_); + json, json_iterator, "callsSucceeded", data.calls_succeeded_); } - if (calls_failed_) { + if (data.calls_failed_) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "callsFailed", calls_failed_); + json, json_iterator, "callsFailed", data.calls_failed_); } - if (calls_started_ != 0) { - gpr_timespec ts = - grpc_millis_to_timespec(last_call_started_millis_, GPR_CLOCK_REALTIME); + if (data.calls_started_ != 0) { + gpr_timespec ts = grpc_millis_to_timespec(data.last_call_started_millis_, + GPR_CLOCK_REALTIME); json_iterator = grpc_json_create_child(json_iterator, json, "lastCallStartedTimestamp", gpr_format_timespec(ts), GRPC_JSON_STRING, true); diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index b7ae1012389..ee2ca40a202 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -91,12 +91,8 @@ class CallCountingHelper { ~CallCountingHelper(); void RecordCallStarted(); - void RecordCallFailed() { - gpr_atm_no_barrier_fetch_add(&calls_failed_, static_cast(1)); - } - void RecordCallSucceeded() { - gpr_atm_no_barrier_fetch_add(&calls_succeeded_, static_cast(1)); - } + void RecordCallFailed(); + void RecordCallSucceeded(); // Common rendering of the call count data and last_call_started_timestamp. void PopulateCallCounts(grpc_json* json); @@ -105,10 +101,18 @@ class CallCountingHelper { // testing peer friend. friend class testing::CallCountingHelperPeer; - gpr_atm calls_started_ = 0; - gpr_atm calls_succeeded_ = 0; - gpr_atm calls_failed_ = 0; - gpr_atm last_call_started_millis_ = 0; + struct CounterData { + gpr_atm calls_started_ = 0; + gpr_atm calls_succeeded_ = 0; + gpr_atm calls_failed_ = 0; + gpr_atm last_call_started_millis_ = 0; + }; + + // collects the sharded data into one CounterData struct. + CounterData Collect(); + + CounterData* per_cpu_counter_data_storage_ = nullptr; + size_t num_cores_ = 0; }; // Handles channelz bookkeeping for channels diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index f3528d527ac..e90eb54cd35 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -116,12 +116,7 @@ class ExecCtx { ExecCtx(const ExecCtx&) = delete; ExecCtx& operator=(const ExecCtx&) = delete; - /** Return starting_cpu. This is only required for stats collection and is - * hence only defined if GRPC_COLLECT_STATS is enabled. - */ -#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) unsigned starting_cpu() const { return starting_cpu_; } -#endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */ struct CombinerData { /* currently active combiner: updated only via combiner.c */ @@ -223,9 +218,7 @@ class ExecCtx { CombinerData combiner_data_ = {nullptr, nullptr}; uintptr_t flags_; -#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) unsigned starting_cpu_ = gpr_cpu_current_cpu(); -#endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */ bool now_is_valid_ = false; grpc_millis now_ = 0; diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index bcda30d9f29..b7b35aede4e 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -49,8 +49,9 @@ class CallCountingHelperPeer { public: explicit CallCountingHelperPeer(CallCountingHelper* node) : node_(node) {} grpc_millis last_call_started_millis() const { + CallCountingHelper::CounterData data = node_->Collect(); return (grpc_millis)gpr_atm_no_barrier_load( - &node_->last_call_started_millis_); + &data.last_call_started_millis_); } private: From 668a16327b28285bc13864de13ed43f38e1fe7a8 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Tue, 2 Oct 2018 18:25:31 -0700 Subject: [PATCH 515/546] Fix the unknown argument issue in resolve_address_test.cc --- test/core/iomgr/resolve_address_test.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index 52e4840c7c6..7c9d8e8913e 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -251,7 +251,10 @@ int main(int argc, char** argv) { gpr_cmdline* cl = gpr_cmdline_create("resolve address test"); gpr_cmdline_add_string(cl, "resolver", "Resolver type (ares or native)", &resolver_type); - gpr_cmdline_parse(cl, argc, argv); + // In case that there are more than one argument on the command line, + // --resolver will always be the first one, so only parse the first argument + // (other arguments may be unknown to cl) + gpr_cmdline_parse(cl, 2, argv); const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER"); if (cur_resolver != nullptr && strlen(cur_resolver) != 0) { gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s", From ffb78c6b2350fbe3cb8c277f8d093eb3eac2fa6f Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 2 Oct 2018 18:41:41 -0700 Subject: [PATCH 516/546] Polish macro again --- src/core/lib/gpr/sync_posix.cc | 4 ---- src/core/lib/iomgr/timer_manager.cc | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 012d85d78c6..69bd6094850 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -27,10 +27,6 @@ #include #include "src/core/lib/profiling/timers.h" -// For debug of the timer manager crash only. -#ifndef kGMS_BuildConfig_EnableGRPC -#define kGMS_BuildConfig_EnableGRPC() GRPC_DEBUG_TIMER_MANAGER -#endif // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index e2e25ff188a..eaba05a5ceb 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -61,10 +61,6 @@ static uint64_t g_timed_waiter_generation; static void timer_thread(void* completed_thread_ptr); -// For debug of the timer manager crash only. -#ifndef kGMS_BuildConfig_EnableGRPC -#define kGMS_BuildConfig_EnableGRPC() GRPC_DEBUG_TIMER_MANAGER -#endif // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER From c0fa62f2b6248e450a15b3e1f24e6dd5b6a28e91 Mon Sep 17 00:00:00 2001 From: Yihua Zhang Date: Tue, 2 Oct 2018 19:21:32 -0700 Subject: [PATCH 517/546] pass a pollset_set to ALTS TSI handshaker --- .../client_channel/http_connect_handshaker.cc | 1 + .../ext/transport/chttp2/client/chttp2_connector.cc | 2 +- .../ext/transport/chttp2/server/chttp2_server.cc | 8 ++++++++ src/core/lib/channel/handshaker_factory.cc | 5 +++-- src/core/lib/channel/handshaker_factory.h | 2 ++ src/core/lib/channel/handshaker_registry.cc | 8 ++++++-- src/core/lib/channel/handshaker_registry.h | 1 + src/core/lib/http/httpcli_security_connector.cc | 3 ++- .../security_connector/alts_security_connector.cc | 12 ++++++------ .../security_connector/security_connector.cc | 7 +++++++ .../security/security_connector/security_connector.h | 5 +++++ .../lib/security/transport/security_handshaker.cc | 10 ++++++++++ src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc | 3 ++- src/core/tsi/alts/handshaker/alts_tsi_handshaker.h | 5 ++++- .../handshake/readahead_handshaker_server_ssl.cc | 1 + .../tsi/alts/handshaker/alts_tsi_handshaker_test.cc | 2 +- 16 files changed, 60 insertions(+), 15 deletions(-) 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 7ce8da8c00e..bfabc68c661 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -351,6 +351,7 @@ static grpc_handshaker* grpc_http_connect_handshaker_create() { static void handshaker_factory_add_handshakers( grpc_handshaker_factory* factory, const grpc_channel_args* args, + grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { grpc_handshake_manager_add(handshake_mgr, grpc_http_connect_handshaker_create()); diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index 0ac84032fd4..5229304fa45 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -160,7 +160,7 @@ static void on_handshake_done(void* arg, grpc_error* error) { static void start_handshake_locked(chttp2_connector* c) { c->handshake_mgr = grpc_handshake_manager_create(); grpc_handshakers_add(HANDSHAKER_CLIENT, c->args.channel_args, - c->handshake_mgr); + c->args.interested_parties, c->handshake_mgr); grpc_endpoint_add_to_pollset_set(c->endpoint, c->args.interested_parties); grpc_handshake_manager_do_handshake( c->handshake_mgr, c->args.interested_parties, c->endpoint, diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 3f8a26ae32b..b95baa91914 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -67,6 +67,7 @@ typedef struct { grpc_timer timer; grpc_closure on_timeout; grpc_closure on_receive_settings; + grpc_pollset_set* interested_parties; } server_connection_state; static void server_connection_state_unref( @@ -76,6 +77,9 @@ static void server_connection_state_unref( GRPC_CHTTP2_UNREF_TRANSPORT(connection_state->transport, "receive settings timeout"); } + grpc_pollset_set_del_pollset(connection_state->interested_parties, + connection_state->accepting_pollset); + grpc_pollset_set_destroy(connection_state->interested_parties); gpr_free(connection_state); } } @@ -189,7 +193,11 @@ static void on_accept(void* arg, grpc_endpoint* tcp, connection_state->accepting_pollset = accepting_pollset; connection_state->acceptor = acceptor; connection_state->handshake_mgr = handshake_mgr; + connection_state->interested_parties = grpc_pollset_set_create(); + grpc_pollset_set_add_pollset(connection_state->interested_parties, + connection_state->accepting_pollset); grpc_handshakers_add(HANDSHAKER_SERVER, state->args, + connection_state->interested_parties, connection_state->handshake_mgr); const grpc_arg* timeout_arg = grpc_channel_args_find(state->args, GRPC_ARG_SERVER_HANDSHAKE_TIMEOUT_MS); diff --git a/src/core/lib/channel/handshaker_factory.cc b/src/core/lib/channel/handshaker_factory.cc index 4fd43635b6b..8ade8fe4e23 100644 --- a/src/core/lib/channel/handshaker_factory.cc +++ b/src/core/lib/channel/handshaker_factory.cc @@ -24,11 +24,12 @@ void grpc_handshaker_factory_add_handshakers( grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, + grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { if (handshaker_factory != nullptr) { GPR_ASSERT(handshaker_factory->vtable != nullptr); - handshaker_factory->vtable->add_handshakers(handshaker_factory, args, - handshake_mgr); + handshaker_factory->vtable->add_handshakers( + handshaker_factory, args, interested_parties, handshake_mgr); } } diff --git a/src/core/lib/channel/handshaker_factory.h b/src/core/lib/channel/handshaker_factory.h index 3e45fcf20e6..e17a6781798 100644 --- a/src/core/lib/channel/handshaker_factory.h +++ b/src/core/lib/channel/handshaker_factory.h @@ -32,6 +32,7 @@ typedef struct grpc_handshaker_factory grpc_handshaker_factory; typedef struct { void (*add_handshakers)(grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, + grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr); void (*destroy)(grpc_handshaker_factory* handshaker_factory); } grpc_handshaker_factory_vtable; @@ -42,6 +43,7 @@ struct grpc_handshaker_factory { void grpc_handshaker_factory_add_handshakers( grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, + grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr); void grpc_handshaker_factory_destroy( diff --git a/src/core/lib/channel/handshaker_registry.cc b/src/core/lib/channel/handshaker_registry.cc index eec3e1b352d..fbafc43e795 100644 --- a/src/core/lib/channel/handshaker_registry.cc +++ b/src/core/lib/channel/handshaker_registry.cc @@ -51,9 +51,11 @@ static void grpc_handshaker_factory_list_register( static void grpc_handshaker_factory_list_add_handshakers( grpc_handshaker_factory_list* list, const grpc_channel_args* args, + grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { for (size_t i = 0; i < list->num_factories; ++i) { - grpc_handshaker_factory_add_handshakers(list->list[i], args, handshake_mgr); + grpc_handshaker_factory_add_handshakers(list->list[i], args, + interested_parties, handshake_mgr); } } @@ -91,7 +93,9 @@ void grpc_handshaker_factory_register(bool at_start, void grpc_handshakers_add(grpc_handshaker_type handshaker_type, const grpc_channel_args* args, + grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { grpc_handshaker_factory_list_add_handshakers( - &g_handshaker_factory_lists[handshaker_type], args, handshake_mgr); + &g_handshaker_factory_lists[handshaker_type], args, interested_parties, + handshake_mgr); } diff --git a/src/core/lib/channel/handshaker_registry.h b/src/core/lib/channel/handshaker_registry.h index 82ad9c5b9af..3dd4316de67 100644 --- a/src/core/lib/channel/handshaker_registry.h +++ b/src/core/lib/channel/handshaker_registry.h @@ -43,6 +43,7 @@ void grpc_handshaker_factory_register(bool at_start, void grpc_handshakers_add(grpc_handshaker_type handshaker_type, const grpc_channel_args* args, + grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr); #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H */ diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 50078c37a17..98fb7d39372 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -189,7 +189,8 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host, grpc_arg channel_arg = grpc_security_connector_to_arg(&sc->base); grpc_channel_args args = {1, &channel_arg}; c->handshake_mgr = grpc_handshake_manager_create(); - grpc_handshakers_add(HANDSHAKER_CLIENT, &args, c->handshake_mgr); + grpc_handshakers_add(HANDSHAKER_CLIENT, &args, + nullptr /* interested_parties */, c->handshake_mgr); grpc_handshake_manager_do_handshake( c->handshake_mgr, nullptr /* interested_parties */, tcp, nullptr /* channel_args */, deadline, nullptr /* acceptor */, diff --git a/src/core/lib/security/security_connector/alts_security_connector.cc b/src/core/lib/security/security_connector/alts_security_connector.cc index 35a787871a8..f157c93171a 100644 --- a/src/core/lib/security/security_connector/alts_security_connector.cc +++ b/src/core/lib/security/security_connector/alts_security_connector.cc @@ -70,9 +70,9 @@ static void alts_channel_add_handshakers( auto c = reinterpret_cast(sc); grpc_alts_credentials* creds = reinterpret_cast(c->base.channel_creds); - GPR_ASSERT(alts_tsi_handshaker_create(creds->options, c->target_name, - creds->handshaker_service_url, true, - &handshaker) == TSI_OK); + GPR_ASSERT(alts_tsi_handshaker_create( + creds->options, c->target_name, creds->handshaker_service_url, + true, sc->base.interested_parties, &handshaker) == TSI_OK); grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( handshaker, &sc->base)); } @@ -84,9 +84,9 @@ static void alts_server_add_handshakers( auto c = reinterpret_cast(sc); grpc_alts_server_credentials* creds = reinterpret_cast(c->base.server_creds); - GPR_ASSERT(alts_tsi_handshaker_create(creds->options, nullptr, - creds->handshaker_service_url, false, - &handshaker) == TSI_OK); + GPR_ASSERT(alts_tsi_handshaker_create( + creds->options, nullptr, creds->handshaker_service_url, false, + sc->base.interested_parties, &handshaker) == TSI_OK); grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( handshaker, &sc->base)); } diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 6246613e7b3..f4490582a3f 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -156,6 +156,13 @@ int grpc_security_connector_cmp(grpc_security_connector* sc, return sc->vtable->cmp(sc, other); } +void grpc_security_connector_set_interested_parties( + grpc_security_connector* sc, grpc_pollset_set* interested_parties) { + if (sc != nullptr) { + sc->interested_parties = interested_parties; + } +} + int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1, grpc_channel_security_connector* sc2) { GPR_ASSERT(sc1->channel_creds != nullptr); diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index 67a506b5767..f0172594ad2 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -63,6 +63,7 @@ struct grpc_security_connector { const grpc_security_connector_vtable* vtable; gpr_refcount refcount; const char* url_scheme; + grpc_pollset_set* interested_parties; }; /* Refcounting. */ @@ -106,6 +107,10 @@ grpc_security_connector* grpc_security_connector_from_arg(const grpc_arg* arg); grpc_security_connector* grpc_security_connector_find_in_args( const grpc_channel_args* args); +/* Util to set the interested_parties whose ownership is not transferred. */ +void grpc_security_connector_set_interested_parties( + grpc_security_connector* sc, grpc_pollset_set* interested_parties); + /* --- channel_security_connector object. --- A channel security connector object represents a way to configure the diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index d76d5826388..f3bdf573b3d 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -475,20 +475,30 @@ static grpc_handshaker* fail_handshaker_create() { static void client_handshaker_factory_add_handshakers( grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, + grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { grpc_channel_security_connector* security_connector = reinterpret_cast( grpc_security_connector_find_in_args(args)); + if (security_connector != nullptr) { + grpc_security_connector_set_interested_parties(&security_connector->base, + interested_parties); + } grpc_channel_security_connector_add_handshakers(security_connector, handshake_mgr); } static void server_handshaker_factory_add_handshakers( grpc_handshaker_factory* hf, const grpc_channel_args* args, + grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { grpc_server_security_connector* security_connector = reinterpret_cast( grpc_security_connector_find_in_args(args)); + if (security_connector != nullptr) { + grpc_security_connector_set_interested_parties(&security_connector->base, + interested_parties); + } grpc_server_security_connector_add_handshakers(security_connector, handshake_mgr); } diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc index 34608a3de19..dfdd659b877 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc @@ -347,7 +347,8 @@ static void init_shared_resources(const char* handshaker_service_url) { tsi_result alts_tsi_handshaker_create( const grpc_alts_credentials_options* options, const char* target_name, - const char* handshaker_service_url, bool is_client, tsi_handshaker** self) { + const char* handshaker_service_url, bool is_client, + grpc_pollset_set* interested_parties, tsi_handshaker** self) { if (handshaker_service_url == nullptr || self == nullptr || options == nullptr || (is_client && target_name == nullptr)) { gpr_log(GPR_ERROR, "Invalid arguments to alts_tsi_handshaker_create()"); diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h index 227b30ce537..48ce69b1dac 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h @@ -23,6 +23,7 @@ #include +#include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h" #include "src/core/tsi/alts_transport_security.h" #include "src/core/tsi/transport_security.h" @@ -51,6 +52,7 @@ typedef struct alts_tsi_handshaker alts_tsi_handshaker; * "host:port". * - is_client: boolean value indicating if the handshaker is used at the client * (is_client = true) or server (is_client = false) side. + * - interested_parties: set of pollsets interested in this connection. * - self: address of ALTS TSI handshaker instance to be returned from the * method. * @@ -58,7 +60,8 @@ typedef struct alts_tsi_handshaker alts_tsi_handshaker; */ tsi_result alts_tsi_handshaker_create( const grpc_alts_credentials_options* options, const char* target_name, - const char* handshaker_service_url, bool is_client, tsi_handshaker** self); + const char* handshaker_service_url, bool is_client, + grpc_pollset_set* interested_parties, tsi_handshaker** self); /** * This method handles handshaker response returned from ALTS handshaker diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc index 97e9c20ee4f..14d96b5d89c 100644 --- a/test/core/handshake/readahead_handshaker_server_ssl.cc +++ b/test/core/handshake/readahead_handshaker_server_ssl.cc @@ -75,6 +75,7 @@ static grpc_handshaker* readahead_handshaker_create() { static void readahead_handshaker_factory_add_handshakers( grpc_handshaker_factory* hf, const grpc_channel_args* args, + grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { grpc_handshake_manager_add(handshake_mgr, readahead_handshaker_create()); } diff --git a/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc b/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc index 85a58114ba6..e9eb7e175f4 100644 --- a/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc +++ b/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc @@ -421,7 +421,7 @@ static tsi_handshaker* create_test_handshaker(bool used_for_success_test, alts_mock_handshaker_client_create(used_for_success_test); grpc_alts_credentials_options* options = grpc_alts_credentials_client_options_create(); - alts_tsi_handshaker_create(options, "target_name", "lame", is_client, + alts_tsi_handshaker_create(options, "target_name", "lame", is_client, nullptr, &handshaker); alts_tsi_handshaker* alts_handshaker = reinterpret_cast(handshaker); From e6824674f428362ba8a8011ce34ca5e83abb0fe5 Mon Sep 17 00:00:00 2001 From: Guantao Liu Date: Tue, 2 Oct 2018 18:34:59 -0700 Subject: [PATCH 518/546] Cover the case that there is no command-line argument. --- test/core/iomgr/resolve_address_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc index 7c9d8e8913e..8d69bab5b12 100644 --- a/test/core/iomgr/resolve_address_test.cc +++ b/test/core/iomgr/resolve_address_test.cc @@ -254,7 +254,7 @@ int main(int argc, char** argv) { // In case that there are more than one argument on the command line, // --resolver will always be the first one, so only parse the first argument // (other arguments may be unknown to cl) - gpr_cmdline_parse(cl, 2, argv); + gpr_cmdline_parse(cl, argc > 2 ? 2 : argc, argv); const char* cur_resolver = gpr_getenv("GRPC_DNS_RESOLVER"); if (cur_resolver != nullptr && strlen(cur_resolver) != 0) { gpr_log(GPR_INFO, "Warning: overriding resolver setting of %s", From 00be69755160399756152eed8f1fbbcba8ec115a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 3 Oct 2018 09:29:15 -0700 Subject: [PATCH 519/546] Test changes --- test/core/end2end/tests/keepalive_timeout.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/end2end/tests/keepalive_timeout.cc b/test/core/end2end/tests/keepalive_timeout.cc index 1ee5285027e..5f6a36dac44 100644 --- a/test/core/end2end/tests/keepalive_timeout.cc +++ b/test/core/end2end/tests/keepalive_timeout.cc @@ -195,7 +195,7 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) { char* details_str = grpc_slice_to_c_string(details); char* method_str = grpc_slice_to_c_string(call_details.method); - GPR_ASSERT(status == GRPC_STATUS_INTERNAL); + GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); GPR_ASSERT(0 == grpc_slice_str_cmp(details, "keepalive watchdog timeout")); GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); From aedbddba688a79fedbcf2f823c1e1d4eb4224feb Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Wed, 3 Oct 2018 13:43:02 -0700 Subject: [PATCH 520/546] Clean-up unused variable --- src/core/lib/iomgr/timer_manager.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index eaba05a5ceb..e272d228f81 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -67,7 +67,6 @@ static void timer_thread(void* completed_thread_ptr); extern int64_t g_timer_manager_init_count; extern int64_t g_timer_manager_shutdown_count; extern int64_t g_fork_count; -extern int64_t g_timer_wait_err; #endif // GRPC_DEBUG_TIMER_MANAGER static void gc_completed_threads(void) { From a139b44acc9ef1d3f6b3a033be223b064c8d05a8 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 3 Oct 2018 13:17:56 -0700 Subject: [PATCH 521/546] Clenaer channelz default values --- include/grpc/impl/codegen/grpc_types.h | 10 +++++++++- src/core/ext/filters/client_channel/subchannel.cc | 6 ++++-- .../ext/transport/chttp2/transport/chttp2_transport.cc | 9 +++++++-- src/core/lib/surface/channel.cc | 8 +++++--- src/core/lib/surface/server.cc | 6 +++--- 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 9ed5b3c1d4b..c0e4342bddb 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -286,13 +286,21 @@ typedef struct { /** The grpc_socket_factory instance to create and bind sockets. A pointer. */ #define GRPC_ARG_SOCKET_FACTORY "grpc.socket_factory" /** The maximum number of trace events to keep in the tracer for each channel or - * subchannel. The default is 10. If set to 0, channel tracing is disabled. */ + * subchannel. The default is 0. If set to 0, channel tracing is disabled. */ #define GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE \ "grpc.max_channel_trace_events_per_node" +/** Note this is not a "channel arg" key. This is the default value for number + * of trace events per node. If the above arg is set, it will override this + * default value. */ +#define GRPC_MAX_CHANNEL_TRACE_EVENTS_PER_NODE_DEFAULT 0 /** If non-zero, gRPC library will track stats and information at at per channel * level. Disabling channelz naturally disables channel tracing. The default * is for channelz to be disabled. */ #define GRPC_ARG_ENABLE_CHANNELZ "grpc.enable_channelz" +/** Note this is not a "channel arg" key. This is the default value for whether + * or not to enable channelz. If the above arg is set, it will override this + * default value. */ +#define GRPC_ENABLE_CHANNELZ_DEFAULT false /** If non-zero, Cronet transport will coalesce packets to fewer frames * when possible. */ #define GRPC_ARG_USE_CRONET_PACKET_COALESCING \ diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 2847f4bdc18..088c9d6c009 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -388,10 +388,12 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, const grpc_arg* arg = grpc_channel_args_find(c->args, GRPC_ARG_ENABLE_CHANNELZ); - bool channelz_enabled = grpc_channel_arg_get_bool(arg, false); + bool channelz_enabled = + grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT); arg = grpc_channel_args_find(c->args, GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); - const grpc_integer_options options = {0, 0, INT_MAX}; + const grpc_integer_options options = { + GRPC_MAX_CHANNEL_TRACE_EVENTS_PER_NODE_DEFAULT, 0, INT_MAX}; size_t channel_tracer_max_nodes = (size_t)grpc_channel_arg_get_integer(arg, options); if (channelz_enabled) { diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 776c15138b8..8de418b1132 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -239,6 +239,7 @@ static bool read_channel_args(grpc_chttp2_transport* t, const grpc_channel_args* channel_args, bool is_client) { bool enable_bdp = true; + bool channelz_enabled = GRPC_ENABLE_CHANNELZ_DEFAULT; size_t i; int j; @@ -341,8 +342,8 @@ static bool read_channel_args(grpc_chttp2_transport* t, } } else if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_ENABLE_CHANNELZ)) { - t->channelz_socket = - grpc_core::MakeRefCounted(); + channelz_enabled = grpc_channel_arg_get_bool( + &channel_args->args[i], GRPC_ENABLE_CHANNELZ_DEFAULT); } else { static const struct { const char* channel_arg_name; @@ -393,6 +394,10 @@ static bool read_channel_args(grpc_chttp2_transport* t, } } } + if (channelz_enabled) { + t->channelz_socket = + grpc_core::MakeRefCounted(); + } return enable_bdp; } diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc index 054fe105c3c..4996c3f1776 100644 --- a/src/core/lib/surface/channel.cc +++ b/src/core/lib/surface/channel.cc @@ -103,7 +103,7 @@ grpc_channel* grpc_channel_create_with_builder( channel->target = target; channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type); size_t channel_tracer_max_nodes = 0; // default to off - bool channelz_enabled = false; + bool channelz_enabled = GRPC_ENABLE_CHANNELZ_DEFAULT; bool internal_channel = false; // this creates the default ChannelNode. Different types of channels may // override this to ensure a correct ChannelNode is created. @@ -144,13 +144,15 @@ grpc_channel* grpc_channel_create_with_builder( GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE)) { GPR_ASSERT(channel_tracer_max_nodes == 0); // max_nodes defaults to 0 (which is off), clamped between 0 and INT_MAX - const grpc_integer_options options = {0, 0, INT_MAX}; + const grpc_integer_options options = { + GRPC_MAX_CHANNEL_TRACE_EVENTS_PER_NODE_DEFAULT, 0, INT_MAX}; channel_tracer_max_nodes = (size_t)grpc_channel_arg_get_integer(&args->args[i], options); } else if (0 == strcmp(args->args[i].key, GRPC_ARG_ENABLE_CHANNELZ)) { // channelz will not be enabled by default until all concerns in // https://github.com/grpc/grpc/issues/15986 are addressed. - channelz_enabled = grpc_channel_arg_get_bool(&args->args[i], false); + channelz_enabled = grpc_channel_arg_get_bool( + &args->args[i], GRPC_ENABLE_CHANNELZ_DEFAULT); } else if (0 == strcmp(args->args[i].key, GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC)) { GPR_ASSERT(args->args[i].type == GRPC_ARG_POINTER); diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index 72ddc2648d9..1dd583c3f73 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -1008,11 +1008,11 @@ grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) { server->channel_args = grpc_channel_args_copy(args); const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_ENABLE_CHANNELZ); - if (grpc_channel_arg_get_bool(arg, false)) { + if (grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT)) { arg = grpc_channel_args_find(args, GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE); - size_t trace_events_per_node = - grpc_channel_arg_get_integer(arg, {0, 0, INT_MAX}); + size_t trace_events_per_node = grpc_channel_arg_get_integer( + arg, {GRPC_MAX_CHANNEL_TRACE_EVENTS_PER_NODE_DEFAULT, 0, INT_MAX}); server->channelz_server = grpc_core::MakeRefCounted( trace_events_per_node); From c08c3ccbae87e7e5f040a3045bac520f27ba20fd Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 22 Aug 2018 14:02:13 +0200 Subject: [PATCH 522/546] build grpc_csharp_ext with cmake --- src/csharp/Grpc.Core/NativeDeps.Linux.csproj.include | 2 +- src/csharp/Grpc.Core/NativeDeps.Mac.csproj.include | 2 +- tools/run_tests/helper_scripts/pre_build_csharp.sh | 10 +++++++++- tools/run_tests/run_tests.py | 3 ++- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/csharp/Grpc.Core/NativeDeps.Linux.csproj.include b/src/csharp/Grpc.Core/NativeDeps.Linux.csproj.include index e3bbeb071e7..af660064a41 100644 --- a/src/csharp/Grpc.Core/NativeDeps.Linux.csproj.include +++ b/src/csharp/Grpc.Core/NativeDeps.Linux.csproj.include @@ -1,6 +1,6 @@ - + libgrpc_csharp_ext.x64.so PreserveNewest false diff --git a/src/csharp/Grpc.Core/NativeDeps.Mac.csproj.include b/src/csharp/Grpc.Core/NativeDeps.Mac.csproj.include index 309e33d47ed..570b0cd8b70 100644 --- a/src/csharp/Grpc.Core/NativeDeps.Mac.csproj.include +++ b/src/csharp/Grpc.Core/NativeDeps.Mac.csproj.include @@ -1,6 +1,6 @@ - + libgrpc_csharp_ext.x64.dylib PreserveNewest false diff --git a/tools/run_tests/helper_scripts/pre_build_csharp.sh b/tools/run_tests/helper_scripts/pre_build_csharp.sh index f9f5440a61e..dd4d2e36b27 100755 --- a/tools/run_tests/helper_scripts/pre_build_csharp.sh +++ b/tools/run_tests/helper_scripts/pre_build_csharp.sh @@ -16,6 +16,14 @@ set -ex # cd to gRPC csharp directory -cd "$(dirname "$0")/../../../src/csharp" +cd "$(dirname "$0")/../../.." + +mkdir -p cmake/build +cd cmake/build + +# TODO(jtattermusch): use RelWithDebInfo for release? +cmake -DgRPC_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE="${MSBUILD_CONFIG}" ../.. + +cd ../../src/csharp dotnet restore Grpc.sln diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 3d73f9ec0eb..1c4bff9cde6 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1028,7 +1028,8 @@ class CSharpLanguage(object): if self.platform == 'windows': return 'cmake/build/%s/Makefile' % self._cmake_arch_option else: - return 'Makefile' + # TODO(jtattermusch): arch option needed? + return 'cmake/build/Makefile' def dockerfile_dir(self): return 'tools/dockerfile/test/csharp_%s_%s' % ( From 49af94dafccc7385f92c84ab9f3c64bb03492967 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 22 Aug 2018 16:46:31 +0200 Subject: [PATCH 523/546] add cmake to C# docker images --- templates/tools/dockerfile/csharp_deps.include | 7 +++++++ tools/dockerfile/grpc_artifact_linux_x64/Dockerfile | 7 +++++++ tools/dockerfile/grpc_artifact_linux_x86/Dockerfile | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/templates/tools/dockerfile/csharp_deps.include b/templates/tools/dockerfile/csharp_deps.include index 3a40711e372..7ed00748670 100644 --- a/templates/tools/dockerfile/csharp_deps.include +++ b/templates/tools/dockerfile/csharp_deps.include @@ -15,3 +15,10 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y ${'\\'} && apt-get clean RUN nuget update -self + +#================= +# Use cmake 3.6 from jessie-backports +# needed to build grpc_csharp_ext with cmake + +RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile index 228efef698e..7ec061ebe58 100644 --- a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile @@ -68,6 +68,13 @@ RUN apt-get update && apt-get install -y \ php5 php5-dev php-pear phpunit && apt-get clean +################## +# C# dependencies (needed to build grpc_csharp_ext) + +# Use cmake 3.6 from jessie-backports +RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean + RUN mkdir /var/local/jenkins # Define the default command. diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile index d33e0f83ea1..f81d8e5ba02 100644 --- a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile +++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile @@ -60,6 +60,13 @@ RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc" RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc" +################## +# C# dependencies (needed to build grpc_csharp_ext) + +# Use cmake 3.6 from jessie-backports +RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean + RUN mkdir /var/local/jenkins # Define the default command. From 87cd70fab3b7388f66b0bfd58e2961b4afe512ef Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 22 Aug 2018 16:47:11 +0200 Subject: [PATCH 524/546] regenerate dockerfiles --- .../dockerfile/interoptest/grpc_interop_csharp/Dockerfile | 7 +++++++ .../interoptest/grpc_interop_csharpcoreclr/Dockerfile | 7 +++++++ tools/dockerfile/test/csharp_jessie_x64/Dockerfile | 7 +++++++ tools/dockerfile/test/multilang_jessie_x64/Dockerfile | 7 +++++++ 4 files changed, 28 insertions(+) diff --git a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile index 511e2932d6a..b2216c79d4c 100644 --- a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile @@ -82,6 +82,13 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ RUN nuget update -self +#================= +# Use cmake 3.6 from jessie-backports +# needed to build grpc_csharp_ext with cmake + +RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean + # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext # dotnet-dev-1.0.0-preview2-003131 diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile index 511e2932d6a..b2216c79d4c 100644 --- a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile +++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile @@ -82,6 +82,13 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ RUN nuget update -self +#================= +# Use cmake 3.6 from jessie-backports +# needed to build grpc_csharp_ext with cmake + +RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean + # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext # dotnet-dev-1.0.0-preview2-003131 diff --git a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile index 56bfb899256..578bf427cd3 100644 --- a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/csharp_jessie_x64/Dockerfile @@ -86,6 +86,13 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ RUN nuget update -self +#================= +# Use cmake 3.6 from jessie-backports +# needed to build grpc_csharp_ext with cmake + +RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean + # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext # dotnet-dev-1.0.0-preview2-003131 diff --git a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile index a82e7050fc4..ad719f330ff 100644 --- a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile +++ b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile @@ -71,6 +71,13 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \ RUN nuget update -self +#================= +# Use cmake 3.6 from jessie-backports +# needed to build grpc_csharp_ext with cmake + +RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list +RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean + # Install dotnet SDK based on https://www.microsoft.com/net/core#debian RUN apt-get update && apt-get install -y curl libunwind8 gettext # dotnet-dev-1.0.0-preview2-003131 From 43836ced828362e174fd7ac20c2995312abd2f99 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 22 Aug 2018 17:14:54 +0200 Subject: [PATCH 525/546] cmake: add backwards compatibility mode --- templates/CMakeLists.txt.template | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index aec1624acdb..5fff74f128e 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -88,6 +88,7 @@ option(gRPC_BUILD_TESTS "Build tests" OFF) option(gRPC_BUILD_CODEGEN "Build codegen" ON) option(gRPC_BUILD_CSHARP_EXT "Build C# extensions" ON) + option(gRPC_BACKWARDS_COMPATIBILITY_MODE "Build libraries that are binary compatible across a larger number of OS and libc versions" OFF) set(gRPC_INSTALL_default ON) if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) @@ -164,6 +165,14 @@ set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf") endif() + if(gRPC_BACKWARDS_COMPATIBILITY_MODE) + add_definitions(-DGPR_BACKWARDS_COMPATIBILITY_MODE) + if (_gRPC_PLATFORM_MAC) + # CMAKE_OSX_DEPLOYMENT_TARGET + add_definitions(-mmacosx-version-min=10.7) + endif() + endif() + if (_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC) # C core has C++ source code, but should not depend on libstc++ (for better portability). # We need to use a few tricks to convince cmake to do that. From 05c23458ab66afda7177df474b8ab138a4a548d1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 22 Aug 2018 17:16:18 +0200 Subject: [PATCH 526/546] regenerate CMakeLists.txt --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index dcd7adeebe3..7cf3ae92901 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ set(gRPC_INSTALL_SHAREDIR "share/grpc" CACHE STRING "Installation directory for option(gRPC_BUILD_TESTS "Build tests" OFF) option(gRPC_BUILD_CODEGEN "Build codegen" ON) option(gRPC_BUILD_CSHARP_EXT "Build C# extensions" ON) +option(gRPC_BACKWARDS_COMPATIBILITY_MODE "Build libraries that are binary compatible across a larger number of OS and libc versions" OFF) set(gRPC_INSTALL_default ON) if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) @@ -115,6 +116,14 @@ else() set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf") endif() +if(gRPC_BACKWARDS_COMPATIBILITY_MODE) + add_definitions(-DGPR_BACKWARDS_COMPATIBILITY_MODE) + if (_gRPC_PLATFORM_MAC) + # CMAKE_OSX_DEPLOYMENT_TARGET + add_definitions(-mmacosx-version-min=10.7) + endif() +endif() + if (_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC) # C core has C++ source code, but should not depend on libstc++ (for better portability). # We need to use a few tricks to convince cmake to do that. From 409def0d7394d4582c4f2e9aaa62460feeac39b7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 2 Oct 2018 15:26:44 +0200 Subject: [PATCH 527/546] build C# artifact using cmake --- tools/run_tests/artifacts/artifact_targets.py | 20 +++++-------------- .../artifacts/build_artifact_csharp.sh | 8 +++++++- tools/run_tests/run_tests.py | 12 ++--------- 3 files changed, 14 insertions(+), 26 deletions(-) diff --git a/tools/run_tests/artifacts/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py index bdeb258e1fc..b2e9f4cc9f7 100644 --- a/tools/run_tests/artifacts/artifact_targets.py +++ b/tools/run_tests/artifacts/artifact_targets.py @@ -248,29 +248,19 @@ class CSharpExtArtifact: ], use_workspace=True) else: - environ = { - 'CONFIG': 'opt', - 'EMBED_OPENSSL': 'true', - 'EMBED_ZLIB': 'true', - 'CFLAGS': '-DGPR_BACKWARDS_COMPATIBILITY_MODE', - 'CXXFLAGS': '-DGPR_BACKWARDS_COMPATIBILITY_MODE', - 'LDFLAGS': '' - } if self.platform == 'linux': return create_docker_jobspec( self.name, 'tools/dockerfile/grpc_artifact_linux_%s' % self.arch, - 'tools/run_tests/artifacts/build_artifact_csharp.sh', - environ=environ) + 'tools/run_tests/artifacts/build_artifact_csharp.sh') else: - archflag = _ARCH_FLAG_MAP[self.arch] - environ['CFLAGS'] += ' %s %s' % (archflag, _MACOS_COMPAT_FLAG) - environ['CXXFLAGS'] += ' %s %s' % (archflag, _MACOS_COMPAT_FLAG) - environ['LDFLAGS'] += ' %s' % archflag + cmake_arch_option = '' # x64 is the default architecture + if self.arch == 'x86': + cmake_arch_option = '-DCMAKE_OSX_ARCHITECTURES=i386' return create_jobspec( self.name, ['tools/run_tests/artifacts/build_artifact_csharp.sh'], - environ=environ, + environ={'CMAKE_ARCH_OPTION': cmake_arch_option}, use_workspace=True) def __str__(self): diff --git a/tools/run_tests/artifacts/build_artifact_csharp.sh b/tools/run_tests/artifacts/build_artifact_csharp.sh index d65340261df..6c946d7a220 100755 --- a/tools/run_tests/artifacts/build_artifact_csharp.sh +++ b/tools/run_tests/artifacts/build_artifact_csharp.sh @@ -17,7 +17,13 @@ set -ex cd "$(dirname "$0")/../../.." +mkdir -p cmake/build +cd cmake/build + +# -DgRPC_BACKWARDS_COMPATIBILITY_MODE=ON +cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DgRPC_BUILD_TESTS=OFF "${CMAKE_ARCH_OPTION}" ../.. make grpc_csharp_ext +cd ../.. mkdir -p "${ARTIFACTS_OUT}" -cp libs/opt/libgrpc_csharp_ext.so "${ARTIFACTS_OUT}" || cp libs/opt/libgrpc_csharp_ext.dylib "${ARTIFACTS_OUT}" +cp cmake/build/libgrpc_csharp_ext.so "${ARTIFACTS_OUT}" || cp cmake/build/libgrpc_csharp_ext.dylib "${ARTIFACTS_OUT}" diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 1c4bff9cde6..c6668d3efe9 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -922,20 +922,13 @@ class CSharpLanguage(object): self.config = config self.args = args if self.platform == 'windows': - _check_compiler(self.args.compiler, ['coreclr', 'default']) + _check_compiler(self.args.compiler, ['default', 'coreclr']) _check_arch(self.args.arch, ['default']) self._cmake_arch_option = 'x64' - self._make_options = [] else: _check_compiler(self.args.compiler, ['default', 'coreclr']) self._docker_distro = 'jessie' - if self.platform == 'mac': - # TODO(jtattermusch): EMBED_ZLIB=true currently breaks the mac build - self._make_options = ['EMBED_OPENSSL=true'] - else: - self._make_options = ['EMBED_OPENSSL=true', 'EMBED_ZLIB=true'] - def test_specs(self): with open('src/csharp/tests.json') as f: tests_by_assembly = json.load(f) @@ -1010,7 +1003,7 @@ class CSharpLanguage(object): return ['grpc_csharp_ext'] def make_options(self): - return self._make_options + return [] def build_steps(self): if self.platform == 'windows': @@ -1028,7 +1021,6 @@ class CSharpLanguage(object): if self.platform == 'windows': return 'cmake/build/%s/Makefile' % self._cmake_arch_option else: - # TODO(jtattermusch): arch option needed? return 'cmake/build/Makefile' def dockerfile_dir(self): From a2b2927f72fdf31441fc49dbf4ff8ede3f1aa997 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 3 Oct 2018 13:51:01 +0200 Subject: [PATCH 528/546] fix backward compatibility mode on macos --- CMakeLists.txt | 4 ++-- templates/CMakeLists.txt.template | 4 ++-- tools/run_tests/artifacts/build_artifact_csharp.sh | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7cf3ae92901..66799c456f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,8 +119,8 @@ endif() if(gRPC_BACKWARDS_COMPATIBILITY_MODE) add_definitions(-DGPR_BACKWARDS_COMPATIBILITY_MODE) if (_gRPC_PLATFORM_MAC) - # CMAKE_OSX_DEPLOYMENT_TARGET - add_definitions(-mmacosx-version-min=10.7) + # some C++11 constructs not supported before OS X 10.9 + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9) endif() endif() diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 5fff74f128e..1628493d000 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -168,8 +168,8 @@ if(gRPC_BACKWARDS_COMPATIBILITY_MODE) add_definitions(-DGPR_BACKWARDS_COMPATIBILITY_MODE) if (_gRPC_PLATFORM_MAC) - # CMAKE_OSX_DEPLOYMENT_TARGET - add_definitions(-mmacosx-version-min=10.7) + # some C++11 constructs not supported before OS X 10.9 + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9) endif() endif() diff --git a/tools/run_tests/artifacts/build_artifact_csharp.sh b/tools/run_tests/artifacts/build_artifact_csharp.sh index 6c946d7a220..f6630a709c7 100755 --- a/tools/run_tests/artifacts/build_artifact_csharp.sh +++ b/tools/run_tests/artifacts/build_artifact_csharp.sh @@ -20,8 +20,7 @@ cd "$(dirname "$0")/../../.." mkdir -p cmake/build cd cmake/build -# -DgRPC_BACKWARDS_COMPATIBILITY_MODE=ON -cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DgRPC_BUILD_TESTS=OFF "${CMAKE_ARCH_OPTION}" ../.. +cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DgRPC_BACKWARDS_COMPATIBILITY_MODE=ON -DgRPC_BUILD_TESTS=OFF "${CMAKE_ARCH_OPTION}" ../.. make grpc_csharp_ext cd ../.. From 01562865e5bbfcd98a5fdf539fe4a70df1cff3d2 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 3 Oct 2018 14:23:40 +0200 Subject: [PATCH 529/546] remove TODO --- tools/run_tests/helper_scripts/pre_build_csharp.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/run_tests/helper_scripts/pre_build_csharp.sh b/tools/run_tests/helper_scripts/pre_build_csharp.sh index dd4d2e36b27..9f98c440a71 100755 --- a/tools/run_tests/helper_scripts/pre_build_csharp.sh +++ b/tools/run_tests/helper_scripts/pre_build_csharp.sh @@ -21,7 +21,6 @@ cd "$(dirname "$0")/../../.." mkdir -p cmake/build cd cmake/build -# TODO(jtattermusch): use RelWithDebInfo for release? cmake -DgRPC_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE="${MSBUILD_CONFIG}" ../.. cd ../../src/csharp From 0b67dfec9b212cb9d6e863c08a22153c05d747da Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 4 Oct 2018 11:17:29 +0200 Subject: [PATCH 530/546] disable assembly optimizations for linux x86 --- tools/run_tests/artifacts/artifact_targets.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/artifacts/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py index b2e9f4cc9f7..6a218102476 100644 --- a/tools/run_tests/artifacts/artifact_targets.py +++ b/tools/run_tests/artifacts/artifact_targets.py @@ -249,10 +249,21 @@ class CSharpExtArtifact: use_workspace=True) else: if self.platform == 'linux': + cmake_arch_option = '' # x64 is the default architecture + if self.arch == 'x86': + # TODO(jtattermusch): more work needed to enable + # boringssl assembly optimizations for 32-bit linux. + # Problem: currently we are building the artifact under + # 32-bit docker image, but CMAKE_SYSTEM_PROCESSOR is still + # set to x86_64, so the resulting boringssl binary + # would have undefined symbols. + cmake_arch_option = '-DOPENSSL_NO_ASM=ON' return create_docker_jobspec( self.name, 'tools/dockerfile/grpc_artifact_linux_%s' % self.arch, - 'tools/run_tests/artifacts/build_artifact_csharp.sh') + 'tools/run_tests/artifacts/build_artifact_csharp.sh', + environ={'CMAKE_ARCH_OPTION': cmake_arch_option} + ) else: cmake_arch_option = '' # x64 is the default architecture if self.arch == 'x86': From ef9cd82b08dea821337d99722f163e5fc3a606c1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 3 Oct 2018 16:22:25 +0200 Subject: [PATCH 531/546] fix build of performance benchmarks --- tools/run_tests/performance/build_performance.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh index 35d9e905986..f235582579e 100755 --- a/tools/run_tests/performance/build_performance.sh +++ b/tools/run_tests/performance/build_performance.sh @@ -53,7 +53,10 @@ do fi ;; "csharp") - python tools/run_tests/run_tests.py -l "$language" -c "$CONFIG" --build_only -j 8 --compiler coreclr + python tools/run_tests/run_tests.py -l "$language" -c "$CONFIG" --build_only -j 8 + # unbreak subsequent make builds by restoring zconf.h (previously renamed by cmake portion of C#'s build) + # See https://github.com/grpc/grpc/issues/11581 + (cd third_party/zlib; git checkout zconf.h) ;; "node"|"node_purejs") tools/run_tests/performance/build_performance_node.sh From 1f5f72ba62f6226eaed388bfd923752867b20513 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 3 Oct 2018 14:24:05 +0200 Subject: [PATCH 532/546] update ssl-performance.md --- doc/ssl-performance.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/ssl-performance.md b/doc/ssl-performance.md index 711b9dff095..3de1ecac00e 100644 --- a/doc/ssl-performance.md +++ b/doc/ssl-performance.md @@ -25,7 +25,10 @@ In addition, we are shipping packages for language implementations. These packag Language | From source | Platform | Uses assembly optimizations ---|---|---|--- -C# | n/a | all | :x: +C# | n/a | Linux, 64bit | :heavy_check_mark: +C# | n/a | Linux, 32bit | :x: +C# | n/a | MacOS | :heavy_check_mark: +C# | n/a | Windows | :x: Node.JS | n/a | Linux | :heavy_check_mark: Node.JS | n/a | MacOS | :heavy_check_mark: Node.JS | n/a | Windows | :x: From b4b24dc13d8300ea50fdaa828c1bafb8b9338717 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 4 Oct 2018 11:59:23 +0200 Subject: [PATCH 533/546] yapf code --- tools/run_tests/artifacts/artifact_targets.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/run_tests/artifacts/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py index 6a218102476..054561aac9b 100644 --- a/tools/run_tests/artifacts/artifact_targets.py +++ b/tools/run_tests/artifacts/artifact_targets.py @@ -262,8 +262,9 @@ class CSharpExtArtifact: self.name, 'tools/dockerfile/grpc_artifact_linux_%s' % self.arch, 'tools/run_tests/artifacts/build_artifact_csharp.sh', - environ={'CMAKE_ARCH_OPTION': cmake_arch_option} - ) + environ={ + 'CMAKE_ARCH_OPTION': cmake_arch_option + }) else: cmake_arch_option = '' # x64 is the default architecture if self.arch == 'x86': From 082ee8964172637fb12984885f5ce53f1ba2ca56 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 4 Oct 2018 19:57:27 +0200 Subject: [PATCH 534/546] add script for automatic generation of C# reference docs --- src/csharp/doc/README.md | 19 ++++++++++++ src/csharp/doc/generate_reference_docs.sh | 38 +++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100755 src/csharp/doc/generate_reference_docs.sh diff --git a/src/csharp/doc/README.md b/src/csharp/doc/README.md index 46cce013a18..427f457eb64 100644 --- a/src/csharp/doc/README.md +++ b/src/csharp/doc/README.md @@ -1,9 +1,28 @@ DocFX-generated C# API Reference -------------------------------- +## Generating docs manually (on Windows) + Install docfx based on instructions here: https://github.com/dotnet/docfx ``` # generate docfx documentation into ./html directory $ docfx ``` + +## Release process: script for regenerating the docs automatically + +After each gRPC C# release, the docs need to be regenerated +and updated on the grpc.io site. The automated script will +re-generate the docs (using dockerized docfx installation) +and make everything ready for creating a PR to update the docs. + +``` +# 1. Run the script on Linux with docker installed +$ ./generate_reference_docs.sh + +# 2. Enter the git repo with updated "gh-pages" branch +$ cd grpc-gh-pages + +# 3. Review the changes and create a pull request +``` diff --git a/src/csharp/doc/generate_reference_docs.sh b/src/csharp/doc/generate_reference_docs.sh new file mode 100755 index 00000000000..c20d6c30bd3 --- /dev/null +++ b/src/csharp/doc/generate_reference_docs.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# Copyright 2018 The 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. + +# Generates C# API docs using docfx inside docker. +set -ex +cd $(dirname $0) + +# cleanup temporary files +rm -rf html obj grpc-gh-pages + +# generate into src/csharp/doc/html directory +cd .. +docker run --rm -v "$(pwd)":/work -w /work/doc --user "$(id -u):$(id -g)" -it tsgkadot/docker-docfx:latest docfx +cd doc + +# prepare a clone of "gh-pages" branch where the generated docs are stored +GITHUB_USER="${USER}" +git clone -b gh-pages -o upstream git@github.com:grpc/grpc.git grpc-gh-pages +cd grpc-gh-pages +git remote add origin "git@github.com:${GITHUB_USER}/grpc.git" + +# replace old generated docs by the ones we just generated +rm -r csharp +cp -r ../html csharp + +echo "Done. Go to src/csharp/doc/grpc-gh-pages git repository and create a pull request to update the generated docs." From 3851be5b14c201e750c1f1c4d06965e3b787030b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 4 Oct 2018 20:35:27 +0200 Subject: [PATCH 535/546] Mention TROUBLESHOOTING.md in issue template --- .github/ISSUE_TEMPLATE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 5b2ac80df6a..d31aea6c736 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -26,6 +26,8 @@ If possible, provide a recipe for reproducing the error. Try being specific and ### What did you see instead? Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs). + +See https://github.com/grpc/grpc/blob/master/TROUBLESHOOTING.md for how to diagnose problems better. ### Anything else we should know about your project / environment? From e6b1edf42ab8f8f142352406899deeb178bb90ee Mon Sep 17 00:00:00 2001 From: Spencer Fang Date: Thu, 4 Oct 2018 12:00:28 -0700 Subject: [PATCH 536/546] Split grpc_cli target into two targets Let's have a util target that contains everything except for the CLI front end. This way, users can depend on the util classes without any risk of CLI flag collisions. --- test/cpp/util/BUILD | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD index 477862a0ee1..c8d4333ef0d 100644 --- a/test/cpp/util/BUILD +++ b/test/cpp/util/BUILD @@ -117,11 +117,10 @@ grpc_cc_library( ) grpc_cc_library( - name = "grpc_cli_libs", + name = "grpc_cli_utils", srcs = [ "cli_call.cc", "cli_credentials.cc", - "grpc_tool.cc", "proto_file_parser.cc", "service_describer.cc", ], @@ -129,7 +128,6 @@ grpc_cc_library( "cli_call.h", "cli_credentials.h", "config_grpc_cli.h", - "grpc_tool.h", "proto_file_parser.h", "service_describer.h", ], @@ -145,6 +143,22 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "grpc_cli_libs", + srcs = [ + "grpc_tool.cc", + ], + hdrs = [ + "grpc_tool.h", + ], + external_deps = [ + "gflags", + ], + deps = [ + ":grpc_cli_utils", + ], +) + grpc_cc_library( name = "metrics_server_lib", srcs = [ From d7bbc60ad664abb3f6d734d7ce91fd726dce2c02 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 4 Oct 2018 13:19:49 -0700 Subject: [PATCH 537/546] Reviewer feedback --- include/grpc/impl/codegen/grpc_types.h | 8 -------- src/core/lib/channel/channelz.h | 9 +++++++++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index c0e4342bddb..d1f8834d117 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -289,18 +289,10 @@ typedef struct { * subchannel. The default is 0. If set to 0, channel tracing is disabled. */ #define GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE \ "grpc.max_channel_trace_events_per_node" -/** Note this is not a "channel arg" key. This is the default value for number - * of trace events per node. If the above arg is set, it will override this - * default value. */ -#define GRPC_MAX_CHANNEL_TRACE_EVENTS_PER_NODE_DEFAULT 0 /** If non-zero, gRPC library will track stats and information at at per channel * level. Disabling channelz naturally disables channel tracing. The default * is for channelz to be disabled. */ #define GRPC_ARG_ENABLE_CHANNELZ "grpc.enable_channelz" -/** Note this is not a "channel arg" key. This is the default value for whether - * or not to enable channelz. If the above arg is set, it will override this - * default value. */ -#define GRPC_ENABLE_CHANNELZ_DEFAULT false /** If non-zero, Cronet transport will coalesce packets to fewer frames * when possible. */ #define GRPC_ARG_USE_CRONET_PACKET_COALESCING \ diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index b7ae1012389..d949e1b449d 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -39,6 +39,15 @@ #define GRPC_ARG_CHANNELZ_CHANNEL_IS_INTERNAL_CHANNEL \ "grpc.channelz_channel_is_internal_channel" +/** This is the default value for whether or not to enable channelz. If + * GRPC_ARG_ENABLE_CHANNELZ is set, it will override this default value. */ +#define GRPC_ENABLE_CHANNELZ_DEFAULT false + +/** This is the default value for number of trace events per node. If + * GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE is set, it will override this + * default value. */ +#define GRPC_MAX_CHANNEL_TRACE_EVENTS_PER_NODE_DEFAULT 0 + namespace grpc_core { namespace channelz { From 664178164a7ecd3b108b9dd61e7821b716848792 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 4 Oct 2018 16:32:01 -0700 Subject: [PATCH 538/546] reviewer feedback --- include/grpc/impl/codegen/grpc_types.h | 8 ++++---- src/core/lib/channel/channel_trace.cc | 10 ++++------ src/core/lib/channel/channel_trace.h | 20 ++++++++++++++++---- src/core/lib/channel/channelz.h | 3 ++- test/core/channel/channel_trace_test.cc | 23 ++++++++++++----------- test/core/end2end/tests/channelz.cc | 18 +++++++----------- 6 files changed, 45 insertions(+), 37 deletions(-) diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 42daf3bb6eb..3ce88a82645 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -285,10 +285,10 @@ typedef struct { #define GRPC_ARG_SOCKET_MUTATOR "grpc.socket_mutator" /** The grpc_socket_factory instance to create and bind sockets. A pointer. */ #define GRPC_ARG_SOCKET_FACTORY "grpc.socket_factory" -/** The maximum ammount of memory that the trace event can use per channel - * trace node. Once the maximum is reached, subsequent events will evict the - * oldest events from the buffer. The unit for this knob is bytes. Setting - * it to zero causes channel tracing to be disabled. */ +/** The maximum amount of memory used by trace events per channel trace node. + * Once the maximum is reached, subsequent events will evict the oldest events + * from the buffer. The unit for this knob is bytes. Setting it to zero causes + * channel tracing to be disabled. */ #define GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE \ "grpc.max_channel_trace_event_memory_per_node" /** If non-zero, gRPC library will track stats and information at at per channel diff --git a/src/core/lib/channel/channel_trace.cc b/src/core/lib/channel/channel_trace.cc index 3227fe53a12..fe81acb617f 100644 --- a/src/core/lib/channel/channel_trace.cc +++ b/src/core/lib/channel/channel_trace.cc @@ -48,18 +48,16 @@ ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data, timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(), GPR_CLOCK_REALTIME)), next_(nullptr), - referenced_entity_(std::move(referenced_entity)) { - memory_usage_ = sizeof(TraceEvent) + grpc_slice_memory_usage(data); -} + referenced_entity_(std::move(referenced_entity)), + memory_usage_(sizeof(TraceEvent) + grpc_slice_memory_usage(data)) {} ChannelTrace::TraceEvent::TraceEvent(Severity severity, grpc_slice data) : severity_(severity), data_(data), timestamp_(grpc_millis_to_timespec(grpc_core::ExecCtx::Get()->Now(), GPR_CLOCK_REALTIME)), - next_(nullptr) { - memory_usage_ = sizeof(TraceEvent) + grpc_slice_memory_usage(data); -} + next_(nullptr), + memory_usage_(sizeof(TraceEvent) + grpc_slice_memory_usage(data)) {} ChannelTrace::TraceEvent::~TraceEvent() { grpc_slice_unref_internal(data_); } diff --git a/src/core/lib/channel/channel_trace.h b/src/core/lib/channel/channel_trace.h index 0e9ce5f6488..8ff91ee8c81 100644 --- a/src/core/lib/channel/channel_trace.h +++ b/src/core/lib/channel/channel_trace.h @@ -30,6 +30,10 @@ namespace grpc_core { namespace channelz { +namespace testing { +size_t GetSizeofTraceEvent(void); +} + class BaseNode; // Object used to hold live data for a channel. This data is exposed via the @@ -49,6 +53,12 @@ class ChannelTrace { // Adds a new trace event to the tracing object // + // NOTE: each ChannelTrace tracks the memory used by its list of trace + // events, so adding an event with a large amount of data could cause other + // trace event to be evicted. If a single trace is larger than the limit, it + // will cause all events to be evicted. The limit is set with the arg: + // GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE. + // // TODO(ncteisen): as this call is used more and more throughout the gRPC // stack, determine if it makes more sense to accept a char* instead of a // slice. @@ -59,9 +69,9 @@ class ChannelTrace { // channel has created a new subchannel, then it would record that with // a TraceEvent referencing the new subchannel. // - // TODO(ncteisen): as this call is used more and more throughout the gRPC - // stack, determine if it makes more sense to accept a char* instead of a - // slice. + // NOTE: see the note in the method above. + // + // TODO(ncteisen): see the todo in the method above. void AddTraceEventWithReference(Severity severity, grpc_slice data, RefCountedPtr referenced_entity); @@ -70,6 +80,8 @@ class ChannelTrace { grpc_json* RenderJson() const; private: + friend size_t testing::GetSizeofTraceEvent(void); + // Private class to encapsulate all the data and bookkeeping needed for a // a trace event. class TraceEvent { @@ -92,7 +104,7 @@ class ChannelTrace { TraceEvent* next() const { return next_; } void set_next(TraceEvent* next) { next_ = next; } - size_t memory_usage() { return memory_usage_; } + size_t memory_usage() const { return memory_usage_; } private: Severity severity_; diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 97eef9868d6..30ec66ced21 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -43,7 +43,8 @@ * GRPC_ARG_ENABLE_CHANNELZ is set, it will override this default value. */ #define GRPC_ENABLE_CHANNELZ_DEFAULT false -/** This is the default value for TODO. If +/** This is the default value for the maximum amount of memory used by trace + * events per channel trace node. If * GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE is set, it will override * this default value. */ #define GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT 0 diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index 8385475e7dd..a569444fed4 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -30,6 +30,7 @@ #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/json/json.h" +#include "src/core/lib/surface/channel.h" #include "test/core/util/test_config.h" #include "test/cpp/util/channel_trace_proto_helper.h" @@ -51,6 +52,8 @@ class ChannelNodePeer { ChannelNode* node_; }; +size_t GetSizeofTraceEvent() { return sizeof(ChannelTrace::TraceEvent); } + namespace { grpc_json* GetJsonChild(grpc_json* parent, const char* key) { @@ -119,11 +122,9 @@ void ValidateChannelTrace(ChannelTrace* tracer, size_t num_events_logged) { class ChannelFixture { public: ChannelFixture(int max_tracer_event_memory) { - grpc_arg client_a; - client_a.type = GRPC_ARG_INTEGER; - client_a.key = - const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); - client_a.value.integer = max_tracer_event_memory; + grpc_arg client_a = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE), + max_tracer_event_memory); grpc_channel_args client_args = {1, &client_a}; channel_ = grpc_insecure_channel_create("fake_target", &client_args, nullptr); @@ -286,9 +287,9 @@ TEST(ChannelTracerTest, TestSmallMemoryLimit) { TEST(ChannelTracerTest, TestEviction) { grpc_core::ExecCtx exec_ctx; - // This depends on sizeof(ChannelTrace). If that struct has been updated, + // This depends on sizeof(ChannelEvent). If that struct has been updated, // this will too. - const int kTraceEventSize = 80; + const int kTraceEventSize = GetSizeofTraceEvent(); const int kNumEvents = 5; ChannelTrace tracer(kTraceEventSize * kNumEvents); for (int i = 1; i <= kNumEvents; ++i) { @@ -305,9 +306,9 @@ TEST(ChannelTracerTest, TestEviction) { TEST(ChannelTracerTest, TestMultipleEviction) { grpc_core::ExecCtx exec_ctx; - // This depends on sizeof(ChannelTrace). If that struct has been updated, + // This depends on sizeof(ChannelEvent). If that struct has been updated, // this will too. - const int kTraceEventSize = 80; + const int kTraceEventSize = GetSizeofTraceEvent(); const int kNumEvents = 5; ChannelTrace tracer(kTraceEventSize * kNumEvents); for (int i = 1; i <= kNumEvents; ++i) { @@ -326,9 +327,9 @@ TEST(ChannelTracerTest, TestMultipleEviction) { TEST(ChannelTracerTest, TestTotalEviction) { grpc_core::ExecCtx exec_ctx; - // This depends on sizeof(ChannelTrace). If that struct has been updated, + // This depends on sizeof(ChannelEvent). If that struct has been updated, // this will too. - const int kTraceEventSize = 80; + const int kTraceEventSize = GetSizeofTraceEvent(); const int kNumEvents = 5; ChannelTrace tracer(kTraceEventSize * kNumEvents); for (int i = 1; i <= kNumEvents; ++i) { diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index 58ffdc18daf..0e3ad6a476a 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -199,10 +199,8 @@ static void run_one_request(grpc_end2end_test_config config, static void test_channelz(grpc_end2end_test_config config) { grpc_end2end_test_fixture f; - grpc_arg arg; - arg.type = GRPC_ARG_INTEGER; - arg.key = const_cast(GRPC_ARG_ENABLE_CHANNELZ); - arg.value.integer = true; + grpc_arg arg = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ENABLE_CHANNELZ), true); grpc_channel_args args = {1, &arg}; f = begin_test(config, "test_channelz", &args, &args); @@ -266,13 +264,11 @@ static void test_channelz_with_channel_trace(grpc_end2end_test_config config) { grpc_end2end_test_fixture f; grpc_arg arg[2]; - arg[0].type = GRPC_ARG_INTEGER; - arg[0].key = - const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE); - arg[0].value.integer = 1024; - arg[1].type = GRPC_ARG_INTEGER; - arg[1].key = const_cast(GRPC_ARG_ENABLE_CHANNELZ); - arg[1].value.integer = true; + arg[0] = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE), + 1024 * 1024); + arg[1] = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ENABLE_CHANNELZ), true); grpc_channel_args args = {GPR_ARRAY_SIZE(arg), arg}; f = begin_test(config, "test_channelz_with_channel_trace", &args, &args); From 2ebbc9acf2ce7e65b8a162533b7f0ecdd659461d Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 4 Oct 2018 16:45:07 -0700 Subject: [PATCH 539/546] Adjust server_auth_filter location. --- src/core/lib/surface/init_secure.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/surface/init_secure.cc b/src/core/lib/surface/init_secure.cc index 28c6f7b121f..765350cced0 100644 --- a/src/core/lib/surface/init_secure.cc +++ b/src/core/lib/surface/init_secure.cc @@ -74,7 +74,7 @@ void grpc_register_security_filters(void) { maybe_prepend_client_auth_filter, nullptr); grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX - 1, maybe_prepend_client_auth_filter, nullptr); - grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX - 1, maybe_prepend_server_auth_filter, nullptr); } From dd5fd814f39c78c07f34fd98d12d93fe016c5d2d Mon Sep 17 00:00:00 2001 From: ncteisen Date: Thu, 4 Oct 2018 15:43:21 -0700 Subject: [PATCH 540/546] reviewer feedback --- src/core/lib/channel/channelz.cc | 23 +++++++++++------------ src/core/lib/channel/channelz.h | 13 ++++++++++--- test/core/channel/channelz_test.cc | 3 ++- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index e9c29489a2d..6d77e1bbcce 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -57,8 +57,8 @@ char* BaseNode::RenderJsonString() { CallCountingHelper::CallCountingHelper() { num_cores_ = GPR_MAX(1, gpr_cpu_num_cores()); - per_cpu_counter_data_storage_ = - static_cast(gpr_zalloc(sizeof(CounterData) * num_cores_)); + per_cpu_counter_data_storage_ = static_cast( + gpr_zalloc(sizeof(AtomicCounterData) * num_cores_)); } CallCountingHelper::~CallCountingHelper() { @@ -90,28 +90,27 @@ void CallCountingHelper::RecordCallSucceeded() { static_cast(1)); } -CallCountingHelper::CounterData CallCountingHelper::Collect() { - CounterData out; - memset(&out, 0, sizeof(out)); +void CallCountingHelper::CollectData(CounterData* out) { + memset(out, 0, sizeof(*out)); for (size_t core = 0; core < num_cores_; ++core) { - out.calls_started_ += gpr_atm_no_barrier_load( + out->calls_started_ += gpr_atm_no_barrier_load( &per_cpu_counter_data_storage_[core].calls_started_); - out.calls_succeeded_ += gpr_atm_no_barrier_load( + out->calls_succeeded_ += gpr_atm_no_barrier_load( &per_cpu_counter_data_storage_[core].calls_succeeded_); - out.calls_failed_ += gpr_atm_no_barrier_load( + out->calls_failed_ += gpr_atm_no_barrier_load( &per_cpu_counter_data_storage_[core].calls_failed_); gpr_atm last_call = gpr_atm_no_barrier_load( &per_cpu_counter_data_storage_[core].last_call_started_millis_); - if (last_call > out.last_call_started_millis_) { - out.last_call_started_millis_ = last_call; + if (last_call > out->last_call_started_millis_) { + out->last_call_started_millis_ = last_call; } } - return out; } void CallCountingHelper::PopulateCallCounts(grpc_json* json) { grpc_json* json_iterator = nullptr; - CounterData data = Collect(); + CounterData data; + CollectData(&data); if (data.calls_started_ != 0) { json_iterator = grpc_json_add_number_string_child( json, json_iterator, "callsStarted", data.calls_started_); diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index ee2ca40a202..ae3e47a1f60 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -101,17 +101,24 @@ class CallCountingHelper { // testing peer friend. friend class testing::CallCountingHelperPeer; - struct CounterData { + struct AtomicCounterData { gpr_atm calls_started_ = 0; gpr_atm calls_succeeded_ = 0; gpr_atm calls_failed_ = 0; gpr_atm last_call_started_millis_ = 0; }; + struct CounterData { + intptr_t calls_started_ = 0; + intptr_t calls_succeeded_ = 0; + intptr_t calls_failed_ = 0; + intptr_t last_call_started_millis_ = 0; + }; + // collects the sharded data into one CounterData struct. - CounterData Collect(); + void CollectData(CounterData* out); - CounterData* per_cpu_counter_data_storage_ = nullptr; + AtomicCounterData* per_cpu_counter_data_storage_ = nullptr; size_t num_cores_ = 0; }; diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index b7b35aede4e..f99893521c1 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -49,7 +49,8 @@ class CallCountingHelperPeer { public: explicit CallCountingHelperPeer(CallCountingHelper* node) : node_(node) {} grpc_millis last_call_started_millis() const { - CallCountingHelper::CounterData data = node_->Collect(); + CallCountingHelper::CounterData data; + node_->CollectData(&data); return (grpc_millis)gpr_atm_no_barrier_load( &data.last_call_started_millis_); } From fb296824af9f5a0d41f7233620388737f7fdeb28 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 5 Oct 2018 09:49:29 +0200 Subject: [PATCH 541/546] Revert "Create and pass pollset_set to ALTS TSI handshaker" --- .../client_channel/http_connect_handshaker.cc | 1 - .../ext/transport/chttp2/client/chttp2_connector.cc | 2 +- .../ext/transport/chttp2/server/chttp2_server.cc | 8 -------- src/core/lib/channel/handshaker_factory.cc | 5 ++--- src/core/lib/channel/handshaker_factory.h | 2 -- src/core/lib/channel/handshaker_registry.cc | 8 ++------ src/core/lib/channel/handshaker_registry.h | 1 - src/core/lib/http/httpcli_security_connector.cc | 3 +-- .../security_connector/alts_security_connector.cc | 12 ++++++------ .../security_connector/security_connector.cc | 7 ------- .../security/security_connector/security_connector.h | 5 ----- .../lib/security/transport/security_handshaker.cc | 10 ---------- src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc | 3 +-- src/core/tsi/alts/handshaker/alts_tsi_handshaker.h | 5 +---- .../handshake/readahead_handshaker_server_ssl.cc | 1 - .../tsi/alts/handshaker/alts_tsi_handshaker_test.cc | 2 +- 16 files changed, 15 insertions(+), 60 deletions(-) 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 bfabc68c661..7ce8da8c00e 100644 --- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc +++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc @@ -351,7 +351,6 @@ static grpc_handshaker* grpc_http_connect_handshaker_create() { static void handshaker_factory_add_handshakers( grpc_handshaker_factory* factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { grpc_handshake_manager_add(handshake_mgr, grpc_http_connect_handshaker_create()); diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index 5229304fa45..0ac84032fd4 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -160,7 +160,7 @@ static void on_handshake_done(void* arg, grpc_error* error) { static void start_handshake_locked(chttp2_connector* c) { c->handshake_mgr = grpc_handshake_manager_create(); grpc_handshakers_add(HANDSHAKER_CLIENT, c->args.channel_args, - c->args.interested_parties, c->handshake_mgr); + c->handshake_mgr); grpc_endpoint_add_to_pollset_set(c->endpoint, c->args.interested_parties); grpc_handshake_manager_do_handshake( c->handshake_mgr, c->args.interested_parties, c->endpoint, diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index b95baa91914..3f8a26ae32b 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -67,7 +67,6 @@ typedef struct { grpc_timer timer; grpc_closure on_timeout; grpc_closure on_receive_settings; - grpc_pollset_set* interested_parties; } server_connection_state; static void server_connection_state_unref( @@ -77,9 +76,6 @@ static void server_connection_state_unref( GRPC_CHTTP2_UNREF_TRANSPORT(connection_state->transport, "receive settings timeout"); } - grpc_pollset_set_del_pollset(connection_state->interested_parties, - connection_state->accepting_pollset); - grpc_pollset_set_destroy(connection_state->interested_parties); gpr_free(connection_state); } } @@ -193,11 +189,7 @@ static void on_accept(void* arg, grpc_endpoint* tcp, connection_state->accepting_pollset = accepting_pollset; connection_state->acceptor = acceptor; connection_state->handshake_mgr = handshake_mgr; - connection_state->interested_parties = grpc_pollset_set_create(); - grpc_pollset_set_add_pollset(connection_state->interested_parties, - connection_state->accepting_pollset); grpc_handshakers_add(HANDSHAKER_SERVER, state->args, - connection_state->interested_parties, connection_state->handshake_mgr); const grpc_arg* timeout_arg = grpc_channel_args_find(state->args, GRPC_ARG_SERVER_HANDSHAKE_TIMEOUT_MS); diff --git a/src/core/lib/channel/handshaker_factory.cc b/src/core/lib/channel/handshaker_factory.cc index 8ade8fe4e23..4fd43635b6b 100644 --- a/src/core/lib/channel/handshaker_factory.cc +++ b/src/core/lib/channel/handshaker_factory.cc @@ -24,12 +24,11 @@ void grpc_handshaker_factory_add_handshakers( grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { if (handshaker_factory != nullptr) { GPR_ASSERT(handshaker_factory->vtable != nullptr); - handshaker_factory->vtable->add_handshakers( - handshaker_factory, args, interested_parties, handshake_mgr); + handshaker_factory->vtable->add_handshakers(handshaker_factory, args, + handshake_mgr); } } diff --git a/src/core/lib/channel/handshaker_factory.h b/src/core/lib/channel/handshaker_factory.h index e17a6781798..3e45fcf20e6 100644 --- a/src/core/lib/channel/handshaker_factory.h +++ b/src/core/lib/channel/handshaker_factory.h @@ -32,7 +32,6 @@ typedef struct grpc_handshaker_factory grpc_handshaker_factory; typedef struct { void (*add_handshakers)(grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr); void (*destroy)(grpc_handshaker_factory* handshaker_factory); } grpc_handshaker_factory_vtable; @@ -43,7 +42,6 @@ struct grpc_handshaker_factory { void grpc_handshaker_factory_add_handshakers( grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr); void grpc_handshaker_factory_destroy( diff --git a/src/core/lib/channel/handshaker_registry.cc b/src/core/lib/channel/handshaker_registry.cc index fbafc43e795..eec3e1b352d 100644 --- a/src/core/lib/channel/handshaker_registry.cc +++ b/src/core/lib/channel/handshaker_registry.cc @@ -51,11 +51,9 @@ static void grpc_handshaker_factory_list_register( static void grpc_handshaker_factory_list_add_handshakers( grpc_handshaker_factory_list* list, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { for (size_t i = 0; i < list->num_factories; ++i) { - grpc_handshaker_factory_add_handshakers(list->list[i], args, - interested_parties, handshake_mgr); + grpc_handshaker_factory_add_handshakers(list->list[i], args, handshake_mgr); } } @@ -93,9 +91,7 @@ void grpc_handshaker_factory_register(bool at_start, void grpc_handshakers_add(grpc_handshaker_type handshaker_type, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { grpc_handshaker_factory_list_add_handshakers( - &g_handshaker_factory_lists[handshaker_type], args, interested_parties, - handshake_mgr); + &g_handshaker_factory_lists[handshaker_type], args, handshake_mgr); } diff --git a/src/core/lib/channel/handshaker_registry.h b/src/core/lib/channel/handshaker_registry.h index 3dd4316de67..82ad9c5b9af 100644 --- a/src/core/lib/channel/handshaker_registry.h +++ b/src/core/lib/channel/handshaker_registry.h @@ -43,7 +43,6 @@ void grpc_handshaker_factory_register(bool at_start, void grpc_handshakers_add(grpc_handshaker_type handshaker_type, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr); #endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H */ diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 98fb7d39372..50078c37a17 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -189,8 +189,7 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host, grpc_arg channel_arg = grpc_security_connector_to_arg(&sc->base); grpc_channel_args args = {1, &channel_arg}; c->handshake_mgr = grpc_handshake_manager_create(); - grpc_handshakers_add(HANDSHAKER_CLIENT, &args, - nullptr /* interested_parties */, c->handshake_mgr); + grpc_handshakers_add(HANDSHAKER_CLIENT, &args, c->handshake_mgr); grpc_handshake_manager_do_handshake( c->handshake_mgr, nullptr /* interested_parties */, tcp, nullptr /* channel_args */, deadline, nullptr /* acceptor */, diff --git a/src/core/lib/security/security_connector/alts_security_connector.cc b/src/core/lib/security/security_connector/alts_security_connector.cc index f157c93171a..35a787871a8 100644 --- a/src/core/lib/security/security_connector/alts_security_connector.cc +++ b/src/core/lib/security/security_connector/alts_security_connector.cc @@ -70,9 +70,9 @@ static void alts_channel_add_handshakers( auto c = reinterpret_cast(sc); grpc_alts_credentials* creds = reinterpret_cast(c->base.channel_creds); - GPR_ASSERT(alts_tsi_handshaker_create( - creds->options, c->target_name, creds->handshaker_service_url, - true, sc->base.interested_parties, &handshaker) == TSI_OK); + GPR_ASSERT(alts_tsi_handshaker_create(creds->options, c->target_name, + creds->handshaker_service_url, true, + &handshaker) == TSI_OK); grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( handshaker, &sc->base)); } @@ -84,9 +84,9 @@ static void alts_server_add_handshakers( auto c = reinterpret_cast(sc); grpc_alts_server_credentials* creds = reinterpret_cast(c->base.server_creds); - GPR_ASSERT(alts_tsi_handshaker_create( - creds->options, nullptr, creds->handshaker_service_url, false, - sc->base.interested_parties, &handshaker) == TSI_OK); + GPR_ASSERT(alts_tsi_handshaker_create(creds->options, nullptr, + creds->handshaker_service_url, false, + &handshaker) == TSI_OK); grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create( handshaker, &sc->base)); } diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index f4490582a3f..6246613e7b3 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -156,13 +156,6 @@ int grpc_security_connector_cmp(grpc_security_connector* sc, return sc->vtable->cmp(sc, other); } -void grpc_security_connector_set_interested_parties( - grpc_security_connector* sc, grpc_pollset_set* interested_parties) { - if (sc != nullptr) { - sc->interested_parties = interested_parties; - } -} - int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1, grpc_channel_security_connector* sc2) { GPR_ASSERT(sc1->channel_creds != nullptr); diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index f0172594ad2..67a506b5767 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -63,7 +63,6 @@ struct grpc_security_connector { const grpc_security_connector_vtable* vtable; gpr_refcount refcount; const char* url_scheme; - grpc_pollset_set* interested_parties; }; /* Refcounting. */ @@ -107,10 +106,6 @@ grpc_security_connector* grpc_security_connector_from_arg(const grpc_arg* arg); grpc_security_connector* grpc_security_connector_find_in_args( const grpc_channel_args* args); -/* Util to set the interested_parties whose ownership is not transferred. */ -void grpc_security_connector_set_interested_parties( - grpc_security_connector* sc, grpc_pollset_set* interested_parties); - /* --- channel_security_connector object. --- A channel security connector object represents a way to configure the diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc index f3bdf573b3d..d76d5826388 100644 --- a/src/core/lib/security/transport/security_handshaker.cc +++ b/src/core/lib/security/transport/security_handshaker.cc @@ -475,30 +475,20 @@ static grpc_handshaker* fail_handshaker_create() { static void client_handshaker_factory_add_handshakers( grpc_handshaker_factory* handshaker_factory, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { grpc_channel_security_connector* security_connector = reinterpret_cast( grpc_security_connector_find_in_args(args)); - if (security_connector != nullptr) { - grpc_security_connector_set_interested_parties(&security_connector->base, - interested_parties); - } grpc_channel_security_connector_add_handshakers(security_connector, handshake_mgr); } static void server_handshaker_factory_add_handshakers( grpc_handshaker_factory* hf, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { grpc_server_security_connector* security_connector = reinterpret_cast( grpc_security_connector_find_in_args(args)); - if (security_connector != nullptr) { - grpc_security_connector_set_interested_parties(&security_connector->base, - interested_parties); - } grpc_server_security_connector_add_handshakers(security_connector, handshake_mgr); } diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc index dfdd659b877..34608a3de19 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc @@ -347,8 +347,7 @@ static void init_shared_resources(const char* handshaker_service_url) { tsi_result alts_tsi_handshaker_create( const grpc_alts_credentials_options* options, const char* target_name, - const char* handshaker_service_url, bool is_client, - grpc_pollset_set* interested_parties, tsi_handshaker** self) { + const char* handshaker_service_url, bool is_client, tsi_handshaker** self) { if (handshaker_service_url == nullptr || self == nullptr || options == nullptr || (is_client && target_name == nullptr)) { gpr_log(GPR_ERROR, "Invalid arguments to alts_tsi_handshaker_create()"); diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h index 48ce69b1dac..227b30ce537 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h @@ -23,7 +23,6 @@ #include -#include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h" #include "src/core/tsi/alts_transport_security.h" #include "src/core/tsi/transport_security.h" @@ -52,7 +51,6 @@ typedef struct alts_tsi_handshaker alts_tsi_handshaker; * "host:port". * - is_client: boolean value indicating if the handshaker is used at the client * (is_client = true) or server (is_client = false) side. - * - interested_parties: set of pollsets interested in this connection. * - self: address of ALTS TSI handshaker instance to be returned from the * method. * @@ -60,8 +58,7 @@ typedef struct alts_tsi_handshaker alts_tsi_handshaker; */ tsi_result alts_tsi_handshaker_create( const grpc_alts_credentials_options* options, const char* target_name, - const char* handshaker_service_url, bool is_client, - grpc_pollset_set* interested_parties, tsi_handshaker** self); + const char* handshaker_service_url, bool is_client, tsi_handshaker** self); /** * This method handles handshaker response returned from ALTS handshaker diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc index 14d96b5d89c..97e9c20ee4f 100644 --- a/test/core/handshake/readahead_handshaker_server_ssl.cc +++ b/test/core/handshake/readahead_handshaker_server_ssl.cc @@ -75,7 +75,6 @@ static grpc_handshaker* readahead_handshaker_create() { static void readahead_handshaker_factory_add_handshakers( grpc_handshaker_factory* hf, const grpc_channel_args* args, - grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr) { grpc_handshake_manager_add(handshake_mgr, readahead_handshaker_create()); } diff --git a/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc b/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc index e9eb7e175f4..85a58114ba6 100644 --- a/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc +++ b/test/core/tsi/alts/handshaker/alts_tsi_handshaker_test.cc @@ -421,7 +421,7 @@ static tsi_handshaker* create_test_handshaker(bool used_for_success_test, alts_mock_handshaker_client_create(used_for_success_test); grpc_alts_credentials_options* options = grpc_alts_credentials_client_options_create(); - alts_tsi_handshaker_create(options, "target_name", "lame", is_client, nullptr, + alts_tsi_handshaker_create(options, "target_name", "lame", is_client, &handshaker); alts_tsi_handshaker* alts_handshaker = reinterpret_cast(handshaker); From ce656957ea897a720e1c2393d182799b24f705d9 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 5 Oct 2018 17:52:44 +0200 Subject: [PATCH 542/546] address review comments --- tools/run_tests/artifacts/build_artifact_csharp.sh | 9 +++++++-- tools/run_tests/helper_scripts/pre_build_csharp.sh | 2 +- tools/run_tests/run_tests.py | 2 ++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/run_tests/artifacts/build_artifact_csharp.sh b/tools/run_tests/artifacts/build_artifact_csharp.sh index f6630a709c7..bb8a91b520d 100755 --- a/tools/run_tests/artifacts/build_artifact_csharp.sh +++ b/tools/run_tests/artifacts/build_artifact_csharp.sh @@ -20,8 +20,13 @@ cd "$(dirname "$0")/../../.." mkdir -p cmake/build cd cmake/build -cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DgRPC_BACKWARDS_COMPATIBILITY_MODE=ON -DgRPC_BUILD_TESTS=OFF "${CMAKE_ARCH_OPTION}" ../.. -make grpc_csharp_ext +cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DgRPC_BACKWARDS_COMPATIBILITY_MODE=ON \ + -DgRPC_BUILD_TESTS=OFF \ + "${CMAKE_ARCH_OPTION}" \ + ../.. + +make grpc_csharp_ext -j2 cd ../.. mkdir -p "${ARTIFACTS_OUT}" diff --git a/tools/run_tests/helper_scripts/pre_build_csharp.sh b/tools/run_tests/helper_scripts/pre_build_csharp.sh index 9f98c440a71..7d83986f90b 100755 --- a/tools/run_tests/helper_scripts/pre_build_csharp.sh +++ b/tools/run_tests/helper_scripts/pre_build_csharp.sh @@ -15,7 +15,7 @@ set -ex -# cd to gRPC csharp directory +# cd to repository root cd "$(dirname "$0")/../../.." mkdir -p cmake/build diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index c6668d3efe9..c9b4c8b28b1 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -1021,6 +1021,8 @@ class CSharpLanguage(object): if self.platform == 'windows': return 'cmake/build/%s/Makefile' % self._cmake_arch_option else: + # no need to set x86 specific flags as run_tests.py + # currently forbids x86 C# builds on both Linux and MacOS. return 'cmake/build/Makefile' def dockerfile_dir(self): From 3c2024c6af1a4212f8ed76f6220e3f7731959b6b Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 5 Oct 2018 09:41:22 -0700 Subject: [PATCH 543/546] reviewer comments --- src/core/lib/channel/channelz.cc | 43 +++++++++++++++--------------- src/core/lib/channel/channelz.h | 16 +++++------ test/core/channel/channelz_test.cc | 3 +-- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 6d77e1bbcce..573292fba12 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -68,41 +68,40 @@ CallCountingHelper::~CallCountingHelper() { void CallCountingHelper::RecordCallStarted() { gpr_atm_no_barrier_fetch_add( &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()] - .calls_started_, + .calls_started, static_cast(1)); gpr_atm_no_barrier_store( &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()] - .last_call_started_millis_, + .last_call_started_millis, (gpr_atm)ExecCtx::Get()->Now()); } void CallCountingHelper::RecordCallFailed() { gpr_atm_no_barrier_fetch_add( &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()] - .calls_failed_, + .calls_failed, static_cast(1)); } void CallCountingHelper::RecordCallSucceeded() { gpr_atm_no_barrier_fetch_add( &per_cpu_counter_data_storage_[grpc_core::ExecCtx::Get()->starting_cpu()] - .calls_succeeded_, + .calls_succeeded, static_cast(1)); } void CallCountingHelper::CollectData(CounterData* out) { - memset(out, 0, sizeof(*out)); for (size_t core = 0; core < num_cores_; ++core) { - out->calls_started_ += gpr_atm_no_barrier_load( - &per_cpu_counter_data_storage_[core].calls_started_); - out->calls_succeeded_ += gpr_atm_no_barrier_load( - &per_cpu_counter_data_storage_[core].calls_succeeded_); - out->calls_failed_ += gpr_atm_no_barrier_load( - &per_cpu_counter_data_storage_[core].calls_failed_); + out->calls_started += gpr_atm_no_barrier_load( + &per_cpu_counter_data_storage_[core].calls_started); + out->calls_succeeded += gpr_atm_no_barrier_load( + &per_cpu_counter_data_storage_[core].calls_succeeded); + out->calls_failed += gpr_atm_no_barrier_load( + &per_cpu_counter_data_storage_[core].calls_failed); gpr_atm last_call = gpr_atm_no_barrier_load( - &per_cpu_counter_data_storage_[core].last_call_started_millis_); - if (last_call > out->last_call_started_millis_) { - out->last_call_started_millis_ = last_call; + &per_cpu_counter_data_storage_[core].last_call_started_millis); + if (last_call > out->last_call_started_millis) { + out->last_call_started_millis = last_call; } } } @@ -111,20 +110,20 @@ void CallCountingHelper::PopulateCallCounts(grpc_json* json) { grpc_json* json_iterator = nullptr; CounterData data; CollectData(&data); - if (data.calls_started_ != 0) { + if (data.calls_started != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "callsStarted", data.calls_started_); + json, json_iterator, "callsStarted", data.calls_started); } - if (data.calls_succeeded_ != 0) { + if (data.calls_succeeded != 0) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "callsSucceeded", data.calls_succeeded_); + json, json_iterator, "callsSucceeded", data.calls_succeeded); } - if (data.calls_failed_) { + if (data.calls_failed) { json_iterator = grpc_json_add_number_string_child( - json, json_iterator, "callsFailed", data.calls_failed_); + json, json_iterator, "callsFailed", data.calls_failed); } - if (data.calls_started_ != 0) { - gpr_timespec ts = grpc_millis_to_timespec(data.last_call_started_millis_, + if (data.calls_started != 0) { + gpr_timespec ts = grpc_millis_to_timespec(data.last_call_started_millis, GPR_CLOCK_REALTIME); json_iterator = grpc_json_create_child(json_iterator, json, "lastCallStartedTimestamp", diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index ae3e47a1f60..27f6bfc8825 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -102,17 +102,17 @@ class CallCountingHelper { friend class testing::CallCountingHelperPeer; struct AtomicCounterData { - gpr_atm calls_started_ = 0; - gpr_atm calls_succeeded_ = 0; - gpr_atm calls_failed_ = 0; - gpr_atm last_call_started_millis_ = 0; + gpr_atm calls_started = 0; + gpr_atm calls_succeeded = 0; + gpr_atm calls_failed = 0; + gpr_atm last_call_started_millis = 0; }; struct CounterData { - intptr_t calls_started_ = 0; - intptr_t calls_succeeded_ = 0; - intptr_t calls_failed_ = 0; - intptr_t last_call_started_millis_ = 0; + intptr_t calls_started = 0; + intptr_t calls_succeeded = 0; + intptr_t calls_failed = 0; + intptr_t last_call_started_millis = 0; }; // collects the sharded data into one CounterData struct. diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index f99893521c1..2454079237c 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -51,8 +51,7 @@ class CallCountingHelperPeer { grpc_millis last_call_started_millis() const { CallCountingHelper::CounterData data; node_->CollectData(&data); - return (grpc_millis)gpr_atm_no_barrier_load( - &data.last_call_started_millis_); + return (grpc_millis)gpr_atm_no_barrier_load(&data.last_call_started_millis); } private: From 460faf4bc2229600dc4d65ca6642277937d62efe Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 5 Oct 2018 20:25:21 +0200 Subject: [PATCH 544/546] dont repeat "ClientCertificate" in enum values --- src/csharp/Grpc.Core/ServerCredentials.cs | 18 ++++++------ .../SslCredentialsTest.cs | 28 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/csharp/Grpc.Core/ServerCredentials.cs b/src/csharp/Grpc.Core/ServerCredentials.cs index dc86f37a42c..8e4e44ba504 100644 --- a/src/csharp/Grpc.Core/ServerCredentials.cs +++ b/src/csharp/Grpc.Core/ServerCredentials.cs @@ -68,7 +68,7 @@ namespace Grpc.Core /// all. (A client may present a self signed or signed certificate or not /// present a certificate at all and any of those option would be accepted) /// - DontRequestClientCertificate = 0, + DontRequest = 0, /// /// Server requests client certificate but does not enforce that the client /// presents a certificate. @@ -78,7 +78,7 @@ namespace Grpc.Core /// The client's key certificate pair must be valid for the SSL connection to /// be established. /// - RequestClientCertificateButDontVerify, + RequestButDontVerify, /// /// Server requests client certificate but does not enforce that the client /// presents a certificate. @@ -89,7 +89,7 @@ namespace Grpc.Core /// The client's key certificate pair must be valid for the SSL connection to /// be established. /// - RequestClientCertificateAndVerify, + RequestAndVerify, /// /// Server requests client certificate and enforces that the client presents a /// certificate. @@ -99,7 +99,7 @@ namespace Grpc.Core /// The client's key certificate pair must be valid for the SSL connection to /// be established. /// - RequestAndRequireClientCertificateButDontVerify, + RequestAndRequireButDontVerify, /// /// Server requests client certificate and enforces that the client presents a /// certificate. @@ -109,7 +109,7 @@ namespace Grpc.Core /// The client's key certificate pair must be valid for the SSL connection to /// be established. /// - RequestAndRequireClientCertificateAndVerify, + RequestAndRequireAndVerify, } /// /// Server-side SSL credentials. @@ -127,7 +127,7 @@ namespace Grpc.Core /// PEM encoded client root certificates used to authenticate client. /// Deprecated, use clientCertificateRequest overload instead. public SslServerCredentials(IEnumerable keyCertificatePairs, string rootCertificates, bool forceClientAuth) - : this(keyCertificatePairs, rootCertificates, forceClientAuth ? SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify : SslClientCertificateRequestType.DontRequestClientCertificate) + : this(keyCertificatePairs, rootCertificates, forceClientAuth ? SslClientCertificateRequestType.RequestAndRequireAndVerify : SslClientCertificateRequestType.DontRequest) { } @@ -142,7 +142,7 @@ namespace Grpc.Core this.keyCertificatePairs = new List(keyCertificatePairs).AsReadOnly(); GrpcPreconditions.CheckArgument(this.keyCertificatePairs.Count > 0, "At least one KeyCertificatePair needs to be provided."); - if (clientCertificateRequest == SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify) + if (clientCertificateRequest == SslClientCertificateRequestType.RequestAndRequireAndVerify) { GrpcPreconditions.CheckNotNull(rootCertificates, "Cannot require and verify client certificate unless you provide rootCertificates."); @@ -157,7 +157,7 @@ namespace Grpc.Core /// (client certificate won't be requested and checked by the server at all). /// /// Key-certificates to use. - public SslServerCredentials(IEnumerable keyCertificatePairs) : this(keyCertificatePairs, null, SslClientCertificateRequestType.DontRequestClientCertificate) + public SslServerCredentials(IEnumerable keyCertificatePairs) : this(keyCertificatePairs, null, SslClientCertificateRequestType.DontRequest) { } @@ -190,7 +190,7 @@ namespace Grpc.Core { get { - return this.clientCertificateRequest == SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify; + return this.clientCertificateRequest == SslClientCertificateRequestType.RequestAndRequireAndVerify; } } diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs index 1a6054f4cf6..b3c47c2d8d3 100644 --- a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs @@ -91,7 +91,7 @@ namespace Grpc.IntegrationTesting { InitClientAndServer( clientAddKeyCertPair: false, - clientCertRequestType: SslClientCertificateRequestType.DontRequestClientCertificate); + clientCertRequestType: SslClientCertificateRequestType.DontRequest); await CheckAccepted(expectPeerAuthenticated: false); } @@ -101,7 +101,7 @@ namespace Grpc.IntegrationTesting { InitClientAndServer( clientAddKeyCertPair: true, - clientCertRequestType: SslClientCertificateRequestType.DontRequestClientCertificate); + clientCertRequestType: SslClientCertificateRequestType.DontRequest); await CheckAccepted(expectPeerAuthenticated: false); } @@ -111,7 +111,7 @@ namespace Grpc.IntegrationTesting { InitClientAndServer( clientAddKeyCertPair: false, - clientCertRequestType: SslClientCertificateRequestType.RequestClientCertificateButDontVerify); + clientCertRequestType: SslClientCertificateRequestType.RequestButDontVerify); await CheckAccepted(expectPeerAuthenticated: false); } @@ -121,7 +121,7 @@ namespace Grpc.IntegrationTesting { InitClientAndServer( clientAddKeyCertPair: false, - clientCertRequestType: SslClientCertificateRequestType.RequestClientCertificateAndVerify); + clientCertRequestType: SslClientCertificateRequestType.RequestAndVerify); await CheckAccepted(expectPeerAuthenticated: false); } @@ -131,7 +131,7 @@ namespace Grpc.IntegrationTesting { InitClientAndServer( clientAddKeyCertPair: true, - clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireClientCertificateButDontVerify); + clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireButDontVerify); await CheckAccepted(expectPeerAuthenticated: true); await CheckAuthContextIsPopulated(); @@ -142,7 +142,7 @@ namespace Grpc.IntegrationTesting { InitClientAndServer( clientAddKeyCertPair: true, - clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify); + clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireAndVerify); await CheckAccepted(expectPeerAuthenticated: true); await CheckAuthContextIsPopulated(); @@ -153,7 +153,7 @@ namespace Grpc.IntegrationTesting { InitClientAndServer( clientAddKeyCertPair: false, - clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireClientCertificateButDontVerify); + clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireButDontVerify); CheckRejected(); } @@ -163,7 +163,7 @@ namespace Grpc.IntegrationTesting { InitClientAndServer( clientAddKeyCertPair: false, - clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify); + clientCertRequestType: SslClientCertificateRequestType.RequestAndRequireAndVerify); CheckRejected(); } @@ -172,20 +172,20 @@ namespace Grpc.IntegrationTesting public void Constructor_LegacyForceClientAuth() { var creds = new SslServerCredentials(new[] { keyCertPair }, rootCert, true); - Assert.AreEqual(SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify, creds.ClientCertificateRequest); + Assert.AreEqual(SslClientCertificateRequestType.RequestAndRequireAndVerify, creds.ClientCertificateRequest); var creds2 = new SslServerCredentials(new[] { keyCertPair }, rootCert, false); - Assert.AreEqual(SslClientCertificateRequestType.DontRequestClientCertificate, creds2.ClientCertificateRequest); + Assert.AreEqual(SslClientCertificateRequestType.DontRequest, creds2.ClientCertificateRequest); } [Test] public void Constructor_NullRootCerts() { var keyCertPairs = new[] { keyCertPair }; - Assert.DoesNotThrow(() => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.DontRequestClientCertificate)); - Assert.DoesNotThrow(() => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestClientCertificateAndVerify)); - Assert.DoesNotThrow(() => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireClientCertificateButDontVerify)); - Assert.Throws(typeof(ArgumentNullException), () => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireClientCertificateAndVerify)); + Assert.DoesNotThrow(() => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.DontRequest)); + Assert.DoesNotThrow(() => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndVerify)); + Assert.DoesNotThrow(() => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireButDontVerify)); + Assert.Throws(typeof(ArgumentNullException), () => new SslServerCredentials(keyCertPairs, null, SslClientCertificateRequestType.RequestAndRequireAndVerify)); } private async Task CheckAccepted(bool expectPeerAuthenticated) From f17efc8860a22fe8c1041494aafb97573177ef7c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 5 Oct 2018 11:27:16 -0700 Subject: [PATCH 545/546] Update status in objc interop tests --- src/objective-c/tests/InteropTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 5750dccd894..9d796068818 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -545,7 +545,7 @@ BOOL isRemoteInteropTest(NSString *host) { } else { // Keepalive should kick after 1s elapsed and fails the call. XCTAssertNotNil(error); - XCTAssertEqual(error.code, GRPC_STATUS_INTERNAL); + XCTAssertEqual(error.code, GRPC_STATUS_UNAVAILABLE); XCTAssertEqualObjects( error.localizedDescription, @"keepalive watchdog timeout", @"Unexpected failure that is not keepalive watchdog timeout."); From 6f6033c91019709c601f90d84617f07f8374699e Mon Sep 17 00:00:00 2001 From: ncteisen Date: Fri, 5 Oct 2018 11:30:14 -0700 Subject: [PATCH 546/546] remove stale commentS --- test/core/channel/channel_trace_test.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc index a569444fed4..3d8de79e376 100644 --- a/test/core/channel/channel_trace_test.cc +++ b/test/core/channel/channel_trace_test.cc @@ -287,8 +287,6 @@ TEST(ChannelTracerTest, TestSmallMemoryLimit) { TEST(ChannelTracerTest, TestEviction) { grpc_core::ExecCtx exec_ctx; - // This depends on sizeof(ChannelEvent). If that struct has been updated, - // this will too. const int kTraceEventSize = GetSizeofTraceEvent(); const int kNumEvents = 5; ChannelTrace tracer(kTraceEventSize * kNumEvents); @@ -306,8 +304,6 @@ TEST(ChannelTracerTest, TestEviction) { TEST(ChannelTracerTest, TestMultipleEviction) { grpc_core::ExecCtx exec_ctx; - // This depends on sizeof(ChannelEvent). If that struct has been updated, - // this will too. const int kTraceEventSize = GetSizeofTraceEvent(); const int kNumEvents = 5; ChannelTrace tracer(kTraceEventSize * kNumEvents); @@ -327,8 +323,6 @@ TEST(ChannelTracerTest, TestMultipleEviction) { TEST(ChannelTracerTest, TestTotalEviction) { grpc_core::ExecCtx exec_ctx; - // This depends on sizeof(ChannelEvent). If that struct has been updated, - // this will too. const int kTraceEventSize = GetSizeofTraceEvent(); const int kNumEvents = 5; ChannelTrace tracer(kTraceEventSize * kNumEvents);