From 215b6555c17b32fbf607aa0045db96d54949ce91 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 24 Apr 2018 15:58:11 -0700 Subject: Add Node perf tests for both implementations --- tools/run_tests/performance/build_performance.sh | 2 + .../performance/build_performance_node.sh | 26 ++++++ tools/run_tests/performance/run_worker_node.sh | 30 +++++++ tools/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 22e0ca9fa0..55762c6a23 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 0000000000..1e3f5df230 --- /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 0000000000..0278beac23 --- /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 f05753154e..b683f2d01d 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) } -- cgit v1.2.3 From 5f3aa5ca0b97d05cc0b81efb149af1f2a5b8d741 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 24 Apr 2018 16:58:58 -0700 Subject: 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 0278beac23..2511522c71 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 b683f2d01d..dde299ae36 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(), -- cgit v1.2.3 From fbf3bd460b12313802b2d4a752f544dbcf241c18 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 26 Apr 2018 14:23:49 -0700 Subject: Fix some issues with Node benchmark scripts --- tools/run_tests/performance/build_performance.sh | 5 +++-- tools/run_tests/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 55762c6a23..35d9e90598 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 1e3f5df230..74adde91f3 --- 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 2511522c71..a9bbdccbc1 --- 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 dde299ae36..bd65b82945 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', -- cgit v1.2.3 From cc8b0c0ab4592bddd3e6d2c715a5f9f0f4b2aa3f Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 26 Apr 2018 14:46:06 -0700 Subject: 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 4eddc18731..24ee71edd1 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 \ -- cgit v1.2.3 From c44cda2c3d98485a7709270cddb94d6645fbead0 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 26 Apr 2018 15:08:54 -0700 Subject: 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 bd65b82945..2e78bd07fb 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: -- cgit v1.2.3 From 07c7eda3e3bfbb2c2d33f8083515d218752506a7 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 30 Apr 2018 14:20:28 -0700 Subject: 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 9a9f74e9e5..e77bdbaa48 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) -- cgit v1.2.3 From f2177c735f12980fa20aeb57876e87f9e8539f28 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 1 May 2018 11:03:22 -0700 Subject: 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 e77bdbaa48..cfe7bfc618 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) -- cgit v1.2.3 From 9324ac67287936619199c03755c54af8da6a3486 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 19 Jun 2018 14:24:37 -0700 Subject: Regenerate build files --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6371521f6a..ab7ae5b400 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 -- cgit v1.2.3 From b51f6aba269c76519d8d1e24b99908c5f712a5e7 Mon Sep 17 00:00:00 2001 From: Carter Sande Date: Fri, 22 Jun 2018 14:31:29 +0000 Subject: 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 01ce5f03e9..7f9d9fd82b 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 80d8e63cdd..36b497ae29 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 -- cgit v1.2.3 From cf54ce355a2034fc45ff9baef27a8f710acb369f Mon Sep 17 00:00:00 2001 From: Carter Sande Date: Fri, 22 Jun 2018 15:25:48 +0000 Subject: 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 1139b3273a..85ffd5147c 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; -- cgit v1.2.3 From d5736045d35bcf2823f97cd740b7953514b76215 Mon Sep 17 00:00:00 2001 From: Carter Sande Date: Tue, 3 Jul 2018 21:34:34 +0000 Subject: 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 7f9d9fd82b..bb8cba9d55 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 -- cgit v1.2.3 From a0a061034351a6cd616ee2d01fae99604216b9ba Mon Sep 17 00:00:00 2001 From: Carter Sande Date: Thu, 5 Jul 2018 18:55:14 +0000 Subject: 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 bb8cba9d55..e850d41c5c 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 */ -- cgit v1.2.3 From 1b6e8514a9e915fb3a74e81a9724ca8043d9e81f Mon Sep 17 00:00:00 2001 From: easy Date: Wed, 11 Jul 2018 14:55:46 +1000 Subject: 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 7e5d1dfeb4..29b221f767 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 7ff2e7a8b8..9e319cb994 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(); -- cgit v1.2.3 From f0397933b007e2614ba38fc98f0ee6391a2eea9d Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 31 May 2018 19:39:52 -0700 Subject: 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 +- .../chttp2/client/insecure/channel_create_posix.cc | 2 +- .../chttp2/server/insecure/server_chttp2_posix.cc | 2 +- .../transport/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 +- .../lib/iomgr/tcp_server_utils_posix_common.cc | 2 +- src/core/lib/iomgr/tcp_windows.cc | 2 +- src/core/lib/iomgr/udp_server.cc | 2 +- src/core/lib/security/transport/secure_endpoint.cc | 4 +- .../lib/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 +- test/core/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 +- test/cpp/microbenchmarks/bm_chttp2_transport.cc | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 + tools/doxygen/Doxyfile.core.internal | 4 + tools/run_tests/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 8523bbb660..c8ee2df3a5 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 7222894af6..8570b2c35c 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 47c9dc7ccd..4edc029d38 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 3067ca9161..711edb0866 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 c277ccafc8..f75baee8a5 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 2857781dd5..9783ce3911 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 57d58cc440..04b29e5730 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 997617c530..9ff1b2bcbe 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 b69d5a7c6f..5b26cd8642 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 0db6afe468..be2325b951 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 a9dc2dc79a..a3ce1d10d2 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 4e8b8b71db..7ce8da8c00 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 dfed824cd5..5bdcb387c9 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 a0228785ee..e4bd91d07b 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 bc6fa0d0eb..7332354699 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 12060074c5..3bd7a2ce59 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 0000000000..4f0b522cca --- /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 0000000000..d42f97ff97 --- /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 92e7930111..44fb47e19d 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 15db1649fa..ea39ea632e 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 c3bc0cc8fd..70d674f750 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 5c5c246f99..3afbfd7254 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 86a0243d2e..e8ee5c4ce9 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 7b368410cf..b17aa90573 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 2189801c18..7bdfa22b8e 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 1139b3273a..6ca985cb22 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 0000000000..3f3da66840 --- /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 0000000000..92292e95e1 --- /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 80d8e63cdd..a06e9f827b 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 296ee74311..9c989b7dfe 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 990e8d632b..e02a1898f2 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 9df2e206b2..97251e7bdc 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 af89bd24db..322af62727 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 8ddf684fea..824db07fbf 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 b9f8145572..9595c028ce 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 5d316d477b..fd146c94b4 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 bdb2d0e764..3dd7cab855 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 840b2e73bc..f40f969bb7 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 aff723ed04..d76d582638 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 49185cc648..2a74d2a95c 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 c03ebcf409..ade23133c5 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 3d133cfc18..f7396a1684 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 f02fa9d998..ea9c000efb 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 fb0490a95f..a3d2ba2fc0 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 0000000000..9ffb71c85f --- /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 8db8ac5ed6..a9e8ba86c5 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 3e87831e44..648150a765 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 1156cd5fc5..ef6fd62b51 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 5958216747..3cc8ad6fe1 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 f2efb049b4..62ed72a629 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 1e9bd273aa..189923a841 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 ba322a90a5..7f526b2e2d 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 576950934e..9307302aef 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 7953fa3772..ef6141dfb1 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 5c556a2f52..3abca8efd8 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, -- cgit v1.2.3 From 0d757a659fd24ecfed801614565d2408e2e302fc Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 16 Jul 2018 16:21:43 -0700 Subject: 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 4f0b522cca..8d1645d0de 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 d42f97ff97..0f66dcc872 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 ea39ea632e..1f590a80ca 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 70d674f750..df2cf508c8 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 92292e95e1..bbe3377b43 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 97251e7bdc..4300a9f882 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 322af62727..eff825cb92 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 648150a765..6447cc234d 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; -- cgit v1.2.3 From f5ee0ffb66aba560a1a4d84fa1484fd88cd4d211 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 17 Jul 2018 07:11:22 -0700 Subject: Fix flow control tracing --- src/core/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 e89c363200..5f3dd98461 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); -- cgit v1.2.3 From bdd13cb0aef7d3f6dbc467148b4b3158485359eb Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 1 Aug 2018 11:22:40 -0700 Subject: 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 ++++++++++++++++ test/core/surface/public_headers_must_be_c89.c | 1 + test/cpp/thread_manager/thread_manager_test.cc | 149 +++++++++++++++++++------ 16 files changed, 445 insertions(+), 63 deletions(-) diff --git a/grpc.def b/grpc.def index 5b98792662..312e916682 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 f0eb2c0121..eb0251443c 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 554437a40d..50bd1cb849 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 81c3907f86..189cf8accf 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 539bc120ce..b6fc7579f7 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 937daf8728..1d5e95e04a 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 daeb0ba171..276e5f7954 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 e0b9b7a62b..0ab3cd0e32 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 0d77510e29..472c5035fc 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 02ac56a3fd..fa9eec5f9b 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 5a40f2de47..01043edb31 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 2443532bb8..78090afd6c 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 b08a1f94f7..1807efa761 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 059ff7b5f8..f3b35fed32 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 9f4ad2b4d7..497f7194d5 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 7a95a9f17d..838f5f72ad 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; } -- cgit v1.2.3 From 9ce673f86176a203811c0429872a2acf639f5285 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 1 Aug 2018 12:12:46 -0700 Subject: 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 189cf8accf..5fab071466 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 0ab3cd0e32..8417c45e64 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 472c5035fc..43e6b27de2 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), -- cgit v1.2.3 From 70a8aa4a7d145b230aa007b5d3da0256a90c0141 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 3 Aug 2018 14:40:25 -0700 Subject: 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 74adde91f3..bd765f8a15 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 a9bbdccbc1..3e5dd18edb 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 -- cgit v1.2.3 From 42c5fb98f6073101c9d25923d61f5bb745611071 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Mon, 6 Aug 2018 10:59:17 -0700 Subject: 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 1d5e95e04a..7b0ed7417a 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 -- cgit v1.2.3 From a2a64e5ad352b7a9760b04ee02facfcf287c0d60 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Mon, 6 Aug 2018 11:58:20 -0700 Subject: 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 5fab071466..189d8bec22 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 43e6b27de2..d32d6b4904 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), -- cgit v1.2.3 From 68f549e43fe433fd5393453b2f407e061f7ca240 Mon Sep 17 00:00:00 2001 From: Matthew Bender Date: Tue, 7 Aug 2018 11:25:37 -0600 Subject: 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 6337acaf60..a373cbea62 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: -- cgit v1.2.3 From 22f00acecbcd329c2706f0721533516b1772eccb Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 9 Aug 2018 12:13:02 -0700 Subject: add comments to transport --- .../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 9ad271753c..983dfa3c05 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); -- cgit v1.2.3 From 17e3611c0d5c55da1c7ae69f956e6024502edc25 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 9 Aug 2018 09:18:17 -0700 Subject: 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 +++--- test/cpp/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 70af96046c..53c93c2b16 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 0e45fc42ca..c30614e7e5 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 8d0bcc0710..b8fb8f534b 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 da095c3e68..2f66a6d53e 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 cf3b54e044..03e809c298 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": [], -- cgit v1.2.3 From 2f4fabaf78fd63904754b979534ab37cb6ef00c3 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 9 Aug 2018 13:23:05 -0700 Subject: 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 bd765f8a15..12e0872264 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 -- cgit v1.2.3 From 5e9994bf309a4fbf0206bf5312758f0c2a23aa3d Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 8 Aug 2018 15:46:25 -0700 Subject: 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 153b404d9e..4416344f11 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; -- cgit v1.2.3 From 9b72650125cd0f8b21ebd77825388e7dc3a9d191 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 9 Aug 2018 18:50:53 -0700 Subject: PF: Check connectivity state before watching --- .../lb_policy/pick_first/pick_first.cc | 103 ++++++++++++++------- .../client_channel/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 2b6a9ba8c5..2c08245a8e 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 0fa2f04e73..0a75fc10c0 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 7fe0da8aae..94f62637ec 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; -- cgit v1.2.3 From 9043a4f56d899a377d8763fa868b277d23e7b213 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 10 Aug 2018 06:11:40 +0000 Subject: 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 2f66a6d53e..4a5487f1c4 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(); -- cgit v1.2.3 From eaa51cbc9de8e06c5714d1347dec25dea389950b Mon Sep 17 00:00:00 2001 From: easy Date: Fri, 10 Aug 2018 16:28:58 +1000 Subject: 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 29b221f767..07a1333986 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 { -- cgit v1.2.3 From fc566ddcc552e5019d914973cea3eba069f410ed Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 10 Aug 2018 11:04:31 -0700 Subject: 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 cfe7bfc618..2b297c4522 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) -- cgit v1.2.3 From d760b26586b7c0621d39803df90af3ee2d3d5698 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Fri, 10 Aug 2018 14:31:21 -0700 Subject: Modify comments --- .../ext/transport/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 983dfa3c05..d8829ca0cd 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); -- cgit v1.2.3 From e84096bbe5f0e471d90906e93cba9332c392aa60 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 9 Aug 2018 13:20:35 -0700 Subject: Experimental infrastructure for callback-based CQ --- grpc.def | 1 + include/grpc/grpc.h | 6 + include/grpc/impl/codegen/grpc_types.h | 19 ++- include/grpcpp/impl/codegen/client_unary_call.h | 4 +- include/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 +- src/core/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 + test/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 5e9d86c769..962a2ec716 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 348c7a316f..4c3af45100 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 5fd080c48b..b5353c1dea 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 a37a81b75b..e4e8364e07 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 5819e068ba..272575dac2 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 7152eaf41f..cbfcf25d0a 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 7da9e6b74c..fd33ce044c 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 84446a4d92..6d8c6c9b06 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 51c1183c5f..ed92dd7eba 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 bda1c3360b..69db340e98 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 38b68462df..8a2edc41f8 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 d6add00d12..5a7884cdcd 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 7b3e875cf0..69b3de16c4 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); -- cgit v1.2.3 From f023814bff78e4af440e66923276899c948c1d44 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Fri, 10 Aug 2018 14:58:08 -0700 Subject: minor comments format fix --- src/core/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 d8829ca0cd..493d679b74 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)) { -- cgit v1.2.3 From 186df431dec8eb09e146a667edf8cfc7d45958de Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 10 Aug 2018 15:00:16 -0700 Subject: As per review --- .../lb_policy/pick_first/pick_first.cc | 28 +++++++++++++++------- .../client_channel/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 2c08245a8e..1cd5ef065d 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 0a75fc10c0..0fa2f04e73 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 94f62637ec..f2368ae7dd 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. -- cgit v1.2.3 From e509e70b2da20fe837efdca0fe8c550ced1128a9 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 10 Aug 2018 15:01:25 -0700 Subject: 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 69db340e98..1e2537a5b1 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 -- cgit v1.2.3 From a0e92e7727ded204e3ada8f5cfa455805098852f Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 10 Aug 2018 14:57:52 -0700 Subject: Add proper synchronization so that stats are setup and destroyed cleanly --- test/cpp/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 4a5487f1c4..06922afda3 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(); -- cgit v1.2.3 From ec8a5f2d74cf997582b476b83332411c4defc57c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 13 Aug 2018 14:55:22 +0200 Subject: 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 73efad1f84..eaad409ec0 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(); -- cgit v1.2.3 From c2f270fe37bcda78bd1c241a7d82339949fca6fd Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 13 Aug 2018 15:55:54 +0200 Subject: 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 ++-- src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj | 4 ++-- src/csharp/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 18993a93e0..d58f046824 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 d2cc5bbc65..7493eb8051 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 9da0539dcb..616e56df10 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 e4f36d8810..ad7033b782 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 d368697124..0c12f38f25 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 @@ - - + + -- cgit v1.2.3 From 4e1e6ceda98b0a196ddb7939153edb78a0a20dbe Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 13 Aug 2018 09:44:53 -0700 Subject: Fix pick_first to not throw away unused subchannels. --- .../lb_policy/pick_first/pick_first.cc | 22 +++------------------- .../client_channel/lb_policy/subchannel_list.h | 9 ++++----- src/core/ext/filters/client_channel/resolver.h | 13 +------------ .../resolver/dns/c_ares/dns_resolver_ares.cc | 12 +----------- .../resolver/dns/native/dns_resolver.cc | 12 +----------- .../client_channel/resolver/fake/fake_resolver.cc | 16 +--------------- .../client_channel/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 1cd5ef065d..d88b2b2ea4 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 0fa2f04e73..91ddaec8b8 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 48f2e89095..e9acbb7c41 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 f2bb5f3c71..dfa52867d8 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 282caf215c..65ff1ec1a5 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 99a33f2277..d090545d0c 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 e5175f9b7b..708eaf1147 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 f74ac5aebe..801734764b 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 f2368ae7dd..50ad78cf13 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); -- cgit v1.2.3 From f6dea9ec6a2d3a9baa5ea16dd99f52dd0a3ca0ef Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 13 Aug 2018 10:33:28 -0700 Subject: 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 50ad78cf13..8e0ee7bd76 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 -- cgit v1.2.3 From 0ec6973b743e8e1f463bdcc8691e1869097c92f0 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 Aug 2018 10:48:41 -0700 Subject: 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 0f66dcc872..cbbf50a657 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 e8ee5c4ce9..86a0243d2e 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 b17aa90573..7b368410cf 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 7bdfa22b8e..2189801c18 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 3f3da66840..8823737e49 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 */ -- cgit v1.2.3 From 82af3609dd58fcdbbfd4fc50c4232840df69a52d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 13 Aug 2018 19:52:16 +0200 Subject: 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 01e0a75b60..c301b1cdb6 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()") -- cgit v1.2.3 From 965102527f402a7e7fd0246f4fb597023f1728d1 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 7 May 2018 19:33:20 +0200 Subject: 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 9d23de866c..225098e3e0 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 50b81e5f9f..e48e87b86e 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 -- cgit v1.2.3 From cf8546255795cac575a11f696126abc4fe10b10a Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 13 Aug 2018 21:00:19 +0200 Subject: 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 225098e3e0..aa6f8d076b 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 e48e87b86e..2e3d75d819 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) -- cgit v1.2.3 From 4af7ef8c1fe10f08d52e1223342cbbcbaeee4137 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 Aug 2018 12:29:56 -0700 Subject: 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 8d1645d0de..6ada23db1c 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 6a16b8d628..d8f58408c7 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); -- cgit v1.2.3 From ac50c81a08025e36dd5a6e9127c98e08d3195c9c Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 Aug 2018 14:28:36 -0700 Subject: 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 bbe3377b43..50037bf0e9 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 b68305ce0e..375f1844ac 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 -- cgit v1.2.3 From 82b1a08e15e3fbc26e1fdd8c6ad4231b89391856 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 Aug 2018 14:55:49 -0700 Subject: 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 2ce9b0f97d..681a11291b 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) { -- cgit v1.2.3 From 5e1cf109da7713592b894366cdb78413e28e44f3 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Mon, 13 Aug 2018 14:55:30 -0700 Subject: 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 5f3dd98461..53932bcb7f 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; } -- cgit v1.2.3 From b49f47d4f26b48392950029762cd33e6365657c6 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 13 Aug 2018 16:28:53 -0700 Subject: 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 50037bf0e9..fc11be9a6d 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 375f1844ac..4d728a75fb 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 d8f58408c7..6d4c096217 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 9ffb71c85f..f1773580bd 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 */ -- cgit v1.2.3 From ca832cea906247c2a160995869af0666be24a97b Mon Sep 17 00:00:00 2001 From: Naresh Date: Tue, 14 Aug 2018 11:20:45 +0530 Subject: 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 0000000000..0d196bd600 --- /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. -- cgit v1.2.3 From a4326eb7b829cb479d14d1c4029c8522ab7f572b Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 13 Aug 2018 23:01:23 -0700 Subject: 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 06922afda3..85767c8758 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()) { -- cgit v1.2.3 From 4eff37345fbe03f850ec0ddb039e73035eaa931b Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 13 Aug 2018 23:13:41 -0700 Subject: 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 c30614e7e5..b8fe017ce7 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) { -- cgit v1.2.3 From fe7f79189be8c774a3cc210d4b86191179742ca6 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 14 Aug 2018 00:58:33 -0700 Subject: 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 fd33ce044c..9086578f7c 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 6d8c6c9b06..5aa54682e0 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: -- cgit v1.2.3 From 217d460ee261fddb2a94b1bd8a8c5e6947bbc07b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 14 Aug 2018 10:09:02 +0200 Subject: 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 9a9f74e9e5..bde2cff8f9 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: -- cgit v1.2.3 From 52e17d7d0b346863b35bf5069f8c3427e95f780b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 14 Aug 2018 10:37:13 +0200 Subject: correctly set performance job metadata on kokoro --- tools/run_tests/performance/bq_upload_result.py | 14 ++++++++------ tools/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 6702587557..b442f0cf83 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 cbb4c32a2a..9d99703725 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 -- cgit v1.2.3 From d0f116c885af5b7b4570373c33f6960108bc8baa Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 14 Aug 2018 01:43:56 -0700 Subject: 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 9086578f7c..3ded712b70 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); -- cgit v1.2.3 From e91ae9d69489d7b031aa09240ba6f044b2692ad6 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 14 Aug 2018 02:18:15 -0700 Subject: 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 5aa54682e0..a7c524d8e8 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 -- cgit v1.2.3 From a59e48e889f6afd6f915fce5d0638f0a3697df06 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 14 Aug 2018 02:18:32 -0700 Subject: 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 68129146cc..b889fd0fc6 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; } -- cgit v1.2.3 From 4bfff0a0ffe865623b6878e89771256272ef8dd0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 14 Aug 2018 17:49:25 +0200 Subject: 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 bde2cff8f9..5bf30e0050 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: -- cgit v1.2.3 From cbca2ff03f436db4f22bb130dde0fe793e55a369 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 14 Aug 2018 12:14:59 -0700 Subject: 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 3ded712b70..0769d9e4f6 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; -- cgit v1.2.3 From f025b6ed899822bcec9b1c8a2e748ccda5f45551 Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 14 Aug 2018 14:42:00 -0700 Subject: 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 d32d6b4904..4cd7ebda93 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: -- cgit v1.2.3 From 6321a53e4a31973a80d5198bb1a4298a96d6212c Mon Sep 17 00:00:00 2001 From: ncteisen Date: Tue, 14 Aug 2018 15:01:28 -0700 Subject: 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 4cd7ebda93..9d9cc7de62 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. -- cgit v1.2.3 From 1a10a9b9bf8f3ebc096b0349ccadf8f8b047251f Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 14 Aug 2018 15:05:18 -0700 Subject: Fix dns_resolver_cooldown_test and fake_resolver_test. --- .../resolvers/dns_resolver_cooldown_test.cc | 114 ++++++--------------- .../client_channel/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 b1f3a1c08a..27de7cac95 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 14caa3ea5d..f6696bf127 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)); -- cgit v1.2.3 From 14ad82a76de99de39460d901cf44767308859ae0 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 14 Aug 2018 15:04:35 -0700 Subject: Create a new method handler for resource exhaustion and tie into thread mgr --- include/grpcpp/impl/codegen/byte_buffer.h | 4 + include/grpcpp/impl/codegen/completion_queue.h | 6 +- include/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 ++++++++++------------ test/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 86c047ebe7..8cc5158115 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 272575dac2..3f7d4fb765 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 851aa2a024..53117f941b 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 153b404d9e..10372de129 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 189d8bec22..72544c0f0b 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 d32d6b4904..66d432c910 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 fa9eec5f9b..e48bf951ea 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 01043edb31..352f80baf4 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 ccf8400a87..94ad684fe7 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 838f5f72ad..99de5a3e01 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 } -- cgit v1.2.3 From 8e354419f478898c957aed82e8ea2c07057259db Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 14 Aug 2018 18:03:17 -0700 Subject: Fix LR test --- .../client_channel/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 1cd5ef065d..ab33d93398 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 -- cgit v1.2.3 From d9781df47461e10ec364290955313773cd1876e1 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 15 Aug 2018 10:13:22 -0700 Subject: 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 66d432c910..92f3f925cb 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 e48bf951ea..3e8606a76f 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. -- cgit v1.2.3 From d08ea3025b653d63652b65d52fa58517bcfa94e5 Mon Sep 17 00:00:00 2001 From: David Garcia Quintas Date: Wed, 15 Aug 2018 13:43:15 -0700 Subject: Fixed ordering in adding pending picks to PF --- .../client_channel/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 2b6a9ba8c5..bc51903ef5 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 7fe0da8aae..26c241b74a 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; -- cgit v1.2.3 From 9c32dab63dc031e71412bdb90865eafbc1f18746 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 15 Aug 2018 14:46:51 -0700 Subject: 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 352f80baf4..6f0bd17c5f 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) -- cgit v1.2.3 From befcfee767956659517266d32d262c4c83fdcbab Mon Sep 17 00:00:00 2001 From: ncteisen Date: Wed, 15 Aug 2018 15:26:54 -0700 Subject: 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 cb7b188b0e..8c7eaee203 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); } -- cgit v1.2.3 From 16f738359db28c5c2293c05d91038192345f75e1 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Wed, 15 Aug 2018 16:30:59 -0700 Subject: 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 94ad684fe7..1a5ed28a2c 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 -- cgit v1.2.3 From 33e5c0d0912900ed9c1fab8c144f5fca67120378 Mon Sep 17 00:00:00 2001 From: Paul Petit Date: Thu, 16 Aug 2018 11:35:30 +0200 Subject: 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 d2c0389ca6..0a25218e19 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) -- cgit v1.2.3 From 8a80364a9fde058d2d1126a8ec2acf3da1cbea5b Mon Sep 17 00:00:00 2001 From: Josh Haberman Date: Thu, 16 Aug 2018 06:50:10 -0700 Subject: 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 c3bfeb7615..477862a0ee 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", ], -- cgit v1.2.3 From b840d5e45c03d7a3a5d371d0358b673a07f0dc65 Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Thu, 16 Aug 2018 08:58:26 -0700 Subject: Revert "Add more filter priority levels" --- .../client_channel/client_channel_plugin.cc | 2 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 2 +- src/core/ext/filters/deadline/deadline_filter.cc | 4 ++-- .../ext/filters/http/client_authority_filter.cc | 12 +++++----- src/core/ext/filters/http/http_filters_plugin.cc | 27 ++++++++++----------- .../load_reporting/server_load_reporting_filter.cc | 3 +-- src/core/ext/filters/max_age/max_age_filter.cc | 2 +- .../filters/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 ++--- test/core/channel/minimal_stack_is_minimal_test.cc | 16 ++++++------- test/core/end2end/tests/filter_call_init_fails.cc | 15 ++++++------ test/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 71da648660..e0784b7e5c 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 6581385ff9..cf029ef4c1 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 3bd3059312..d23ad67ad5 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 3c0ae47e8d..ddc939ed12 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 38757710f3..f03fa0141d 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 0c4ffea27b..6529046a5e 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 7db30d5b48..1fe8288bd0 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 1bd9cf1426..c7fc3f2e62 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 c78849a29b..e2ea334ded 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 280daf040d..faa1c73a21 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 6543796b4c..f01852473b 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 7807b261d4..0ad82fed99 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 8058aaa804..28c6f7b121 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 0634b0416f..422e7bb65e 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 359c72737c..5e569c97e6 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 f79e0e0e96..f978ed3bf5 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 5b651ed39b..e5953acedc 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 07e1421446..ab96879fe4 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 891c1b8c1f..a7f4268803 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 02a4d07927..a89db7b094 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 6ed1de15c6..ba3cbfa6d1 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 9b603ca5b4..7bdd53f9e7 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 a8022823b1..88f8f380c3 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 -- cgit v1.2.3 From 052beefdec5d84ddd329e702ccb06fc0139a17b2 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 16 Aug 2018 11:08:00 -0700 Subject: 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 6d4c096217..8a479d2ccc 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)) { -- cgit v1.2.3 From 981f19bed286b8eb8e1a51a077d3b4aad4503398 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Thu, 16 Aug 2018 11:07:31 -0700 Subject: Remove protobuf js_embed hack --- .../protobuf_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 ba93621e4f..0000000000 --- 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 c6bcee497f..c13dfe9ade 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', -- cgit v1.2.3 From 7a7e4f56529c4da16ec6a3035e7b3bdf9dfb6f67 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 16 Aug 2018 12:04:24 -0700 Subject: 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 +- .../tsi/ssl/session_cache/ssl_session_cache.cc | 10 +++--- tools/doxygen/Doxyfile.c++.internal | 1 + tools/doxygen/Doxyfile.core.internal | 1 + tools/run_tests/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 35cf86288d..7835e8ea25 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 bd9c4237a1..bb72c41a8c 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 1d3cedb16b..ae3bd4b312 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 1998bc8b4c..146e5cc1ed 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 55d53cb71d..a5252b06fd 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 91d1fa79b5..da820dece5 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 76bdd5ac8f..c89d490b00 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 6581385ff9..a624850f4b 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 2b6a9ba8c5..0f5041ff51 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 fea84331d8..c730b3bd2b 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 38496b3d78..f79d2f0c17 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 0000000000..54751d5fe4 --- /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 96eae30345..b082634af1 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 fe4f83a13d..ce74fde343 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 592b0b20e6..43ebf8cad9 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 fa2ad93a45..0f5047a305 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 34e23f09c2..f81f3bb677 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" ], -- cgit v1.2.3 From 381bcab8bde911a0aa03d2148f2b291c1c846481 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 16 Aug 2018 15:44:19 -0700 Subject: 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/core/ext/filters/census/grpc_context.cc | 38 ++++++++++++++++++++++ src/cpp/ext/filters/census/grpc_context.cc | 38 ---------------------- src/python/grpcio/grpc_core_dependencies.py | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- tools/run_tests/generated/sources_and_headers.json | 2 +- 15 files changed, 60 insertions(+), 63 deletions(-) create mode 100644 src/core/ext/filters/census/grpc_context.cc delete mode 100644 src/cpp/ext/filters/census/grpc_context.cc diff --git a/BUILD b/BUILD index c1b573f9cf..76d5026f6c 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 c4526d2af5..32d7a9b94d 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 aa6f8d076b..3454ef8587 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 2cb349510a..e3539bc0fc 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 a46b076fe9..7825274eea 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 3aea5fa7f2..a9d1e6c9d0 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 f828185752..6f51d21c5e 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 55d53cb71d..cbb380fcea 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 ba4e8185c6..a36998bcb3 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 76bdd5ac8f..02e41bee56 100644 --- a/package.xml +++ b/package.xml @@ -758,7 +758,7 @@ - + diff --git a/src/core/ext/filters/census/grpc_context.cc b/src/core/ext/filters/census/grpc_context.cc new file mode 100644 index 0000000000..599a798dda --- /dev/null +++ b/src/core/ext/filters/census/grpc_context.cc @@ -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. + * + */ + +#include + +#include +#include +#include "src/core/lib/surface/api_trace.h" +#include "src/core/lib/surface/call.h" + +void grpc_census_call_set_context(grpc_call* call, census_context* context) { + GRPC_API_TRACE("grpc_census_call_set_context(call=%p, census_context=%p)", 2, + (call, context)); + if (context != nullptr) { + grpc_call_context_set(call, GRPC_CONTEXT_TRACING, context, nullptr); + } +} + +census_context* grpc_census_call_get_context(grpc_call* call) { + GRPC_API_TRACE("grpc_census_call_get_context(call=%p)", 1, (call)); + return static_cast( + grpc_call_context_get(call, GRPC_CONTEXT_TRACING)); +} diff --git a/src/cpp/ext/filters/census/grpc_context.cc b/src/cpp/ext/filters/census/grpc_context.cc deleted file mode 100644 index 599a798dda..0000000000 --- a/src/cpp/ext/filters/census/grpc_context.cc +++ /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. - * - */ - -#include - -#include -#include -#include "src/core/lib/surface/api_trace.h" -#include "src/core/lib/surface/call.h" - -void grpc_census_call_set_context(grpc_call* call, census_context* context) { - GRPC_API_TRACE("grpc_census_call_set_context(call=%p, census_context=%p)", 2, - (call, context)); - if (context != nullptr) { - grpc_call_context_set(call, GRPC_CONTEXT_TRACING, context, nullptr); - } -} - -census_context* grpc_census_call_get_context(grpc_call* call) { - GRPC_API_TRACE("grpc_census_call_get_context(call=%p)", 1, (call)); - return static_cast( - grpc_call_context_get(call, GRPC_CONTEXT_TRACING)); -} diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index a8158311fb..6e6d756eec 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 fa2ad93a45..d91cf09465 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 a9327bded1..886c8517c3 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" -- cgit v1.2.3 From 79851428e9d46b7e830d60e5150f9dd788a6332f Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 16 Aug 2018 15:55:53 -0700 Subject: Add a sanity check to avoid reintroducing dependence on cpp by core --- tools/run_tests/sanity/check_bad_dependencies.sh | 31 ++++++++++++++++++++++++ tools/run_tests/sanity/check_unsecure.sh | 27 --------------------- tools/run_tests/sanity/sanity_tests.yaml | 2 +- 3 files changed, 32 insertions(+), 28 deletions(-) create mode 100755 tools/run_tests/sanity/check_bad_dependencies.sh delete mode 100755 tools/run_tests/sanity/check_unsecure.sh diff --git a/tools/run_tests/sanity/check_bad_dependencies.sh b/tools/run_tests/sanity/check_bad_dependencies.sh new file mode 100755 index 0000000000..5ae0e02c81 --- /dev/null +++ b/tools/run_tests/sanity/check_bad_dependencies.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +# Make sure that there is no path from known unsecure libraries and targets +# to an SSL library. Any failure among these will make the script fail. + +test "$(bazel query 'somepath("//:grpc_unsecure", "//external:libssl")' 2>/dev/null | wc -l)" -eq 0 || exit 1 +test "$(bazel query 'somepath("//:grpc++_unsecure", "//external:libssl")' 2>/dev/null | wc -l)" -eq 0 || exit 1 +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/check_unsecure.sh b/tools/run_tests/sanity/check_unsecure.sh deleted file mode 100755 index cca1235479..0000000000 --- a/tools/run_tests/sanity/check_unsecure.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh -# Copyright 2017 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -e - -# Make sure that there is no path from known unsecure libraries and targets -# to an SSL library. Any failure among these will make the script fail. - -test "$(bazel query 'somepath("//:grpc_unsecure", "//external:libssl")' 2>/dev/null | wc -l)" -eq 0 || exit 1 -test "$(bazel query 'somepath("//:grpc++_unsecure", "//external:libssl")' 2>/dev/null | wc -l)" -eq 0 || exit 1 -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 - -exit 0 - diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml index ac0d4c70e5..91b53eb38d 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 -- cgit v1.2.3 From ccc4771630d04000c5a4998b3dc27bcb7dc8c834 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 16 Aug 2018 16:11:51 -0700 Subject: Fix Bazel BUILD --- BUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD b/BUILD index 76d5026f6c..46063008c4 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", -- cgit v1.2.3 From d9f4c7635612f0868aea70902b085bbad9abe163 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 16 Aug 2018 16:26:42 -0700 Subject: 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 46872c85a1..67f3f177ae 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); } -- cgit v1.2.3 From d19fd1c689b1d60cf329331da7fab5d1ca6063cc Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Thu, 16 Aug 2018 17:54:27 -0700 Subject: 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 bc51903ef5..ab33d93398 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 26c241b74a..68219c16dc 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; -- cgit v1.2.3 From b22c3009d4e0dcabb6228e321c39ae77989a1cd7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 16 Aug 2018 18:15:26 -0700 Subject: 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 67f3f177ae..36c709eb45 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); } -- cgit v1.2.3 From 4d6f002780e936290ddc629a6eb04a95567f5f8a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 17 Aug 2018 08:09:32 -0700 Subject: Code review changes and fix threading bug in test. --- .../filters/client_channel/lb_policy/pick_first/pick_first.cc | 11 +++-------- .../ext/filters/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 fa39d9eb93..464e3fc216 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 d090545d0c..144ac24a56 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 8e0ee7bd76..d0b7e79654 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 *******"); -- cgit v1.2.3 From aad7884233fbe037fdf7f37dd7e526a0219faa4c Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 17 Aug 2018 11:24:54 -0700 Subject: 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 2dbf9fc6b6..6ccf16aaa1 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 *******"); -- cgit v1.2.3 From 25f7d0f6f4a40dc969685192b45257d8c000a58d Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 17 Aug 2018 13:25:15 -0700 Subject: Revert to TRANSIENT_FAILURE during backoff --- src/core/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 48c6030c89..0e40f42e18 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 28f9ae6f40..b69b861fcf 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(); -- cgit v1.2.3 From 616b5d798a818d976b0bbb2ab2b1ce8c4fa6ac0e Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 17 Aug 2018 13:38:48 -0700 Subject: 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 fa19b52002..5c231eda2c 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 a0bbd659e2..9f1a052168 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: -- cgit v1.2.3 From 66a4efc5a863f40feb3574fcea59172779b81bff Mon Sep 17 00:00:00 2001 From: ZhouyihaiDing Date: Fri, 17 Aug 2018 18:09:13 -0700 Subject: 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 2bb5c4bb85..7515a01233 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(); -- cgit v1.2.3 From 49e74c087e6a6261709ce8fe7fca6b7d90a1d096 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Fri, 17 Aug 2018 20:41:16 -0700 Subject: 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 e30b297aea..4e7094d9bb 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 -- cgit v1.2.3 From add72762a7a7fb8e72a95bf5e573f2e909371ce5 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 20 Aug 2018 07:08:59 -0700 Subject: Fix round_robin to avoid negative size_t value. --- .../ext/filters/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 fea84331d8..960780a27a 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 -- cgit v1.2.3 From c818320a3d0534a95055dba521b59553b6c7d6c3 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Aug 2018 17:26:22 +0200 Subject: 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 3d4be5da6b..1ca821320c 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 dcf60848f7..ab0c0eb46a 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 7419f1a277..e1c44ecf3c 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 a8c9cb505a..f3a4382cf1 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 -- cgit v1.2.3 From 5be131147202fc210752548e73bcce3f15955c0e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Aug 2018 17:32:30 +0200 Subject: upgrade HelloworldLegacyCsproj to grpc1.14.1 and protobuf 3.6.1 --- .../HelloworldLegacyCsproj/Greeter/Greeter.csproj | 19 ++++++++++++------- .../HelloworldLegacyCsproj/Greeter/packages.config | 8 ++++---- .../GreeterClient/GreeterClient.csproj | 19 ++++++++++++------- .../GreeterClient/packages.config | 6 +++--- .../GreeterServer/GreeterServer.csproj | 19 ++++++++++++------- .../GreeterServer/packages.config | 6 +++--- .../csharp/HelloworldLegacyCsproj/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 ab584c86d3..197a9fb625 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 8e61429a8e..23857be22f 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 2d2961d128..3bb7ff1ee1 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 da7dbcd8cb..df4df8282c 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 1d47d70595..4396b04efe 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 da7dbcd8cb..df4df8282c 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 45b097e837..d1e7160f91 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 -- cgit v1.2.3 From a554a5cd709346cb1e2d23247715e82cb17b273d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 20 Aug 2018 17:34:04 +0200 Subject: regenerate protos for C# examples --- examples/csharp/Helloworld/Greeter/Helloworld.cs | 38 +++++++-- .../csharp/Helloworld/Greeter/HelloworldGrpc.cs | 23 +++--- .../HelloworldLegacyCsproj/Greeter/Helloworld.cs | 38 +++++++-- .../Greeter/HelloworldGrpc.cs | 23 +++--- .../csharp/RouteGuide/RouteGuide/RouteGuide.cs | 94 ++++++++++++++++++---- .../csharp/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 ecfc8e131c..e008ec27e5 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 c808884e57..d6b959adc6 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 ecfc8e131c..e008ec27e5 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 c808884e57..d6b959adc6 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 603809ee76..10c9aec5f8 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 765d5d520b..445708e446 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)); } -- cgit v1.2.3 From 0a69991080e0aa153d4b27df5654f699b5e12323 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Mon, 20 Aug 2018 09:32:30 -0700 Subject: 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 69a190446f..f7571d178e 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

- - + +
-
- - + + -- cgit v1.2.3 From ba4f66e705d149a4f30993befb4d6d5825b13841 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 20 Aug 2018 12:30:28 -0700 Subject: Allow more timing slack in dns cooldown test. --- test/core/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 27de7cac95..1a7db40f59 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; -- cgit v1.2.3 From 4312d1217ec6cb4ab5b7104ebd9a43f404b17462 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 20 Aug 2018 13:10:22 -0700 Subject: 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 6ccf16aaa1..e5d6132012 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()) { -- cgit v1.2.3 From 461c910a8ca883d5cabc4f9879f51840a9c99c3c Mon Sep 17 00:00:00 2001 From: ZhouyihaiDing Date: Mon, 20 Aug 2018 16:28:17 -0700 Subject: PHP: fix failed test 16392 --- .../PersistentChannelTests/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 7515a01233..5423368cdf 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']); -- cgit v1.2.3 From 22d8e60bdb7a9410023b019c277dcf5b2ee42651 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 21 Aug 2018 13:59:31 +0200 Subject: improve BUILDING.md --- BUILDING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/BUILDING.md b/BUILDING.md index e408402a76..81edb68e43 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 -- cgit v1.2.3 From 9e515951ac422faec2699fd8c7d75e7dfed6e377 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 17 Aug 2018 15:47:03 -0700 Subject: 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 e1a55d98ab..405e336028 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 a65b267d46..2c0dd75845 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*>( -- cgit v1.2.3 From 72695b886e3064cc846e3fe391d63e4fc21f5623 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Tue, 21 Aug 2018 08:51:19 -0700 Subject: 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 +++++++++++++++++++++ tools/run_tests/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 32d7a9b94d..a330fefc27 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 3454ef8587..e9a9486a3c 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 34bec00933..bf119cd71b 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 dd16694204..37999a98d1 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 0000000000..05257dd4bf --- /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 bff045f786..3a7db7d107 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 a51be28ad5..51c7b57d8a 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, -- cgit v1.2.3 From 7132cd7164198855347ae21332e104b8f4e15700 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 21 Aug 2018 18:01:53 +0200 Subject: 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 83f642a675..19a7d779b3 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) -- cgit v1.2.3 From 1096fa81a41c58d40e88a29e4ca20613a4276e6b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 21 Aug 2018 18:28:07 +0200 Subject: 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 176c8d8f24..711b9dff09 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 -- cgit v1.2.3 From 91cb48ad1aef109633365cd156e8482011c74b51 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 26 Jul 2018 11:06:24 -0700 Subject: 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 5d5c355ff9..d68fa0714b 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 8ddab0d381..f3528d527a 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 7f534476df..17e933b865 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 b1d919b292..fd65d1abf1 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; } -- cgit v1.2.3 From 087bbb2f4eddc654011ce18acbb4a0e2a243ce1d Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Tue, 21 Aug 2018 09:52:53 -0700 Subject: 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 fd65d1abf1..feedf3f149 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(); -- cgit v1.2.3 From f94d98833b6975a0f067cb29bd679a36c4151e3e Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Tue, 21 Aug 2018 13:20:59 -0700 Subject: 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 4e7094d9bb..77f9357146 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 -- cgit v1.2.3 From 0aa1bd2ed481f12b1d6348b4bf0a19093eafc7fb Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Tue, 21 Aug 2018 17:03:48 -0700 Subject: 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 1a2d2c0117..869c2f4d2f 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__': -- cgit v1.2.3 From fba18d8551dcd515b8f6b85b03a9dbda1c2e0272 Mon Sep 17 00:00:00 2001 From: Chris Lamb Date: Wed, 22 Aug 2018 16:52:46 +0100 Subject: 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 +- src/core/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 ++-- src/csharp/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 49a95b353c..105a648284 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 b06f09d8c7..d2bf4f388d 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 ddc939ed12..1ca20ebb26 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 b9b8eaf4ad..a448c9f61c 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 6c7781c51d..8742a3ba61 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 43dd68e874..44b093557f 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 52053e686b..2923a86646 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 e66fc9ba03..44bad0d19a 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 9946d1a6cf..3c9e090ba4 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 53a859d18f..085e7faf59 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 8ddda9be5c..622cfde9e7 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 ebc2d6d8d6..24fde75e5a 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 764cda17fb..e66eda64a8 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 1b9d7cbbe6..cfed7ca12a 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 fbf594a655..fc50362ca5 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 8a793e4bb2..97156761bd 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}; -- cgit v1.2.3 From f8cf7ee56d4150ae870f44298a406f7b2ca038c0 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 25 Jun 2018 10:25:28 -0700 Subject: 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 +- .../grpcio/grpc/_cython/_cygrpc/channel.pxd.pxi | 1 + .../grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi | 63 ++- .../grpc/_cython/_cygrpc/completion_queue.pyx.pxi | 2 +- .../grpc/_cython/_cygrpc/credentials.pyx.pxi | 8 +- .../grpcio/grpc/_cython/_cygrpc/fork_posix.pxd.pxi | 29 ++ .../grpcio/grpc/_cython/_cygrpc/fork_posix.pyx.pxi | 203 ++++++++++ .../grpc/_cython/_cygrpc/fork_windows.pyx.pxi | 63 +++ .../grpcio/grpc/_cython/_cygrpc/records.pyx.pxi | 2 +- .../grpcio/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 + src/python/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 + .../grpcio_tests/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 ebe9d507cd..e68755c674 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 f6d9a87d2c..0288c39680 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 123e22c4c6..5a7404f0d9 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 66e0f1fd6d..aa5016bd8f 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 b37384b8db..a5b61fb4ce 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 e9246991df..6876601785 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 a0de862d94..24e85b08e7 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 f067d76fab..ced32abba1 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 aa187e88a6..a81ff4d823 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 a2d765546a..141116df5d 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 0a25218e19..e3c1c8215c 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 0000000000..a925bdd2e6 --- /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 0000000000..1176258da8 --- /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 0000000000..8dc1ef3b1a --- /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 37b98ebbdb..fe98d559f3 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 da3dd21244..db59d468dc 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 0cc26bc0d0..8258b857bc 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 3cac406687..026f7ba2e3 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 a23c980017..0dfbf3180b 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 a94c0963ec..61c98fa038 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 0000000000..9a26bac010 --- /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 0000000000..9a32629ed5 --- /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 0000000000..889ef13cb2 --- /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 ebc41c63f0..76d5d22d57 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 0000000000..aeb02458a7 --- /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) -- cgit v1.2.3 From 0ff641a2468e9c2563e2884a0aac987ea55849c4 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Wed, 22 Aug 2018 12:25:08 -0700 Subject: 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 4c2ebaeaea..0a3097111f 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() -- cgit v1.2.3 From b59d8674d24d9b40d8d8b2b40f2be0118ff524d2 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Fri, 10 Aug 2018 10:13:36 -0700 Subject: 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 009de4e868..72e3e90c62 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 897b89851a..4e50cd0bac 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 a5b61fb4ce..ac85c81de2 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 9353208332..193f51447d 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 1176258da8..0d2516977b 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 bcbfec0c9f..4781219319 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 37b97aabd4..f44f89dfa0 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 f7a00046e3..99433f0e40 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 42dc95b9bb..b832a1661b 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); -- cgit v1.2.3 From 3a5da64e5d556b1ff57341239c0c981902c74c7e Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Wed, 22 Aug 2018 18:09:44 -0700 Subject: Move _server_cert_config_fetcher_wrapper to credentials.pyx.pxi --- .../grpc/_cython/_cygrpc/credentials.pyx.pxi | 38 ++++++++++++++++++++++ .../grpcio/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 e3c1c8215c..38fd9e78b2 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 db59d468dc..ce701724fd 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): -- cgit v1.2.3 From dc7bedd128f030b53541ed7d356858cd3bb094e6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 Aug 2018 11:36:46 +0200 Subject: 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 62cc904a61..843d88bfb6 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 7d658576e5..f23c9e9757 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 e9930b6fbc..7912b06b71 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 ba482897d7..3ce32f31b7 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."); -- cgit v1.2.3 From e7fb4e57ae5628285b75a82b54df6b6bf9e15b5e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 Aug 2018 15:43:15 +0200 Subject: avoid deadlock while cancelling a call --- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 27 +++++++++++++++++--- src/csharp/Grpc.Core/Internal/AsyncCallBase.cs | 32 ++++++++++++++++++++---- src/csharp/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 3c9e090ba4..66902f3caa 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 3273c26b88..5a53049e4b 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 11acb27533..0ceca4abb8 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) -- cgit v1.2.3 From b03578c679bd97589bf2dc58c280c0c6ba636bad Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 23 Aug 2018 07:04:30 -0700 Subject: 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 05257dd4bf..c174d8f44e 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); -- cgit v1.2.3 From ba9c343e3dd464f4e789ad4a89fc3c468c28e64d Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 23 Aug 2018 08:08:47 -0700 Subject: 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 c174d8f44e..59d8ed987f 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; -- cgit v1.2.3 From a80fa8732f0d67783e7230c89c708ae9e3334398 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 23 Aug 2018 18:15:19 +0200 Subject: 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 8916731757..171c5c470e 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 0e4456278c..281952d6d4 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; } -- cgit v1.2.3 From acc020caf77240f7504af9c2c1ea5a0dac1884d6 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Mon, 20 Aug 2018 23:00:02 -0700 Subject: 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 +++++++++++++++++++++ .../grpcio/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 fb4c71ef71..dd71ccdd0c 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 0d2516977b..303bcd976c 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: -- cgit v1.2.3 From 3d1dacd73d2e75ab4214231f32300c466c30f536 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 23 Aug 2018 09:12:23 -0700 Subject: Check poll strategy in core fork handler and log error if unsupported --- src/core/lib/iomgr/fork_posix.cc | 6 ++++++ src/python/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 ac85c81de2..e957bad73d 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 303bcd976c..433ae1f374 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) -- cgit v1.2.3 From b24b212ee585d376c618235905757b2445ac6461 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Tue, 14 Aug 2018 10:21:27 -0700 Subject: 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 + src/core/lib/security/credentials/jwt/json_token.h | 2 + .../lib/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 + src/core/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 +- src/objective-c/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 +- .../src/core/tsi/grpc_shadow_boringssl.h.template | 40 + .../objective-c/BoringSSL-GRPC.podspec.template | 1561 +++++++ test/core/iomgr/ios/CFStreamTests/Podfile | 1 + tools/buildgen/plugins/grpc_shadow_boringssl.py | 32 + .../distrib/check_shadow_boringssl_symbol_list.sh | 32 + .../generate_grpc_shadow_boringssl_symbol_list.sh | 45 + .../clang_format_all_the_things.sh | 2 +- tools/doxygen/Doxyfile.core.internal | 1 + tools/run_tests/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 81390dd1aa..b76d47b325 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 70af96046c..4f7efc90d0 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 1d9237bf62..f33cfb652b 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 5c3649afbd..e62a7962a2 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 c250316b99..841e272733 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 acdc6ffdb3..b8c4eed2eb 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 d0fb4ebd0a..3ed990140d 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 5c47276e32..c7d1b36ff0 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 02b1ac4492..c638ce76ee 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 0000000000..074be6d8d9 --- /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 115221ec06..e847267cb3 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 a90cca1a2e..37fa2d124c 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 e66fc9ba03..1d6383afdb 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 b15d02be39..0ce5e2ee6f 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 0000000000..704b35a29e --- /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 dc56680393..0000000000 --- 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 9ea2f61927..bebd55bd62 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 a2c2b82cc9..8214371bc5 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 0000000000..33a6ed0e25 --- /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 c7127b3e78..2c2344334c 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 a6dfb154a4..75a669da4d 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 3c2a34fb49..507d251b48 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 8ff4633582..204fb7de37 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 5098f351db..f912154301 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 0000000000..0b5e612881 --- /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 0000000000..986216fdbf --- /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 630168a363..e6ec66d549 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 0000000000..da4d8c12af --- /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 0000000000..34ba09e07d --- /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 0000000000..2e5bb44548 --- /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 3b901ae4bf..0c8ecc21a0 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 18f56984fe..a2b7e4fce1 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 a686dae8b4..2e1acc61f4 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 ac0d4c70e5..72bfad90bc 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 -- cgit v1.2.3 From 0cd641b4449f7d379d59940a2fd4714f7e796c5f Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 23 Aug 2018 10:02:33 -0700 Subject: 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 dd71ccdd0c..73563e3aa2 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); -- cgit v1.2.3 From 32a8a860459370c540f1150767a0a703c3c433e0 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Wed, 22 Aug 2018 23:09:55 -0700 Subject: Fix build issue --- .../ext/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 6529046a5e..8ac34c629f 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 { -- cgit v1.2.3 From 71655cf48a09621a2cfcdd497e0804b6a452df7d Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 21 Aug 2018 06:58:17 +0200 Subject: 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 e66fc9ba03..c329f41348 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 b477904d60..baffad6ea3 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); } } -- cgit v1.2.3 From 927fc8d3a3f65eb66c8127bae0055b2fae3a73c3 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 23 Aug 2018 14:36:04 -0700 Subject: 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 8a479d2ccc..44829e2ac5 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) { -- cgit v1.2.3 From b01a2774f4944c18830b83caded74c102a15cc01 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 23 Aug 2018 15:36:29 -0700 Subject: 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 73563e3aa2..b5e008ef05 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; -- cgit v1.2.3 From 676f99a8ebd397eb38f59b5b2f91d3e6c4f654d2 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 23 Aug 2018 15:44:26 -0700 Subject: 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 0288c39680..3b9c16510a 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_; -- cgit v1.2.3 From edac3c6f9b07533aa56ea50e838ff72fd1608019 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 23 Aug 2018 16:05:18 -0700 Subject: 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 b5e008ef05..16562538a6 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__) -- cgit v1.2.3 From 571109e40030548a17ea10ff208a1dec6b79f8a3 Mon Sep 17 00:00:00 2001 From: Muxi Yan Date: Thu, 23 Aug 2018 16:44:02 -0700 Subject: 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 40aba0317b..32e3956a1e 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. -- cgit v1.2.3 From 373cb20ea81f24948385954ecd06df199c4267c0 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 23 Aug 2018 17:40:28 -0700 Subject: 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 59d8ed987f..653e8a4c8e 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); -- cgit v1.2.3 From 4f98f82c36d47ff6b3c85b61854c093f93c15eb3 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Thu, 23 Aug 2018 17:45:27 -0700 Subject: 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 653e8a4c8e..a07b4df29a 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; } -- cgit v1.2.3 From 679cbb83a4178e3073d08e293a020fb39244bfe0 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 24 Aug 2018 09:04:28 -0700 Subject: 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 a07b4df29a..0d6c7c75a8 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); -- cgit v1.2.3 From 841f186041240612cca1b0010b21c5841a55fc98 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 23 Aug 2018 15:04:46 -0700 Subject: %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 44829e2ac5..1db2790265 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) { -- cgit v1.2.3 From 5f84445781ef29e50435c2eea661ca435a19b6bc Mon Sep 17 00:00:00 2001 From: Adele Zhou Date: Fri, 24 Aug 2018 14:17:12 -0700 Subject: 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 ++++---- tools/internal_ci/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 d7519b1453..4096720569 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 8f9658f78a..6419030bbb 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 aa1e613d78..7d11719ea4 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 338b1b6a0d..1eda166620 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 c7ab5b104a..ffe644a48b 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 \ -- cgit v1.2.3 From ffdcad5e0699f36b5b1a45aa5a8a8e2733d592f1 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 24 Aug 2018 16:07:49 -0700 Subject: 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 fc11be9a6d..9d122808f9 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 1db2790265..ac1e919acb 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 f1773580bd..9cdeee7a1a 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( -- cgit v1.2.3 From 8f0f66b3b33a826c4ba154eaea5b0c14a25513c7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 24 Aug 2018 17:07:16 -0700 Subject: %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 9cdeee7a1a..c7f30fa092 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; -- cgit v1.2.3 From 839a0520a2d53a220103aed68bbbe95dfd3aba05 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Thu, 23 Aug 2018 15:14:51 -0700 Subject: 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 +++ test/cpp/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 +- test/cpp/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 57592662c4..a4a9c8fe57 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 9d7469c9b5..a0961dc770 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 cabbd51843..11cfb4aa05 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 fede4d8045..cda89f7ddf 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 ba72b5b332..6275128f34 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 f2e977d48b..56d1730252 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 0ff692255c..c95e0df251 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 df929b9811..6044f4265a 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 bb415e9d63..a559c82cc8 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); -- cgit v1.2.3 From e360d822166d3e3a2d42571da0c4f4636dbc2c96 Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Sat, 25 Aug 2018 19:31:00 -0700 Subject: 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 a0961dc770..0b4b2ff0a9 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 c95e0df251..eaa0dd992c 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; -- cgit v1.2.3 From 97ba943f179cf6eda6f1a85abee01d459f507673 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 27 Aug 2018 12:43:20 +0200 Subject: 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 +- .../chttp2/client/insecure/channel_create_posix.cc | 2 +- .../chttp2/server/insecure/server_chttp2_posix.cc | 2 +- .../transport/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 +- .../lib/iomgr/tcp_server_utils_posix_common.cc | 2 +- src/core/lib/iomgr/tcp_windows.cc | 2 +- src/core/lib/iomgr/udp_server.cc | 2 +- src/core/lib/security/transport/secure_endpoint.cc | 4 +- .../lib/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 +- test/core/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 +- test/cpp/microbenchmarks/bm_chttp2_transport.cc | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 - tools/doxygen/Doxyfile.core.internal | 4 - tools/run_tests/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 c01b971281..e1b00a5cf0 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 3895d4c0f1..a330fefc27 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 7caf585ee9..e9a9486a3c 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 a7ebee7572..ce21068c31 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 af3624cdd1..7825274eea 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 ad91ee40bd..a9d1e6c9d0 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 a387794f57..207d7baa8f 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 9832283e5c..f1a9bce7f2 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 c8e58faec9..5c38071d15 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 654a531092..a36998bcb3 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 537c5404e7..1bdf127c36 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 7ce8da8c00..4e8b8b71db 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 5bdcb387c9..dfed824cd5 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 e4bd91d07b..a0228785ee 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 027a57d606..36511fa608 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 3bd7a2ce59..12060074c5 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 6ada23db1c..0000000000 --- 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 cbbf50a657..0000000000 --- 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 44fb47e19d..92e7930111 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 1f590a80ca..15db1649fa 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 df2cf508c8..c3bc0cc8fd 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 3afbfd7254..5c5c246f99 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 d4377e2d50..0205363d5c 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 8823737e49..0000000000 --- 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 fc11be9a6d..0000000000 --- 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 a4688fd0ef..066417b93c 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 9c989b7dfe..296ee74311 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 e02a1898f2..990e8d632b 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 1db2790265..b53ffbf01c 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 eff825cb92..af89bd24db 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 824db07fbf..8ddf684fea 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 9595c028ce..b9f8145572 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 64c4a56ae9..b3cb442f18 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 3dd7cab855..bdb2d0e764 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 f40f969bb7..840b2e73bc 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 d76d582638..aff723ed04 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 0f68e823d7..6e6d756eec 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 ade23133c5..c03ebcf409 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 f7396a1684..3d133cfc18 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 ea9c000efb..f02fa9d998 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 675d9e6278..002671a5fa 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 f1773580bd..0000000000 --- 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 a9e8ba86c5..8db8ac5ed6 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 6447cc234d..3e87831e44 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 ef6fd62b51..1156cd5fc5 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 3cc8ad6fe1..5958216747 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 62ed72a629..f2efb049b4 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 189923a841..1e9bd273aa 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 e6d4b1d98f..43ebf8cad9 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 7cd1dc7bf3..c1706fd070 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 8ea5126fde..5014aea9cd 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 fba76d69d1..51c7b57d8a 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, -- cgit v1.2.3 From 63322ac828c52136643159f191b7d24b5999550a Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 27 Aug 2018 14:26:45 -0700 Subject: 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 e1b00a5cf0..379c9a1f3a 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 ce21068c31..edf94b1d93 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 b3ed9bd713..c89a6cb572 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) -- cgit v1.2.3 From 8ceb27a324b5efaf2ed096a7bbdf241295272bf5 Mon Sep 17 00:00:00 2001 From: Juanli Shen Date: Mon, 27 Aug 2018 14:27:55 -0700 Subject: 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 a330fefc27..7672e26c44 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 e9a9486a3c..2609441a95 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 207d7baa8f..d5f275318b 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 f1a9bce7f2..0b4f79ac8b 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 79ec679e3a..75fd592e75 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 7a461e270f..ecd786e7b3 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 bf3f56bd54..9164b2169a 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 1bdf127c36..cb1978e2ab 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 e92fe2c5a1..a44f9acdc3 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 b8fca9a6ee..cc797f1546 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 45bd8ebd85..18515ea1e8 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 295e0f2577..55d09dda7a 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 8f38f0aa20..24d016104c 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 9c53114b84..4e7ac4e414 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 5e9a9a4513..200cee5b7b 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 52fe0dd050..38862e102a 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 d532eed245..82833102ad 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 91913d73d2..f31423f8c0 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 99dd9d68f0..469a48e782 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 c33911ebc1..24e1557578 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 9337800a33..6ffe1eb827 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 3b84f7a4c5..e080bf2cbc 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 7b0e48ea23..4b3b95fee9 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 df9953fa25..c12aa153a4 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 b2cf129e4f..f4b8a34a46 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 5c21a5b168..0c3e1ef734 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 1b5e2c362b..03d977c064 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 ccb69a8ebc..581dab3b4e 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 688c271fea..9a97ee84f2 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 43ebf8cad9..de1f48d369 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 -- cgit v1.2.3 From 82af30de3493a6bd5c95efbfa0e0a9931f8f12ae Mon Sep 17 00:00:00 2001 From: Adele Zhou Date: Mon, 27 Aug 2018 14:27:55 -0700 Subject: 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 6419030bbb..b35e6102fc 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 7d11719ea4..dc766b883d 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 1eda166620..ad3e28a394 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 ffe644a48b..5426ca56f7 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" != "" ] -- cgit v1.2.3 From 8d47cd4992c3c3546bef23568fde5fe132144666 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 27 Aug 2018 14:56:01 -0700 Subject: 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 +- .../chttp2/client/insecure/channel_create_posix.cc | 2 +- .../chttp2/server/insecure/server_chttp2_posix.cc | 2 +- .../transport/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 +- .../lib/iomgr/tcp_server_utils_posix_common.cc | 2 +- src/core/lib/iomgr/tcp_windows.cc | 2 +- src/core/lib/iomgr/udp_server.cc | 2 +- src/core/lib/security/transport/secure_endpoint.cc | 4 +- .../lib/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 +- test/core/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 +- test/cpp/microbenchmarks/bm_chttp2_transport.cc | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 + tools/doxygen/Doxyfile.core.internal | 4 + tools/run_tests/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 e1b00a5cf0..c01b971281 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 a330fefc27..3895d4c0f1 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 e9a9486a3c..7caf585ee9 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 ce21068c31..a7ebee7572 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 7825274eea..af3624cdd1 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 a9d1e6c9d0..ad91ee40bd 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 207d7baa8f..a387794f57 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 f1a9bce7f2..9832283e5c 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 5c38071d15..c8e58faec9 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 a36998bcb3..654a531092 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 1bdf127c36..537c5404e7 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 4e8b8b71db..7ce8da8c00 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 dfed824cd5..5bdcb387c9 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 a0228785ee..e4bd91d07b 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 36511fa608..027a57d606 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 12060074c5..3bd7a2ce59 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 0000000000..6ada23db1c --- /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 0000000000..cbbf50a657 --- /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 92e7930111..44fb47e19d 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 15db1649fa..1f590a80ca 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 c3bc0cc8fd..df2cf508c8 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 5c5c246f99..3afbfd7254 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 0205363d5c..d4377e2d50 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 0000000000..8823737e49 --- /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 0000000000..fc11be9a6d --- /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 066417b93c..a4688fd0ef 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 296ee74311..9c989b7dfe 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 990e8d632b..e02a1898f2 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 b53ffbf01c..1db2790265 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 af89bd24db..eff825cb92 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 8ddf684fea..824db07fbf 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 b9f8145572..9595c028ce 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 b3cb442f18..64c4a56ae9 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 bdb2d0e764..3dd7cab855 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 840b2e73bc..f40f969bb7 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 aff723ed04..d76d582638 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 6e6d756eec..0f68e823d7 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 c03ebcf409..ade23133c5 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 3d133cfc18..f7396a1684 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 f02fa9d998..ea9c000efb 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 002671a5fa..675d9e6278 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 0000000000..f1773580bd --- /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 8db8ac5ed6..a9e8ba86c5 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 3e87831e44..6447cc234d 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 1156cd5fc5..ef6fd62b51 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 5958216747..3cc8ad6fe1 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 f2efb049b4..62ed72a629 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 1e9bd273aa..189923a841 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 43ebf8cad9..e6d4b1d98f 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 c1706fd070..7cd1dc7bf3 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 5014aea9cd..8ea5126fde 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 51c7b57d8a..fba76d69d1 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, -- cgit v1.2.3 From 0cb982974f12ead39b6a8969949f2fbbe59cf3cf Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 27 Aug 2018 15:10:25 -0700 Subject: 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 8823737e49..99c22e9055 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 a4688fd0ef..abf96662f5 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 -- cgit v1.2.3 From bbfb05f61fce9f179484b6d4cf4d1c3c35b500ea Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 28 Aug 2018 10:33:00 +0200 Subject: 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 b35e6102fc..3d4d90317c 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 dc766b883d..19cfc1739a 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 ad3e28a394..edb2069fb2 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 5426ca56f7..f8c9314236 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" != "" ] -- cgit v1.2.3 From 99ce3e19afeb445245a8c2a341196ca3356501a4 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 28 Aug 2018 08:51:52 -0700 Subject: Implement Watch method in health check service. --- include/grpcpp/impl/codegen/completion_queue.h | 1 + .../server/health/default_health_check_service.cc | 484 ++++++++++++++++++--- .../server/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 + test/cpp/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 3f7d4fb765..6c8428ebde 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 bfda67d086..670da63a4a 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 a1ce5aa64e..edad594936 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 09bd98a3d9..5c214c7160 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 29e1f3bacb..9d54ccd618 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 36c709eb45..3cadf65c80 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 4b4677b8a4..38843ff1e7 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 1c48b9d151..fca65dfc13 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 6b98619c32..1c2ef9b768 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 # -- cgit v1.2.3 From 69b416a08c266f65e75fa5be70cd95788fbd968d Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 28 Aug 2018 08:53:31 -0700 Subject: 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 676aa9f298..581c550567 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 7c209db12e..9676a4535b 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). -- cgit v1.2.3 From 25d570c39c166f3dd6139f45779a15f725db5c4f Mon Sep 17 00:00:00 2001 From: Bill Feng Date: Tue, 28 Aug 2018 10:31:43 -0700 Subject: 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 5bfb253090..6b23d848be 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 -- cgit v1.2.3