aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Yash Tibrewal <yashkt@google.com>2017-11-21 16:52:06 -0800
committerGravatar Yash Tibrewal <yashkt@google.com>2017-11-21 16:52:06 -0800
commit7486144de0577e3e9453feec328741180d1f1bfa (patch)
tree23eb0c5490c5a0a6057407a05f62efac1181389b
parentd48981221542a5bd760b64e5af379adb0e846bba (diff)
parentd88421a995bf473202ecf0650eb8339a3cea3e93 (diff)
Merge master
-rw-r--r--BUILD2
-rw-r--r--CMakeLists.txt37
-rw-r--r--Makefile55
-rw-r--r--WORKSPACE61
-rw-r--r--build.yaml15
-rw-r--r--config.m41
-rw-r--r--config.w321
-rw-r--r--gRPC-Core.podspec3
-rw-r--r--grpc.gemspec2
-rw-r--r--grpc.gyp6
-rw-r--r--include/grpc++/impl/codegen/call.h1
-rw-r--r--include/grpc/impl/codegen/grpc_types.h4
-rw-r--r--include/grpc/impl/codegen/port_platform.h21
-rw-r--r--package.xml2
-rw-r--r--src/core/ext/filters/client_channel/channel_connectivity.cc2
-rw-r--r--src/core/ext/filters/client_channel/client_channel.cc63
-rw-r--r--src/core/ext/filters/client_channel/client_channel.h2
-rw-r--r--src/core/ext/filters/client_channel/client_channel_plugin.cc4
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.cc8
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.h4
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc55
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc22
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc36
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc46
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/subchannel_list.h4
-rw-r--r--src/core/ext/filters/client_channel/resolver.cc10
-rw-r--r--src/core/ext/filters/client_channel/resolver.h4
-rw-r--r--src/core/ext/filters/client_channel/subchannel.cc2
-rw-r--r--src/core/ext/filters/http/http_filters_plugin.cc1
-rw-r--r--src/core/ext/filters/http/message_compress/message_compress_filter.cc4
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_plugin.cc9
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.cc40
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.h12
-rw-r--r--src/core/ext/transport/chttp2/transport/flow_control.cc6
-rw-r--r--src/core/ext/transport/chttp2/transport/flow_control.h5
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_settings.cc7
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.cc6
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.h2
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_parser.cc4
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_table.cc6
-rw-r--r--src/core/ext/transport/chttp2/transport/internal.h12
-rw-r--r--src/core/ext/transport/chttp2/transport/parsing.cc8
-rw-r--r--src/core/ext/transport/chttp2/transport/stream_lists.cc9
-rw-r--r--src/core/ext/transport/chttp2/transport/writing.cc14
-rw-r--r--src/core/ext/transport/inproc/inproc_plugin.cc7
-rw-r--r--src/core/ext/transport/inproc/inproc_transport.cc10
-rw-r--r--src/core/ext/transport/inproc/inproc_transport.h2
-rw-r--r--src/core/lib/channel/channel_stack.cc2
-rw-r--r--src/core/lib/channel/channel_stack.h5
-rw-r--r--src/core/lib/channel/channel_stack_builder.cc4
-rw-r--r--src/core/lib/channel/channel_stack_builder.h2
-rw-r--r--src/core/lib/debug/trace.cc119
-rw-r--r--src/core/lib/debug/trace.h84
-rw-r--r--src/core/lib/http/parser.cc4
-rw-r--r--src/core/lib/http/parser.h2
-rw-r--r--src/core/lib/iomgr/call_combiner.cc31
-rw-r--r--src/core/lib/iomgr/call_combiner.h2
-rw-r--r--src/core/lib/iomgr/closure.cc216
-rw-r--r--src/core/lib/iomgr/closure.h239
-rw-r--r--src/core/lib/iomgr/combiner.cc17
-rw-r--r--src/core/lib/iomgr/combiner.h2
-rw-r--r--src/core/lib/iomgr/error.cc17
-rw-r--r--src/core/lib/iomgr/error.h4
-rw-r--r--src/core/lib/iomgr/ev_epoll1_linux.cc64
-rw-r--r--src/core/lib/iomgr/ev_epollex_linux.cc84
-rw-r--r--src/core/lib/iomgr/ev_epollsig_linux.cc26
-rw-r--r--src/core/lib/iomgr/ev_poll_posix.cc10
-rw-r--r--src/core/lib/iomgr/ev_posix.cc12
-rw-r--r--src/core/lib/iomgr/ev_posix.h2
-rw-r--r--src/core/lib/iomgr/ev_windows.cc4
-rw-r--r--src/core/lib/iomgr/exec_ctx.cc85
-rw-r--r--src/core/lib/iomgr/executor.cc16
-rw-r--r--src/core/lib/iomgr/iomgr_posix.cc1
-rw-r--r--src/core/lib/iomgr/iomgr_uv.cc2
-rw-r--r--src/core/lib/iomgr/load_file.cc1
-rw-r--r--src/core/lib/iomgr/lockfree_event.cc14
-rw-r--r--src/core/lib/iomgr/lockfree_event.h7
-rw-r--r--src/core/lib/iomgr/pollset.h4
-rw-r--r--src/core/lib/iomgr/pollset_uv.cc5
-rw-r--r--src/core/lib/iomgr/pollset_windows.cc5
-rw-r--r--src/core/lib/iomgr/resource_quota.cc27
-rw-r--r--src/core/lib/iomgr/resource_quota.h2
-rw-r--r--src/core/lib/iomgr/tcp_client_posix.cc8
-rw-r--r--src/core/lib/iomgr/tcp_client_uv.cc6
-rw-r--r--src/core/lib/iomgr/tcp_posix.cc90
-rw-r--r--src/core/lib/iomgr/tcp_posix.h2
-rw-r--r--src/core/lib/iomgr/tcp_server_posix.cc2
-rw-r--r--src/core/lib/iomgr/tcp_server_uv.cc8
-rw-r--r--src/core/lib/iomgr/tcp_uv.cc140
-rw-r--r--src/core/lib/iomgr/tcp_uv.h2
-rw-r--r--src/core/lib/iomgr/tcp_windows.cc6
-rw-r--r--src/core/lib/iomgr/timer_generic.cc39
-rw-r--r--src/core/lib/iomgr/timer_manager.cc28
-rw-r--r--src/core/lib/iomgr/timer_uv.cc7
-rw-r--r--src/core/lib/security/context/security_context.cc10
-rw-r--r--src/core/lib/security/context/security_context.h4
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_credentials.cc2
-rw-r--r--src/core/lib/security/credentials/oauth2/oauth2_credentials.cc2
-rw-r--r--src/core/lib/security/credentials/plugin/plugin_credentials.cc17
-rw-r--r--src/core/lib/security/credentials/plugin/plugin_credentials.h2
-rw-r--r--src/core/lib/security/transport/secure_endpoint.cc11
-rw-r--r--src/core/lib/security/transport/secure_endpoint.h2
-rw-r--r--src/core/lib/security/transport/security_connector.cc10
-rw-r--r--src/core/lib/security/transport/security_connector.h4
-rw-r--r--src/core/lib/slice/slice_internal.h2
-rw-r--r--src/core/lib/support/abstract.h29
-rw-r--r--src/core/lib/support/cpu_posix.cc30
-rw-r--r--src/core/lib/support/manual_constructor.h135
-rw-r--r--src/core/lib/surface/alarm.cc12
-rw-r--r--src/core/lib/surface/alarm_internal.h4
-rw-r--r--src/core/lib/surface/api_trace.cc2
-rw-r--r--src/core/lib/surface/api_trace.h12
-rw-r--r--src/core/lib/surface/call.cc49
-rw-r--r--src/core/lib/surface/call.h7
-rw-r--r--src/core/lib/surface/completion_queue.cc56
-rw-r--r--src/core/lib/surface/completion_queue.h13
-rw-r--r--src/core/lib/surface/init.cc24
-rw-r--r--src/core/lib/surface/init_secure.cc19
-rw-r--r--src/core/lib/surface/lame_client.cc2
-rw-r--r--src/core/lib/surface/server.cc15
-rw-r--r--src/core/lib/surface/server.h2
-rw-r--r--src/core/lib/transport/bdp_estimator.cc9
-rw-r--r--src/core/lib/transport/bdp_estimator.h6
-rw-r--r--src/core/lib/transport/connectivity_state.cc13
-rw-r--r--src/core/lib/transport/connectivity_state.h2
-rw-r--r--src/core/lib/transport/error_utils.cc8
-rw-r--r--src/core/lib/transport/error_utils.h8
-rw-r--r--src/core/lib/transport/metadata.cc18
-rw-r--r--src/core/lib/transport/metadata.h4
-rw-r--r--src/core/lib/transport/transport.cc10
-rw-r--r--src/core/lib/transport/transport.h4
-rw-r--r--src/core/tsi/fake_transport_security.cc8
-rw-r--r--src/core/tsi/ssl_transport_security.cc2
-rw-r--r--src/core/tsi/transport_security.cc2
-rw-r--r--src/core/tsi/transport_security.h2
-rw-r--r--src/core/tsi/transport_security_interface.h2
-rw-r--r--src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs28
-rw-r--r--src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs106
-rw-r--r--src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs58
-rw-r--r--src/csharp/Grpc.Core.Tests/PInvokeTest.cs4
-rw-r--r--src/csharp/Grpc.Core/Channel.cs28
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCall.cs37
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallBase.cs20
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallServer.cs42
-rw-r--r--src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs54
-rw-r--r--src/csharp/Grpc.Core/Internal/CallSafeHandle.cs61
-rw-r--r--src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs4
-rw-r--r--src/csharp/Grpc.Core/Internal/CompletionRegistry.cs91
-rw-r--r--src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs12
-rw-r--r--src/csharp/Grpc.Core/Internal/INativeCall.cs57
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeMethods.cs4
-rw-r--r--src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs23
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerCallHandler.cs12
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs6
-rw-r--r--src/csharp/Grpc.Core/Server.cs2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/ClientRunners.cs15
-rw-r--r--src/csharp/Grpc.IntegrationTesting/ControlExtensions.cs43
-rw-r--r--src/csharp/Grpc.IntegrationTesting/ServerRunners.cs3
-rw-r--r--src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs78
-rw-r--r--src/csharp/Grpc.Microbenchmarks/GCStats.cs69
-rw-r--r--src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj4
-rw-r--r--src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs64
-rw-r--r--src/csharp/Grpc.Microbenchmarks/Program.cs70
-rw-r--r--src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs14
-rw-r--r--src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs3
-rw-r--r--src/python/grpcio/grpc/__init__.py78
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi15
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi111
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi40
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi38
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py1
-rw-r--r--src/python/grpcio_health_checking/setup.py18
-rw-r--r--src/python/grpcio_reflection/setup.py18
-rw-r--r--src/python/grpcio_tests/tests/interop/client.py31
-rw-r--r--src/python/grpcio_tests/tests/interop/server.py7
-rw-r--r--src/python/grpcio_tests/tests/tests.json4
-rw-r--r--src/python/grpcio_tests/tests/unit/_api_test.py16
-rw-r--r--src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py519
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/README1
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/README.md15
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/certs/ca.cert.pem31
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/client.cert.pem28
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/intermediate.cert.pem31
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/localhost-1.cert.pem30
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/client.key.pem27
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/localhost-1.key.pem27
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/certs/ca.cert.pem31
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/client.cert.pem28
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/intermediate.cert.pem31
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/localhost-1.cert.pem30
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/client.key.pem27
-rw-r--r--src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/localhost-1.key.pem27
-rw-r--r--src/python/grpcio_tests/tests/unit/resources.py80
-rw-r--r--templates/Makefile.template12
-rw-r--r--templates/test/core/surface/public_headers_must_be_c89.c.template8
-rw-r--r--test/core/end2end/fixtures/http_proxy_fixture.cc16
-rw-r--r--test/core/iomgr/timer_list_test.cc13
-rw-r--r--test/core/support/BUILD10
-rw-r--r--test/core/support/manual_constructor_test.cc99
-rw-r--r--test/core/surface/public_headers_must_be_c89.c564
-rw-r--r--test/core/transport/connectivity_state_test.cc3
-rw-r--r--test/core/util/BUILD2
-rw-r--r--test/core/util/tracer_util.cc31
-rw-r--r--test/core/util/tracer_util.h32
-rw-r--r--test/cpp/microbenchmarks/bm_error.cc6
-rw-r--r--test/cpp/qps/client_async.cc36
-rw-r--r--third_party/cares/cares.BUILD209
-rw-r--r--third_party/cares/cares_local_files.BUILD57
-rwxr-xr-xtools/distrib/python/check_grpcio_tools.py20
-rw-r--r--tools/distrib/python/grpcio_tools/protoc_lib_deps.py4
-rwxr-xr-xtools/distrib/python/make_grpcio_tools.py20
-rw-r--r--tools/doxygen/Doxyfile.c++.internal1
-rw-r--r--tools/doxygen/Doxyfile.core.internal2
-rw-r--r--tools/run_tests/generated/sources_and_headers.json21
-rw-r--r--tools/run_tests/generated/tests.json24
-rwxr-xr-xtools/run_tests/sanity/check_bazel_workspace.py49
-rw-r--r--tools/run_tests/sanity/sanity_tests.yaml1
217 files changed, 4232 insertions, 2031 deletions
diff --git a/BUILD b/BUILD
index 6a514496f6..25daba8e1e 100644
--- a/BUILD
+++ b/BUILD
@@ -480,6 +480,7 @@ grpc_cc_library(
],
hdrs = [
"src/core/lib/profiling/timers.h",
+ "src/core/lib/support/abstract.h",
"src/core/lib/support/arena.h",
"src/core/lib/support/atomic.h",
"src/core/lib/support/atomic_with_atm.h",
@@ -558,7 +559,6 @@ grpc_cc_library(
"src/core/lib/http/httpcli.cc",
"src/core/lib/http/parser.cc",
"src/core/lib/iomgr/call_combiner.cc",
- "src/core/lib/iomgr/closure.cc",
"src/core/lib/iomgr/combiner.cc",
"src/core/lib/iomgr/endpoint.cc",
"src/core/lib/iomgr/endpoint_pair_posix.cc",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 153e3a0a01..77b60e898a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -430,6 +430,7 @@ add_dependencies(buildtests_c gpr_env_test)
add_dependencies(buildtests_c gpr_histogram_test)
add_dependencies(buildtests_c gpr_host_port_test)
add_dependencies(buildtests_c gpr_log_test)
+add_dependencies(buildtests_c gpr_manual_constructor_test)
add_dependencies(buildtests_c gpr_mpscq_test)
add_dependencies(buildtests_c gpr_spinlock_test)
add_dependencies(buildtests_c gpr_stack_lockfree_test)
@@ -978,7 +979,6 @@ add_library(grpc
src/core/lib/http/httpcli.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/call_combiner.cc
- src/core/lib/iomgr/closure.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.cc
src/core/lib/iomgr/endpoint_pair_posix.cc
@@ -1319,7 +1319,6 @@ add_library(grpc_cronet
src/core/lib/http/httpcli.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/call_combiner.cc
- src/core/lib/iomgr/closure.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.cc
src/core/lib/iomgr/endpoint_pair_posix.cc
@@ -1621,6 +1620,7 @@ add_library(grpc_test_util
test/core/util/port.cc
test/core/util/port_server_client.cc
test/core/util/slice_splitter.cc
+ test/core/util/tracer_util.cc
test/core/util/trickle_endpoint.cc
src/core/lib/backoff/backoff.cc
src/core/lib/channel/channel_args.cc
@@ -1641,7 +1641,6 @@ add_library(grpc_test_util
src/core/lib/http/httpcli.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/call_combiner.cc
- src/core/lib/iomgr/closure.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.cc
src/core/lib/iomgr/endpoint_pair_posix.cc
@@ -1887,6 +1886,7 @@ add_library(grpc_test_util_unsecure
test/core/util/port.cc
test/core/util/port_server_client.cc
test/core/util/slice_splitter.cc
+ test/core/util/tracer_util.cc
test/core/util/trickle_endpoint.cc
src/core/lib/backoff/backoff.cc
src/core/lib/channel/channel_args.cc
@@ -1907,7 +1907,6 @@ add_library(grpc_test_util_unsecure
src/core/lib/http/httpcli.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/call_combiner.cc
- src/core/lib/iomgr/closure.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.cc
src/core/lib/iomgr/endpoint_pair_posix.cc
@@ -2159,7 +2158,6 @@ add_library(grpc_unsecure
src/core/lib/http/httpcli.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/call_combiner.cc
- src/core/lib/iomgr/closure.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.cc
src/core/lib/iomgr/endpoint_pair_posix.cc
@@ -2910,7 +2908,6 @@ add_library(grpc++_cronet
src/core/lib/http/httpcli.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/call_combiner.cc
- src/core/lib/iomgr/closure.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.cc
src/core/lib/iomgr/endpoint_pair_posix.cc
@@ -6394,6 +6391,34 @@ target_link_libraries(gpr_log_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(gpr_manual_constructor_test
+ test/core/support/manual_constructor_test.cc
+)
+
+
+target_include_directories(gpr_manual_constructor_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${BORINGSSL_ROOT_DIR}/include
+ PRIVATE ${PROTOBUF_ROOT_DIR}/src
+ PRIVATE ${BENCHMARK_ROOT_DIR}/include
+ PRIVATE ${ZLIB_ROOT_DIR}
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+ PRIVATE ${CARES_INCLUDE_DIR}
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp
+)
+
+target_link_libraries(gpr_manual_constructor_test
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ gpr_test_util
+ gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(gpr_mpscq_test
test/core/support/mpscq_test.cc
)
diff --git a/Makefile b/Makefile
index 0dacde8c0d..25a7933b2f 100644
--- a/Makefile
+++ b/Makefile
@@ -328,6 +328,7 @@ ifeq ($(SYSTEM),Darwin)
CXXFLAGS += -stdlib=libc++
endif
CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1 -Ithird_party/abseil-cpp
+COREFLAGS += -fno-rtti -fno-exceptions
LDFLAGS += -g
CPPFLAGS += $(CPPFLAGS_$(CONFIG))
@@ -990,6 +991,7 @@ gpr_env_test: $(BINDIR)/$(CONFIG)/gpr_env_test
gpr_histogram_test: $(BINDIR)/$(CONFIG)/gpr_histogram_test
gpr_host_port_test: $(BINDIR)/$(CONFIG)/gpr_host_port_test
gpr_log_test: $(BINDIR)/$(CONFIG)/gpr_log_test
+gpr_manual_constructor_test: $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test
gpr_mpscq_test: $(BINDIR)/$(CONFIG)/gpr_mpscq_test
gpr_spinlock_test: $(BINDIR)/$(CONFIG)/gpr_spinlock_test
gpr_stack_lockfree_test: $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test
@@ -1384,6 +1386,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/gpr_histogram_test \
$(BINDIR)/$(CONFIG)/gpr_host_port_test \
$(BINDIR)/$(CONFIG)/gpr_log_test \
+ $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test \
$(BINDIR)/$(CONFIG)/gpr_mpscq_test \
$(BINDIR)/$(CONFIG)/gpr_spinlock_test \
$(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test \
@@ -1831,6 +1834,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/gpr_host_port_test || ( echo test gpr_host_port_test failed ; exit 1 )
$(E) "[RUN] Testing gpr_log_test"
$(Q) $(BINDIR)/$(CONFIG)/gpr_log_test || ( echo test gpr_log_test failed ; exit 1 )
+ $(E) "[RUN] Testing gpr_manual_constructor_test"
+ $(Q) $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test || ( echo test gpr_manual_constructor_test failed ; exit 1 )
$(E) "[RUN] Testing gpr_mpscq_test"
$(Q) $(BINDIR)/$(CONFIG)/gpr_mpscq_test || ( echo test gpr_mpscq_test failed ; exit 1 )
$(E) "[RUN] Testing gpr_spinlock_test"
@@ -2579,6 +2584,16 @@ $(OBJDIR)/$(CONFIG)/src/compiler/%.o : src/compiler/%.cc
$(Q) mkdir -p `dirname $@`
$(Q) $(HOST_CXX) $(HOST_CXXFLAGS) $(HOST_CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+$(OBJDIR)/$(CONFIG)/src/core/%.o : src/core/%.cc
+ $(E) "[CXX] Compiling $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COREFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+
+$(OBJDIR)/$(CONFIG)/test/core/%.o : test/core/%.cc
+ $(E) "[CXX] Compiling $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COREFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+
$(OBJDIR)/$(CONFIG)/%.o : %.cc
$(E) "[CXX] Compiling $<"
$(Q) mkdir -p `dirname $@`
@@ -2968,7 +2983,6 @@ LIBGRPC_SRC = \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/call_combiner.cc \
- src/core/lib/iomgr/closure.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
src/core/lib/iomgr/endpoint_pair_posix.cc \
@@ -3308,7 +3322,6 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/call_combiner.cc \
- src/core/lib/iomgr/closure.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
src/core/lib/iomgr/endpoint_pair_posix.cc \
@@ -3608,6 +3621,7 @@ LIBGRPC_TEST_UTIL_SRC = \
test/core/util/port.cc \
test/core/util/port_server_client.cc \
test/core/util/slice_splitter.cc \
+ test/core/util/tracer_util.cc \
test/core/util/trickle_endpoint.cc \
src/core/lib/backoff/backoff.cc \
src/core/lib/channel/channel_args.cc \
@@ -3628,7 +3642,6 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/call_combiner.cc \
- src/core/lib/iomgr/closure.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
src/core/lib/iomgr/endpoint_pair_posix.cc \
@@ -3864,6 +3877,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
test/core/util/port.cc \
test/core/util/port_server_client.cc \
test/core/util/slice_splitter.cc \
+ test/core/util/tracer_util.cc \
test/core/util/trickle_endpoint.cc \
src/core/lib/backoff/backoff.cc \
src/core/lib/channel/channel_args.cc \
@@ -3884,7 +3898,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/call_combiner.cc \
- src/core/lib/iomgr/closure.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
src/core/lib/iomgr/endpoint_pair_posix.cc \
@@ -4113,7 +4126,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/call_combiner.cc \
- src/core/lib/iomgr/closure.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
src/core/lib/iomgr/endpoint_pair_posix.cc \
@@ -4842,7 +4854,6 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/call_combiner.cc \
- src/core/lib/iomgr/closure.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
src/core/lib/iomgr/endpoint_pair_posix.cc \
@@ -10151,6 +10162,38 @@ endif
endif
+GPR_MANUAL_CONSTRUCTOR_TEST_SRC = \
+ test/core/support/manual_constructor_test.cc \
+
+GPR_MANUAL_CONSTRUCTOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_MANUAL_CONSTRUCTOR_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/gpr_manual_constructor_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LD) $(LDFLAGS) $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/support/manual_constructor_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
GPR_MPSCQ_TEST_SRC = \
test/core/support/mpscq_test.cc \
diff --git a/WORKSPACE b/WORKSPACE
index 5f87d68a2f..6df24e9c2f 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -10,7 +10,7 @@ bind(
bind(
name = "zlib",
- actual = "@submodule_zlib//:z",
+ actual = "@com_github_madler_zlib//:z",
)
bind(
@@ -35,22 +35,22 @@ bind(
bind(
name = "cares",
- actual = "@submodule_cares//:ares",
+ actual = "@com_github_cares_cares//:ares",
)
bind(
name = "gtest",
- actual = "@submodule_gtest//:gtest",
+ actual = "@com_github_google_googletest//:gtest",
)
bind(
name = "gmock",
- actual = "@submodule_gtest//:gmock",
+ actual = "@com_github_google_googletest//:gmock",
)
bind(
name = "benchmark",
- actual = "@submodule_benchmark//:benchmark",
+ actual = "@com_github_google_benchmark//:benchmark",
)
bind(
@@ -58,47 +58,60 @@ bind(
actual = "@com_github_gflags_gflags//:gflags",
)
-local_repository(
+http_archive(
name = "boringssl",
- path = "third_party/boringssl-with-bazel",
+ # on the master-with-bazel branch
+ url = "https://boringssl.googlesource.com/boringssl/+archive/886e7d75368e3f4fab3f4d0d3584e4abfc557755.tar.gz",
)
-new_local_repository(
- name = "submodule_zlib",
+new_http_archive(
+ name = "com_github_madler_zlib",
build_file = "third_party/zlib.BUILD",
- path = "third_party/zlib",
+ strip_prefix = "zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f",
+ url = "https://github.com/madler/zlib/archive/cacf7f1d4e3d44d871b605da3b647f07d718623f.tar.gz",
)
-new_local_repository(
+http_archive(
name = "com_google_protobuf",
- build_file = "third_party/protobuf/BUILD",
- path = "third_party/protobuf",
+ strip_prefix = "protobuf-80a37e0782d2d702d52234b62dd4b9ec74fd2c95",
+ url = "https://github.com/google/protobuf/archive/80a37e0782d2d702d52234b62dd4b9ec74fd2c95.tar.gz",
)
-new_local_repository(
- name = "submodule_gtest",
+new_http_archive(
+ name = "com_github_google_googletest",
build_file = "third_party/gtest.BUILD",
- path = "third_party/googletest",
+ strip_prefix = "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780",
+ url = "https://github.com/google/googletest/archive/ec44c6c1675c25b9827aacd08c02433cccde7780.tar.gz",
)
-local_repository(
+http_archive(
name = "com_github_gflags_gflags",
- path = "third_party/gflags",
+ strip_prefix = "gflags-30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e",
+ url = "https://github.com/gflags/gflags/archive/30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e.tar.gz",
)
-new_local_repository(
- name = "submodule_benchmark",
- path = "third_party/benchmark",
+new_http_archive(
+ name = "com_github_google_benchmark",
build_file = "third_party/benchmark.BUILD",
+ strip_prefix = "benchmark-5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8",
+ url = "https://github.com/google/benchmark/archive/5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8.tar.gz",
)
new_local_repository(
- name = "submodule_cares",
+ name = "cares_local_files",
+ build_file = "third_party/cares/cares_local_files.BUILD",
path = "third_party/cares",
+)
+
+new_http_archive(
+ name = "com_github_cares_cares",
build_file = "third_party/cares/cares.BUILD",
+ strip_prefix = "c-ares-3be1924221e1326df520f8498d704a5c4c8d0cce",
+ url = "https://github.com/c-ares/c-ares/archive/3be1924221e1326df520f8498d704a5c4c8d0cce.tar.gz",
)
-local_repository(
+http_archive(
name = "com_google_absl",
- path = "third_party/abseil-cpp",
+ strip_prefix = "abseil-cpp-cc4bed2d74f7c8717e31f9579214ab52a9c9c610",
+ url = "https://github.com/abseil/abseil-cpp/archive/cc4bed2d74f7c8717e31f9579214ab52a9c9c610.tar.gz",
)
diff --git a/build.yaml b/build.yaml
index 18f9449243..16e31eb588 100644
--- a/build.yaml
+++ b/build.yaml
@@ -104,6 +104,7 @@ filegroups:
- include/grpc/support/useful.h
headers:
- src/core/lib/profiling/timers.h
+ - src/core/lib/support/abstract.h
- src/core/lib/support/arena.h
- src/core/lib/support/atomic.h
- src/core/lib/support/atomic_with_atm.h
@@ -168,7 +169,6 @@ filegroups:
- src/core/lib/http/httpcli.cc
- src/core/lib/http/parser.cc
- src/core/lib/iomgr/call_combiner.cc
- - src/core/lib/iomgr/closure.cc
- src/core/lib/iomgr/combiner.cc
- src/core/lib/iomgr/endpoint.cc
- src/core/lib/iomgr/endpoint_pair_posix.cc
@@ -714,6 +714,7 @@ filegroups:
- test/core/util/port.h
- test/core/util/port_server_client.h
- test/core/util/slice_splitter.h
+ - test/core/util/tracer_util.h
- test/core/util/trickle_endpoint.h
src:
- src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
@@ -730,6 +731,7 @@ filegroups:
- test/core/util/port.cc
- test/core/util/port_server_client.cc
- test/core/util/slice_splitter.cc
+ - test/core/util/tracer_util.cc
- test/core/util/trickle_endpoint.cc
deps:
- gpr_test_util
@@ -2214,6 +2216,16 @@ targets:
- gpr_test_util
- gpr
uses_polling: false
+- name: gpr_manual_constructor_test
+ cpu_cost: 3
+ build: test
+ language: c
+ src:
+ - test/core/support/manual_constructor_test.cc
+ deps:
+ - gpr_test_util
+ - gpr
+ uses_polling: false
- name: gpr_mpscq_test
cpu_cost: 30
build: test
@@ -4964,6 +4976,7 @@ defaults:
CPPFLAGS: -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM
-D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
global:
+ COREFLAGS: -fno-rtti -fno-exceptions
CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1
-Ithird_party/abseil-cpp
LDFLAGS: -g
diff --git a/config.m4 b/config.m4
index 5cb46cf054..d2f2520fea 100644
--- a/config.m4
+++ b/config.m4
@@ -104,7 +104,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/call_combiner.cc \
- src/core/lib/iomgr/closure.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
src/core/lib/iomgr/endpoint_pair_posix.cc \
diff --git a/config.w32 b/config.w32
index 0fc5066b29..8a713751dc 100644
--- a/config.w32
+++ b/config.w32
@@ -81,7 +81,6 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\http\\httpcli.cc " +
"src\\core\\lib\\http\\parser.cc " +
"src\\core\\lib\\iomgr\\call_combiner.cc " +
- "src\\core\\lib\\iomgr\\closure.cc " +
"src\\core\\lib\\iomgr\\combiner.cc " +
"src\\core\\lib\\iomgr\\endpoint.cc " +
"src\\core\\lib\\iomgr\\endpoint_pair_posix.cc " +
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 01b8d65977..2f97565f1b 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -187,6 +187,7 @@ Pod::Spec.new do |s|
# To save you from scrolling, this is the last part of the podspec.
ss.source_files = 'src/core/lib/profiling/timers.h',
+ 'src/core/lib/support/abstract.h',
'src/core/lib/support/arena.h',
'src/core/lib/support/atomic.h',
'src/core/lib/support/atomic_with_atm.h',
@@ -478,7 +479,6 @@ Pod::Spec.new do |s|
'src/core/lib/http/httpcli.cc',
'src/core/lib/http/parser.cc',
'src/core/lib/iomgr/call_combiner.cc',
- 'src/core/lib/iomgr/closure.cc',
'src/core/lib/iomgr/combiner.cc',
'src/core/lib/iomgr/endpoint.cc',
'src/core/lib/iomgr/endpoint_pair_posix.cc',
@@ -707,6 +707,7 @@ Pod::Spec.new do |s|
'src/core/plugin_registry/grpc_plugin_registry.cc'
ss.private_header_files = 'src/core/lib/profiling/timers.h',
+ 'src/core/lib/support/abstract.h',
'src/core/lib/support/arena.h',
'src/core/lib/support/atomic.h',
'src/core/lib/support/atomic_with_atm.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 2fe2536cc7..0dd7ceb350 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -84,6 +84,7 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/impl/codegen/sync_posix.h )
s.files += %w( include/grpc/impl/codegen/sync_windows.h )
s.files += %w( src/core/lib/profiling/timers.h )
+ s.files += %w( src/core/lib/support/abstract.h )
s.files += %w( src/core/lib/support/arena.h )
s.files += %w( src/core/lib/support/atomic.h )
s.files += %w( src/core/lib/support/atomic_with_atm.h )
@@ -413,7 +414,6 @@ Gem::Specification.new do |s|
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/call_combiner.cc )
- s.files += %w( src/core/lib/iomgr/closure.cc )
s.files += %w( src/core/lib/iomgr/combiner.cc )
s.files += %w( src/core/lib/iomgr/endpoint.cc )
s.files += %w( src/core/lib/iomgr/endpoint_pair_posix.cc )
diff --git a/grpc.gyp b/grpc.gyp
index 7075aa9afd..fb153915ff 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -245,7 +245,6 @@
'src/core/lib/http/httpcli.cc',
'src/core/lib/http/parser.cc',
'src/core/lib/iomgr/call_combiner.cc',
- 'src/core/lib/iomgr/closure.cc',
'src/core/lib/iomgr/combiner.cc',
'src/core/lib/iomgr/endpoint.cc',
'src/core/lib/iomgr/endpoint_pair_posix.cc',
@@ -515,6 +514,7 @@
'test/core/util/port.cc',
'test/core/util/port_server_client.cc',
'test/core/util/slice_splitter.cc',
+ 'test/core/util/tracer_util.cc',
'test/core/util/trickle_endpoint.cc',
'src/core/lib/backoff/backoff.cc',
'src/core/lib/channel/channel_args.cc',
@@ -535,7 +535,6 @@
'src/core/lib/http/httpcli.cc',
'src/core/lib/http/parser.cc',
'src/core/lib/iomgr/call_combiner.cc',
- 'src/core/lib/iomgr/closure.cc',
'src/core/lib/iomgr/combiner.cc',
'src/core/lib/iomgr/endpoint.cc',
'src/core/lib/iomgr/endpoint_pair_posix.cc',
@@ -723,6 +722,7 @@
'test/core/util/port.cc',
'test/core/util/port_server_client.cc',
'test/core/util/slice_splitter.cc',
+ 'test/core/util/tracer_util.cc',
'test/core/util/trickle_endpoint.cc',
'src/core/lib/backoff/backoff.cc',
'src/core/lib/channel/channel_args.cc',
@@ -743,7 +743,6 @@
'src/core/lib/http/httpcli.cc',
'src/core/lib/http/parser.cc',
'src/core/lib/iomgr/call_combiner.cc',
- 'src/core/lib/iomgr/closure.cc',
'src/core/lib/iomgr/combiner.cc',
'src/core/lib/iomgr/endpoint.cc',
'src/core/lib/iomgr/endpoint_pair_posix.cc',
@@ -936,7 +935,6 @@
'src/core/lib/http/httpcli.cc',
'src/core/lib/http/parser.cc',
'src/core/lib/iomgr/call_combiner.cc',
- 'src/core/lib/iomgr/closure.cc',
'src/core/lib/iomgr/combiner.cc',
'src/core/lib/iomgr/endpoint.cc',
'src/core/lib/iomgr/endpoint_pair_posix.cc',
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index 1a988297dc..41e95866cf 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -579,6 +579,7 @@ class CallOpClientRecvStatus {
op->data.recv_status_on_client.trailing_metadata = metadata_map_->arr();
op->data.recv_status_on_client.status = &status_code_;
op->data.recv_status_on_client.status_details = &error_message_;
+ op->data.recv_status_on_client.error_string = nullptr;
op->flags = 0;
op->reserved = NULL;
}
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 326529e638..957286d27f 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -558,6 +558,10 @@ typedef struct grpc_op {
grpc_metadata_array* trailing_metadata;
grpc_status_code* status;
grpc_slice* status_details;
+ /** If this is not nullptr, it will be populated with the full fidelity
+ * error string for debugging purposes. The application is responsible
+ * for freeing the data. */
+ const char** error_string;
} recv_status_on_client;
struct grpc_op_recv_close_on_server {
/** out argument, set to 1 if the call failed in any way (seen as a
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index fb4bfc3162..1906886d5e 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -297,6 +297,27 @@
#endif
#endif /* GPR_NO_AUTODETECT_PLATFORM */
+/*
+ * There are platforms for which TLS should not be used even though the
+ * compiler makes it seem like it's supported (Android NDK < r12b for example).
+ * This is primarily because of linker problems and toolchain misconfiguration:
+ * TLS isn't supported until NDK r12b per
+ * https://developer.android.com/ndk/downloads/revision_history.html
+ * Since NDK r16, `__NDK_MAJOR__` and `__NDK_MINOR__` are defined in
+ * <android/ndk-version.h>. For NDK < r16, users should define these macros,
+ * e.g. `-D__NDK_MAJOR__=11 -D__NKD_MINOR__=0` for NDK r11. */
+#if defined(__ANDROID__) && defined(__clang__) && defined(GPR_GCC_TLS)
+#if __has_include(<android/ndk-version.h>)
+#include <android/ndk-version.h>
+#endif /* __has_include(<android/ndk-version.h>) */
+#if defined(__ANDROID__) && defined(__clang__) && defined(__NDK_MAJOR__) && \
+ defined(__NDK_MINOR__) && \
+ ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1)))
+#undef GPR_GCC_TLS
+#define GPR_PTHREAD_TLS 1
+#endif
+#endif /*defined(__ANDROID__) && defined(__clang__) && defined(GPR_GCC_TLS) */
+
#if defined(__has_include)
#if __has_include(<atomic>)
#define GRPC_HAS_CXX11_ATOMIC
diff --git a/package.xml b/package.xml
index 9dee62f871..59d49dd165 100644
--- a/package.xml
+++ b/package.xml
@@ -96,6 +96,7 @@
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/support/abstract.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/arena.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/atomic.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/atomic_with_atm.h" role="src" />
@@ -425,7 +426,6 @@
<file baseinstalldir="/" name="src/core/lib/http/httpcli.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/parser.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/call_combiner.cc" role="src" />
- <file baseinstalldir="/" name="src/core/lib/iomgr/closure.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/combiner.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_posix.cc" role="src" />
diff --git a/src/core/ext/filters/client_channel/channel_connectivity.cc b/src/core/ext/filters/client_channel/channel_connectivity.cc
index f6b8536757..1d5386643a 100644
--- a/src/core/ext/filters/client_channel/channel_connectivity.cc
+++ b/src/core/ext/filters/client_channel/channel_connectivity.cc
@@ -120,7 +120,7 @@ static void partly_done(state_watcher* w, bool due_to_completion,
gpr_mu_lock(&w->mu);
if (due_to_completion) {
- if (GRPC_TRACER_ON(grpc_trace_operation_failures)) {
+ if (grpc_trace_operation_failures.enabled()) {
GRPC_LOG_IF_ERROR("watch_completion_error", GRPC_ERROR_REF(error));
}
GRPC_ERROR_UNREF(error);
diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc
index 2d5e04abbc..b80be2b651 100644
--- a/src/core/ext/filters/client_channel/client_channel.cc
+++ b/src/core/ext/filters/client_channel/client_channel.cc
@@ -56,8 +56,7 @@
/* Client channel implementation */
-grpc_tracer_flag grpc_client_channel_trace =
- GRPC_TRACER_INITIALIZER(false, "client_channel");
+grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel");
/*************************************************************************
* METHOD-CONFIG TABLE
@@ -246,7 +245,7 @@ static void set_channel_connectivity_state_locked(channel_data* chand,
GRPC_ERROR_REF(error));
}
}
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p: setting connectivity state to %s", chand,
grpc_connectivity_state_name(state));
}
@@ -258,7 +257,7 @@ static void on_lb_policy_state_changed_locked(void* arg, grpc_error* error) {
grpc_connectivity_state publish_state = w->state;
/* check if the notification is for the latest policy */
if (w->lb_policy == w->chand->lb_policy) {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p: lb_policy=%p state changed to %s", w->chand,
w->lb_policy, grpc_connectivity_state_name(w->state));
}
@@ -295,7 +294,7 @@ static void watch_lb_policy_locked(channel_data* chand,
}
static void start_resolving_locked(channel_data* chand) {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p: starting name resolution", chand);
}
GPR_ASSERT(!chand->started_resolving);
@@ -367,7 +366,7 @@ static void parse_retry_throttle_params(const grpc_json* field, void* arg) {
static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
channel_data* chand = (channel_data*)arg;
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p: got resolver result: error=%s", chand,
grpc_error_string(error));
}
@@ -475,7 +474,7 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
grpc_channel_args_destroy(chand->resolver_result);
chand->resolver_result = nullptr;
}
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG,
"chand=%p: resolver result: lb_policy_name=\"%s\"%s, "
"service_config=\"%s\"",
@@ -516,7 +515,7 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
if (new_lb_policy != nullptr || error != GRPC_ERROR_NONE ||
chand->resolver == nullptr) {
if (chand->lb_policy != nullptr) {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p: unreffing lb_policy=%p", chand,
chand->lb_policy);
}
@@ -529,11 +528,11 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
// Now that we've swapped out the relevant fields of chand, check for
// error or shutdown.
if (error != GRPC_ERROR_NONE || chand->resolver == nullptr) {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p: shutting down", chand);
}
if (chand->resolver != nullptr) {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p: shutting down resolver", chand);
}
grpc_resolver_shutdown_locked(chand->resolver);
@@ -555,7 +554,7 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
grpc_error* state_error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy");
if (new_lb_policy != nullptr) {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p: initializing new LB policy", chand);
}
GRPC_ERROR_UNREF(state_error);
@@ -869,7 +868,7 @@ static void fail_pending_batch_in_call_combiner(void* arg, grpc_error* error) {
static void waiting_for_pick_batches_fail(grpc_call_element* elem,
grpc_error* error) {
call_data* calld = (call_data*)elem->call_data;
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG,
"chand=%p calld=%p: failing %" PRIuPTR " pending batches: %s",
elem->channel_data, calld, calld->waiting_for_pick_batches_count,
@@ -909,7 +908,7 @@ static void run_pending_batch_in_call_combiner(void* arg, grpc_error* ignored) {
static void waiting_for_pick_batches_resume(grpc_call_element* elem) {
channel_data* chand = (channel_data*)elem->channel_data;
call_data* calld = (call_data*)elem->call_data;
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG,
"chand=%p calld=%p: sending %" PRIuPTR
" pending batches to subchannel_call=%p",
@@ -934,7 +933,7 @@ static void waiting_for_pick_batches_resume(grpc_call_element* elem) {
static void apply_service_config_to_call_locked(grpc_call_element* elem) {
channel_data* chand = (channel_data*)elem->channel_data;
call_data* calld = (call_data*)elem->call_data;
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: applying service config to call",
chand, calld);
}
@@ -978,7 +977,7 @@ static void create_subchannel_call_locked(grpc_call_element* elem,
};
grpc_error* new_error = grpc_connected_subchannel_create_call(
calld->connected_subchannel, &call_args, &calld->subchannel_call);
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: create subchannel_call=%p: error=%s",
chand, calld, calld->subchannel_call, grpc_error_string(new_error));
}
@@ -1003,7 +1002,7 @@ static void pick_done_locked(grpc_call_element* elem, grpc_error* error) {
"Call dropped by load balancing policy")
: GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Failed to create subchannel", &error, 1);
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG,
"chand=%p calld=%p: failed to create subchannel: error=%s", chand,
calld, grpc_error_string(calld->error));
@@ -1035,7 +1034,7 @@ static void pick_callback_cancel_locked(void* arg, grpc_error* error) {
channel_data* chand = (channel_data*)elem->channel_data;
call_data* calld = (call_data*)elem->call_data;
if (calld->lb_policy != nullptr) {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: cancelling pick from LB policy %p",
chand, calld, calld->lb_policy);
}
@@ -1051,7 +1050,7 @@ static void pick_callback_done_locked(void* arg, grpc_error* error) {
grpc_call_element* elem = (grpc_call_element*)arg;
channel_data* chand = (channel_data*)elem->channel_data;
call_data* calld = (call_data*)elem->call_data;
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: pick completed asynchronously",
chand, calld);
}
@@ -1067,7 +1066,7 @@ static void pick_callback_done_locked(void* arg, grpc_error* error) {
static bool pick_callback_start_locked(grpc_call_element* elem) {
channel_data* chand = (channel_data*)elem->channel_data;
call_data* calld = (call_data*)elem->call_data;
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: starting pick on lb_policy=%p",
chand, calld, chand->lb_policy);
}
@@ -1105,7 +1104,7 @@ static bool pick_callback_start_locked(grpc_call_element* elem) {
calld->subchannel_call_context, nullptr, &calld->lb_pick_closure);
if (pick_done) {
/* synchronous grpc_lb_policy_pick call. Unref the LB policy. */
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: pick completed synchronously",
chand, calld);
}
@@ -1149,7 +1148,7 @@ static void pick_after_resolver_result_cancel_locked(void* arg,
grpc_call_element* elem = args->elem;
channel_data* chand = (channel_data*)elem->channel_data;
call_data* calld = (call_data*)elem->call_data;
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG,
"chand=%p calld=%p: cancelling pick waiting for resolver result",
chand, calld);
@@ -1170,7 +1169,7 @@ static void pick_after_resolver_result_done_locked(void* arg,
pick_after_resolver_result_args* args = (pick_after_resolver_result_args*)arg;
if (args->finished) {
/* cancelled, do nothing */
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "call cancelled before resolver result");
}
gpr_free(args);
@@ -1181,13 +1180,13 @@ static void pick_after_resolver_result_done_locked(void* arg,
channel_data* chand = (channel_data*)elem->channel_data;
call_data* calld = (call_data*)elem->call_data;
if (error != GRPC_ERROR_NONE) {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: resolver failed to return data",
chand, calld);
}
async_pick_done_locked(elem, GRPC_ERROR_REF(error));
} else if (chand->lb_policy != nullptr) {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: resolver returned, doing pick",
chand, calld);
}
@@ -1209,7 +1208,7 @@ static void pick_after_resolver_result_done_locked(void* arg,
// right way to deal with it.
else if (chand->resolver != nullptr) {
// No LB policy, so try again.
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG,
"chand=%p calld=%p: resolver returned but no LB policy, "
"trying again",
@@ -1217,7 +1216,7 @@ static void pick_after_resolver_result_done_locked(void* arg,
}
pick_after_resolver_result_start_locked(elem);
} else {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: resolver disconnected", chand,
calld);
}
@@ -1229,7 +1228,7 @@ static void pick_after_resolver_result_done_locked(void* arg,
static void pick_after_resolver_result_start_locked(grpc_call_element* elem) {
channel_data* chand = (channel_data*)elem->channel_data;
call_data* calld = (call_data*)elem->call_data;
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG,
"chand=%p calld=%p: deferring pick pending resolver result", chand,
calld);
@@ -1310,7 +1309,7 @@ static void cc_start_transport_stream_op_batch(
GPR_TIMER_BEGIN("cc_start_transport_stream_op_batch", 0);
// If we've previously been cancelled, immediately fail any new batches.
if (calld->error != GRPC_ERROR_NONE) {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: failing batch with error: %s",
chand, calld, grpc_error_string(calld->error));
}
@@ -1326,7 +1325,7 @@ static void cc_start_transport_stream_op_batch(
// error to the caller when the first batch does get passed down.
GRPC_ERROR_UNREF(calld->error);
calld->error = GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error);
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: recording cancel_error=%s", chand,
calld, grpc_error_string(calld->error));
}
@@ -1354,7 +1353,7 @@ static void cc_start_transport_stream_op_batch(
// the channel combiner, which is more efficient (especially for
// streaming calls).
if (calld->subchannel_call != nullptr) {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG,
"chand=%p calld=%p: sending batch to subchannel_call=%p", chand,
calld, calld->subchannel_call);
@@ -1368,7 +1367,7 @@ static void cc_start_transport_stream_op_batch(
// For batches containing a send_initial_metadata op, enter the channel
// combiner to start a pick.
if (batch->send_initial_metadata) {
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: entering client_channel combiner",
chand, calld);
}
@@ -1378,7 +1377,7 @@ static void cc_start_transport_stream_op_batch(
GRPC_ERROR_NONE);
} else {
// For all other batches, release the call combiner.
- if (GRPC_TRACER_ON(grpc_client_channel_trace)) {
+ if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG,
"chand=%p calld=%p: saved batch, yeilding call combiner", chand,
calld);
diff --git a/src/core/ext/filters/client_channel/client_channel.h b/src/core/ext/filters/client_channel/client_channel.h
index b84e7e8c62..170ad451bd 100644
--- a/src/core/ext/filters/client_channel/client_channel.h
+++ b/src/core/ext/filters/client_channel/client_channel.h
@@ -23,7 +23,7 @@
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/lib/channel/channel_stack.h"
-extern grpc_tracer_flag grpc_client_channel_trace;
+extern grpc_core::TraceFlag grpc_client_channel_trace;
// Channel arg key for server URI string.
#define GRPC_ARG_SERVER_URI "grpc.server_uri"
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 f30b3b2c27..71d4db63dc 100644
--- a/src/core/ext/filters/client_channel/client_channel_plugin.cc
+++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc
@@ -75,10 +75,6 @@ extern "C" void grpc_client_channel_init(void) {
GRPC_CLIENT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, append_filter,
(void*)&grpc_client_channel_filter);
grpc_http_connect_register_handshaker_factory();
- grpc_register_tracer(&grpc_client_channel_trace);
-#ifndef NDEBUG
- grpc_register_tracer(&grpc_trace_resolver_refcount);
-#endif
}
extern "C" void grpc_client_channel_shutdown(void) {
diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc
index c48c845573..6e2559936b 100644
--- a/src/core/ext/filters/client_channel/lb_policy.cc
+++ b/src/core/ext/filters/client_channel/lb_policy.cc
@@ -21,10 +21,8 @@
#define WEAK_REF_BITS 16
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_lb_policy_refcount =
- GRPC_TRACER_INITIALIZER(false, "lb_policy_refcount");
-#endif
+grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount(
+ false, "lb_policy_refcount");
void grpc_lb_policy_init(grpc_lb_policy* policy,
const grpc_lb_policy_vtable* vtable,
@@ -52,7 +50,7 @@ static gpr_atm ref_mutate(grpc_lb_policy* c, gpr_atm delta,
gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta)
: gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta);
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_lb_policy_refcount)) {
+ if (grpc_trace_lb_policy_refcount.enabled()) {
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"LB_POLICY: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", c,
purpose, old_val, old_val + delta, reason);
diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h
index 4501df0946..ca1afc42ee 100644
--- a/src/core/ext/filters/client_channel/lb_policy.h
+++ b/src/core/ext/filters/client_channel/lb_policy.h
@@ -33,9 +33,7 @@ typedef struct grpc_lb_policy grpc_lb_policy;
typedef struct grpc_lb_policy_vtable grpc_lb_policy_vtable;
typedef struct grpc_lb_policy_args grpc_lb_policy_args;
-#ifndef NDEBUG
-extern grpc_tracer_flag grpc_trace_lb_policy_refcount;
-#endif
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount;
struct grpc_lb_policy {
const grpc_lb_policy_vtable* vtable;
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 46de9b45af..9ed435988f 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
@@ -126,7 +126,7 @@
#define GRPC_GRPCLB_RECONNECT_JITTER 0.2
#define GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS 10000
-grpc_tracer_flag grpc_lb_glb_trace = GRPC_TRACER_INITIALIZER(false, "glb");
+grpc_core::TraceFlag grpc_lb_glb_trace(false, "glb");
/* add lb_token of selected subchannel (address) to the call's initial
* metadata */
@@ -216,7 +216,7 @@ static void wrapped_rr_closure(void* arg, grpc_error* error) {
} else {
grpc_grpclb_client_stats_unref(wc_arg->client_stats);
}
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO, "[grpclb %p] Unreffing RR %p", wc_arg->glb_policy,
wc_arg->rr_policy);
}
@@ -622,7 +622,7 @@ static void update_lb_connectivity_status_locked(
GPR_ASSERT(rr_state_error == GRPC_ERROR_NONE);
}
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(
GPR_INFO,
"[grpclb %p] Setting grpclb's state to %s from new RR policy %p state.",
@@ -653,7 +653,7 @@ static bool pick_from_internal_rr_locked(
}
if (server->drop) {
// Not using the RR policy, so unref it.
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO, "[grpclb %p] Unreffing RR %p for drop", glb_policy,
wc_arg->rr_policy);
}
@@ -683,7 +683,7 @@ static bool pick_from_internal_rr_locked(
(void**)&wc_arg->lb_token, &wc_arg->wrapper_closure);
if (pick_done) {
/* synchronous grpc_lb_policy_pick call. Unref the RR policy. */
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO, "[grpclb %p] Unreffing RR %p", glb_policy,
wc_arg->rr_policy);
}
@@ -799,7 +799,7 @@ static void create_rr_locked(glb_lb_policy* glb_policy,
pp->wrapped_on_complete_arg.rr_policy = glb_policy->rr_policy;
pp->wrapped_on_complete_arg.client_stats =
grpc_grpclb_client_stats_ref(glb_policy->client_stats);
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Pending pick about to (async) PICK from RR %p",
glb_policy, glb_policy->rr_policy);
@@ -814,7 +814,7 @@ static void create_rr_locked(glb_lb_policy* glb_policy,
glb_policy->pending_pings = pping->next;
GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_ping");
pping->wrapped_notify_arg.rr_policy = glb_policy->rr_policy;
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO, "[grpclb %p] Pending ping about to PING from RR %p",
glb_policy, glb_policy->rr_policy);
}
@@ -829,14 +829,14 @@ static void rr_handover_locked(glb_lb_policy* glb_policy) {
grpc_lb_policy_args* args = lb_policy_args_create(glb_policy);
GPR_ASSERT(args != nullptr);
if (glb_policy->rr_policy != nullptr) {
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_DEBUG, "[grpclb %p] Updating RR policy %p", glb_policy,
glb_policy->rr_policy);
}
grpc_lb_policy_update_locked(glb_policy->rr_policy, args);
} else {
create_rr_locked(glb_policy, args);
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_DEBUG, "[grpclb %p] Created new RR policy %p", glb_policy,
glb_policy->rr_policy);
}
@@ -1169,7 +1169,7 @@ static int glb_pick_locked(grpc_lb_policy* pol,
// need to make sure we aren't trying to pick from a RR policy instance
// that's in shutdown.
if (rr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] NOT picking from from RR %p: RR conn state=%s",
glb_policy, glb_policy->rr_policy,
@@ -1179,7 +1179,7 @@ static int glb_pick_locked(grpc_lb_policy* pol,
on_complete);
pick_done = false;
} else { // RR not in shutdown
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO, "[grpclb %p] about to PICK from RR %p", glb_policy,
glb_policy->rr_policy);
}
@@ -1202,8 +1202,8 @@ static int glb_pick_locked(grpc_lb_policy* pol,
pick_done = pick_from_internal_rr_locked(
glb_policy, pick_args, false /* force_async */, target, wc_arg);
}
- } else { // glb_policy->rr_policy == nullptr
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ } else { // glb_policy->rr_policy == NULL
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_DEBUG,
"[grpclb %p] No RR policy. Adding to grpclb's pending picks",
glb_policy);
@@ -1250,7 +1250,7 @@ static void lb_call_on_retry_timer_locked(void* arg, grpc_error* error) {
glb_policy->retry_timer_active = false;
if (!glb_policy->shutting_down && glb_policy->lb_call == nullptr &&
error == GRPC_ERROR_NONE) {
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO, "[grpclb %p] Restarting call to LB server", glb_policy);
}
query_for_backends_locked(glb_policy);
@@ -1269,7 +1269,7 @@ static void maybe_restart_lb_call(glb_lb_policy* glb_policy) {
/* if we aren't shutting down, restart the LB client call after some time */
grpc_millis next_try = grpc_backoff_step(&glb_policy->lb_call_backoff_state)
.next_attempt_start_time;
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_DEBUG, "[grpclb %p] Connection to LB server lost...",
glb_policy);
grpc_millis timeout = next_try - grpc_core::ExecCtx::Get()->Now();
@@ -1315,6 +1315,9 @@ static void client_load_report_done_locked(void* arg, grpc_error* error) {
if (error != GRPC_ERROR_NONE || glb_policy->lb_call == nullptr) {
glb_policy->client_load_report_timer_pending = false;
GRPC_LB_POLICY_WEAK_UNREF(&glb_policy->base, "client_load_report");
+ if (glb_policy->lb_call == nullptr) {
+ maybe_restart_lb_call(glb_policy);
+ }
return;
}
schedule_next_client_load_report(glb_policy);
@@ -1461,7 +1464,7 @@ static void query_for_backends_locked(glb_lb_policy* glb_policy) {
lb_call_init_locked(glb_policy);
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Query for backends (lb_channel: %p, lb_call: %p)",
glb_policy, glb_policy->lb_channel, glb_policy->lb_call);
@@ -1551,7 +1554,7 @@ static void lb_on_response_received_locked(void* arg, grpc_error* error) {
glb_policy->client_stats_report_interval = GPR_MAX(
GPR_MS_PER_SEC, grpc_grpclb_duration_to_millis(
&response->client_stats_report_interval));
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Received initial LB response message; "
"client load reporting interval = %" PRIdPTR " milliseconds",
@@ -1563,7 +1566,7 @@ static void lb_on_response_received_locked(void* arg, grpc_error* error) {
glb_policy->client_load_report_timer_pending = true;
GRPC_LB_POLICY_WEAK_REF(&glb_policy->base, "client_load_report");
schedule_next_client_load_report(glb_policy);
- } else if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ } else if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Received initial LB response message; client load "
"reporting NOT enabled",
@@ -1576,7 +1579,7 @@ static void lb_on_response_received_locked(void* arg, grpc_error* error) {
grpc_grpclb_response_parse_serverlist(response_slice);
if (serverlist != nullptr) {
GPR_ASSERT(glb_policy->lb_call != nullptr);
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Serverlist with %" PRIuPTR " servers received",
glb_policy, serverlist->num_servers);
@@ -1594,7 +1597,7 @@ static void lb_on_response_received_locked(void* arg, grpc_error* error) {
if (serverlist->num_servers > 0) {
if (grpc_grpclb_serverlist_equals(glb_policy->serverlist,
serverlist)) {
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Incoming server list identical to current, "
"ignoring.",
@@ -1622,7 +1625,7 @@ static void lb_on_response_received_locked(void* arg, grpc_error* error) {
rr_handover_locked(glb_policy);
}
} else {
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Received empty server list, ignoring.",
glb_policy);
@@ -1669,7 +1672,7 @@ static void lb_on_fallback_timer_locked(void* arg, grpc_error* error) {
* actually runs, don't fall back. */
if (glb_policy->serverlist == nullptr) {
if (!glb_policy->shutting_down && error == GRPC_ERROR_NONE) {
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Falling back to use backends from resolver",
glb_policy);
@@ -1684,7 +1687,7 @@ static void lb_on_fallback_timer_locked(void* arg, grpc_error* error) {
static void lb_on_server_status_received_locked(void* arg, grpc_error* error) {
glb_lb_policy* glb_policy = (glb_lb_policy*)arg;
GPR_ASSERT(glb_policy->lb_call != nullptr);
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
char* status_details =
grpc_slice_to_c_string(glb_policy->lb_call_status_details);
gpr_log(GPR_INFO,
@@ -1863,7 +1866,7 @@ static grpc_lb_policy* glb_create(grpc_lb_policy_factory* factory,
GPR_ASSERT(uri->path[0] != '\0');
glb_policy->server_name =
gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path);
- if (GRPC_TRACER_ON(grpc_lb_glb_trace)) {
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Will use '%s' as the server name for LB request.",
glb_policy, glb_policy->server_name);
@@ -1957,10 +1960,6 @@ static bool maybe_add_client_load_reporting_filter(
extern "C" void grpc_lb_policy_grpclb_init() {
grpc_register_lb_policy(grpc_glb_lb_factory_create());
- grpc_register_tracer(&grpc_lb_glb_trace);
-#ifndef NDEBUG
- grpc_register_tracer(&grpc_trace_lb_policy_refcount);
-#endif
grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL,
GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
maybe_add_client_load_reporting_filter,
diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
index 159a087ee0..93b5feb86b 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
@@ -29,8 +29,7 @@
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/transport/connectivity_state.h"
-grpc_tracer_flag grpc_lb_pick_first_trace =
- GRPC_TRACER_INITIALIZER(false, "pick_first");
+grpc_core::TraceFlag grpc_lb_pick_first_trace(false, "pick_first");
typedef struct pending_pick {
struct pending_pick* next;
@@ -66,13 +65,13 @@ static void pf_destroy(grpc_lb_policy* pol) {
grpc_connectivity_state_destroy(&p->state_tracker);
gpr_free(p);
grpc_subchannel_index_unref();
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_DEBUG, "Pick First %p destroyed.", (void*)p);
}
}
static void shutdown_locked(pick_first_lb_policy* p, grpc_error* error) {
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_DEBUG, "Pick First %p Shutting down", p);
}
p->shutdown = true;
@@ -253,7 +252,7 @@ static void pf_update_locked(grpc_lb_policy* policy,
}
const grpc_lb_addresses* addresses =
(const grpc_lb_addresses*)arg->value.pointer.p;
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO, "Pick First %p received update with %lu addresses",
(void*)p, (unsigned long)addresses->num_addresses);
}
@@ -290,7 +289,7 @@ static void pf_update_locked(grpc_lb_policy* policy,
grpc_lb_subchannel_data* sd = &subchannel_list->subchannels[i];
if (sd->subchannel == p->selected->subchannel) {
// The currently selected subchannel is in the update: we are done.
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
"Pick First %p found already selected subchannel %p "
"at update index %" PRIuPTR " of %" PRIuPTR "; update done",
@@ -328,7 +327,7 @@ static void pf_update_locked(grpc_lb_policy* policy,
// for it to report READY before swapping it into the current
// subchannel list.
if (p->latest_pending_subchannel_list != nullptr) {
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_DEBUG,
"Pick First %p Shutting down latest pending subchannel list "
"%p, about to be replaced by newer latest %p",
@@ -353,7 +352,7 @@ static void pf_update_locked(grpc_lb_policy* policy,
static void pf_connectivity_changed_locked(void* arg, grpc_error* error) {
grpc_lb_subchannel_data* sd = (grpc_lb_subchannel_data*)arg;
pick_first_lb_policy* p = (pick_first_lb_policy*)sd->subchannel_list->policy;
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_DEBUG,
"Pick First %p connectivity changed for subchannel %p (%" PRIuPTR
" of %" PRIuPTR
@@ -449,7 +448,7 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) {
grpc_subchannel_get_connected_subchannel(sd->subchannel),
"connected");
p->selected = sd;
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", (void*)p,
(void*)sd->subchannel);
}
@@ -461,7 +460,7 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) {
p->pending_picks = pp->next;
*pp->target = GRPC_CONNECTED_SUBCHANNEL_REF(
p->selected->connected_subchannel, "picked");
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
"Servicing pending pick with selected subchannel %p",
(void*)p->selected);
@@ -557,7 +556,7 @@ static grpc_lb_policy* create_pick_first(grpc_lb_policy_factory* factory,
grpc_lb_policy_args* args) {
GPR_ASSERT(args->client_channel_factory != nullptr);
pick_first_lb_policy* p = (pick_first_lb_policy*)gpr_zalloc(sizeof(*p));
- if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_DEBUG, "Pick First %p created.", (void*)p);
}
pf_update_locked(&p->base, args);
@@ -581,7 +580,6 @@ static grpc_lb_policy_factory* pick_first_lb_factory_create() {
extern "C" void grpc_lb_policy_pick_first_init() {
grpc_register_lb_policy(pick_first_lb_factory_create());
- grpc_register_tracer(&grpc_lb_pick_first_trace);
}
extern "C" void grpc_lb_policy_pick_first_shutdown() {}
diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
index 2382f066e8..7f21cc8f3c 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
@@ -39,8 +39,7 @@
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/static_metadata.h"
-grpc_tracer_flag grpc_lb_round_robin_trace =
- GRPC_TRACER_INITIALIZER(false, "round_robin");
+grpc_core::TraceFlag grpc_lb_round_robin_trace(false, "round_robin");
/** List of entities waiting for a pick.
*
@@ -101,7 +100,7 @@ typedef struct round_robin_lb_policy {
static size_t get_next_ready_subchannel_index_locked(
const round_robin_lb_policy* p) {
GPR_ASSERT(p->subchannel_list != nullptr);
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO,
"[RR %p] getting next ready subchannel (out of %lu), "
"last_ready_subchannel_index=%lu",
@@ -111,7 +110,7 @@ static size_t get_next_ready_subchannel_index_locked(
for (size_t i = 0; i < p->subchannel_list->num_subchannels; ++i) {
const size_t index = (i + p->last_ready_subchannel_index + 1) %
p->subchannel_list->num_subchannels;
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(
GPR_DEBUG,
"[RR %p] checking subchannel %p, subchannel_list %p, index %lu: "
@@ -123,7 +122,7 @@ static size_t get_next_ready_subchannel_index_locked(
}
if (p->subchannel_list->subchannels[index].curr_connectivity_state ==
GRPC_CHANNEL_READY) {
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG,
"[RR %p] found next ready subchannel (%p) at index %lu of "
"subchannel_list %p",
@@ -134,7 +133,7 @@ static size_t get_next_ready_subchannel_index_locked(
return index;
}
}
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG, "[RR %p] no subchannels in ready state", (void*)p);
}
return p->subchannel_list->num_subchannels;
@@ -145,7 +144,7 @@ static void update_last_ready_subchannel_index_locked(round_robin_lb_policy* p,
size_t last_ready_index) {
GPR_ASSERT(last_ready_index < p->subchannel_list->num_subchannels);
p->last_ready_subchannel_index = last_ready_index;
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG,
"[RR %p] setting last_ready_subchannel_index=%lu (SC %p, CSC %p)",
(void*)p, (unsigned long)last_ready_index,
@@ -157,7 +156,7 @@ static void update_last_ready_subchannel_index_locked(round_robin_lb_policy* p,
static void rr_destroy(grpc_lb_policy* pol) {
round_robin_lb_policy* p = (round_robin_lb_policy*)pol;
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG, "[RR %p] Destroying Round Robin policy at %p",
(void*)pol, (void*)pol);
}
@@ -169,7 +168,7 @@ static void rr_destroy(grpc_lb_policy* pol) {
}
static void shutdown_locked(round_robin_lb_policy* p, grpc_error* error) {
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG, "[RR %p] Shutting down", p);
}
p->shutdown = true;
@@ -271,7 +270,7 @@ static int rr_pick_locked(grpc_lb_policy* pol,
grpc_call_context_element* context, void** user_data,
grpc_closure* on_complete) {
round_robin_lb_policy* p = (round_robin_lb_policy*)pol;
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO, "[RR %p] Trying to pick (shutdown: %d)", (void*)pol,
p->shutdown);
}
@@ -287,7 +286,7 @@ static int rr_pick_locked(grpc_lb_policy* pol,
if (user_data != nullptr) {
*user_data = sd->user_data;
}
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(
GPR_DEBUG,
"[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, "
@@ -386,7 +385,7 @@ static grpc_connectivity_state update_lb_connectivity_status_locked(
GRPC_ERROR_REF(error), "rr_shutdown");
p->shutdown = true;
new_state = GRPC_CHANNEL_SHUTDOWN;
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO,
"[RR %p] Shutting down: all subchannels have gone into shutdown",
(void*)p);
@@ -411,7 +410,7 @@ static void rr_connectivity_changed_locked(void* arg, grpc_error* error) {
grpc_lb_subchannel_data* sd = (grpc_lb_subchannel_data*)arg;
round_robin_lb_policy* p =
(round_robin_lb_policy*)sd->subchannel_list->policy;
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(
GPR_DEBUG,
"[RR %p] connectivity changed for subchannel %p, subchannel_list %p: "
@@ -475,7 +474,7 @@ static void rr_connectivity_changed_locked(void* arg, grpc_error* error) {
// for sds belonging to outdated subchannel lists.
GPR_ASSERT(sd->subchannel_list == p->latest_pending_subchannel_list);
GPR_ASSERT(!sd->subchannel_list->shutting_down);
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
const unsigned long num_subchannels =
p->subchannel_list != nullptr
? (unsigned long)p->subchannel_list->num_subchannels
@@ -514,7 +513,7 @@ static void rr_connectivity_changed_locked(void* arg, grpc_error* error) {
if (pp->user_data != nullptr) {
*pp->user_data = selected->user_data;
}
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG,
"[RR %p] Fulfilling pending pick. Target <-- subchannel %p "
"(subchannel_list %p, index %lu)",
@@ -578,7 +577,7 @@ static void rr_update_locked(grpc_lb_policy* policy,
return;
}
grpc_lb_addresses* addresses = (grpc_lb_addresses*)arg->value.pointer.p;
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG, "[RR %p] received update with %" PRIuPTR " addresses", p,
addresses->num_addresses);
}
@@ -599,7 +598,7 @@ static void rr_update_locked(grpc_lb_policy* policy,
}
if (p->started_picking) {
if (p->latest_pending_subchannel_list != nullptr) {
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG,
"[RR %p] Shutting down latest pending subchannel list %p, "
"about to be replaced by newer latest %p",
@@ -656,7 +655,7 @@ static grpc_lb_policy* round_robin_create(grpc_lb_policy_factory* factory,
grpc_connectivity_state_init(&p->state_tracker, GRPC_CHANNEL_IDLE,
"round_robin");
rr_update_locked(&p->base, args);
- if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG, "[RR %p] Created with %lu subchannels", (void*)p,
(unsigned long)p->subchannel_list->num_subchannels);
}
@@ -678,7 +677,6 @@ static grpc_lb_policy_factory* round_robin_lb_factory_create() {
extern "C" void grpc_lb_policy_round_robin_init() {
grpc_register_lb_policy(round_robin_lb_factory_create());
- grpc_register_tracer(&grpc_lb_round_robin_trace);
}
extern "C" void grpc_lb_policy_round_robin_shutdown() {}
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
index e804a98ce7..a3b4c8e524 100644
--- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
@@ -31,11 +31,11 @@
void grpc_lb_subchannel_data_unref_subchannel(grpc_lb_subchannel_data* sd,
const char* reason) {
if (sd->subchannel != nullptr) {
- if (GRPC_TRACER_ON(*sd->subchannel_list->tracer)) {
+ if (sd->subchannel_list->tracer->enabled()) {
gpr_log(GPR_DEBUG,
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
" (subchannel %p): unreffing subchannel",
- sd->subchannel_list->tracer->name, sd->subchannel_list->policy,
+ sd->subchannel_list->tracer->name(), sd->subchannel_list->policy,
sd->subchannel_list,
(size_t)(sd - sd->subchannel_list->subchannels),
sd->subchannel_list->num_subchannels, sd->subchannel);
@@ -56,11 +56,11 @@ void grpc_lb_subchannel_data_unref_subchannel(grpc_lb_subchannel_data* sd,
void grpc_lb_subchannel_data_start_connectivity_watch(
grpc_lb_subchannel_data* sd) {
- if (GRPC_TRACER_ON(*sd->subchannel_list->tracer)) {
+ if (sd->subchannel_list->tracer->enabled()) {
gpr_log(GPR_DEBUG,
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
" (subchannel %p): requesting connectivity change notification",
- sd->subchannel_list->tracer->name, sd->subchannel_list->policy,
+ sd->subchannel_list->tracer->name(), sd->subchannel_list->policy,
sd->subchannel_list,
(size_t)(sd - sd->subchannel_list->subchannels),
sd->subchannel_list->num_subchannels, sd->subchannel);
@@ -74,11 +74,11 @@ void grpc_lb_subchannel_data_start_connectivity_watch(
void grpc_lb_subchannel_data_stop_connectivity_watch(
grpc_lb_subchannel_data* sd) {
- if (GRPC_TRACER_ON(*sd->subchannel_list->tracer)) {
+ if (sd->subchannel_list->tracer->enabled()) {
gpr_log(GPR_DEBUG,
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
" (subchannel %p): stopping connectivity watch",
- sd->subchannel_list->tracer->name, sd->subchannel_list->policy,
+ sd->subchannel_list->tracer->name(), sd->subchannel_list->policy,
sd->subchannel_list,
(size_t)(sd - sd->subchannel_list->subchannels),
sd->subchannel_list->num_subchannels, sd->subchannel);
@@ -88,15 +88,15 @@ void grpc_lb_subchannel_data_stop_connectivity_watch(
}
grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
- grpc_lb_policy* p, grpc_tracer_flag* tracer,
+ grpc_lb_policy* p, grpc_core::TraceFlag* tracer,
const grpc_lb_addresses* addresses, const grpc_lb_policy_args* args,
grpc_iomgr_cb_func connectivity_changed_cb) {
grpc_lb_subchannel_list* subchannel_list =
(grpc_lb_subchannel_list*)gpr_zalloc(sizeof(*subchannel_list));
- if (GRPC_TRACER_ON(*tracer)) {
+ if (tracer->enabled()) {
gpr_log(GPR_DEBUG,
"[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels",
- tracer->name, p, subchannel_list, addresses->num_addresses);
+ tracer->name(), p, subchannel_list, addresses->num_addresses);
}
subchannel_list->policy = p;
subchannel_list->tracer = tracer;
@@ -126,24 +126,24 @@ grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
grpc_channel_args_destroy(new_args);
if (subchannel == nullptr) {
// Subchannel could not be created.
- if (GRPC_TRACER_ON(*tracer)) {
+ if (tracer->enabled()) {
char* address_uri =
grpc_sockaddr_to_uri(&addresses->addresses[i].address);
gpr_log(GPR_DEBUG,
"[%s %p] could not create subchannel for address uri %s, "
"ignoring",
- tracer->name, subchannel_list->policy, address_uri);
+ tracer->name(), subchannel_list->policy, address_uri);
gpr_free(address_uri);
}
continue;
}
- if (GRPC_TRACER_ON(*tracer)) {
+ if (tracer->enabled()) {
char* address_uri =
grpc_sockaddr_to_uri(&addresses->addresses[i].address);
gpr_log(GPR_DEBUG,
"[%s %p] subchannel list %p index %" PRIuPTR
": Created subchannel %p for address uri %s",
- tracer->name, p, subchannel_list, subchannel_index, subchannel,
+ tracer->name(), p, subchannel_list, subchannel_index, subchannel,
address_uri);
gpr_free(address_uri);
}
@@ -171,9 +171,9 @@ grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
}
static void subchannel_list_destroy(grpc_lb_subchannel_list* subchannel_list) {
- if (GRPC_TRACER_ON(*subchannel_list->tracer)) {
+ if (subchannel_list->tracer->enabled()) {
gpr_log(GPR_DEBUG, "[%s %p] Destroying subchannel_list %p",
- subchannel_list->tracer->name, subchannel_list->policy,
+ subchannel_list->tracer->name(), subchannel_list->policy,
subchannel_list);
}
for (size_t i = 0; i < subchannel_list->num_subchannels; i++) {
@@ -187,10 +187,10 @@ static void subchannel_list_destroy(grpc_lb_subchannel_list* subchannel_list) {
void grpc_lb_subchannel_list_ref(grpc_lb_subchannel_list* subchannel_list,
const char* reason) {
gpr_ref_non_zero(&subchannel_list->refcount);
- if (GRPC_TRACER_ON(*subchannel_list->tracer)) {
+ if (subchannel_list->tracer->enabled()) {
const gpr_atm count = gpr_atm_acq_load(&subchannel_list->refcount.count);
gpr_log(GPR_DEBUG, "[%s %p] subchannel_list %p REF %lu->%lu (%s)",
- subchannel_list->tracer->name, subchannel_list->policy,
+ subchannel_list->tracer->name(), subchannel_list->policy,
subchannel_list, (unsigned long)(count - 1), (unsigned long)count,
reason);
}
@@ -199,10 +199,10 @@ void grpc_lb_subchannel_list_ref(grpc_lb_subchannel_list* subchannel_list,
void grpc_lb_subchannel_list_unref(grpc_lb_subchannel_list* subchannel_list,
const char* reason) {
const bool done = gpr_unref(&subchannel_list->refcount);
- if (GRPC_TRACER_ON(*subchannel_list->tracer)) {
+ if (subchannel_list->tracer->enabled()) {
const gpr_atm count = gpr_atm_acq_load(&subchannel_list->refcount.count);
gpr_log(GPR_DEBUG, "[%s %p] subchannel_list %p UNREF %lu->%lu (%s)",
- subchannel_list->tracer->name, subchannel_list->policy,
+ subchannel_list->tracer->name(), subchannel_list->policy,
subchannel_list, (unsigned long)(count + 1), (unsigned long)count,
reason);
}
@@ -225,11 +225,11 @@ void grpc_lb_subchannel_list_unref_for_connectivity_watch(
static void subchannel_data_cancel_connectivity_watch(
grpc_lb_subchannel_data* sd, const char* reason) {
- if (GRPC_TRACER_ON(*sd->subchannel_list->tracer)) {
+ if (sd->subchannel_list->tracer->enabled()) {
gpr_log(GPR_DEBUG,
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
" (subchannel %p): canceling connectivity watch (%s)",
- sd->subchannel_list->tracer->name, sd->subchannel_list->policy,
+ sd->subchannel_list->tracer->name(), sd->subchannel_list->policy,
sd->subchannel_list,
(size_t)(sd - sd->subchannel_list->subchannels),
sd->subchannel_list->num_subchannels, sd->subchannel, reason);
@@ -240,9 +240,9 @@ static void subchannel_data_cancel_connectivity_watch(
void grpc_lb_subchannel_list_shutdown_and_unref(
grpc_lb_subchannel_list* subchannel_list, const char* reason) {
- if (GRPC_TRACER_ON(*subchannel_list->tracer)) {
+ if (subchannel_list->tracer->enabled()) {
gpr_log(GPR_DEBUG, "[%s %p] Shutting down subchannel_list %p (%s)",
- subchannel_list->tracer->name, subchannel_list->policy,
+ subchannel_list->tracer->name(), subchannel_list->policy,
subchannel_list, reason);
}
GPR_ASSERT(!subchannel_list->shutting_down);
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 70a43fe132..6221e3694f 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
@@ -87,7 +87,7 @@ struct grpc_lb_subchannel_list {
/** backpointer to owning policy */
grpc_lb_policy* policy;
- grpc_tracer_flag* tracer;
+ grpc_core::TraceFlag* tracer;
/** all our subchannels */
size_t num_subchannels;
@@ -120,7 +120,7 @@ struct grpc_lb_subchannel_list {
};
grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
- grpc_lb_policy* p, grpc_tracer_flag* tracer,
+ grpc_lb_policy* p, grpc_core::TraceFlag* tracer,
const grpc_lb_addresses* addresses, const grpc_lb_policy_args* args,
grpc_iomgr_cb_func connectivity_changed_cb);
diff --git a/src/core/ext/filters/client_channel/resolver.cc b/src/core/ext/filters/client_channel/resolver.cc
index fdb10d908e..ff54e7179d 100644
--- a/src/core/ext/filters/client_channel/resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver.cc
@@ -19,10 +19,8 @@
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/lib/iomgr/combiner.h"
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_resolver_refcount =
- GRPC_TRACER_INITIALIZER(false, "resolver_refcount");
-#endif
+grpc_core::DebugOnlyTraceFlag grpc_trace_resolver_refcount(false,
+ "resolver_refcount");
void grpc_resolver_init(grpc_resolver* resolver,
const grpc_resolver_vtable* vtable,
@@ -35,7 +33,7 @@ void grpc_resolver_init(grpc_resolver* resolver,
#ifndef NDEBUG
void grpc_resolver_ref(grpc_resolver* resolver, const char* file, int line,
const char* reason) {
- if (GRPC_TRACER_ON(grpc_trace_resolver_refcount)) {
+ if (grpc_trace_resolver_refcount.enabled()) {
gpr_atm old_refs = gpr_atm_no_barrier_load(&resolver->refs.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"RESOLVER:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", resolver,
@@ -50,7 +48,7 @@ void grpc_resolver_ref(grpc_resolver* resolver) {
#ifndef NDEBUG
void grpc_resolver_unref(grpc_resolver* resolver, const char* file, int line,
const char* reason) {
- if (GRPC_TRACER_ON(grpc_trace_resolver_refcount)) {
+ if (grpc_trace_resolver_refcount.enabled()) {
gpr_atm old_refs = gpr_atm_no_barrier_load(&resolver->refs.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"RESOLVER:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", resolver,
diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h
index 30b0afaf74..7ff21b4d2c 100644
--- a/src/core/ext/filters/client_channel/resolver.h
+++ b/src/core/ext/filters/client_channel/resolver.h
@@ -29,9 +29,7 @@ extern "C" {
typedef struct grpc_resolver grpc_resolver;
typedef struct grpc_resolver_vtable grpc_resolver_vtable;
-#ifndef NDEBUG
-extern grpc_tracer_flag grpc_trace_resolver_refcount;
-#endif
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_resolver_refcount;
/** \a grpc_resolver provides \a grpc_channel_args objects to its caller */
struct grpc_resolver {
diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc
index df53622e54..0d2be2a3f7 100644
--- a/src/core/ext/filters/client_channel/subchannel.cc
+++ b/src/core/ext/filters/client_channel/subchannel.cc
@@ -194,7 +194,7 @@ static gpr_atm ref_mutate(grpc_subchannel* c, gpr_atm delta,
gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta)
: gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta);
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_stream_refcount)) {
+ if (grpc_trace_stream_refcount.enabled()) {
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", c,
purpose, old_val, old_val + delta, reason);
diff --git a/src/core/ext/filters/http/http_filters_plugin.cc b/src/core/ext/filters/http/http_filters_plugin.cc
index 9d47f6889a..47ff0f30ef 100644
--- a/src/core/ext/filters/http/http_filters_plugin.cc
+++ b/src/core/ext/filters/http/http_filters_plugin.cc
@@ -63,7 +63,6 @@ static bool maybe_add_required_filter(grpc_channel_stack_builder* builder,
}
extern "C" void grpc_http_filters_init(void) {
- grpc_register_tracer(&grpc_compression_trace);
grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL,
GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
maybe_add_optional_filter, &compress_filter);
diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.cc b/src/core/ext/filters/http/message_compress/message_compress_filter.cc
index bf9e12840d..9ae13d2ed2 100644
--- a/src/core/ext/filters/http/message_compress/message_compress_filter.cc
+++ b/src/core/ext/filters/http/message_compress/message_compress_filter.cc
@@ -238,7 +238,7 @@ static void finish_send_message(grpc_call_element* elem) {
bool did_compress =
grpc_msg_compress(calld->compression_algorithm, &calld->slices, &tmp);
if (did_compress) {
- if (GRPC_TRACER_ON(grpc_compression_trace)) {
+ if (grpc_compression_trace.enabled()) {
const char* algo_name;
const size_t before_size = calld->slices.length;
const size_t after_size = tmp.length;
@@ -253,7 +253,7 @@ static void finish_send_message(grpc_call_element* elem) {
grpc_slice_buffer_swap(&calld->slices, &tmp);
send_flags |= GRPC_WRITE_INTERNAL_COMPRESS;
} else {
- if (GRPC_TRACER_ON(grpc_compression_trace)) {
+ if (grpc_compression_trace.enabled()) {
const char* algo_name;
GPR_ASSERT(grpc_compression_algorithm_name(calld->compression_algorithm,
&algo_name));
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
index ac9ae5c395..2569347def 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
@@ -20,13 +20,6 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/transport/metadata.h"
-extern "C" void grpc_chttp2_plugin_init(void) {
- grpc_register_tracer(&grpc_http_trace);
- grpc_register_tracer(&grpc_flowctl_trace);
- grpc_register_tracer(&grpc_trace_http2_stream_state);
-#ifndef NDEBUG
- grpc_register_tracer(&grpc_trace_chttp2_refcount);
-#endif
-}
+extern "C" void grpc_chttp2_plugin_init(void) {}
extern "C" void grpc_chttp2_plugin_shutdown(void) {}
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index ec9e4c2223..bebacf1eda 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -90,13 +90,9 @@ static int g_default_max_pings_without_data = DEFAULT_MAX_PINGS_BETWEEN_DATA;
static int g_default_max_ping_strikes = DEFAULT_MAX_PING_STRIKES;
#define MAX_CLIENT_STREAM_ID 0x7fffffffu
-grpc_tracer_flag grpc_http_trace = GRPC_TRACER_INITIALIZER(false, "http");
-grpc_tracer_flag grpc_flowctl_trace = GRPC_TRACER_INITIALIZER(false, "flowctl");
-
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_chttp2_refcount =
- GRPC_TRACER_INITIALIZER(false, "chttp2_refcount");
-#endif
+grpc_core::TraceFlag grpc_http_trace(false, "http");
+grpc_core::DebugOnlyTraceFlag grpc_trace_chttp2_refcount(false,
+ "chttp2_refcount");
/* forward declarations of various callbacks that we'll build closures around */
static void write_action_begin_locked(void* t, grpc_error* error);
@@ -205,7 +201,7 @@ static void destruct_transport(grpc_chttp2_transport* t) {
#ifndef NDEBUG
void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason,
const char* file, int line) {
- if (GRPC_TRACER_ON(grpc_trace_chttp2_refcount)) {
+ if (grpc_trace_chttp2_refcount.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count);
gpr_log(GPR_DEBUG, "chttp2:unref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]",
t, val, val - 1, reason, file, line);
@@ -216,7 +212,7 @@ void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason,
void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason,
const char* file, int line) {
- if (GRPC_TRACER_ON(grpc_trace_chttp2_refcount)) {
+ if (grpc_trace_chttp2_refcount.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count);
gpr_log(GPR_DEBUG, "chttp2: ref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]",
t, val, val + 1, reason, file, line);
@@ -1169,7 +1165,7 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t,
return;
}
closure->next_data.scratch -= CLOSURE_BARRIER_FIRST_REF_BIT;
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
const char* errstr = grpc_error_string(error);
gpr_log(
GPR_DEBUG,
@@ -1322,7 +1318,7 @@ static void perform_stream_op_locked(void* stream_op,
GRPC_STATS_INC_HTTP2_OP_BATCHES();
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
char* str = grpc_transport_stream_op_batch_string(op);
gpr_log(GPR_DEBUG, "perform_stream_op_locked: %s; on_complete = %p", str,
op->on_complete);
@@ -1609,7 +1605,7 @@ static void perform_stream_op(grpc_transport* gt, grpc_stream* gs,
}
}
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
char* str = grpc_transport_stream_op_batch_string(op);
gpr_log(GPR_DEBUG, "perform_stream_op[s=%p]: %s", s, str);
gpr_free(str);
@@ -1677,7 +1673,7 @@ static void send_goaway(grpc_chttp2_transport* t, grpc_error* error) {
grpc_http2_error_code http_error;
grpc_slice slice;
grpc_error_get_status(error, GRPC_MILLIS_INF_FUTURE, nullptr, &slice,
- &http_error);
+ &http_error, nullptr);
grpc_chttp2_goaway_append(t->last_new_stream_id, (uint32_t)http_error,
grpc_slice_ref_internal(slice), &t->qbuf);
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_GOAWAY_SENT);
@@ -1965,7 +1961,7 @@ void grpc_chttp2_cancel_stream(grpc_chttp2_transport* t, grpc_chttp2_stream* s,
if (s->id != 0) {
grpc_http2_error_code http_error;
grpc_error_get_status(due_to_error, s->deadline, nullptr, nullptr,
- &http_error);
+ &http_error, nullptr);
grpc_slice_buffer_add(
&t->qbuf, grpc_chttp2_rst_stream_create(s->id, (uint32_t)http_error,
&s->stats.outgoing));
@@ -1982,7 +1978,7 @@ void grpc_chttp2_fake_status(grpc_chttp2_transport* t, grpc_chttp2_stream* s,
grpc_error* error) {
grpc_status_code status;
grpc_slice slice;
- grpc_error_get_status(error, s->deadline, &status, &slice, nullptr);
+ grpc_error_get_status(error, s->deadline, &status, &slice, nullptr, nullptr);
if (status != GRPC_STATUS_OK) {
s->seen_error = true;
}
@@ -2141,7 +2137,8 @@ static void close_from_api(grpc_chttp2_transport* t, grpc_chttp2_stream* s,
uint32_t len = 0;
grpc_status_code grpc_status;
grpc_slice slice;
- grpc_error_get_status(error, s->deadline, &grpc_status, &slice, nullptr);
+ grpc_error_get_status(error, s->deadline, &grpc_status, &slice, nullptr,
+ nullptr);
GPR_ASSERT(grpc_status >= 0 && (int)grpc_status < 100);
@@ -2472,7 +2469,7 @@ static void schedule_bdp_ping_locked(grpc_chttp2_transport* t) {
static void start_bdp_ping_locked(void* tp, grpc_error* error) {
grpc_chttp2_transport* t = (grpc_chttp2_transport*)tp;
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
gpr_log(GPR_DEBUG, "%s: Start BDP ping err=%s", t->peer_string,
grpc_error_string(error));
}
@@ -2485,7 +2482,7 @@ static void start_bdp_ping_locked(void* tp, grpc_error* error) {
static void finish_bdp_ping_locked(void* tp, grpc_error* error) {
grpc_chttp2_transport* t = (grpc_chttp2_transport*)tp;
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
gpr_log(GPR_DEBUG, "%s: Complete BDP ping err=%s", t->peer_string,
grpc_error_string(error));
}
@@ -2959,7 +2956,7 @@ static void benign_reclaimer_locked(void* arg, grpc_error* error) {
grpc_chttp2_stream_map_size(&t->stream_map) == 0) {
/* Channel with no active streams: send a goaway to try and make it
* disconnect cleanly */
- if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
+ if (grpc_resource_quota_trace.enabled()) {
gpr_log(GPR_DEBUG, "HTTP2: %s - send goaway to free memory",
t->peer_string);
}
@@ -2967,8 +2964,7 @@ static void benign_reclaimer_locked(void* arg, grpc_error* error) {
grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Buffers full"),
GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_ENHANCE_YOUR_CALM));
- } else if (error == GRPC_ERROR_NONE &&
- GRPC_TRACER_ON(grpc_resource_quota_trace)) {
+ } else if (error == GRPC_ERROR_NONE && grpc_resource_quota_trace.enabled()) {
gpr_log(GPR_DEBUG,
"HTTP2: %s - skip benign reclamation, there are still %" PRIdPTR
" streams",
@@ -2989,7 +2985,7 @@ static void destructive_reclaimer_locked(void* arg, grpc_error* error) {
if (error == GRPC_ERROR_NONE && n > 0) {
grpc_chttp2_stream* s =
(grpc_chttp2_stream*)grpc_chttp2_stream_map_rand(&t->stream_map);
- if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
+ if (grpc_resource_quota_trace.enabled()) {
gpr_log(GPR_DEBUG, "HTTP2: %s - abandon stream id %d", t->peer_string,
s->id);
}
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h
index 39a4de53cf..9df2d728d0 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h
@@ -23,18 +23,14 @@
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/transport/transport.h"
+extern grpc_core::TraceFlag grpc_http_trace;
+extern grpc_core::TraceFlag grpc_trace_http2_stream_state;
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_chttp2_refcount;
+
#ifdef __cplusplus
extern "C" {
#endif
-extern grpc_tracer_flag grpc_http_trace;
-extern grpc_tracer_flag grpc_flowctl_trace;
-extern grpc_tracer_flag grpc_trace_http2_stream_state;
-
-#ifndef NDEBUG
-extern grpc_tracer_flag grpc_trace_chttp2_refcount;
-#endif
-
grpc_transport* grpc_create_chttp2_transport(
const grpc_channel_args* channel_args, grpc_endpoint* ep, int is_client);
diff --git a/src/core/ext/transport/chttp2/transport/flow_control.cc b/src/core/ext/transport/chttp2/transport/flow_control.cc
index 14f089859e..ca48cc7e0a 100644
--- a/src/core/ext/transport/chttp2/transport/flow_control.cc
+++ b/src/core/ext/transport/chttp2/transport/flow_control.cc
@@ -31,6 +31,8 @@
#include "src/core/ext/transport/chttp2/transport/internal.h"
#include "src/core/lib/support/string.h"
+grpc_core::TraceFlag grpc_flowctl_trace(false, "flowctl");
+
namespace grpc_core {
namespace chttp2 {
@@ -310,7 +312,9 @@ double TransportFlowControl::SmoothLogBdp(double value) {
double bdp_error = value - pid_controller_.last_control_value();
const double dt = (double)(now - last_pid_update_) * 1e-3;
last_pid_update_ = now;
- return pid_controller_.Update(bdp_error, dt);
+ // Limit dt to 100ms
+ const double kMaxDt = 0.1;
+ return pid_controller_.Update(bdp_error, dt > kMaxDt ? kMaxDt : dt);
}
FlowControlAction::Urgency TransportFlowControl::DeltaUrgency(
diff --git a/src/core/ext/transport/chttp2/transport/flow_control.h b/src/core/ext/transport/chttp2/transport/flow_control.h
index c705a22d2e..8306047dbc 100644
--- a/src/core/ext/transport/chttp2/transport/flow_control.h
+++ b/src/core/ext/transport/chttp2/transport/flow_control.h
@@ -19,6 +19,7 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FLOW_CONTROL_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FLOW_CONTROL_H
+#include <grpc/support/port_platform.h>
#include <stdint.h>
#include <grpc/support/useful.h>
@@ -30,7 +31,7 @@
struct grpc_chttp2_transport;
struct grpc_chttp2_stream;
-extern "C" grpc_tracer_flag grpc_flowctl_trace;
+extern grpc_core::TraceFlag grpc_flowctl_trace;
namespace grpc {
namespace testing {
@@ -118,7 +119,7 @@ class FlowControlTrace {
StreamFlowControl* sfc);
void Finish();
- const bool enabled_ = GRPC_TRACER_ON(grpc_flowctl_trace);
+ const bool enabled_ = grpc_flowctl_trace.enabled();
TransportFlowControl* tfc_;
StreamFlowControl* sfc_;
diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.cc b/src/core/ext/transport/chttp2/transport/frame_settings.cc
index 0761a6e6b3..d4f84f352d 100644
--- a/src/core/ext/transport/chttp2/transport/frame_settings.cc
+++ b/src/core/ext/transport/chttp2/transport/frame_settings.cc
@@ -203,20 +203,19 @@ grpc_error* grpc_chttp2_settings_parser_parse(void* p, grpc_chttp2_transport* t,
parser->incoming_settings[id] != parser->value) {
t->initial_window_update +=
(int64_t)parser->value - parser->incoming_settings[id];
- if (GRPC_TRACER_ON(grpc_http_trace) ||
- GRPC_TRACER_ON(grpc_flowctl_trace)) {
+ if (grpc_http_trace.enabled() || grpc_flowctl_trace.enabled()) {
gpr_log(GPR_DEBUG, "%p[%s] adding %d for initial_window change",
t, t->is_client ? "cli" : "svr",
(int)t->initial_window_update);
}
}
parser->incoming_settings[id] = parser->value;
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
gpr_log(GPR_DEBUG, "CHTTP2:%s:%s: got setting %s = %d",
t->is_client ? "CLI" : "SVR", t->peer_string, sp->name,
parser->value);
}
- } else if (GRPC_TRACER_ON(grpc_http_trace)) {
+ } else if (grpc_http_trace.enabled()) {
gpr_log(GPR_ERROR, "CHTTP2: Ignoring unknown setting %d (value %d)",
parser->id, parser->value);
}
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
index 0da7d3ba57..3a5692a694 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
@@ -57,8 +57,6 @@ static const grpc_slice terminal_slice = {
{{nullptr, 0}} /* data.refcounted */
};
-extern "C" grpc_tracer_flag grpc_http_trace;
-
typedef struct {
int is_first_frame;
/* number of bytes in 'output' when we started the frame - used to calculate
@@ -460,7 +458,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem,
"Reserved header (colon-prefixed) happening after regular ones.");
}
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
char* k = grpc_slice_to_c_string(GRPC_MDKEY(elem));
char* v = nullptr;
if (grpc_is_binary_header(GRPC_MDKEY(elem))) {
@@ -652,7 +650,7 @@ void grpc_chttp2_hpack_compressor_set_max_table_size(
}
}
c->advertise_table_size_change = 1;
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
gpr_log(GPR_DEBUG, "set max table size from encoder to %d", max_table_size);
}
}
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
index 81bd266e51..a7a0d9c5a9 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
@@ -34,6 +34,8 @@
/* maximum table size we'll actually use */
#define GRPC_CHTTP2_HPACKC_MAX_TABLE_SIZE (1024 * 1024)
+extern grpc_core::TraceFlag grpc_http_trace;
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc
index bd9d4c2e34..a395ab234c 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc
@@ -624,7 +624,7 @@ static const uint8_t inverse_base64[256] = {
/* emission helpers */
static grpc_error* on_hdr(grpc_chttp2_hpack_parser* p, grpc_mdelem md,
int add_to_table) {
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
char* k = grpc_slice_to_c_string(GRPC_MDKEY(md));
char* v = nullptr;
if (grpc_is_binary_header(GRPC_MDKEY(md))) {
@@ -993,7 +993,7 @@ static grpc_error* parse_lithdr_nvridx_v(grpc_chttp2_hpack_parser* p,
/* finish parsing a max table size change */
static grpc_error* finish_max_tbl_size(grpc_chttp2_hpack_parser* p,
const uint8_t* cur, const uint8_t* end) {
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", p->index);
}
grpc_error* err =
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc
index ef0adf718f..c325465daa 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc
@@ -28,7 +28,7 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/support/murmur_hash.h"
-extern "C" grpc_tracer_flag grpc_http_trace;
+extern grpc_core::TraceFlag grpc_http_trace;
static struct {
const char* key;
@@ -242,7 +242,7 @@ void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl* tbl,
if (tbl->max_bytes == max_bytes) {
return;
}
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes);
}
while (tbl->mem_used > max_bytes) {
@@ -265,7 +265,7 @@ grpc_error* grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl* tbl,
gpr_free(msg);
return err;
}
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
gpr_log(GPR_DEBUG, "Update hpack parser table size to %d", bytes);
}
while (tbl->mem_used > bytes) {
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index 3f27da6d0a..5f74ac286a 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -666,13 +666,13 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t,
#define GRPC_CHTTP2_CLIENT_CONNECT_STRLEN \
(sizeof(GRPC_CHTTP2_CLIENT_CONNECT_STRING) - 1)
-extern grpc_tracer_flag grpc_http_trace;
-extern grpc_tracer_flag grpc_flowctl_trace;
+// extern grpc_core::TraceFlag grpc_http_trace;
+// extern grpc_core::TraceFlag grpc_flowctl_trace;
-#define GRPC_CHTTP2_IF_TRACING(stmt) \
- if (!(GRPC_TRACER_ON(grpc_http_trace))) \
- ; \
- else \
+#define GRPC_CHTTP2_IF_TRACING(stmt) \
+ if (!(grpc_http_trace.enabled())) \
+ ; \
+ else \
stmt
void grpc_chttp2_fake_status(grpc_chttp2_transport* t,
diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc
index a9d08c34d0..a56f89cc75 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.cc
+++ b/src/core/ext/transport/chttp2/transport/parsing.cc
@@ -300,7 +300,7 @@ static grpc_error* init_frame_parser(grpc_chttp2_transport* t) {
case GRPC_CHTTP2_FRAME_GOAWAY:
return init_goaway_parser(t);
default:
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
gpr_log(GPR_ERROR, "Unknown frame type %02x", t->incoming_frame_type);
}
return init_skip_frame_parser(t, 0);
@@ -398,7 +398,7 @@ static void on_initial_header(void* tp, grpc_mdelem md) {
GPR_ASSERT(s != nullptr);
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
char* key = grpc_slice_to_c_string(GRPC_MDKEY(md));
char* value =
grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII);
@@ -481,7 +481,7 @@ static void on_trailing_header(void* tp, grpc_mdelem md) {
GPR_ASSERT(s != nullptr);
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
char* key = grpc_slice_to_c_string(GRPC_MDKEY(md));
char* value =
grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII);
@@ -731,7 +731,7 @@ static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, grpc_slice slice,
if (err == GRPC_ERROR_NONE) {
return err;
} else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, nullptr)) {
- if (GRPC_TRACER_ON(grpc_http_trace)) {
+ if (grpc_http_trace.enabled()) {
const char* msg = grpc_error_string(err);
gpr_log(GPR_ERROR, "%s", msg);
}
diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.cc b/src/core/ext/transport/chttp2/transport/stream_lists.cc
index d92527f05c..c95d02541a 100644
--- a/src/core/ext/transport/chttp2/transport/stream_lists.cc
+++ b/src/core/ext/transport/chttp2/transport/stream_lists.cc
@@ -39,8 +39,7 @@ static const char* stream_list_id_string(grpc_chttp2_stream_list_id id) {
GPR_UNREACHABLE_CODE(return "unknown");
}
-grpc_tracer_flag grpc_trace_http2_stream_state =
- GRPC_TRACER_INITIALIZER(false, "http2_stream_state");
+grpc_core::TraceFlag grpc_trace_http2_stream_state(false, "http2_stream_state");
/* core list management */
@@ -66,7 +65,7 @@ static bool stream_list_pop(grpc_chttp2_transport* t,
s->included[id] = 0;
}
*stream = s;
- if (s && GRPC_TRACER_ON(grpc_trace_http2_stream_state)) {
+ if (s && grpc_trace_http2_stream_state.enabled()) {
gpr_log(GPR_DEBUG, "%p[%d][%s]: pop from %s", t, s->id,
t->is_client ? "cli" : "svr", stream_list_id_string(id));
}
@@ -88,7 +87,7 @@ static void stream_list_remove(grpc_chttp2_transport* t, grpc_chttp2_stream* s,
} else {
t->lists[id].tail = s->links[id].prev;
}
- if (GRPC_TRACER_ON(grpc_trace_http2_stream_state)) {
+ if (grpc_trace_http2_stream_state.enabled()) {
gpr_log(GPR_DEBUG, "%p[%d][%s]: remove from %s", t, s->id,
t->is_client ? "cli" : "svr", stream_list_id_string(id));
}
@@ -120,7 +119,7 @@ static void stream_list_add_tail(grpc_chttp2_transport* t,
}
t->lists[id].tail = s;
s->included[id] = 1;
- if (GRPC_TRACER_ON(grpc_trace_http2_stream_state)) {
+ if (grpc_trace_http2_stream_state.enabled()) {
gpr_log(GPR_DEBUG, "%p[%d][%s]: add to %s", t, s->id,
t->is_client ? "cli" : "svr", stream_list_id_string(id));
}
diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc
index 77cdd9c71a..33c2707ac4 100644
--- a/src/core/ext/transport/chttp2/transport/writing.cc
+++ b/src/core/ext/transport/chttp2/transport/writing.cc
@@ -49,8 +49,7 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) {
}
if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_INFLIGHT])) {
/* ping already in-flight: wait */
- if (GRPC_TRACER_ON(grpc_http_trace) ||
- GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
+ if (grpc_http_trace.enabled() || grpc_bdp_estimator_trace.enabled()) {
gpr_log(GPR_DEBUG, "%s: Ping delayed [%p]: already pinging",
t->is_client ? "CLIENT" : "SERVER", t->peer_string);
}
@@ -59,8 +58,7 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) {
if (t->ping_state.pings_before_data_required == 0 &&
t->ping_policy.max_pings_without_data != 0) {
/* need to receive something of substance before sending a ping again */
- if (GRPC_TRACER_ON(grpc_http_trace) ||
- GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
+ if (grpc_http_trace.enabled() || grpc_bdp_estimator_trace.enabled()) {
gpr_log(GPR_DEBUG, "%s: Ping delayed [%p]: too many recent pings: %d/%d",
t->is_client ? "CLIENT" : "SERVER", t->peer_string,
t->ping_state.pings_before_data_required,
@@ -79,8 +77,7 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) {
}
if (next_allowed_ping > now) {
/* not enough elapsed time between successive pings */
- if (GRPC_TRACER_ON(grpc_http_trace) ||
- GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
+ if (grpc_http_trace.enabled() || grpc_bdp_estimator_trace.enabled()) {
gpr_log(GPR_DEBUG,
"%s: Ping delayed [%p]: not enough time elapsed since last ping",
t->is_client ? "CLIENT" : "SERVER", t->peer_string);
@@ -101,8 +98,7 @@ static void maybe_initiate_ping(grpc_chttp2_transport* t) {
grpc_chttp2_ping_create(false, pq->inflight_id));
GRPC_STATS_INC_HTTP2_PINGS_SENT();
t->ping_state.last_ping_sent_time = now;
- if (GRPC_TRACER_ON(grpc_http_trace) ||
- GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
+ if (grpc_http_trace.enabled() || grpc_bdp_estimator_trace.enabled()) {
gpr_log(GPR_DEBUG, "%s: Ping sent [%p]: %d/%d",
t->is_client ? "CLIENT" : "SERVER", t->peer_string,
t->ping_state.pings_before_data_required,
@@ -319,7 +315,7 @@ class DataSendContext {
GPR_MIN(stream_remote_window(), t_->flow_control->remote_window()));
}
- bool AnyOutgoing() const { return max_outgoing() != 0; }
+ bool AnyOutgoing() const { return max_outgoing() > 0; }
void FlushCompressedBytes() {
uint32_t send_bytes =
diff --git a/src/core/ext/transport/inproc/inproc_plugin.cc b/src/core/ext/transport/inproc/inproc_plugin.cc
index 5d8a1c74ab..2526dbfa06 100644
--- a/src/core/ext/transport/inproc/inproc_plugin.cc
+++ b/src/core/ext/transport/inproc/inproc_plugin.cc
@@ -19,12 +19,9 @@
#include "src/core/ext/transport/inproc/inproc_transport.h"
#include "src/core/lib/debug/trace.h"
-grpc_tracer_flag grpc_inproc_trace = GRPC_TRACER_INITIALIZER(false, "inproc");
+grpc_core::TraceFlag grpc_inproc_trace(false, "inproc");
-extern "C" void grpc_inproc_plugin_init(void) {
- grpc_register_tracer(&grpc_inproc_trace);
- grpc_inproc_transport_init();
-}
+extern "C" void grpc_inproc_plugin_init(void) { grpc_inproc_transport_init(); }
extern "C" void grpc_inproc_plugin_shutdown(void) {
grpc_inproc_transport_shutdown();
diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc
index 4ce870f7c3..18e77b9b1c 100644
--- a/src/core/ext/transport/inproc/inproc_transport.cc
+++ b/src/core/ext/transport/inproc/inproc_transport.cc
@@ -32,9 +32,9 @@
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/transport_impl.h"
-#define INPROC_LOG(...) \
- do { \
- if (GRPC_TRACER_ON(grpc_inproc_trace)) gpr_log(__VA_ARGS__); \
+#define INPROC_LOG(...) \
+ do { \
+ if (grpc_inproc_trace.enabled()) gpr_log(__VA_ARGS__); \
} while (0)
static grpc_slice g_empty_slice;
@@ -195,7 +195,7 @@ static grpc_error* fill_in_metadata(inproc_stream* s,
const grpc_metadata_batch* metadata,
uint32_t flags, grpc_metadata_batch* out_md,
uint32_t* outflags, bool* markfilled) {
- if (GRPC_TRACER_ON(grpc_inproc_trace)) {
+ if (grpc_inproc_trace.enabled()) {
log_metadata(metadata, s->t->is_client, outflags != nullptr);
}
@@ -853,7 +853,7 @@ static void perform_stream_op(grpc_transport* gt, grpc_stream* gs,
gpr_mu* mu = &s->t->mu->mu; // save aside in case s gets closed
gpr_mu_lock(mu);
- if (GRPC_TRACER_ON(grpc_inproc_trace)) {
+ if (grpc_inproc_trace.enabled()) {
if (op->send_initial_metadata) {
log_metadata(op->payload->send_initial_metadata.send_initial_metadata,
s->t->is_client, true);
diff --git a/src/core/ext/transport/inproc/inproc_transport.h b/src/core/ext/transport/inproc/inproc_transport.h
index 6e83af3b4c..f27789a50d 100644
--- a/src/core/ext/transport/inproc/inproc_transport.h
+++ b/src/core/ext/transport/inproc/inproc_transport.h
@@ -29,7 +29,7 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server,
grpc_channel_args* args,
void* reserved);
-extern grpc_tracer_flag grpc_inproc_trace;
+extern grpc_core::TraceFlag grpc_inproc_trace;
void grpc_inproc_transport_init(void);
void grpc_inproc_transport_shutdown(void);
diff --git a/src/core/lib/channel/channel_stack.cc b/src/core/lib/channel/channel_stack.cc
index 45d6fceb03..195fe0b195 100644
--- a/src/core/lib/channel/channel_stack.cc
+++ b/src/core/lib/channel/channel_stack.cc
@@ -23,7 +23,7 @@
#include <stdlib.h>
#include <string.h>
-grpc_tracer_flag grpc_trace_channel = GRPC_TRACER_INITIALIZER(false, "channel");
+grpc_core::TraceFlag grpc_trace_channel(false, "channel");
/* Memory layouts.
diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index 4496b864dc..63382c05b2 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -84,6 +84,7 @@ typedef struct {
typedef struct {
grpc_call_stats stats;
grpc_status_code final_status;
+ const char** error_string;
} grpc_call_final_info;
/* Channel filters specify:
@@ -273,10 +274,10 @@ void grpc_call_log_op(const char* file, int line, gpr_log_severity severity,
grpc_call_element* elem,
grpc_transport_stream_op_batch* op);
-extern grpc_tracer_flag grpc_trace_channel;
+extern grpc_core::TraceFlag grpc_trace_channel;
#define GRPC_CALL_LOG_OP(sev, elem, op) \
- if (GRPC_TRACER_ON(grpc_trace_channel)) grpc_call_log_op(sev, elem, op)
+ if (grpc_trace_channel.enabled()) grpc_call_log_op(sev, elem, op)
#ifdef __cplusplus
}
diff --git a/src/core/lib/channel/channel_stack_builder.cc b/src/core/lib/channel/channel_stack_builder.cc
index 9cef3501bc..fcba826644 100644
--- a/src/core/lib/channel/channel_stack_builder.cc
+++ b/src/core/lib/channel/channel_stack_builder.cc
@@ -23,8 +23,8 @@
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
-grpc_tracer_flag grpc_trace_channel_stack_builder =
- GRPC_TRACER_INITIALIZER(false, "channel_stack_builder");
+grpc_core::TraceFlag grpc_trace_channel_stack_builder(false,
+ "channel_stack_builder");
typedef struct filter_node {
struct filter_node* next;
diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h
index f4e4a200d9..302083e8d4 100644
--- a/src/core/lib/channel/channel_stack_builder.h
+++ b/src/core/lib/channel/channel_stack_builder.h
@@ -157,7 +157,7 @@ grpc_error* grpc_channel_stack_builder_finish(
/// Destroy the builder without creating a channel stack
void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder* builder);
-extern grpc_tracer_flag grpc_trace_channel_stack_builder;
+extern grpc_core::TraceFlag grpc_trace_channel_stack_builder;
#ifdef __cplusplus
}
diff --git a/src/core/lib/debug/trace.cc b/src/core/lib/debug/trace.cc
index 9c75ef124a..4c63983bdc 100644
--- a/src/core/lib/debug/trace.cc
+++ b/src/core/lib/debug/trace.cc
@@ -27,26 +27,61 @@
int grpc_tracer_set_enabled(const char* name, int enabled);
-typedef struct tracer {
- grpc_tracer_flag* flag;
- struct tracer* next;
-} tracer;
-static tracer* tracers;
-
-#ifdef GRPC_THREADSAFE_TRACER
-#define TRACER_SET(flag, on) gpr_atm_no_barrier_store(&(flag).value, (on))
-#else
-#define TRACER_SET(flag, on) (flag).value = (on)
-#endif
-
-void grpc_register_tracer(grpc_tracer_flag* flag) {
- tracer* t = (tracer*)gpr_malloc(sizeof(*t));
- t->flag = flag;
- t->next = tracers;
- TRACER_SET(*flag, false);
- tracers = t;
+namespace grpc_core {
+
+TraceFlag* TraceFlagList::root_tracer_ = nullptr;
+
+bool TraceFlagList::Set(const char* name, bool enabled) {
+ TraceFlag* t;
+ if (0 == strcmp(name, "all")) {
+ for (t = root_tracer_; t; t = t->next_tracer_) {
+ t->set_enabled(enabled);
+ }
+ } else if (0 == strcmp(name, "list_tracers")) {
+ LogAllTracers();
+ } else if (0 == strcmp(name, "refcount")) {
+ for (t = root_tracer_; t; t = t->next_tracer_) {
+ if (strstr(t->name_, "refcount") != nullptr) {
+ t->set_enabled(enabled);
+ }
+ }
+ } else {
+ bool found = false;
+ for (t = root_tracer_; t; t = t->next_tracer_) {
+ if (0 == strcmp(name, t->name_)) {
+ t->set_enabled(enabled);
+ found = true;
+ }
+ }
+ if (!found) {
+ gpr_log(GPR_ERROR, "Unknown trace var: '%s'", name);
+ return false; /* early return */
+ }
+ }
+ return true;
+}
+
+void TraceFlagList::Add(TraceFlag* flag) {
+ flag->next_tracer_ = root_tracer_;
+ root_tracer_ = flag;
}
+void TraceFlagList::LogAllTracers() {
+ gpr_log(GPR_DEBUG, "available tracers:");
+ TraceFlag* t;
+ for (t = root_tracer_; t != nullptr; t = t->next_tracer_) {
+ gpr_log(GPR_DEBUG, "\t%s", t->name_);
+ }
+}
+
+// Flags register themselves on the list during construction
+TraceFlag::TraceFlag(bool default_enabled, const char* name)
+ : name_(name), value_(default_enabled) {
+ TraceFlagList::Add(this);
+}
+
+} // namespace grpc_core
+
static void add(const char* beg, const char* end, char*** ss, size_t* ns) {
size_t n = *ns;
size_t np = n + 1;
@@ -80,9 +115,9 @@ static void parse(const char* s) {
for (i = 0; i < nstrings; i++) {
if (strings[i][0] == '-') {
- grpc_tracer_set_enabled(strings[i] + 1, 0);
+ grpc_core::TraceFlagList::Set(strings[i] + 1, false);
} else {
- grpc_tracer_set_enabled(strings[i], 1);
+ grpc_core::TraceFlagList::Set(strings[i], true);
}
}
@@ -92,14 +127,6 @@ static void parse(const char* s) {
gpr_free(strings);
}
-static void list_tracers() {
- gpr_log(GPR_DEBUG, "available tracers:");
- tracer* t;
- for (t = tracers; t; t = t->next) {
- gpr_log(GPR_DEBUG, "\t%s", t->flag->name);
- }
-}
-
void grpc_tracer_init(const char* env_var) {
char* e = gpr_getenv(env_var);
if (e != nullptr) {
@@ -108,40 +135,8 @@ void grpc_tracer_init(const char* env_var) {
}
}
-void grpc_tracer_shutdown(void) {
- while (tracers) {
- tracer* t = tracers;
- tracers = t->next;
- gpr_free(t);
- }
-}
+void grpc_tracer_shutdown(void) {}
int grpc_tracer_set_enabled(const char* name, int enabled) {
- tracer* t;
- if (0 == strcmp(name, "all")) {
- for (t = tracers; t; t = t->next) {
- TRACER_SET(*t->flag, enabled);
- }
- } else if (0 == strcmp(name, "list_tracers")) {
- list_tracers();
- } else if (0 == strcmp(name, "refcount")) {
- for (t = tracers; t; t = t->next) {
- if (strstr(t->flag->name, "refcount") != nullptr) {
- TRACER_SET(*t->flag, enabled);
- }
- }
- } else {
- int found = 0;
- for (t = tracers; t; t = t->next) {
- if (0 == strcmp(name, t->flag->name)) {
- TRACER_SET(*t->flag, enabled);
- found = 1;
- }
- }
- if (!found) {
- gpr_log(GPR_ERROR, "Unknown trace var: '%s'", name);
- return 0; /* early return */
- }
- }
- return 1;
+ return grpc_core::TraceFlagList::Set(name, enabled != 0);
}
diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h
index 7447d5d94a..b58c16f3ca 100644
--- a/src/core/lib/debug/trace.h
+++ b/src/core/lib/debug/trace.h
@@ -27,37 +27,89 @@
extern "C" {
#endif
+void grpc_tracer_init(const char* env_var_name);
+void grpc_tracer_shutdown(void);
+
+#ifdef __cplusplus
+}
+#endif
+
#if defined(__has_feature)
#if __has_feature(thread_sanitizer)
#define GRPC_THREADSAFE_TRACER
#endif
#endif
-typedef struct {
+#ifdef __cplusplus
+
+namespace grpc_core {
+
+class TraceFlag;
+class TraceFlagList {
+ public:
+ static bool Set(const char* name, bool enabled);
+ static void Add(TraceFlag* flag);
+
+ private:
+ static void LogAllTracers();
+ static TraceFlag* root_tracer_;
+};
+
+namespace testing {
+void grpc_tracer_enable_flag(grpc_core::TraceFlag* flag);
+}
+
+class TraceFlag {
+ public:
+ TraceFlag(bool default_enabled, const char* name);
+ ~TraceFlag() {}
+
+ const char* name() const { return name_; }
+
+ bool enabled() {
+#ifdef GRPC_THREADSAFE_TRACER
+ return gpr_atm_no_barrier_load(&value_) != 0;
+#else
+ return value_;
+#endif
+ }
+
+ private:
+ friend void grpc_core::testing::grpc_tracer_enable_flag(TraceFlag* flag);
+ friend class TraceFlagList;
+
+ void set_enabled(bool enabled) {
#ifdef GRPC_THREADSAFE_TRACER
- gpr_atm value;
+ gpr_atm_no_barrier_store(&value_, enabled);
#else
- bool value;
+ value_ = enabled;
#endif
- const char* name;
-} grpc_tracer_flag;
+ }
+ TraceFlag* next_tracer_;
+ const char* const name_;
#ifdef GRPC_THREADSAFE_TRACER
-#define GRPC_TRACER_ON(flag) (gpr_atm_no_barrier_load(&(flag).value) != 0)
-#define GRPC_TRACER_INITIALIZER(on, name) \
- { (gpr_atm)(on), (name) }
+ gpr_atm value_;
#else
-#define GRPC_TRACER_ON(flag) ((flag).value)
-#define GRPC_TRACER_INITIALIZER(on, name) \
- { (on), (name) }
+ bool value_;
#endif
+};
-void grpc_register_tracer(grpc_tracer_flag* flag);
-void grpc_tracer_init(const char* env_var_name);
-void grpc_tracer_shutdown(void);
+#ifndef NDEBUG
+typedef TraceFlag DebugOnlyTraceFlag;
+#else
+class DebugOnlyTraceFlag {
+ public:
+ DebugOnlyTraceFlag(bool default_enabled, const char* name) {}
+ bool enabled() { return false; }
-#ifdef __cplusplus
-}
+ private:
+ void set_enabled(bool enabled) {}
+};
#endif
+} // namespace grpc_core
+
+#endif // __cplusplus
+
#endif /* GRPC_CORE_LIB_DEBUG_TRACE_H */
diff --git a/src/core/lib/http/parser.cc b/src/core/lib/http/parser.cc
index 9134b0ced2..fb4eb234a7 100644
--- a/src/core/lib/http/parser.cc
+++ b/src/core/lib/http/parser.cc
@@ -25,7 +25,7 @@
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
-grpc_tracer_flag grpc_http1_trace = GRPC_TRACER_INITIALIZER(false, "http1");
+grpc_core::TraceFlag grpc_http1_trace(false, "http1");
static char* buf2str(void* buffer, size_t length) {
char* out = (char*)gpr_malloc(length + 1);
@@ -294,7 +294,7 @@ static grpc_error* addbyte(grpc_http_parser* parser, uint8_t byte,
case GRPC_HTTP_FIRST_LINE:
case GRPC_HTTP_HEADERS:
if (parser->cur_line_length >= GRPC_HTTP_PARSER_MAX_HEADER_LENGTH) {
- if (GRPC_TRACER_ON(grpc_http1_trace))
+ if (grpc_http1_trace.enabled())
gpr_log(GPR_ERROR, "HTTP header max line length (%d) exceeded",
GRPC_HTTP_PARSER_MAX_HEADER_LENGTH);
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
diff --git a/src/core/lib/http/parser.h b/src/core/lib/http/parser.h
index 3d28481c4c..391bd350de 100644
--- a/src/core/lib/http/parser.h
+++ b/src/core/lib/http/parser.h
@@ -111,7 +111,7 @@ grpc_error* grpc_http_parser_eof(grpc_http_parser* parser);
void grpc_http_request_destroy(grpc_http_request* request);
void grpc_http_response_destroy(grpc_http_response* response);
-extern grpc_tracer_flag grpc_http1_trace;
+extern grpc_core::TraceFlag grpc_http1_trace;
#ifdef __cplusplus
}
diff --git a/src/core/lib/iomgr/call_combiner.cc b/src/core/lib/iomgr/call_combiner.cc
index 32b4244748..a9f48fb3c2 100644
--- a/src/core/lib/iomgr/call_combiner.cc
+++ b/src/core/lib/iomgr/call_combiner.cc
@@ -24,8 +24,7 @@
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/profiling/timers.h"
-grpc_tracer_flag grpc_call_combiner_trace =
- GRPC_TRACER_INITIALIZER(false, "call_combiner");
+grpc_core::TraceFlag grpc_call_combiner_trace(false, "call_combiner");
static grpc_error* decode_cancel_state_error(gpr_atm cancel_state) {
if (cancel_state & 1) {
@@ -62,7 +61,7 @@ void grpc_call_combiner_start(grpc_call_combiner* call_combiner,
grpc_error* error DEBUG_ARGS,
const char* reason) {
GPR_TIMER_BEGIN("call_combiner_start", 0);
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG,
"==> grpc_call_combiner_start() [%p] closure=%p [" DEBUG_FMT_STR
"%s] error=%s",
@@ -71,7 +70,7 @@ void grpc_call_combiner_start(grpc_call_combiner* call_combiner,
}
size_t prev_size =
(size_t)gpr_atm_full_fetch_add(&call_combiner->size, (gpr_atm)1);
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG, " size: %" PRIdPTR " -> %" PRIdPTR, prev_size,
prev_size + 1);
}
@@ -80,13 +79,13 @@ void grpc_call_combiner_start(grpc_call_combiner* call_combiner,
GRPC_STATS_INC_CALL_COMBINER_LOCKS_INITIATED();
GPR_TIMER_MARK("call_combiner_initiate", 0);
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG, " EXECUTING IMMEDIATELY");
}
// Queue was empty, so execute this closure immediately.
GRPC_CLOSURE_SCHED(closure, error);
} else {
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_INFO, " QUEUING");
}
// Queue was not empty, so add closure to queue.
@@ -99,21 +98,21 @@ void grpc_call_combiner_start(grpc_call_combiner* call_combiner,
void grpc_call_combiner_stop(grpc_call_combiner* call_combiner DEBUG_ARGS,
const char* reason) {
GPR_TIMER_BEGIN("call_combiner_stop", 0);
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG,
"==> grpc_call_combiner_stop() [%p] [" DEBUG_FMT_STR "%s]",
call_combiner DEBUG_FMT_ARGS, reason);
}
size_t prev_size =
(size_t)gpr_atm_full_fetch_add(&call_combiner->size, (gpr_atm)-1);
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG, " size: %" PRIdPTR " -> %" PRIdPTR, prev_size,
prev_size - 1);
}
GPR_ASSERT(prev_size >= 1);
if (prev_size > 1) {
while (true) {
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG, " checking queue");
}
bool empty;
@@ -122,19 +121,19 @@ void grpc_call_combiner_stop(grpc_call_combiner* call_combiner DEBUG_ARGS,
if (closure == nullptr) {
// This can happen either due to a race condition within the mpscq
// code or because of a race with grpc_call_combiner_start().
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG, " queue returned no result; checking again");
}
continue;
}
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG, " EXECUTING FROM QUEUE: closure=%p error=%s",
closure, grpc_error_string(closure->error_data.error));
}
GRPC_CLOSURE_SCHED(closure, closure->error_data.error);
break;
}
- } else if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ } else if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG, " queue empty");
}
GPR_TIMER_END("call_combiner_stop", 0);
@@ -150,7 +149,7 @@ void grpc_call_combiner_set_notify_on_cancel(grpc_call_combiner* call_combiner,
// If error is set, invoke the cancellation closure immediately.
// Otherwise, store the new closure.
if (original_error != GRPC_ERROR_NONE) {
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG,
"call_combiner=%p: scheduling notify_on_cancel callback=%p "
"for pre-existing cancellation",
@@ -161,7 +160,7 @@ void grpc_call_combiner_set_notify_on_cancel(grpc_call_combiner* call_combiner,
} else {
if (gpr_atm_full_cas(&call_combiner->cancel_state, original_state,
(gpr_atm)closure)) {
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG, "call_combiner=%p: setting notify_on_cancel=%p",
call_combiner, closure);
}
@@ -170,7 +169,7 @@ void grpc_call_combiner_set_notify_on_cancel(grpc_call_combiner* call_combiner,
// up any resources they may be holding for the callback.
if (original_state != 0) {
closure = (grpc_closure*)original_state;
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG,
"call_combiner=%p: scheduling old cancel callback=%p",
call_combiner, closure);
@@ -198,7 +197,7 @@ void grpc_call_combiner_cancel(grpc_call_combiner* call_combiner,
encode_cancel_state_error(error))) {
if (original_state != 0) {
grpc_closure* notify_on_cancel = (grpc_closure*)original_state;
- if (GRPC_TRACER_ON(grpc_call_combiner_trace)) {
+ if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_DEBUG,
"call_combiner=%p: scheduling notify_on_cancel callback=%p",
call_combiner, notify_on_cancel);
diff --git a/src/core/lib/iomgr/call_combiner.h b/src/core/lib/iomgr/call_combiner.h
index 364f77a167..cf928a13f4 100644
--- a/src/core/lib/iomgr/call_combiner.h
+++ b/src/core/lib/iomgr/call_combiner.h
@@ -40,7 +40,7 @@ extern "C" {
// when it is done with the action that was kicked off by the original
// callback.
-extern grpc_tracer_flag grpc_call_combiner_trace;
+extern grpc_core::TraceFlag grpc_call_combiner_trace;
typedef struct {
gpr_atm size; // size_t, num closures in queue or currently executing
diff --git a/src/core/lib/iomgr/closure.cc b/src/core/lib/iomgr/closure.cc
deleted file mode 100644
index 32766110cc..0000000000
--- a/src/core/lib/iomgr/closure.cc
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "src/core/lib/iomgr/closure.h"
-
-#include <assert.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-
-#include "src/core/lib/profiling/timers.h"
-
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_closure = GRPC_TRACER_INITIALIZER(false, "closure");
-#endif
-
-#ifndef NDEBUG
-grpc_closure* grpc_closure_init(const char* file, int line,
- grpc_closure* closure, grpc_iomgr_cb_func cb,
- void* cb_arg,
- grpc_closure_scheduler* scheduler) {
-#else
-grpc_closure* grpc_closure_init(grpc_closure* closure, grpc_iomgr_cb_func cb,
- void* cb_arg,
- grpc_closure_scheduler* scheduler) {
-#endif
- closure->cb = cb;
- closure->cb_arg = cb_arg;
- closure->scheduler = scheduler;
-#ifndef NDEBUG
- closure->scheduled = false;
- closure->file_initiated = nullptr;
- closure->line_initiated = 0;
- closure->run = false;
- closure->file_created = file;
- closure->line_created = line;
-#endif
- return closure;
-}
-
-void grpc_closure_list_init(grpc_closure_list* closure_list) {
- closure_list->head = closure_list->tail = nullptr;
-}
-
-bool grpc_closure_list_append(grpc_closure_list* closure_list,
- grpc_closure* closure, grpc_error* error) {
- if (closure == nullptr) {
- GRPC_ERROR_UNREF(error);
- return false;
- }
- closure->error_data.error = error;
- closure->next_data.next = nullptr;
- bool was_empty = (closure_list->head == nullptr);
- if (was_empty) {
- closure_list->head = closure;
- } else {
- closure_list->tail->next_data.next = closure;
- }
- closure_list->tail = closure;
- return was_empty;
-}
-
-void grpc_closure_list_fail_all(grpc_closure_list* list,
- grpc_error* forced_failure) {
- for (grpc_closure* c = list->head; c != nullptr; c = c->next_data.next) {
- if (c->error_data.error == GRPC_ERROR_NONE) {
- c->error_data.error = GRPC_ERROR_REF(forced_failure);
- }
- }
- GRPC_ERROR_UNREF(forced_failure);
-}
-
-bool grpc_closure_list_empty(grpc_closure_list closure_list) {
- return closure_list.head == nullptr;
-}
-
-void grpc_closure_list_move(grpc_closure_list* src, grpc_closure_list* dst) {
- if (src->head == nullptr) {
- return;
- }
- if (dst->head == nullptr) {
- *dst = *src;
- } else {
- dst->tail->next_data.next = src->head;
- dst->tail = src->tail;
- }
- src->head = src->tail = nullptr;
-}
-
-typedef struct {
- grpc_iomgr_cb_func cb;
- void* cb_arg;
- grpc_closure wrapper;
-} wrapped_closure;
-
-static void closure_wrapper(void* arg, grpc_error* error) {
- wrapped_closure* wc = (wrapped_closure*)arg;
- grpc_iomgr_cb_func cb = wc->cb;
- void* cb_arg = wc->cb_arg;
- gpr_free(wc);
- cb(cb_arg, error);
-}
-
-#ifndef NDEBUG
-grpc_closure* grpc_closure_create(const char* file, int line,
- grpc_iomgr_cb_func cb, void* cb_arg,
- grpc_closure_scheduler* scheduler) {
-#else
-grpc_closure* grpc_closure_create(grpc_iomgr_cb_func cb, void* cb_arg,
- grpc_closure_scheduler* scheduler) {
-#endif
- wrapped_closure* wc = (wrapped_closure*)gpr_malloc(sizeof(*wc));
- wc->cb = cb;
- wc->cb_arg = cb_arg;
-#ifndef NDEBUG
- grpc_closure_init(file, line, &wc->wrapper, closure_wrapper, wc, scheduler);
-#else
- grpc_closure_init(&wc->wrapper, closure_wrapper, wc, scheduler);
-#endif
- return &wc->wrapper;
-}
-
-#ifndef NDEBUG
-void grpc_closure_run(const char* file, int line, grpc_closure* c,
- grpc_error* error) {
-#else
-void grpc_closure_run(grpc_closure* c, grpc_error* error) {
-#endif
- GPR_TIMER_BEGIN("grpc_closure_run", 0);
- if (c != nullptr) {
-#ifndef NDEBUG
- c->file_initiated = file;
- c->line_initiated = line;
- c->run = true;
-#endif
- assert(c->cb);
- c->scheduler->vtable->run(c, error);
- } else {
- GRPC_ERROR_UNREF(error);
- }
- GPR_TIMER_END("grpc_closure_run", 0);
-}
-
-#ifndef NDEBUG
-void grpc_closure_sched(const char* file, int line, grpc_closure* c,
- grpc_error* error) {
-#else
-void grpc_closure_sched(grpc_closure* c, grpc_error* error) {
-#endif
- GPR_TIMER_BEGIN("grpc_closure_sched", 0);
- if (c != nullptr) {
-#ifndef NDEBUG
- if (c->scheduled) {
- gpr_log(GPR_ERROR,
- "Closure already scheduled. (closure: %p, created: [%s:%d], "
- "previously scheduled at: [%s: %d] run?: %s",
- c, c->file_created, c->line_created, c->file_initiated,
- c->line_initiated, c->run ? "true" : "false");
- abort();
- }
- c->scheduled = true;
- c->file_initiated = file;
- c->line_initiated = line;
- c->run = false;
-#endif
- assert(c->cb);
- c->scheduler->vtable->sched(c, error);
- } else {
- GRPC_ERROR_UNREF(error);
- }
- GPR_TIMER_END("grpc_closure_sched", 0);
-}
-
-#ifndef NDEBUG
-void grpc_closure_list_sched(const char* file, int line,
- grpc_closure_list* list) {
-#else
-void grpc_closure_list_sched(grpc_closure_list* list) {
-#endif
- grpc_closure* c = list->head;
- while (c != nullptr) {
- grpc_closure* next = c->next_data.next;
-#ifndef NDEBUG
- if (c->scheduled) {
- gpr_log(GPR_ERROR,
- "Closure already scheduled. (closure: %p, created: [%s:%d], "
- "previously scheduled at: [%s: %d] run?: %s",
- c, c->file_created, c->line_created, c->file_initiated,
- c->line_initiated, c->run ? "true" : "false");
- abort();
- }
- c->scheduled = true;
- c->file_initiated = file;
- c->line_initiated = line;
- c->run = false;
-#endif
- assert(c->cb);
- c->scheduler->vtable->sched(c, c->error_data.error);
- c = next;
- }
- list->head = list->tail = nullptr;
-}
diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h
index 63843ad76d..88af76006a 100644
--- a/src/core/lib/iomgr/closure.h
+++ b/src/core/lib/iomgr/closure.h
@@ -21,21 +21,19 @@
#include <grpc/support/port_platform.h>
+#include <assert.h>
#include <grpc/impl/codegen/exec_ctx_fwd.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
#include <stdbool.h>
#include "src/core/lib/iomgr/error.h"
+#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/support/mpscq.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
struct grpc_closure;
typedef struct grpc_closure grpc_closure;
-#ifndef NDEBUG
-extern grpc_tracer_flag grpc_trace_closure;
-#endif
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_closure;
typedef struct grpc_closure_list {
grpc_closure* head;
@@ -82,8 +80,8 @@ struct grpc_closure {
/** Arguments to be passed to "cb". */
void* cb_arg;
- /** Scheduler to schedule against: NULL to schedule against current execution
- context */
+ /** Scheduler to schedule against: nullptr to schedule against current
+ execution context */
grpc_closure_scheduler* scheduler;
/** Once queued, the result of the closure. Before then: scratch space */
@@ -104,96 +102,253 @@ struct grpc_closure {
#endif
};
+#ifndef NDEBUG
+inline grpc_closure* grpc_closure_init(const char* file, int line,
+ grpc_closure* closure,
+ grpc_iomgr_cb_func cb, void* cb_arg,
+ grpc_closure_scheduler* scheduler) {
+#else
+inline grpc_closure* grpc_closure_init(grpc_closure* closure,
+ grpc_iomgr_cb_func cb, void* cb_arg,
+ grpc_closure_scheduler* scheduler) {
+#endif
+ closure->cb = cb;
+ closure->cb_arg = cb_arg;
+ closure->scheduler = scheduler;
+#ifndef NDEBUG
+ closure->scheduled = false;
+ closure->file_initiated = nullptr;
+ closure->line_initiated = 0;
+ closure->run = false;
+ closure->file_created = file;
+ closure->line_created = line;
+#endif
+ return closure;
+}
+
/** Initializes \a closure with \a cb and \a cb_arg. Returns \a closure. */
#ifndef NDEBUG
-grpc_closure* grpc_closure_init(const char* file, int line,
- grpc_closure* closure, grpc_iomgr_cb_func cb,
- void* cb_arg,
- grpc_closure_scheduler* scheduler);
#define GRPC_CLOSURE_INIT(closure, cb, cb_arg, scheduler) \
grpc_closure_init(__FILE__, __LINE__, closure, cb, cb_arg, scheduler)
#else
-grpc_closure* grpc_closure_init(grpc_closure* closure, grpc_iomgr_cb_func cb,
- void* cb_arg,
- grpc_closure_scheduler* scheduler);
#define GRPC_CLOSURE_INIT(closure, cb, cb_arg, scheduler) \
grpc_closure_init(closure, cb, cb_arg, scheduler)
#endif
+namespace closure_impl {
+
+typedef struct {
+ grpc_iomgr_cb_func cb;
+ void* cb_arg;
+ grpc_closure wrapper;
+} wrapped_closure;
+
+inline void closure_wrapper(void* arg, grpc_error* error) {
+ wrapped_closure* wc = (wrapped_closure*)arg;
+ grpc_iomgr_cb_func cb = wc->cb;
+ void* cb_arg = wc->cb_arg;
+ gpr_free(wc);
+ cb(cb_arg, error);
+}
+
+} // namespace closure_impl
+
+#ifndef NDEBUG
+inline grpc_closure* grpc_closure_create(const char* file, int line,
+ grpc_iomgr_cb_func cb, void* cb_arg,
+ grpc_closure_scheduler* scheduler) {
+#else
+inline grpc_closure* grpc_closure_create(grpc_iomgr_cb_func cb, void* cb_arg,
+ grpc_closure_scheduler* scheduler) {
+#endif
+ closure_impl::wrapped_closure* wc =
+ (closure_impl::wrapped_closure*)gpr_malloc(sizeof(*wc));
+ wc->cb = cb;
+ wc->cb_arg = cb_arg;
+#ifndef NDEBUG
+ grpc_closure_init(file, line, &wc->wrapper, closure_impl::closure_wrapper, wc,
+ scheduler);
+#else
+ grpc_closure_init(&wc->wrapper, closure_impl::closure_wrapper, wc, scheduler);
+#endif
+ return &wc->wrapper;
+}
+
/* Create a heap allocated closure: try to avoid except for very rare events */
#ifndef NDEBUG
-grpc_closure* grpc_closure_create(const char* file, int line,
- grpc_iomgr_cb_func cb, void* cb_arg,
- grpc_closure_scheduler* scheduler);
#define GRPC_CLOSURE_CREATE(cb, cb_arg, scheduler) \
grpc_closure_create(__FILE__, __LINE__, cb, cb_arg, scheduler)
#else
-grpc_closure* grpc_closure_create(grpc_iomgr_cb_func cb, void* cb_arg,
- grpc_closure_scheduler* scheduler);
#define GRPC_CLOSURE_CREATE(cb, cb_arg, scheduler) \
grpc_closure_create(cb, cb_arg, scheduler)
#endif
#define GRPC_CLOSURE_LIST_INIT \
- { NULL, NULL }
+ { nullptr, nullptr }
-void grpc_closure_list_init(grpc_closure_list* list);
+inline void grpc_closure_list_init(grpc_closure_list* closure_list) {
+ closure_list->head = closure_list->tail = nullptr;
+}
/** add \a closure to the end of \a list
and set \a closure's result to \a error
Returns true if \a list becomes non-empty */
-bool grpc_closure_list_append(grpc_closure_list* list, grpc_closure* closure,
- grpc_error* error);
+inline bool grpc_closure_list_append(grpc_closure_list* closure_list,
+ grpc_closure* closure, grpc_error* error) {
+ if (closure == nullptr) {
+ GRPC_ERROR_UNREF(error);
+ return false;
+ }
+ closure->error_data.error = error;
+ closure->next_data.next = nullptr;
+ bool was_empty = (closure_list->head == nullptr);
+ if (was_empty) {
+ closure_list->head = closure;
+ } else {
+ closure_list->tail->next_data.next = closure;
+ }
+ closure_list->tail = closure;
+ return was_empty;
+}
/** force all success bits in \a list to false */
-void grpc_closure_list_fail_all(grpc_closure_list* list,
- grpc_error* forced_failure);
+inline void grpc_closure_list_fail_all(grpc_closure_list* list,
+ grpc_error* forced_failure) {
+ for (grpc_closure* c = list->head; c != nullptr; c = c->next_data.next) {
+ if (c->error_data.error == GRPC_ERROR_NONE) {
+ c->error_data.error = GRPC_ERROR_REF(forced_failure);
+ }
+ }
+ GRPC_ERROR_UNREF(forced_failure);
+}
/** append all closures from \a src to \a dst and empty \a src. */
-void grpc_closure_list_move(grpc_closure_list* src, grpc_closure_list* dst);
+inline void grpc_closure_list_move(grpc_closure_list* src,
+ grpc_closure_list* dst) {
+ if (src->head == nullptr) {
+ return;
+ }
+ if (dst->head == nullptr) {
+ *dst = *src;
+ } else {
+ dst->tail->next_data.next = src->head;
+ dst->tail = src->tail;
+ }
+ src->head = src->tail = nullptr;
+}
/** return whether \a list is empty. */
-bool grpc_closure_list_empty(grpc_closure_list list);
+inline bool grpc_closure_list_empty(grpc_closure_list closure_list) {
+ return closure_list.head == nullptr;
+}
+
+#ifndef NDEBUG
+inline void grpc_closure_run(const char* file, int line, grpc_closure* c,
+ grpc_error* error) {
+#else
+inline void grpc_closure_run(grpc_closure* c, grpc_error* error) {
+#endif
+ GPR_TIMER_BEGIN("grpc_closure_run", 0);
+ if (c != nullptr) {
+#ifndef NDEBUG
+ c->file_initiated = file;
+ c->line_initiated = line;
+ c->run = true;
+#endif
+ assert(c->cb);
+ c->scheduler->vtable->run(c, error);
+ } else {
+ GRPC_ERROR_UNREF(error);
+ }
+ GPR_TIMER_END("grpc_closure_run", 0);
+}
/** Run a closure directly. Caller ensures that no locks are being held above.
* Note that calling this at the end of a closure callback function itself is
* by definition safe. */
#ifndef NDEBUG
-void grpc_closure_run(const char* file, int line, grpc_closure* closure,
- grpc_error* error);
#define GRPC_CLOSURE_RUN(closure, error) \
grpc_closure_run(__FILE__, __LINE__, closure, error)
#else
-void grpc_closure_run(grpc_closure* closure, grpc_error* error);
#define GRPC_CLOSURE_RUN(closure, error) grpc_closure_run(closure, error)
#endif
+#ifndef NDEBUG
+inline void grpc_closure_sched(const char* file, int line, grpc_closure* c,
+ grpc_error* error) {
+#else
+inline void grpc_closure_sched(grpc_closure* c, grpc_error* error) {
+#endif
+ GPR_TIMER_BEGIN("grpc_closure_sched", 0);
+ if (c != nullptr) {
+#ifndef NDEBUG
+ if (c->scheduled) {
+ gpr_log(GPR_ERROR,
+ "Closure already scheduled. (closure: %p, created: [%s:%d], "
+ "previously scheduled at: [%s: %d] run?: %s",
+ c, c->file_created, c->line_created, c->file_initiated,
+ c->line_initiated, c->run ? "true" : "false");
+ abort();
+ }
+ c->scheduled = true;
+ c->file_initiated = file;
+ c->line_initiated = line;
+ c->run = false;
+#endif
+ assert(c->cb);
+ c->scheduler->vtable->sched(c, error);
+ } else {
+ GRPC_ERROR_UNREF(error);
+ }
+ GPR_TIMER_END("grpc_closure_sched", 0);
+}
+
/** Schedule a closure to be run. Does not need to be run from a safe point. */
#ifndef NDEBUG
-void grpc_closure_sched(const char* file, int line, grpc_closure* closure,
- grpc_error* error);
#define GRPC_CLOSURE_SCHED(closure, error) \
grpc_closure_sched(__FILE__, __LINE__, closure, error)
#else
-void grpc_closure_sched(grpc_closure* closure, grpc_error* error);
#define GRPC_CLOSURE_SCHED(closure, error) grpc_closure_sched(closure, error)
#endif
+#ifndef NDEBUG
+inline void grpc_closure_list_sched(const char* file, int line,
+ grpc_closure_list* list) {
+#else
+inline void grpc_closure_list_sched(grpc_closure_list* list) {
+#endif
+ grpc_closure* c = list->head;
+ while (c != nullptr) {
+ grpc_closure* next = c->next_data.next;
+#ifndef NDEBUG
+ if (c->scheduled) {
+ gpr_log(GPR_ERROR,
+ "Closure already scheduled. (closure: %p, created: [%s:%d], "
+ "previously scheduled at: [%s: %d] run?: %s",
+ c, c->file_created, c->line_created, c->file_initiated,
+ c->line_initiated, c->run ? "true" : "false");
+ abort();
+ }
+ c->scheduled = true;
+ c->file_initiated = file;
+ c->line_initiated = line;
+ c->run = false;
+#endif
+ assert(c->cb);
+ c->scheduler->vtable->sched(c, c->error_data.error);
+ c = next;
+ }
+ list->head = list->tail = nullptr;
+}
+
/** Schedule all closures in a list to be run. Does not need to be run from a
* safe point. */
#ifndef NDEBUG
-void grpc_closure_list_sched(const char* file, int line,
- grpc_closure_list* closure_list);
#define GRPC_CLOSURE_LIST_SCHED(closure_list) \
grpc_closure_list_sched(__FILE__, __LINE__, closure_list)
#else
-void grpc_closure_list_sched(grpc_closure_list* closure_list);
#define GRPC_CLOSURE_LIST_SCHED(closure_list) \
grpc_closure_list_sched(closure_list)
#endif
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_IOMGR_CLOSURE_H */
diff --git a/src/core/lib/iomgr/combiner.cc b/src/core/lib/iomgr/combiner.cc
index d2b7cf4b10..e4d7a6abd8 100644
--- a/src/core/lib/iomgr/combiner.cc
+++ b/src/core/lib/iomgr/combiner.cc
@@ -29,14 +29,13 @@
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/profiling/timers.h"
-grpc_tracer_flag grpc_combiner_trace =
- GRPC_TRACER_INITIALIZER(false, "combiner");
-
-#define GRPC_COMBINER_TRACE(fn) \
- do { \
- if (GRPC_TRACER_ON(grpc_combiner_trace)) { \
- fn; \
- } \
+grpc_core::TraceFlag grpc_combiner_trace(false, "combiner");
+
+#define GRPC_COMBINER_TRACE(fn) \
+ do { \
+ if (grpc_combiner_trace.enabled()) { \
+ fn; \
+ } \
} while (0)
#define STATE_UNORPHANED 1
@@ -104,7 +103,7 @@ static void start_destroy(grpc_combiner* lock) {
#ifndef NDEBUG
#define GRPC_COMBINER_DEBUG_SPAM(op, delta) \
- if (GRPC_TRACER_ON(grpc_combiner_trace)) { \
+ if (grpc_combiner_trace.enabled()) { \
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, \
"C:%p %s %" PRIdPTR " --> %" PRIdPTR " %s", lock, (op), \
gpr_atm_no_barrier_load(&lock->refs.count), \
diff --git a/src/core/lib/iomgr/combiner.h b/src/core/lib/iomgr/combiner.h
index bb450db2fc..8555fa979f 100644
--- a/src/core/lib/iomgr/combiner.h
+++ b/src/core/lib/iomgr/combiner.h
@@ -63,7 +63,7 @@ grpc_closure_scheduler* grpc_combiner_finally_scheduler(grpc_combiner* lock);
bool grpc_combiner_continue_exec_ctx();
-extern grpc_tracer_flag grpc_combiner_trace;
+extern grpc_core::TraceFlag grpc_combiner_trace;
#ifdef __cplusplus
}
diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc
index 2364b1a369..42cd7c455d 100644
--- a/src/core/lib/iomgr/error.cc
+++ b/src/core/lib/iomgr/error.cc
@@ -37,10 +37,9 @@
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/slice_internal.h"
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_error_refcount =
- GRPC_TRACER_INITIALIZER(false, "error_refcount");
-#endif
+grpc_core::DebugOnlyTraceFlag grpc_trace_error_refcount(false,
+ "error_refcount");
+grpc_core::DebugOnlyTraceFlag grpc_trace_closure(false, "closure");
static const char* error_int_name(grpc_error_ints key) {
switch (key) {
@@ -130,7 +129,7 @@ bool grpc_error_is_special(grpc_error* err) {
#ifndef NDEBUG
grpc_error* grpc_error_ref(grpc_error* err, const char* file, int line) {
if (grpc_error_is_special(err)) return err;
- if (GRPC_TRACER_ON(grpc_trace_error_refcount)) {
+ if (grpc_trace_error_refcount.enabled()) {
gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d]", err,
gpr_atm_no_barrier_load(&err->atomics.refs.count),
gpr_atm_no_barrier_load(&err->atomics.refs.count) + 1, file, line);
@@ -179,7 +178,7 @@ static void error_destroy(grpc_error* err) {
#ifndef NDEBUG
void grpc_error_unref(grpc_error* err, const char* file, int line) {
if (grpc_error_is_special(err)) return;
- if (GRPC_TRACER_ON(grpc_trace_error_refcount)) {
+ if (grpc_trace_error_refcount.enabled()) {
gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d]", err,
gpr_atm_no_barrier_load(&err->atomics.refs.count),
gpr_atm_no_barrier_load(&err->atomics.refs.count) - 1, file, line);
@@ -212,7 +211,7 @@ static uint8_t get_placement(grpc_error** err, size_t size) {
*err = (grpc_error*)gpr_realloc(
*err, sizeof(grpc_error) + (*err)->arena_capacity * sizeof(intptr_t));
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_error_refcount)) {
+ if (grpc_trace_error_refcount.enabled()) {
if (*err != orig) {
gpr_log(GPR_DEBUG, "realloc %p -> %p", orig, *err);
}
@@ -325,7 +324,7 @@ grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc,
return GRPC_ERROR_OOM;
}
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_error_refcount)) {
+ if (grpc_trace_error_refcount.enabled()) {
gpr_log(GPR_DEBUG, "%p create [%s:%d]", err, file, line);
}
#endif
@@ -407,7 +406,7 @@ static grpc_error* copy_error_and_unref(grpc_error* in) {
out = (grpc_error*)gpr_malloc(sizeof(*in) +
new_arena_capacity * sizeof(intptr_t));
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_error_refcount)) {
+ if (grpc_trace_error_refcount.enabled()) {
gpr_log(GPR_DEBUG, "%p create copying %p", out, in);
}
#endif
diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h
index 8d7aea4872..d10bf0b359 100644
--- a/src/core/lib/iomgr/error.h
+++ b/src/core/lib/iomgr/error.h
@@ -39,9 +39,7 @@ extern "C" {
typedef struct grpc_error grpc_error;
-#ifndef NDEBUG
-extern grpc_tracer_flag grpc_trace_error_refcount;
-#endif
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_error_refcount;
typedef enum {
/// 'errno' from the operating system
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc
index 1598657afe..d9e8a30f5e 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.cc
+++ b/src/core/lib/iomgr/ev_epoll1_linux.cc
@@ -263,12 +263,14 @@ static grpc_fd* fd_create(int fd, const char* name) {
if (new_fd == nullptr) {
new_fd = (grpc_fd*)gpr_malloc(sizeof(grpc_fd));
+ new_fd->read_closure.Init();
+ new_fd->write_closure.Init();
}
new_fd->fd = fd;
- new_fd->read_closure.Init();
- new_fd->write_closure.Init();
- gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm) nullptr);
+ new_fd->read_closure->InitEvent();
+ new_fd->write_closure->InitEvent();
+ gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
new_fd->freelist_next = nullptr;
@@ -276,7 +278,7 @@ static grpc_fd* fd_create(int fd, const char* name) {
gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name);
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_fd_refcount)) {
+ if (grpc_trace_fd_refcount.enabled()) {
gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, new_fd, fd_name);
}
#endif
@@ -334,8 +336,8 @@ 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);
- fd->read_closure.Destroy();
- fd->write_closure.Destroy();
+ fd->read_closure->DestroyEvent();
+ fd->write_closure->DestroyEvent();
gpr_mu_lock(&fd_freelist_mu);
fd->freelist_next = fd_freelist;
@@ -637,7 +639,7 @@ static grpc_error* do_epoll_wait(grpc_pollset* ps, grpc_millis deadline) {
GRPC_STATS_INC_POLL_EVENTS_RETURNED(r);
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "ps: %p poll got %d events", ps, r);
}
@@ -658,7 +660,7 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
worker->schedule_on_end_work = (grpc_closure_list)GRPC_CLOSURE_LIST_INIT;
pollset->begin_refs++;
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, "PS:%p BEGIN_STARTS:%p", pollset, worker);
}
@@ -677,7 +679,7 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
retry_lock_neighborhood:
gpr_mu_lock(&neighborhood->mu);
gpr_mu_lock(&pollset->mu);
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, "PS:%p BEGIN_REORG:%p kick_state=%s is_reassigning=%d",
pollset, worker, kick_state_string(worker->state),
is_reassigning);
@@ -729,7 +731,7 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
worker->initialized_cv = true;
gpr_cv_init(&worker->cv);
while (worker->state == UNKICKED && !pollset->shutting_down) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, "PS:%p BEGIN_WAIT:%p kick_state=%s shutdown=%d",
pollset, worker, kick_state_string(worker->state),
pollset->shutting_down);
@@ -746,7 +748,7 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
grpc_core::ExecCtx::Get()->InvalidateNow();
}
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR,
"PS:%p BEGIN_DONE:%p kick_state=%s shutdown=%d "
"kicked_without_poller: %d",
@@ -791,7 +793,7 @@ static bool check_neighborhood_for_available_poller(
case UNKICKED:
if (gpr_atm_no_barrier_cas(&g_active_poller, 0,
(gpr_atm)inspect_worker)) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, " .. choose next poller to be %p",
inspect_worker);
}
@@ -802,7 +804,7 @@ static bool check_neighborhood_for_available_poller(
gpr_cv_signal(&inspect_worker->cv);
}
} else {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, " .. beaten to choose next poller");
}
}
@@ -820,7 +822,7 @@ static bool check_neighborhood_for_available_poller(
} while (!found_worker && inspect_worker != inspect->root_worker);
}
if (!found_worker) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, " .. mark pollset %p inactive", inspect);
}
inspect->seen_inactive = true;
@@ -841,7 +843,7 @@ static bool check_neighborhood_for_available_poller(
static void end_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
grpc_pollset_worker** worker_hdl) {
GPR_TIMER_BEGIN("end_worker", 0);
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PS:%p END_WORKER:%p", pollset, worker);
}
if (worker_hdl != nullptr) *worker_hdl = nullptr;
@@ -851,7 +853,7 @@ static void end_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
grpc_core::ExecCtx::Get()->closure_list());
if (gpr_atm_no_barrier_load(&g_active_poller) == (gpr_atm)worker) {
if (worker->next != worker && worker->next->state == UNKICKED) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, " .. choose next poller to be peer %p", worker);
}
GPR_ASSERT(worker->next->initialized_cv);
@@ -903,7 +905,7 @@ static void end_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
if (worker->initialized_cv) {
gpr_cv_destroy(&worker->cv);
}
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, " .. remove worker");
}
if (EMPTIED == worker_remove(pollset, worker)) {
@@ -975,7 +977,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
GPR_TIMER_BEGIN("pollset_kick", 0);
GRPC_STATS_INC_POLLSET_KICK();
grpc_error* ret_err = GRPC_ERROR_NONE;
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_strvec log;
gpr_strvec_init(&log);
char* tmp;
@@ -1008,7 +1010,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
if (root_worker == nullptr) {
GRPC_STATS_INC_POLLSET_KICKED_WITHOUT_POLLER();
pollset->kicked_without_poller = true;
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, " .. kicked_without_poller");
}
goto done;
@@ -1016,14 +1018,14 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
grpc_pollset_worker* next_worker = root_worker->next;
if (root_worker->state == KICKED) {
GRPC_STATS_INC_POLLSET_KICKED_AGAIN();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, " .. already kicked %p", root_worker);
}
SET_KICK_STATE(root_worker, KICKED);
goto done;
} else if (next_worker->state == KICKED) {
GRPC_STATS_INC_POLLSET_KICKED_AGAIN();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, " .. already kicked %p", next_worker);
}
SET_KICK_STATE(next_worker, KICKED);
@@ -1034,7 +1036,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
root_worker == (grpc_pollset_worker*)gpr_atm_no_barrier_load(
&g_active_poller)) {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, " .. kicked %p", root_worker);
}
SET_KICK_STATE(root_worker, KICKED);
@@ -1042,7 +1044,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
goto done;
} else if (next_worker->state == UNKICKED) {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_CV();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, " .. kicked %p", next_worker);
}
GPR_ASSERT(next_worker->initialized_cv);
@@ -1051,7 +1053,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
goto done;
} else if (next_worker->state == DESIGNATED_POLLER) {
if (root_worker->state != DESIGNATED_POLLER) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(
GPR_ERROR,
" .. kicked root non-poller %p (initialized_cv=%d) (poller=%p)",
@@ -1065,7 +1067,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
goto done;
} else {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, " .. non-root poller %p (root=%p)", next_worker,
root_worker);
}
@@ -1081,7 +1083,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
}
} else {
GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, " .. kicked while waking up");
}
goto done;
@@ -1091,14 +1093,14 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
}
if (specific_worker->state == KICKED) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, " .. specific worker already kicked");
}
goto done;
} else if (gpr_tls_get(&g_current_thread_worker) ==
(intptr_t)specific_worker) {
GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, " .. mark %p kicked", specific_worker);
}
SET_KICK_STATE(specific_worker, KICKED);
@@ -1106,7 +1108,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
} else if (specific_worker ==
(grpc_pollset_worker*)gpr_atm_no_barrier_load(&g_active_poller)) {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, " .. kick active poller");
}
SET_KICK_STATE(specific_worker, KICKED);
@@ -1114,7 +1116,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
goto done;
} else if (specific_worker->initialized_cv) {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_CV();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, " .. kick waiting worker");
}
SET_KICK_STATE(specific_worker, KICKED);
@@ -1122,7 +1124,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
goto done;
} else {
GRPC_STATS_INC_POLLSET_KICKED_AGAIN();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, " .. kick non-waiting worker");
}
SET_KICK_STATE(specific_worker, KICKED);
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index d83fe8f80a..b2817156a8 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -59,10 +59,8 @@
#define MAX_EPOLL_EVENTS 100
#define MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL 5
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_pollable_refcount =
- GRPC_TRACER_INITIALIZER(false, "pollable_refcount");
-#endif
+grpc_core::DebugOnlyTraceFlag grpc_trace_pollable_refcount(false,
+ "pollable_refcount");
/*******************************************************************************
* pollable Declarations
@@ -262,7 +260,7 @@ static gpr_mu fd_freelist_mu;
#define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__)
static void ref_by(grpc_fd* fd, int n, const char* reason, const char* file,
int line) {
- if (GRPC_TRACER_ON(grpc_trace_fd_refcount)) {
+ if (grpc_trace_fd_refcount.enabled()) {
gpr_log(GPR_DEBUG,
"FD %d %p ref %d %" PRIdPTR " -> %" PRIdPTR " [%s; %s:%d]",
fd->fd, fd, n, gpr_atm_no_barrier_load(&fd->refst),
@@ -287,8 +285,8 @@ static void fd_destroy(void* arg, grpc_error* error) {
fd->freelist_next = fd_freelist;
fd_freelist = fd;
- fd->read_closure.Destroy();
- fd->write_closure.Destroy();
+ fd->read_closure->DestroyEvent();
+ fd->write_closure->DestroyEvent();
gpr_mu_unlock(&fd_freelist_mu);
}
@@ -296,7 +294,7 @@ static void fd_destroy(void* arg, grpc_error* error) {
#ifndef NDEBUG
static void unref_by(grpc_fd* fd, int n, const char* reason, const char* file,
int line) {
- if (GRPC_TRACER_ON(grpc_trace_fd_refcount)) {
+ if (grpc_trace_fd_refcount.enabled()) {
gpr_log(GPR_DEBUG,
"FD %d %p unref %d %" PRIdPTR " -> %" PRIdPTR " [%s; %s:%d]",
fd->fd, fd, n, gpr_atm_no_barrier_load(&fd->refst),
@@ -340,6 +338,8 @@ static grpc_fd* fd_create(int fd, const char* name) {
if (new_fd == nullptr) {
new_fd = (grpc_fd*)gpr_malloc(sizeof(grpc_fd));
+ new_fd->read_closure.Init();
+ new_fd->write_closure.Init();
}
gpr_mu_init(&new_fd->pollable_mu);
@@ -347,9 +347,9 @@ static grpc_fd* fd_create(int fd, const char* name) {
new_fd->pollable_obj = nullptr;
gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
new_fd->fd = fd;
- new_fd->read_closure.Init();
- new_fd->write_closure.Init();
- gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm) nullptr);
+ new_fd->read_closure->InitEvent();
+ new_fd->write_closure->InitEvent();
+ gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
new_fd->freelist_next = nullptr;
new_fd->on_done_closure = nullptr;
@@ -358,7 +358,7 @@ static grpc_fd* fd_create(int fd, const char* name) {
gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name);
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_fd_refcount)) {
+ if (grpc_trace_fd_refcount.enabled()) {
gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, new_fd, fd_name);
}
#endif
@@ -477,7 +477,7 @@ static grpc_error* pollable_create(pollable_type type, pollable** p) {
static pollable* pollable_ref(pollable* p) {
#else
static pollable* pollable_ref(pollable* p, int line, const char* reason) {
- if (GRPC_TRACER_ON(grpc_trace_pollable_refcount)) {
+ if (grpc_trace_pollable_refcount.enabled()) {
int r = (int)gpr_atm_no_barrier_load(&p->refs.count);
gpr_log(__FILE__, line, GPR_LOG_SEVERITY_DEBUG,
"POLLABLE:%p ref %d->%d %s", p, r, r + 1, reason);
@@ -492,7 +492,7 @@ static void pollable_unref(pollable* p) {
#else
static void pollable_unref(pollable* p, int line, const char* reason) {
if (p == nullptr) return;
- if (GRPC_TRACER_ON(grpc_trace_pollable_refcount)) {
+ if (grpc_trace_pollable_refcount.enabled()) {
int r = (int)gpr_atm_no_barrier_load(&p->refs.count);
gpr_log(__FILE__, line, GPR_LOG_SEVERITY_DEBUG,
"POLLABLE:%p unref %d->%d %s", p, r, r - 1, reason);
@@ -510,7 +510,7 @@ static grpc_error* pollable_add_fd(pollable* p, grpc_fd* fd) {
static const char* err_desc = "pollable_add_fd";
const int epfd = p->epfd;
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "add fd %p (%d) to pollable %p", fd, fd->fd, p);
}
@@ -551,7 +551,7 @@ static void pollset_global_shutdown(void) {
/* pollset->mu must be held while calling this function */
static void pollset_maybe_finish_shutdown(grpc_pollset* pollset) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG,
"PS:%p (pollable:%p) maybe_finish_shutdown sc=%p (target:!NULL) "
"rw=%p (target:NULL) cpsc=%d (target:0)",
@@ -573,14 +573,14 @@ static grpc_error* kick_one_worker(grpc_pollset_worker* specific_worker) {
grpc_core::mu_guard lock(&p->mu);
GPR_ASSERT(specific_worker != nullptr);
if (specific_worker->kicked) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PS:%p kicked_specific_but_already_kicked", p);
}
GRPC_STATS_INC_POLLSET_KICKED_AGAIN();
return GRPC_ERROR_NONE;
}
if (gpr_tls_get(&g_current_thread_worker) == (intptr_t)specific_worker) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PS:%p kicked_specific_but_awake", p);
}
GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD();
@@ -589,7 +589,7 @@ static grpc_error* kick_one_worker(grpc_pollset_worker* specific_worker) {
}
if (specific_worker == p->root_worker) {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PS:%p kicked_specific_via_wakeup_fd", p);
}
specific_worker->kicked = true;
@@ -598,7 +598,7 @@ static grpc_error* kick_one_worker(grpc_pollset_worker* specific_worker) {
}
if (specific_worker->initialized_cv) {
GRPC_STATS_INC_POLLSET_KICK_WAKEUP_CV();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PS:%p kicked_specific_via_cv", p);
}
specific_worker->kicked = true;
@@ -613,7 +613,7 @@ static grpc_error* kick_one_worker(grpc_pollset_worker* specific_worker) {
static grpc_error* pollset_kick(grpc_pollset* pollset,
grpc_pollset_worker* specific_worker) {
GRPC_STATS_INC_POLLSET_KICK();
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG,
"PS:%p kick %p tls_pollset=%p tls_worker=%p pollset.root_worker=%p",
pollset, specific_worker,
@@ -623,7 +623,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
if (specific_worker == nullptr) {
if (gpr_tls_get(&g_current_thread_pollset) != (intptr_t)pollset) {
if (pollset->root_worker == nullptr) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PS:%p kicked_any_without_poller", pollset);
}
GRPC_STATS_INC_POLLSET_KICKED_WITHOUT_POLLER();
@@ -649,7 +649,7 @@ static grpc_error* pollset_kick(grpc_pollset* pollset,
pollset->root_worker->links[PWLINK_POLLSET].next);
}
} else {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PS:%p kicked_any_but_awake", pollset);
}
GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD();
@@ -750,7 +750,7 @@ static grpc_error* pollable_process_events(grpc_pollset* pollset,
struct epoll_event* ev = &pollable_obj->events[n];
void* data_ptr = ev->data.ptr;
if (1 & (intptr_t)data_ptr) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PS:%p got pollset_wakeup %p", pollset, data_ptr);
}
append_error(&error,
@@ -762,7 +762,7 @@ static grpc_error* pollable_process_events(grpc_pollset* pollset,
bool cancel = (ev->events & (EPOLLERR | EPOLLHUP)) != 0;
bool read_ev = (ev->events & (EPOLLIN | EPOLLPRI)) != 0;
bool write_ev = (ev->events & EPOLLOUT) != 0;
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG,
"PS:%p got fd %p: cancel=%d read=%d "
"write=%d",
@@ -789,7 +789,7 @@ static void pollset_destroy(grpc_pollset* pollset) {
static grpc_error* pollable_epoll(pollable* p, grpc_millis deadline) {
int timeout = poll_deadline_to_millis_timeout(deadline);
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
char* desc = pollable_desc(p);
gpr_log(GPR_DEBUG, "POLLABLE:%p[%s] poll for %dms", p, desc, timeout);
gpr_free(desc);
@@ -809,7 +809,7 @@ static grpc_error* pollable_epoll(pollable* p, grpc_millis deadline) {
if (r < 0) return GRPC_OS_ERROR(errno, "epoll_wait");
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "POLLABLE:%p got %d events", p, r);
}
@@ -876,7 +876,7 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
worker->initialized_cv = true;
gpr_cv_init(&worker->cv);
gpr_mu_unlock(&pollset->mu);
- if (GRPC_TRACER_ON(grpc_polling_trace) &&
+ if (grpc_polling_trace.enabled() &&
worker->pollable_obj->root_worker != worker) {
gpr_log(GPR_DEBUG, "PS:%p wait %p w=%p for %dms", pollset,
worker->pollable_obj, worker,
@@ -885,18 +885,18 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
while (do_poll && worker->pollable_obj->root_worker != worker) {
if (gpr_cv_wait(&worker->cv, &worker->pollable_obj->mu,
grpc_millis_to_timespec(deadline, GPR_CLOCK_REALTIME))) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PS:%p timeout_wait %p w=%p", pollset,
worker->pollable_obj, worker);
}
do_poll = false;
} else if (worker->kicked) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PS:%p wakeup %p w=%p", pollset,
worker->pollable_obj, worker);
}
do_poll = false;
- } else if (GRPC_TRACER_ON(grpc_polling_trace) &&
+ } else if (grpc_polling_trace.enabled() &&
worker->pollable_obj->root_worker != worker) {
gpr_log(GPR_DEBUG, "PS:%p spurious_wakeup %p w=%p", pollset,
worker->pollable_obj, worker);
@@ -966,7 +966,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
#ifndef NDEBUG
WORKER_PTR->originator = gettid();
#endif
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG,
"PS:%p work hdl=%p worker=%p now=%" PRIdPTR " deadline=%" PRIdPTR
" kwp=%d pollable=%p",
@@ -1007,7 +1007,7 @@ static grpc_error* pollset_transition_pollable_from_empty_to_fd_locked(
grpc_pollset* pollset, grpc_fd* fd) {
static const char* err_desc = "pollset_transition_pollable_from_empty_to_fd";
grpc_error* error = GRPC_ERROR_NONE;
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG,
"PS:%p add fd %p (%d); transition pollable from empty to fd",
pollset, fd, fd->fd);
@@ -1023,7 +1023,7 @@ static grpc_error* pollset_transition_pollable_from_fd_to_multi_locked(
grpc_pollset* pollset, grpc_fd* and_add_fd) {
static const char* err_desc = "pollset_transition_pollable_from_fd_to_multi";
grpc_error* error = GRPC_ERROR_NONE;
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(
GPR_DEBUG,
"PS:%p add fd %p (%d); transition pollable from fd %p to multipoller",
@@ -1168,7 +1168,7 @@ static void pollset_set_unref(grpc_pollset_set* pss) {
}
static void pollset_set_add_fd(grpc_pollset_set* pss, grpc_fd* fd) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PSS:%p: add fd %p (%d)", pss, fd, fd->fd);
}
grpc_error* error = GRPC_ERROR_NONE;
@@ -1191,7 +1191,7 @@ static void pollset_set_add_fd(grpc_pollset_set* pss, grpc_fd* fd) {
}
static void pollset_set_del_fd(grpc_pollset_set* pss, grpc_fd* fd) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PSS:%p: del fd %p", pss, fd);
}
pss = pss_lock_adam(pss);
@@ -1211,7 +1211,7 @@ static void pollset_set_del_fd(grpc_pollset_set* pss, grpc_fd* fd) {
}
static void pollset_set_del_pollset(grpc_pollset_set* pss, grpc_pollset* ps) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PSS:%p: del pollset %p", pss, ps);
}
pss = pss_lock_adam(pss);
@@ -1261,7 +1261,7 @@ static grpc_error* add_fds_to_pollsets(grpc_fd** fds, size_t fd_count,
}
static void pollset_set_add_pollset(grpc_pollset_set* pss, grpc_pollset* ps) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PSS:%p: add pollset %p", pss, ps);
}
grpc_error* error = GRPC_ERROR_NONE;
@@ -1297,7 +1297,7 @@ static void pollset_set_add_pollset(grpc_pollset_set* pss, grpc_pollset* ps) {
static void pollset_set_add_pollset_set(grpc_pollset_set* a,
grpc_pollset_set* b) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PSS: merge (%p, %p)", a, b);
}
grpc_error* error = GRPC_ERROR_NONE;
@@ -1331,7 +1331,7 @@ static void pollset_set_add_pollset_set(grpc_pollset_set* a,
if (b_size > a_size) {
GPR_SWAP(grpc_pollset_set*, a, b);
}
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "PSS: parent %p to %p", b, a);
}
gpr_ref(&a->refs);
@@ -1431,10 +1431,6 @@ const grpc_event_engine_vtable* grpc_init_epollex_linux(
return nullptr;
}
-#ifndef NDEBUG
- grpc_register_tracer(&grpc_trace_pollable_refcount);
-#endif
-
fd_global_init();
if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) {
diff --git a/src/core/lib/iomgr/ev_epollsig_linux.cc b/src/core/lib/iomgr/ev_epollsig_linux.cc
index cbea6e4680..7a8962f4a8 100644
--- a/src/core/lib/iomgr/ev_epollsig_linux.cc
+++ b/src/core/lib/iomgr/ev_epollsig_linux.cc
@@ -54,9 +54,9 @@
#define GRPC_POLLSET_KICK_BROADCAST ((grpc_pollset_worker*)1)
-#define GRPC_POLLING_TRACE(...) \
- if (GRPC_TRACER_ON(grpc_polling_trace)) { \
- gpr_log(GPR_INFO, __VA_ARGS__); \
+#define GRPC_POLLING_TRACE(...) \
+ if (grpc_polling_trace.enabled()) { \
+ gpr_log(GPR_INFO, __VA_ARGS__); \
}
static int grpc_wakeup_signal = -1;
@@ -288,7 +288,7 @@ static void pi_unref(polling_island* pi);
#ifndef NDEBUG
static void pi_add_ref_dbg(polling_island* pi, const char* reason,
const char* file, int line) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_atm old_cnt = gpr_atm_acq_load(&pi->ref_count);
gpr_log(GPR_DEBUG,
"Add ref pi: %p, old:%" PRIdPTR " -> new:%" PRIdPTR
@@ -300,7 +300,7 @@ static void pi_add_ref_dbg(polling_island* pi, const char* reason,
static void pi_unref_dbg(polling_island* pi, const char* reason,
const char* file, int line) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_atm old_cnt = gpr_atm_acq_load(&pi->ref_count);
gpr_log(GPR_DEBUG,
"Unref pi: %p, old:%" PRIdPTR " -> new:%" PRIdPTR
@@ -731,7 +731,7 @@ static gpr_mu fd_freelist_mu;
#define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__)
static void ref_by(grpc_fd* fd, int n, const char* reason, const char* file,
int line) {
- if (GRPC_TRACER_ON(grpc_trace_fd_refcount)) {
+ if (grpc_trace_fd_refcount.enabled()) {
gpr_log(GPR_DEBUG,
"FD %d %p ref %d %" PRIdPTR " -> %" PRIdPTR " [%s; %s:%d]",
fd->fd, fd, n, gpr_atm_no_barrier_load(&fd->refst),
@@ -748,7 +748,7 @@ static void ref_by(grpc_fd* fd, int n) {
#ifndef NDEBUG
static void unref_by(grpc_fd* fd, int n, const char* reason, const char* file,
int line) {
- if (GRPC_TRACER_ON(grpc_trace_fd_refcount)) {
+ if (grpc_trace_fd_refcount.enabled()) {
gpr_log(GPR_DEBUG,
"FD %d %p unref %d %" PRIdPTR " -> %" PRIdPTR " [%s; %s:%d]",
fd->fd, fd, n, gpr_atm_no_barrier_load(&fd->refst),
@@ -765,8 +765,8 @@ static void unref_by(grpc_fd* fd, int n) {
fd_freelist = fd;
grpc_iomgr_unregister_object(&fd->iomgr_object);
- fd->read_closure.Destroy();
- fd->write_closure.Destroy();
+ fd->read_closure->DestroyEvent();
+ fd->write_closure->DestroyEvent();
gpr_mu_unlock(&fd_freelist_mu);
} else {
@@ -817,6 +817,8 @@ static grpc_fd* fd_create(int fd, const char* name) {
if (new_fd == nullptr) {
new_fd = (grpc_fd*)gpr_malloc(sizeof(grpc_fd));
gpr_mu_init(&new_fd->po.mu);
+ new_fd->read_closure.Init();
+ new_fd->write_closure.Init();
}
/* Note: It is not really needed to get the new_fd->po.mu lock here. If this
@@ -831,9 +833,9 @@ static grpc_fd* fd_create(int fd, const char* name) {
gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
new_fd->fd = fd;
new_fd->orphaned = false;
- new_fd->read_closure.Init();
- new_fd->write_closure.Init();
- gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm) nullptr);
+ new_fd->read_closure->InitEvent();
+ new_fd->write_closure->InitEvent();
+ gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
new_fd->freelist_next = nullptr;
new_fd->on_done_closure = nullptr;
diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc
index 09ebe894fa..1246b382d5 100644
--- a/src/core/lib/iomgr/ev_poll_posix.cc
+++ b/src/core/lib/iomgr/ev_poll_posix.cc
@@ -284,7 +284,7 @@ cv_fd_table g_cvfds;
#define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__)
static void ref_by(grpc_fd* fd, int n, const char* reason, const char* file,
int line) {
- if (GRPC_TRACER_ON(grpc_trace_fd_refcount)) {
+ if (grpc_trace_fd_refcount.enabled()) {
gpr_log(GPR_DEBUG,
"FD %d %p ref %d %" PRIdPTR " -> %" PRIdPTR " [%s; %s:%d]",
fd->fd, fd, n, gpr_atm_no_barrier_load(&fd->refst),
@@ -301,7 +301,7 @@ static void ref_by(grpc_fd* fd, int n) {
#ifndef NDEBUG
static void unref_by(grpc_fd* fd, int n, const char* reason, const char* file,
int line) {
- if (GRPC_TRACER_ON(grpc_trace_fd_refcount)) {
+ if (grpc_trace_fd_refcount.enabled()) {
gpr_log(GPR_DEBUG,
"FD %d %p unref %d %" PRIdPTR " -> %" PRIdPTR " [%s; %s:%d]",
fd->fd, fd, n, gpr_atm_no_barrier_load(&fd->refst),
@@ -978,7 +978,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
r = grpc_poll_function(pfds, pfd_count, timeout);
GRPC_SCHEDULING_END_BLOCKING_REGION;
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "%p poll=%d", pollset, r);
}
@@ -1002,7 +1002,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
}
} else {
if (pfds[0].revents & POLLIN_CHECK) {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "%p: got_wakeup", pollset);
}
work_combine_error(
@@ -1012,7 +1012,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
if (watchers[i].fd == nullptr) {
fd_end_poll(&watchers[i], 0, 0, nullptr);
} else {
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_DEBUG, "%p got_event: %d r:%d w:%d [%d]", pollset,
pfds[i].fd, (pfds[i].revents & POLLIN_CHECK) != 0,
(pfds[i].revents & POLLOUT_CHECK) != 0, pfds[i].revents);
diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc
index 985469942f..6dd7dcea30 100644
--- a/src/core/lib/iomgr/ev_posix.cc
+++ b/src/core/lib/iomgr/ev_posix.cc
@@ -36,13 +36,9 @@
#include "src/core/lib/iomgr/ev_poll_posix.h"
#include "src/core/lib/support/env.h"
-grpc_tracer_flag grpc_polling_trace =
- GRPC_TRACER_INITIALIZER(false, "polling"); /* Disabled by default */
-
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_fd_refcount =
- GRPC_TRACER_INITIALIZER(false, "fd_refcount");
-#endif
+grpc_core::TraceFlag grpc_polling_trace(false,
+ "polling"); /* Disabled by default */
+grpc_core::DebugOnlyTraceFlag grpc_trace_fd_refcount(false, "fd_refcount");
/** Default poll() function - a pointer so that it can be overridden by some
* tests */
@@ -153,8 +149,6 @@ const grpc_event_engine_vtable* grpc_get_event_engine_test_only() {
const char* grpc_get_poll_strategy_name() { return g_poll_strategy_name; }
void grpc_event_engine_init(void) {
- grpc_register_tracer(&grpc_polling_trace);
-
char* s = gpr_getenv("GRPC_POLL_STRATEGY");
if (s == nullptr) {
s = gpr_strdup("all");
diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h
index 93d8618d4d..39017a9fdd 100644
--- a/src/core/lib/iomgr/ev_posix.h
+++ b/src/core/lib/iomgr/ev_posix.h
@@ -31,7 +31,7 @@
extern "C" {
#endif
-extern grpc_tracer_flag grpc_polling_trace; /* Disabled by default */
+extern grpc_core::TraceFlag grpc_polling_trace; /* Disabled by default */
typedef struct grpc_fd grpc_fd;
diff --git a/src/core/lib/iomgr/ev_windows.cc b/src/core/lib/iomgr/ev_windows.cc
index c24dfaeaf7..697697d0b0 100644
--- a/src/core/lib/iomgr/ev_windows.cc
+++ b/src/core/lib/iomgr/ev_windows.cc
@@ -22,7 +22,7 @@
#include "src/core/lib/debug/trace.h"
-grpc_tracer_flag grpc_polling_trace =
- GRPC_TRACER_INITIALIZER(false, "polling"); /* Disabled by default */
+grpc_core::TraceFlag grpc_polling_trace(false,
+ "polling"); /* Disabled by default */
#endif // GRPC_WINSOCK_SOCKET
diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc
index a5d65f3d2c..4bd92a4141 100644
--- a/src/core/lib/iomgr/exec_ctx.cc
+++ b/src/core/lib/iomgr/exec_ctx.cc
@@ -25,13 +25,10 @@
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/profiling/timers.h"
-#define GRPC_START_TIME_UPDATE_INTERVAL 10000
-extern "C" grpc_tracer_flag grpc_timer_check_trace;
-
static void exec_ctx_run(grpc_closure* closure, grpc_error* error) {
#ifndef NDEBUG
closure->scheduled = false;
- if (GRPC_TRACER_ON(grpc_trace_closure)) {
+ if (grpc_trace_closure.enabled()) {
gpr_log(GPR_DEBUG, "running closure %p: created [%s:%d]: %s [%s:%d]",
closure, closure->file_created, closure->line_created,
closure->run ? "run" : "scheduled", closure->file_initiated,
@@ -40,7 +37,7 @@ static void exec_ctx_run(grpc_closure* closure, grpc_error* error) {
#endif
closure->cb(closure->cb_arg, error);
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_closure)) {
+ if (grpc_trace_closure.enabled()) {
gpr_log(GPR_DEBUG, "closure %p finished", closure);
}
#endif
@@ -52,39 +49,10 @@ static void exec_ctx_sched(grpc_closure* closure, grpc_error* error) {
error);
}
-/* This time pair is not entirely thread-safe as store/load of tv_sec and
- * tv_nsec are performed separately. However g_start_time do not need to have
- * sub-second precision, so it is ok if the value of tv_nsec is off in this
- * case. */
-typedef struct time_atm_pair {
- gpr_atm tv_sec;
- gpr_atm tv_nsec;
-} time_atm_pair;
-
-static time_atm_pair
- g_start_time[GPR_TIMESPAN + 1]; // assumes GPR_TIMESPAN is the
- // last enum value in
- // gpr_clock_type
-static grpc_millis g_last_start_time_update;
-
-static gpr_timespec timespec_from_time_atm_pair(const time_atm_pair* src,
- gpr_clock_type clock_type) {
- gpr_timespec time;
- time.tv_nsec = (int32_t)gpr_atm_no_barrier_load(&src->tv_nsec);
- time.tv_sec = (int64_t)gpr_atm_no_barrier_load(&src->tv_sec);
- time.clock_type = clock_type;
- return time;
-}
-
-static void time_atm_pair_store(time_atm_pair* dst, const gpr_timespec src) {
- gpr_atm_no_barrier_store(&dst->tv_sec, src.tv_sec);
- gpr_atm_no_barrier_store(&dst->tv_nsec, src.tv_nsec);
-}
+static gpr_timespec g_start_time;
static gpr_atm timespec_to_atm_round_down(gpr_timespec ts) {
- gpr_timespec start_time =
- timespec_from_time_atm_pair(&g_start_time[ts.clock_type], ts.clock_type);
- ts = gpr_time_sub(ts, start_time);
+ ts = gpr_time_sub(ts, g_start_time);
double x =
GPR_MS_PER_SEC * (double)ts.tv_sec + (double)ts.tv_nsec / GPR_NS_PER_MS;
if (x < 0) return 0;
@@ -93,9 +61,7 @@ static gpr_atm timespec_to_atm_round_down(gpr_timespec ts) {
}
static gpr_atm timespec_to_atm_round_up(gpr_timespec ts) {
- gpr_timespec start_time =
- timespec_from_time_atm_pair(&g_start_time[ts.clock_type], ts.clock_type);
- ts = gpr_time_sub(ts, start_time);
+ ts = gpr_time_sub(ts, g_start_time);
double x = GPR_MS_PER_SEC * (double)ts.tv_sec +
(double)ts.tv_nsec / GPR_NS_PER_MS +
(double)(GPR_NS_PER_SEC - 1) / (double)GPR_NS_PER_SEC;
@@ -118,41 +84,18 @@ gpr_timespec grpc_millis_to_timespec(grpc_millis millis,
if (clock_type == GPR_TIMESPAN) {
return gpr_time_from_millis(millis, GPR_TIMESPAN);
}
- gpr_timespec start_time =
- timespec_from_time_atm_pair(&g_start_time[clock_type], clock_type);
- return gpr_time_add(start_time, gpr_time_from_millis(millis, GPR_TIMESPAN));
+ return gpr_time_add(gpr_convert_clock_type(g_start_time, clock_type),
+ gpr_time_from_millis(millis, GPR_TIMESPAN));
}
grpc_millis grpc_timespec_to_millis_round_down(gpr_timespec ts) {
- return timespec_to_atm_round_down(ts);
+ return timespec_to_atm_round_down(
+ gpr_convert_clock_type(ts, g_start_time.clock_type));
}
grpc_millis grpc_timespec_to_millis_round_up(gpr_timespec ts) {
- return timespec_to_atm_round_up(ts);
-}
-
-void grpc_exec_ctx_maybe_update_start_time() {
- grpc_millis now = grpc_core::ExecCtx::Get()->Now();
- grpc_millis last_start_time_update =
- gpr_atm_no_barrier_load(&g_last_start_time_update);
-
- if (now > last_start_time_update &&
- now - last_start_time_update > GRPC_START_TIME_UPDATE_INTERVAL) {
- /* Get the current system time and subtract \a now from it, where \a now is
- * the relative time from grpc_init() from monotonic clock. This calibrates
- * the time when grpc_exec_ctx_global_init was called based on current
- * system clock. */
- gpr_atm_no_barrier_store(&g_last_start_time_update, now);
- gpr_timespec real_now = gpr_now(GPR_CLOCK_REALTIME);
- gpr_timespec real_start_time =
- gpr_time_sub(real_now, gpr_time_from_millis(now, GPR_TIMESPAN));
- time_atm_pair_store(&g_start_time[GPR_CLOCK_REALTIME], real_start_time);
-
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
- gpr_log(GPR_DEBUG, "Update realtime clock start time: %" PRId64 "s %dns",
- real_start_time.tv_sec, real_start_time.tv_nsec);
- }
- }
+ return timespec_to_atm_round_up(
+ gpr_convert_clock_type(ts, g_start_time.clock_type));
}
static const grpc_closure_scheduler_vtable exec_ctx_scheduler_vtable = {
@@ -189,11 +132,7 @@ bool ExecCtx::Flush() {
}
void ExecCtx::GlobalInit(void) {
- for (int i = 0; i < GPR_TIMESPAN; i++) {
- time_atm_pair_store(&g_start_time[i], gpr_now((gpr_clock_type)i));
- }
- // allows uniform treatment in conversion functions
- time_atm_pair_store(&g_start_time[GPR_TIMESPAN], gpr_time_0(GPR_TIMESPAN));
+ g_start_time = gpr_now(GPR_CLOCK_MONOTONIC);
#ifdef GPR_PTHREAD_TLS
gpr_tls_init(&exec_ctx_);
#endif
diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc
index 12f336cb37..d2fb772765 100644
--- a/src/core/lib/iomgr/executor.cc
+++ b/src/core/lib/iomgr/executor.cc
@@ -51,8 +51,7 @@ static gpr_spinlock g_adding_thread_lock = GPR_SPINLOCK_STATIC_INITIALIZER;
GPR_TLS_DECL(g_this_thread_state);
-static grpc_tracer_flag executor_trace =
- GRPC_TRACER_INITIALIZER(false, "executor");
+grpc_core::TraceFlag executor_trace(false, "executor");
static void executor_thread(void* arg);
@@ -63,7 +62,7 @@ static size_t run_closures(grpc_closure_list list) {
while (c != nullptr) {
grpc_closure* next = c->next_data.next;
grpc_error* error = c->error_data.error;
- if (GRPC_TRACER_ON(executor_trace)) {
+ if (executor_trace.enabled()) {
#ifndef NDEBUG
gpr_log(GPR_DEBUG, "EXECUTOR: run %p [created by %s:%d]", c,
c->file_created, c->line_created);
@@ -134,7 +133,6 @@ void grpc_executor_set_threading(bool threading) {
}
void grpc_executor_init() {
- grpc_register_tracer(&executor_trace);
gpr_atm_no_barrier_store(&g_cur_threads, 0);
grpc_executor_set_threading(true);
}
@@ -149,7 +147,7 @@ static void executor_thread(void* arg) {
size_t subtract_depth = 0;
for (;;) {
- if (GRPC_TRACER_ON(executor_trace)) {
+ if (executor_trace.enabled()) {
gpr_log(GPR_DEBUG, "EXECUTOR[%d]: step (sub_depth=%" PRIdPTR ")",
(int)(ts - g_thread_state), subtract_depth);
}
@@ -160,7 +158,7 @@ static void executor_thread(void* arg) {
gpr_cv_wait(&ts->cv, &ts->mu, gpr_inf_future(GPR_CLOCK_REALTIME));
}
if (ts->shutdown) {
- if (GRPC_TRACER_ON(executor_trace)) {
+ if (executor_trace.enabled()) {
gpr_log(GPR_DEBUG, "EXECUTOR[%d]: shutdown",
(int)(ts - g_thread_state));
}
@@ -171,7 +169,7 @@ static void executor_thread(void* arg) {
grpc_closure_list exec = ts->elems;
ts->elems = GRPC_CLOSURE_LIST_INIT;
gpr_mu_unlock(&ts->mu);
- if (GRPC_TRACER_ON(executor_trace)) {
+ if (executor_trace.enabled()) {
gpr_log(GPR_DEBUG, "EXECUTOR[%d]: execute", (int)(ts - g_thread_state));
}
@@ -192,7 +190,7 @@ static void executor_push(grpc_closure* closure, grpc_error* error,
retry_push = false;
size_t cur_thread_count = (size_t)gpr_atm_no_barrier_load(&g_cur_threads);
if (cur_thread_count == 0) {
- if (GRPC_TRACER_ON(executor_trace)) {
+ if (executor_trace.enabled()) {
#ifndef NDEBUG
gpr_log(GPR_DEBUG, "EXECUTOR: schedule %p (created %s:%d) inline",
closure, closure->file_created, closure->line_created);
@@ -215,7 +213,7 @@ static void executor_push(grpc_closure* closure, grpc_error* error,
bool try_new_thread;
for (;;) {
- if (GRPC_TRACER_ON(executor_trace)) {
+ if (executor_trace.enabled()) {
#ifndef NDEBUG
gpr_log(
GPR_DEBUG,
diff --git a/src/core/lib/iomgr/iomgr_posix.cc b/src/core/lib/iomgr/iomgr_posix.cc
index f5875a247e..f8f6fe2353 100644
--- a/src/core/lib/iomgr/iomgr_posix.cc
+++ b/src/core/lib/iomgr/iomgr_posix.cc
@@ -28,7 +28,6 @@
void grpc_iomgr_platform_init(void) {
grpc_wakeup_fd_global_init();
grpc_event_engine_init();
- grpc_register_tracer(&grpc_tcp_trace);
}
void grpc_iomgr_platform_flush(void) {}
diff --git a/src/core/lib/iomgr/iomgr_uv.cc b/src/core/lib/iomgr/iomgr_uv.cc
index 5823bb7ec2..95b06e2ca5 100644
--- a/src/core/lib/iomgr/iomgr_uv.cc
+++ b/src/core/lib/iomgr/iomgr_uv.cc
@@ -31,7 +31,7 @@ gpr_thd_id g_init_thread;
void grpc_iomgr_platform_init(void) {
grpc_core::ExecCtx _local_exec_ctx;
grpc_pollset_global_init();
- grpc_register_tracer(&grpc_tcp_trace);
+
grpc_executor_set_threading(false);
g_init_thread = gpr_thd_currentid();
}
diff --git a/src/core/lib/iomgr/load_file.cc b/src/core/lib/iomgr/load_file.cc
index 03ed98f3ba..1afe6ba96d 100644
--- a/src/core/lib/iomgr/load_file.cc
+++ b/src/core/lib/iomgr/load_file.cc
@@ -30,6 +30,7 @@
grpc_error* grpc_load_file(const char* filename, int add_null_terminator,
grpc_slice* output) {
+ grpc_core::ExecCtx exec_ctx;
unsigned char* contents = nullptr;
size_t contents_size = 0;
grpc_slice result = grpc_empty_slice();
diff --git a/src/core/lib/iomgr/lockfree_event.cc b/src/core/lib/iomgr/lockfree_event.cc
index 288e597c29..7b194e3db5 100644
--- a/src/core/lib/iomgr/lockfree_event.cc
+++ b/src/core/lib/iomgr/lockfree_event.cc
@@ -22,7 +22,7 @@
#include "src/core/lib/debug/trace.h"
-extern grpc_tracer_flag grpc_polling_trace;
+extern grpc_core::TraceFlag grpc_polling_trace;
/* 'state' holds the to call when the fd is readable or writable respectively.
It can contain one of the following values:
@@ -57,7 +57,9 @@ extern grpc_tracer_flag grpc_polling_trace;
namespace grpc_core {
-LockfreeEvent::LockfreeEvent() {
+LockfreeEvent::LockfreeEvent() { InitEvent(); }
+
+void LockfreeEvent::InitEvent() {
/* Perform an atomic store to start the state machine.
Note carefully that LockfreeEvent *MAY* be used whilst in a destroyed
@@ -67,7 +69,7 @@ LockfreeEvent::LockfreeEvent() {
gpr_atm_no_barrier_store(&state_, kClosureNotReady);
}
-LockfreeEvent::~LockfreeEvent() {
+void LockfreeEvent::DestroyEvent() {
gpr_atm curr;
do {
curr = gpr_atm_no_barrier_load(&state_);
@@ -86,7 +88,7 @@ LockfreeEvent::~LockfreeEvent() {
void LockfreeEvent::NotifyOn(grpc_closure* closure) {
while (true) {
gpr_atm curr = gpr_atm_no_barrier_load(&state_);
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, "LockfreeEvent::NotifyOn: %p curr=%p closure=%p", this,
(void*)curr, closure);
}
@@ -152,7 +154,7 @@ bool LockfreeEvent::SetShutdown(grpc_error* shutdown_err) {
while (true) {
gpr_atm curr = gpr_atm_no_barrier_load(&state_);
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, "LockfreeEvent::SetShutdown: %p curr=%p err=%s",
&state_, (void*)curr, grpc_error_string(shutdown_err));
}
@@ -201,7 +203,7 @@ void LockfreeEvent::SetReady() {
while (true) {
gpr_atm curr = gpr_atm_no_barrier_load(&state_);
- if (GRPC_TRACER_ON(grpc_polling_trace)) {
+ if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, "LockfreeEvent::SetReady: %p curr=%p", &state_,
(void*)curr);
}
diff --git a/src/core/lib/iomgr/lockfree_event.h b/src/core/lib/iomgr/lockfree_event.h
index 70fa1ac89d..3bd3fd72f1 100644
--- a/src/core/lib/iomgr/lockfree_event.h
+++ b/src/core/lib/iomgr/lockfree_event.h
@@ -30,11 +30,16 @@ namespace grpc_core {
class LockfreeEvent {
public:
LockfreeEvent();
- ~LockfreeEvent();
LockfreeEvent(const LockfreeEvent&) = delete;
LockfreeEvent& operator=(const LockfreeEvent&) = delete;
+ // These methods are used to initialize and destroy the internal state. These
+ // cannot be done in constructor and destructor because SetReady may be called
+ // when the event is destroyed and put in a freelist.
+ void InitEvent();
+ void DestroyEvent();
+
bool IsShutdown() const {
return (gpr_atm_no_barrier_load(&state_) & kShutdownBit) != 0;
}
diff --git a/src/core/lib/iomgr/pollset.h b/src/core/lib/iomgr/pollset.h
index 0645c7d919..c32c086971 100644
--- a/src/core/lib/iomgr/pollset.h
+++ b/src/core/lib/iomgr/pollset.h
@@ -29,9 +29,7 @@
extern "C" {
#endif
-#ifndef NDEBUG
-extern grpc_tracer_flag grpc_trace_fd_refcount;
-#endif
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_fd_refcount;
/* A grpc_pollset is a set of file descriptors that a higher level item is
interested in. For example:
diff --git a/src/core/lib/iomgr/pollset_uv.cc b/src/core/lib/iomgr/pollset_uv.cc
index 89d28a0f9d..d040c0cccb 100644
--- a/src/core/lib/iomgr/pollset_uv.cc
+++ b/src/core/lib/iomgr/pollset_uv.cc
@@ -34,10 +34,7 @@
#include "src/core/lib/debug/trace.h"
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_fd_refcount =
- GRPC_TRACER_INITIALIZER(false, "fd_refcount");
-#endif
+grpc_core::DebugOnlyTraceFlag grpc_trace_fd_refcount(false, "fd_refcount");
struct grpc_pollset {
uv_timer_t* timer;
diff --git a/src/core/lib/iomgr/pollset_windows.cc b/src/core/lib/iomgr/pollset_windows.cc
index 81e1d009ca..162037a8da 100644
--- a/src/core/lib/iomgr/pollset_windows.cc
+++ b/src/core/lib/iomgr/pollset_windows.cc
@@ -30,10 +30,7 @@
#define GRPC_POLLSET_KICK_BROADCAST ((grpc_pollset_worker*)1)
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_fd_refcount =
- GRPC_TRACER_INITIALIZER(false, "fd_refcount");
-#endif
+grpc_core::DebugOnlyTraceFlag grpc_trace_fd_refcount(false, "fd_refcount");
gpr_mu grpc_polling_mu;
static grpc_pollset_worker* g_active_poller;
diff --git a/src/core/lib/iomgr/resource_quota.cc b/src/core/lib/iomgr/resource_quota.cc
index 819d997ce9..55d559c466 100644
--- a/src/core/lib/iomgr/resource_quota.cc
+++ b/src/core/lib/iomgr/resource_quota.cc
@@ -31,8 +31,7 @@
#include "src/core/lib/iomgr/combiner.h"
-grpc_tracer_flag grpc_resource_quota_trace =
- GRPC_TRACER_INITIALIZER(false, "resource_quota");
+grpc_core::TraceFlag grpc_resource_quota_trace(false, "resource_quota");
#define MEMORY_USAGE_ESTIMATION_MAX 65536
@@ -287,7 +286,7 @@ static bool rq_alloc(grpc_resource_quota* resource_quota) {
while ((resource_user = rulist_pop_head(resource_quota,
GRPC_RULIST_AWAITING_ALLOCATION))) {
gpr_mu_lock(&resource_user->mu);
- if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
+ if (grpc_resource_quota_trace.enabled()) {
gpr_log(GPR_DEBUG,
"RQ: check allocation for user %p shutdown=%" PRIdPTR
" free_pool=%" PRId64,
@@ -313,14 +312,14 @@ static bool rq_alloc(grpc_resource_quota* resource_quota) {
resource_user->free_pool = 0;
resource_quota->free_pool -= amt;
rq_update_estimate(resource_quota);
- if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
+ if (grpc_resource_quota_trace.enabled()) {
gpr_log(GPR_DEBUG,
"RQ %s %s: grant alloc %" PRId64
" bytes; rq_free_pool -> %" PRId64,
resource_quota->name, resource_user->name, amt,
resource_quota->free_pool);
}
- } else if (GRPC_TRACER_ON(grpc_resource_quota_trace) &&
+ } else if (grpc_resource_quota_trace.enabled() &&
resource_user->free_pool >= 0) {
gpr_log(GPR_DEBUG, "RQ %s %s: discard already satisfied alloc request",
resource_quota->name, resource_user->name);
@@ -351,7 +350,7 @@ static bool rq_reclaim_from_per_user_free_pool(
resource_user->free_pool = 0;
resource_quota->free_pool += amt;
rq_update_estimate(resource_quota);
- if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
+ if (grpc_resource_quota_trace.enabled()) {
gpr_log(GPR_DEBUG,
"RQ %s %s: reclaim_from_per_user_free_pool %" PRId64
" bytes; rq_free_pool -> %" PRId64,
@@ -374,7 +373,7 @@ static bool rq_reclaim(grpc_resource_quota* resource_quota, bool destructive) {
: GRPC_RULIST_RECLAIMER_BENIGN;
grpc_resource_user* resource_user = rulist_pop_head(resource_quota, list);
if (resource_user == nullptr) return false;
- if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
+ if (grpc_resource_quota_trace.enabled()) {
gpr_log(GPR_DEBUG, "RQ %s %s: initiate %s reclamation",
resource_quota->name, resource_user->name,
destructive ? "destructive" : "benign");
@@ -504,7 +503,7 @@ static void ru_post_destructive_reclaimer(void* ru, grpc_error* error) {
}
static void ru_shutdown(void* ru, grpc_error* error) {
- if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
+ if (grpc_resource_quota_trace.enabled()) {
gpr_log(GPR_DEBUG, "RU shutdown %p", ru);
}
grpc_resource_user* resource_user = (grpc_resource_user*)ru;
@@ -787,7 +786,7 @@ void grpc_resource_user_alloc(grpc_resource_user* resource_user, size_t size,
ru_ref_by(resource_user, (gpr_atm)size);
resource_user->free_pool -= (int64_t)size;
resource_user->outstanding_allocations += (int64_t)size;
- if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
+ if (grpc_resource_quota_trace.enabled()) {
gpr_log(GPR_DEBUG, "RQ %s %s: alloc %" PRIdPTR "; free_pool -> %" PRId64,
resource_user->resource_quota->name, resource_user->name, size,
resource_user->free_pool);
@@ -810,7 +809,7 @@ void grpc_resource_user_free(grpc_resource_user* resource_user, size_t size) {
gpr_mu_lock(&resource_user->mu);
bool was_zero_or_negative = resource_user->free_pool <= 0;
resource_user->free_pool += (int64_t)size;
- if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
+ if (grpc_resource_quota_trace.enabled()) {
gpr_log(GPR_DEBUG, "RQ %s %s: free %" PRIdPTR "; free_pool -> %" PRId64,
resource_user->resource_quota->name, resource_user->name, size,
resource_user->free_pool);
@@ -836,7 +835,7 @@ void grpc_resource_user_post_reclaimer(grpc_resource_user* resource_user,
}
void grpc_resource_user_finish_reclamation(grpc_resource_user* resource_user) {
- if (GRPC_TRACER_ON(grpc_resource_quota_trace)) {
+ if (grpc_resource_quota_trace.enabled()) {
gpr_log(GPR_DEBUG, "RQ %s %s: reclamation complete",
resource_user->resource_quota->name, resource_user->name);
}
@@ -864,9 +863,3 @@ void grpc_resource_user_alloc_slices(
grpc_resource_user_alloc(slice_allocator->resource_user, count * length,
&slice_allocator->on_allocated);
}
-
-grpc_slice grpc_resource_user_slice_malloc(grpc_resource_user* resource_user,
- size_t size) {
- grpc_resource_user_alloc(resource_user, size, nullptr);
- return ru_slice_create(resource_user, size);
-}
diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h
index b5ccdc76ca..ae7f487b5d 100644
--- a/src/core/lib/iomgr/resource_quota.h
+++ b/src/core/lib/iomgr/resource_quota.h
@@ -65,7 +65,7 @@ extern "C" {
maintain lists of users (which users arrange to leave before they are
destroyed) */
-extern grpc_tracer_flag grpc_resource_quota_trace;
+extern grpc_core::TraceFlag grpc_resource_quota_trace;
grpc_resource_quota* grpc_resource_quota_ref_internal(
grpc_resource_quota* resource_quota);
diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc
index 6e0fbf2a3c..84c5a674d4 100644
--- a/src/core/lib/iomgr/tcp_client_posix.cc
+++ b/src/core/lib/iomgr/tcp_client_posix.cc
@@ -43,7 +43,7 @@
#include "src/core/lib/iomgr/unix_sockets_posix.h"
#include "src/core/lib/support/string.h"
-extern grpc_tracer_flag grpc_tcp_trace;
+extern grpc_core::TraceFlag grpc_tcp_trace;
typedef struct {
gpr_mu mu;
@@ -99,7 +99,7 @@ done:
static void tc_on_alarm(void* acp, grpc_error* error) {
int done;
async_connect* ac = (async_connect*)acp;
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s", ac->addr_str,
str);
@@ -136,7 +136,7 @@ static void on_writable(void* acp, grpc_error* error) {
GRPC_ERROR_REF(error);
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_writable: error=%s",
ac->addr_str, str);
@@ -312,7 +312,7 @@ static void tcp_client_connect_impl(grpc_closure* closure, grpc_endpoint** ep,
grpc_schedule_on_exec_ctx);
ac->channel_args = grpc_channel_args_copy(channel_args);
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: asynchronously connecting fd %p",
ac->addr_str, fdobj);
}
diff --git a/src/core/lib/iomgr/tcp_client_uv.cc b/src/core/lib/iomgr/tcp_client_uv.cc
index 0bf3a043df..0ba074500b 100644
--- a/src/core/lib/iomgr/tcp_client_uv.cc
+++ b/src/core/lib/iomgr/tcp_client_uv.cc
@@ -32,7 +32,7 @@
#include "src/core/lib/iomgr/tcp_uv.h"
#include "src/core/lib/iomgr/timer.h"
-extern grpc_tracer_flag grpc_tcp_trace;
+extern grpc_core::TraceFlag grpc_tcp_trace;
typedef struct grpc_uv_tcp_connect {
uv_connect_t connect_req;
@@ -57,7 +57,7 @@ static void tcp_close_callback(uv_handle_t* handle) { gpr_free(handle); }
static void uv_tc_on_alarm(void* acp, grpc_error* error) {
int done;
grpc_uv_tcp_connect* connect = (grpc_uv_tcp_connect*)acp;
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: on_alarm: error=%s",
connect->addr_name, str);
@@ -143,7 +143,7 @@ static void tcp_client_connect_impl(grpc_closure* closure, grpc_endpoint** ep,
connect->connect_req.data = connect;
connect->refs = 2; // One for the connect operation, one for the timer.
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "CLIENT_CONNECT: %s: asynchronously connecting",
connect->addr_name);
}
diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc
index c1305bef8e..155329d2e8 100644
--- a/src/core/lib/iomgr/tcp_posix.cc
+++ b/src/core/lib/iomgr/tcp_posix.cc
@@ -61,7 +61,7 @@ typedef GRPC_MSG_IOVLEN_TYPE msg_iovlen_type;
typedef size_t msg_iovlen_type;
#endif
-grpc_tracer_flag grpc_tcp_trace = GRPC_TRACER_INITIALIZER(false, "tcp");
+grpc_core::TraceFlag grpc_tcp_trace(false, "tcp");
typedef struct {
grpc_endpoint base;
@@ -81,9 +81,7 @@ typedef struct {
grpc_slice_buffer* incoming_buffer;
grpc_slice_buffer* outgoing_buffer;
- /** slice within outgoing_buffer to write next */
- size_t outgoing_slice_idx;
- /** byte within outgoing_buffer->slices[outgoing_slice_idx] to write next */
+ /** byte within outgoing_buffer->slices[0] to write next */
size_t outgoing_byte_idx;
grpc_closure* read_cb;
@@ -117,7 +115,7 @@ static void tcp_drop_uncovered_then_handle_write(void* arg /* grpc_tcp */,
static void done_poller(void* bp, grpc_error* error_ignored) {
backup_poller* p = (backup_poller*)bp;
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p destroy", p);
}
grpc_pollset_destroy(BACKUP_POLLER_POLLSET(p));
@@ -126,7 +124,7 @@ static void done_poller(void* bp, grpc_error* error_ignored) {
static void run_poller(void* bp, grpc_error* error_ignored) {
backup_poller* p = (backup_poller*)bp;
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p run", p);
}
gpr_mu_lock(p->pollset_mu);
@@ -142,18 +140,18 @@ static void run_poller(void* bp, grpc_error* error_ignored) {
gpr_atm_full_cas(&g_uncovered_notifications_pending, 1, 0)) {
gpr_mu_lock(p->pollset_mu);
bool cas_ok = gpr_atm_full_cas(&g_backup_poller, (gpr_atm)p, 0);
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p done cas_ok=%d", p, cas_ok);
}
gpr_mu_unlock(p->pollset_mu);
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p shutdown", p);
}
grpc_pollset_shutdown(BACKUP_POLLER_POLLSET(p),
GRPC_CLOSURE_INIT(&p->run_poller, done_poller, p,
grpc_schedule_on_exec_ctx));
} else {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p reschedule", p);
}
GRPC_CLOSURE_SCHED(&p->run_poller, GRPC_ERROR_NONE);
@@ -164,7 +162,7 @@ static void drop_uncovered(grpc_tcp* tcp) {
backup_poller* p = (backup_poller*)gpr_atm_acq_load(&g_backup_poller);
gpr_atm old_count =
gpr_atm_no_barrier_fetch_add(&g_uncovered_notifications_pending, -1);
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p uncover cnt %d->%d", p, (int)old_count,
(int)old_count - 1);
}
@@ -175,14 +173,14 @@ static void cover_self(grpc_tcp* tcp) {
backup_poller* p;
gpr_atm old_count =
gpr_atm_no_barrier_fetch_add(&g_uncovered_notifications_pending, 2);
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "BACKUP_POLLER: cover cnt %d->%d", (int)old_count,
2 + (int)old_count);
}
if (old_count == 0) {
GRPC_STATS_INC_TCP_BACKUP_POLLERS_CREATED();
p = (backup_poller*)gpr_zalloc(sizeof(*p) + grpc_pollset_size());
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p create", p);
}
grpc_pollset_init(BACKUP_POLLER_POLLSET(p), &p->pollset_mu);
@@ -197,7 +195,7 @@ static void cover_self(grpc_tcp* tcp) {
// spin waiting for backup poller
}
}
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "BACKUP_POLLER:%p add %p", p, tcp);
}
grpc_pollset_add_fd(BACKUP_POLLER_POLLSET(p), tcp->em_fd);
@@ -207,7 +205,7 @@ static void cover_self(grpc_tcp* tcp) {
}
static void notify_on_read(grpc_tcp* tcp) {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "TCP:%p notify_on_read", tcp);
}
GRPC_CLOSURE_INIT(&tcp->read_done_closure, tcp_handle_read, tcp,
@@ -216,7 +214,7 @@ static void notify_on_read(grpc_tcp* tcp) {
}
static void notify_on_write(grpc_tcp* tcp) {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "TCP:%p notify_on_write", tcp);
}
cover_self(tcp);
@@ -227,7 +225,7 @@ static void notify_on_write(grpc_tcp* tcp) {
}
static void tcp_drop_uncovered_then_handle_write(void* arg, grpc_error* error) {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "TCP:%p got_write: %s", arg, grpc_error_string(error));
}
drop_uncovered((grpc_tcp*)arg);
@@ -300,7 +298,7 @@ static void tcp_free(grpc_tcp* tcp) {
#define TCP_REF(tcp, reason) tcp_ref((tcp), (reason), __FILE__, __LINE__)
static void tcp_unref(grpc_tcp* tcp, const char* reason, const char* file,
int line) {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"TCP unref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp, reason, val,
@@ -313,7 +311,7 @@ static void tcp_unref(grpc_tcp* tcp, const char* reason, const char* file,
static void tcp_ref(grpc_tcp* tcp, const char* reason, const char* file,
int line) {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"TCP ref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp, reason, val,
@@ -343,7 +341,7 @@ static void tcp_destroy(grpc_endpoint* ep) {
static void call_read_cb(grpc_tcp* tcp, grpc_error* error) {
grpc_closure* cb = tcp->read_cb;
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "TCP:%p call_cb %p %p:%p", tcp, cb, cb->cb, cb->cb_arg);
size_t i;
const char* str = grpc_error_string(error);
@@ -436,7 +434,7 @@ static void tcp_do_read(grpc_tcp* tcp) {
static void tcp_read_allocation_done(void* tcpp, grpc_error* error) {
grpc_tcp* tcp = (grpc_tcp*)tcpp;
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "TCP:%p read_allocation_done: %s", tcp,
grpc_error_string(error));
}
@@ -454,13 +452,13 @@ static void tcp_continue_read(grpc_tcp* tcp) {
size_t target_read_size = get_target_read_size(tcp);
if (tcp->incoming_buffer->length < target_read_size &&
tcp->incoming_buffer->count < MAX_READ_IOVEC) {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "TCP:%p alloc_slices", tcp);
}
grpc_resource_user_alloc_slices(&tcp->slice_allocator, target_read_size, 1,
tcp->incoming_buffer);
} else {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "TCP:%p do_read", tcp);
}
tcp_do_read(tcp);
@@ -470,7 +468,7 @@ static void tcp_continue_read(grpc_tcp* tcp) {
static void tcp_handle_read(void* arg /* grpc_tcp */, grpc_error* error) {
grpc_tcp* tcp = (grpc_tcp*)arg;
GPR_ASSERT(!tcp->finished_edge);
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "TCP:%p got_read: %s", tcp, grpc_error_string(error));
}
@@ -513,23 +511,26 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
size_t unwind_slice_idx;
size_t unwind_byte_idx;
+ // We always start at zero, because we eagerly unref and trim the slice
+ // buffer as we write
+ size_t outgoing_slice_idx = 0;
+
for (;;) {
sending_length = 0;
- unwind_slice_idx = tcp->outgoing_slice_idx;
+ unwind_slice_idx = outgoing_slice_idx;
unwind_byte_idx = tcp->outgoing_byte_idx;
- for (iov_size = 0; tcp->outgoing_slice_idx != tcp->outgoing_buffer->count &&
+ for (iov_size = 0; outgoing_slice_idx != tcp->outgoing_buffer->count &&
iov_size != MAX_WRITE_IOVEC;
iov_size++) {
iov[iov_size].iov_base =
GRPC_SLICE_START_PTR(
- tcp->outgoing_buffer->slices[tcp->outgoing_slice_idx]) +
+ tcp->outgoing_buffer->slices[outgoing_slice_idx]) +
tcp->outgoing_byte_idx;
iov[iov_size].iov_len =
- GRPC_SLICE_LENGTH(
- tcp->outgoing_buffer->slices[tcp->outgoing_slice_idx]) -
+ GRPC_SLICE_LENGTH(tcp->outgoing_buffer->slices[outgoing_slice_idx]) -
tcp->outgoing_byte_idx;
sending_length += iov[iov_size].iov_len;
- tcp->outgoing_slice_idx++;
+ outgoing_slice_idx++;
tcp->outgoing_byte_idx = 0;
}
GPR_ASSERT(iov_size > 0);
@@ -555,16 +556,23 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
if (sent_length < 0) {
if (errno == EAGAIN) {
- tcp->outgoing_slice_idx = unwind_slice_idx;
tcp->outgoing_byte_idx = unwind_byte_idx;
+ // unref all and forget about all slices that have been written to this
+ // point
+ for (size_t idx = 0; idx < unwind_slice_idx; ++idx) {
+ grpc_slice_unref_internal(
+ grpc_slice_buffer_take_first(tcp->outgoing_buffer));
+ }
return false;
} else if (errno == EPIPE) {
*error = grpc_error_set_int(GRPC_OS_ERROR(errno, "sendmsg"),
GRPC_ERROR_INT_GRPC_STATUS,
GRPC_STATUS_UNAVAILABLE);
+ grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer);
return true;
} else {
*error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp);
+ grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer);
return true;
}
}
@@ -574,9 +582,9 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
while (trailing > 0) {
size_t slice_length;
- tcp->outgoing_slice_idx--;
- slice_length = GRPC_SLICE_LENGTH(
- tcp->outgoing_buffer->slices[tcp->outgoing_slice_idx]);
+ outgoing_slice_idx--;
+ slice_length =
+ GRPC_SLICE_LENGTH(tcp->outgoing_buffer->slices[outgoing_slice_idx]);
if (slice_length > trailing) {
tcp->outgoing_byte_idx = slice_length - trailing;
break;
@@ -585,11 +593,12 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
}
}
- if (tcp->outgoing_slice_idx == tcp->outgoing_buffer->count) {
+ if (outgoing_slice_idx == tcp->outgoing_buffer->count) {
*error = GRPC_ERROR_NONE;
+ grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer);
return true;
}
- };
+ }
}
static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) {
@@ -605,14 +614,14 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) {
}
if (!tcp_flush(tcp, &error)) {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "write: delayed");
}
notify_on_write(tcp);
} else {
cb = tcp->write_cb;
tcp->write_cb = nullptr;
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
gpr_log(GPR_DEBUG, "write: %s", str);
}
@@ -627,7 +636,7 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf,
grpc_tcp* tcp = (grpc_tcp*)ep;
grpc_error* error = GRPC_ERROR_NONE;
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
size_t i;
for (i = 0; i < buf->count; i++) {
@@ -651,18 +660,17 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf,
return;
}
tcp->outgoing_buffer = buf;
- tcp->outgoing_slice_idx = 0;
tcp->outgoing_byte_idx = 0;
if (!tcp_flush(tcp, &error)) {
TCP_REF(tcp, "write");
tcp->write_cb = cb;
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "write: delayed");
}
notify_on_write(tcp);
} else {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
gpr_log(GPR_DEBUG, "write: %s", str);
}
diff --git a/src/core/lib/iomgr/tcp_posix.h b/src/core/lib/iomgr/tcp_posix.h
index a6320306fd..2fa1256ec7 100644
--- a/src/core/lib/iomgr/tcp_posix.h
+++ b/src/core/lib/iomgr/tcp_posix.h
@@ -37,7 +37,7 @@
extern "C" {
#endif
-extern grpc_tracer_flag grpc_tcp_trace;
+extern grpc_core::TraceFlag grpc_tcp_trace;
/* Create a tcp endpoint given a file desciptor and a read slice size.
Takes ownership of fd. */
diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc
index 475e9fef79..99e1c6cd06 100644
--- a/src/core/lib/iomgr/tcp_server_posix.cc
+++ b/src/core/lib/iomgr/tcp_server_posix.cc
@@ -240,7 +240,7 @@ static void on_read(void* arg, grpc_error* err) {
addr_str = grpc_sockaddr_to_uri(&addr);
gpr_asprintf(&name, "tcp-server-connection:%s", addr_str);
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "SERVER_CONNECT: incoming connection: %s", addr_str);
}
diff --git a/src/core/lib/iomgr/tcp_server_uv.cc b/src/core/lib/iomgr/tcp_server_uv.cc
index daa7afe95f..2181b12b23 100644
--- a/src/core/lib/iomgr/tcp_server_uv.cc
+++ b/src/core/lib/iomgr/tcp_server_uv.cc
@@ -205,7 +205,7 @@ static void finish_accept(grpc_tcp_listener* sp) {
} else {
gpr_log(GPR_INFO, "uv_tcp_getpeername error: %s", uv_strerror(err));
}
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
if (peer_name_string) {
gpr_log(GPR_DEBUG, "SERVER_CONNECT: %p accepted connection: %s",
sp->server, peer_name_string);
@@ -238,7 +238,7 @@ static void on_connect(uv_stream_t* server, int status) {
GPR_ASSERT(!sp->has_pending_connection);
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "SERVER_CONNECT: %p incoming connection", sp->server);
}
@@ -393,7 +393,7 @@ grpc_error* grpc_tcp_server_add_port(grpc_tcp_server* s,
gpr_free(allocated_addr);
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
char* port_string;
grpc_sockaddr_to_string(&port_string, addr, 0);
const char* str = grpc_error_string(error);
@@ -425,7 +425,7 @@ void grpc_tcp_server_start(grpc_tcp_server* server, grpc_pollset** pollsets,
(void)pollsets;
(void)pollset_count;
GRPC_UV_ASSERT_SAME_THREAD();
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "SERVER_START %p", server);
}
GPR_ASSERT(on_accept_cb);
diff --git a/src/core/lib/iomgr/tcp_uv.cc b/src/core/lib/iomgr/tcp_uv.cc
index 742ab9a754..d1e91357ea 100644
--- a/src/core/lib/iomgr/tcp_uv.cc
+++ b/src/core/lib/iomgr/tcp_uv.cc
@@ -38,7 +38,7 @@
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
-grpc_tracer_flag grpc_tcp_trace = GRPC_TRACER_INITIALIZER(false, "tcp");
+grpc_core::TraceFlag grpc_tcp_trace(false, "tcp");
typedef struct {
grpc_endpoint base;
@@ -52,12 +52,12 @@ typedef struct {
grpc_closure* read_cb;
grpc_closure* write_cb;
- grpc_slice read_slice;
grpc_slice_buffer* read_slices;
grpc_slice_buffer* write_slices;
uv_buf_t* write_buffers;
grpc_resource_user* resource_user;
+ grpc_resource_user_slice_allocator slice_allocator;
bool shutting_down;
@@ -65,8 +65,7 @@ typedef struct {
grpc_pollset* pollset;
} grpc_tcp;
-static void tcp_free(grpc_tcp* tcp) {
- grpc_slice_unref_internal(tcp->read_slice);
+static void tcp_free(grpc_exec_ctx* exec_ctx, grpc_tcp* tcp) {
grpc_resource_user_unref(tcp->resource_user);
gpr_free(tcp->handle);
gpr_free(tcp->peer_string);
@@ -78,7 +77,7 @@ static void tcp_free(grpc_tcp* tcp) {
#define TCP_REF(tcp, reason) tcp_ref((tcp), (reason), __FILE__, __LINE__)
static void tcp_unref(grpc_tcp* tcp, const char* reason, const char* file,
int line) {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"TCP unref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp, reason, val,
@@ -91,7 +90,7 @@ static void tcp_unref(grpc_tcp* tcp, const char* reason, const char* file,
static void tcp_ref(grpc_tcp* tcp, const char* reason, const char* file,
int line) {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"TCP ref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp, reason, val,
@@ -117,88 +116,116 @@ static void uv_close_callback(uv_handle_t* handle) {
TCP_UNREF(tcp, "destroy");
}
-static grpc_slice alloc_read_slice(grpc_resource_user* resource_user) {
- return grpc_resource_user_slice_malloc(resource_user,
- GRPC_TCP_DEFAULT_READ_SLICE_SIZE);
-}
-
static void alloc_uv_buf(uv_handle_t* handle, size_t suggested_size,
uv_buf_t* buf) {
grpc_core::ExecCtx _local_exec_ctx;
grpc_tcp* tcp = (grpc_tcp*)handle->data;
(void)suggested_size;
- buf->base = (char*)GRPC_SLICE_START_PTR(tcp->read_slice);
- buf->len = GRPC_SLICE_LENGTH(tcp->read_slice);
+ /* Before calling uv_read_start, we allocate a buffer with exactly one slice
+ * to tcp->read_slices and wait for the callback indicating that the
+ * allocation was successful. So slices[0] should always exist here */
+ buf->base = (char*)GRPC_SLICE_START_PTR(tcp->read_slices->slices[0]);
+ buf->len = GRPC_SLICE_LENGTH(tcp->read_slices->slices[0]);
+ grpc_exec_ctx_finish();
+}
+
+static void call_read_cb(grpc_exec_ctx* exec_ctx, grpc_tcp* tcp,
+ grpc_error* error) {
+ grpc_closure* cb = tcp->read_cb;
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "TCP:%p call_cb %p %p:%p", tcp, cb, cb->cb, cb->cb_arg);
+ size_t i;
+ const char* str = grpc_error_string(error);
+ gpr_log(GPR_DEBUG, "read: error=%s", str);
+
+ for (i = 0; i < tcp->read_slices->count; i++) {
+ char* dump = grpc_dump_slice(tcp->read_slices->slices[i],
+ GPR_DUMP_HEX | GPR_DUMP_ASCII);
+ gpr_log(GPR_DEBUG, "READ %p (peer=%s): %s", tcp, tcp->peer_string, dump);
+ gpr_free(dump);
+ }
+ }
+ tcp->read_slices = NULL;
+ tcp->read_cb = NULL;
+ GRPC_CLOSURE_RUN(exec_ctx, cb, error);
}
static void read_callback(uv_stream_t* stream, ssize_t nread,
const uv_buf_t* buf) {
- grpc_slice sub;
grpc_error* error;
grpc_core::ExecCtx _local_exec_ctx;
grpc_tcp* tcp = (grpc_tcp*)stream->data;
- grpc_closure* cb = tcp->read_cb;
+ grpc_slice_buffer garbage;
if (nread == 0) {
// Nothing happened. Wait for the next callback
return;
}
TCP_UNREF(tcp, "read");
- tcp->read_cb = NULL;
// TODO(murgatroid99): figure out what the return value here means
uv_read_stop(stream);
if (nread == UV_EOF) {
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("EOF");
+ grpc_slice_buffer_reset_and_unref_internal(&exec_ctx, tcp->read_slices);
} else if (nread > 0) {
// Successful read
- sub = grpc_slice_sub_no_ref(tcp->read_slice, 0, (size_t)nread);
- grpc_slice_buffer_add(tcp->read_slices, sub);
- tcp->read_slice = alloc_read_slice(tcp->resource_user);
error = GRPC_ERROR_NONE;
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
- size_t i;
- const char* str = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "read: error=%s", str);
-
- for (i = 0; i < tcp->read_slices->count; i++) {
- char* dump = grpc_dump_slice(tcp->read_slices->slices[i],
- GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_DEBUG, "READ %p (peer=%s): %s", tcp, tcp->peer_string,
- dump);
- gpr_free(dump);
- }
+ if ((size_t)nread < tcp->read_slices->length) {
+ /* TODO(murgatroid99): Instead of discarding the unused part of the read
+ * buffer, reuse it as the next read buffer. */
+ grpc_slice_buffer_init(&garbage);
+ grpc_slice_buffer_trim_end(
+ tcp->read_slices, tcp->read_slices->length - (size_t)nread, &garbage);
+ grpc_slice_buffer_reset_and_unref_internal(&exec_ctx, &garbage);
}
} else {
// nread < 0: Error
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("TCP Read failed");
+ grpc_slice_buffer_reset_and_unref_internal(&exec_ctx, tcp->read_slices);
+ }
+ call_read_cb(tcp, error);
+ grpc_exec_ctx_finish();
+}
+
+static void tcp_read_allocation_done(void* tcpp, grpc_error* error) {
+ int status;
+ grpc_tcp* tcp = (grpc_tcp*)tcpp;
+ if (grpc_tcp_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "TCP:%p read_allocation_done: %s", tcp,
+ grpc_error_string(error));
+ }
+ if (error == GRPC_ERROR_NONE) {
+ status =
+ uv_read_start((uv_stream_t*)tcp->handle, alloc_uv_buf, read_callback);
+ if (status != 0) {
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("TCP Read failed at start");
+ error = grpc_error_set_str(
+ error, GRPC_ERROR_STR_OS_ERROR,
+ grpc_slice_from_static_string(uv_strerror(status)));
+ }
+ }
+ if (error != GRPC_ERROR_NONE) {
+ grpc_slice_buffer_reset_and_unref_internal(tcp->read_slices);
+ call_read_cb(tcp, GRPC_ERROR_REF(error));
+ TCP_UNREF(tcp, "read");
+ }
+ if (grpc_tcp_trace.enabled()) {
+ const char* str = grpc_error_string(error);
+ gpr_log(GPR_DEBUG, "Initiating read on %p: error=%s", tcp, str);
}
- GRPC_CLOSURE_SCHED(cb, error);
}
static void uv_endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* read_slices,
grpc_closure* cb) {
grpc_tcp* tcp = (grpc_tcp*)ep;
- int status;
- grpc_error* error = GRPC_ERROR_NONE;
GRPC_UV_ASSERT_SAME_THREAD();
GPR_ASSERT(tcp->read_cb == NULL);
tcp->read_cb = cb;
tcp->read_slices = read_slices;
grpc_slice_buffer_reset_and_unref_internal(read_slices);
TCP_REF(tcp, "read");
- // TODO(murgatroid99): figure out what the return value here means
- status =
- uv_read_start((uv_stream_t*)tcp->handle, alloc_uv_buf, read_callback);
- if (status != 0) {
- error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("TCP Read failed at start");
- error =
- grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR,
- grpc_slice_from_static_string(uv_strerror(status)));
- GRPC_CLOSURE_SCHED(cb, error);
- }
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
- const char* str = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "Initiating read on %p: error=%s", tcp, str);
- }
+ grpc_resource_user_alloc_slices(&tcp->slice_allocator,
+ GRPC_TCP_DEFAULT_READ_SLICE_SIZE, 1,
+ tcp->read_slices);
}
static void write_callback(uv_write_t* req, int status) {
@@ -213,14 +240,13 @@ static void write_callback(uv_write_t* req, int status) {
} else {
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("TCP Write failed");
}
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
gpr_log(GPR_DEBUG, "write complete on %p: error=%s", tcp, str);
}
gpr_free(tcp->write_buffers);
- grpc_resource_user_free(tcp->resource_user,
- sizeof(uv_buf_t) * tcp->write_slices->count);
GRPC_CLOSURE_SCHED(cb, error);
+ grpc_exec_ctx_finish();
}
static void uv_endpoint_write(grpc_endpoint* ep,
@@ -234,7 +260,7 @@ static void uv_endpoint_write(grpc_endpoint* ep,
uv_write_t* write_req;
GRPC_UV_ASSERT_SAME_THREAD();
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
size_t j;
for (j = 0; j < write_slices->count; j++) {
@@ -264,8 +290,6 @@ static void uv_endpoint_write(grpc_endpoint* ep,
tcp->write_cb = cb;
buffer_count = (unsigned int)tcp->write_slices->count;
buffers = (uv_buf_t*)gpr_malloc(sizeof(uv_buf_t) * buffer_count);
- grpc_resource_user_alloc(tcp->resource_user, sizeof(uv_buf_t) * buffer_count,
- NULL);
for (i = 0; i < buffer_count; i++) {
slice = &tcp->write_slices->slices[i];
buffers[i].base = (char*)GRPC_SLICE_START_PTR(*slice);
@@ -310,7 +334,7 @@ static void shutdown_callback(uv_shutdown_t* req, int status) {}
static void uv_endpoint_shutdown(grpc_endpoint* ep, grpc_error* why) {
grpc_tcp* tcp = (grpc_tcp*)ep;
if (!tcp->shutting_down) {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(why);
gpr_log(GPR_DEBUG, "TCP %p shutdown why=%s", tcp->handle, str);
}
@@ -357,7 +381,7 @@ grpc_endpoint* grpc_tcp_create(uv_tcp_t* handle,
grpc_tcp* tcp = (grpc_tcp*)gpr_malloc(sizeof(grpc_tcp));
grpc_core::ExecCtx _local_exec_ctx;
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "Creating TCP endpoint %p", tcp);
}
@@ -371,8 +395,10 @@ grpc_endpoint* grpc_tcp_create(uv_tcp_t* handle,
gpr_ref_init(&tcp->refcount, 1);
tcp->peer_string = gpr_strdup(peer_string);
tcp->shutting_down = false;
+ tcp->read_slices = NULL;
tcp->resource_user = grpc_resource_user_create(resource_quota, peer_string);
- tcp->read_slice = alloc_read_slice(tcp->resource_user);
+ grpc_resource_user_slice_allocator_init(
+ &tcp->slice_allocator, tcp->resource_user, tcp_read_allocation_done, tcp);
/* Tell network status tracking code about the new endpoint */
grpc_network_status_register_endpoint(&tcp->base);
diff --git a/src/core/lib/iomgr/tcp_uv.h b/src/core/lib/iomgr/tcp_uv.h
index 708e8469e6..4b4da3608f 100644
--- a/src/core/lib/iomgr/tcp_uv.h
+++ b/src/core/lib/iomgr/tcp_uv.h
@@ -38,7 +38,7 @@
#include <uv.h>
-extern grpc_tracer_flag grpc_tcp_trace;
+extern grpc_core::TraceFlag grpc_tcp_trace;
#define GRPC_TCP_DEFAULT_READ_SLICE_SIZE 8192
diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc
index ab9a8a5c1e..6d091b77bb 100644
--- a/src/core/lib/iomgr/tcp_windows.cc
+++ b/src/core/lib/iomgr/tcp_windows.cc
@@ -49,7 +49,7 @@
#define GRPC_FIONBIO FIONBIO
#endif
-grpc_tracer_flag grpc_tcp_trace = GRPC_TRACER_INITIALIZER(false, "tcp");
+grpc_core::TraceFlag grpc_tcp_trace(false, "tcp");
static grpc_error* set_non_block(SOCKET sock) {
int status;
@@ -123,7 +123,7 @@ static void tcp_free(grpc_tcp* tcp) {
#define TCP_REF(tcp, reason) tcp_ref((tcp), (reason), __FILE__, __LINE__)
static void tcp_unref(grpc_tcp* tcp, const char* reason, const char* file,
int line) {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"TCP unref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp, reason, val,
@@ -136,7 +136,7 @@ static void tcp_unref(grpc_tcp* tcp, const char* reason, const char* file,
static void tcp_ref(grpc_tcp* tcp, const char* reason, const char* file,
int line) {
- if (GRPC_TRACER_ON(grpc_tcp_trace)) {
+ if (grpc_tcp_trace.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&tcp->refcount.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"TCP ref %p : %s %" PRIdPTR " -> %" PRIdPTR, tcp, reason, val,
diff --git a/src/core/lib/iomgr/timer_generic.cc b/src/core/lib/iomgr/timer_generic.cc
index 861a85577b..103144eb3b 100644
--- a/src/core/lib/iomgr/timer_generic.cc
+++ b/src/core/lib/iomgr/timer_generic.cc
@@ -42,11 +42,8 @@
#define MIN_QUEUE_WINDOW_DURATION 0.01
#define MAX_QUEUE_WINDOW_DURATION 1
-extern "C" {
-grpc_tracer_flag grpc_timer_trace = GRPC_TRACER_INITIALIZER(false, "timer");
-grpc_tracer_flag grpc_timer_check_trace =
- GRPC_TRACER_INITIALIZER(false, "timer_check");
-}
+grpc_core::TraceFlag grpc_timer_trace(false, "timer");
+grpc_core::TraceFlag grpc_timer_check_trace(false, "timer_check");
/* A "timer shard". Contains a 'heap' and a 'list' of timers. All timers with
* deadlines earlier than 'queue_deadline" cap are maintained in the heap and
@@ -252,8 +249,6 @@ void grpc_timer_list_init() {
g_shared_mutables.min_timer = grpc_core::ExecCtx::Get()->Now();
gpr_tls_init(&g_last_seen_min_timer);
gpr_tls_set(&g_last_seen_min_timer, 0);
- grpc_register_tracer(&grpc_timer_trace);
- grpc_register_tracer(&grpc_timer_check_trace);
for (i = 0; i < g_num_shards; i++) {
timer_shard* shard = &g_shards[i];
@@ -338,7 +333,7 @@ void grpc_timer_init(grpc_timer* timer, grpc_millis deadline,
timer->hash_table_next = nullptr;
#endif
- if (GRPC_TRACER_ON(grpc_timer_trace)) {
+ if (grpc_timer_trace.enabled()) {
gpr_log(GPR_DEBUG,
"TIMER %p: SET %" PRIdPTR " now %" PRIdPTR " call %p[%p]", timer,
deadline, grpc_core::ExecCtx::Get()->Now(), closure, closure->cb);
@@ -374,7 +369,7 @@ void grpc_timer_init(grpc_timer* timer, grpc_millis deadline,
timer->heap_index = INVALID_HEAP_INDEX;
list_join(&shard->list, timer);
}
- if (GRPC_TRACER_ON(grpc_timer_trace)) {
+ if (grpc_timer_trace.enabled()) {
gpr_log(GPR_DEBUG,
" .. add to shard %d with queue_deadline_cap=%" PRIdPTR
" => is_first_timer=%s",
@@ -396,7 +391,7 @@ void grpc_timer_init(grpc_timer* timer, grpc_millis deadline,
grpc_timer_check. */
if (is_first_timer) {
gpr_mu_lock(&g_shared_mutables.mu);
- if (GRPC_TRACER_ON(grpc_timer_trace)) {
+ if (grpc_timer_trace.enabled()) {
gpr_log(GPR_DEBUG, " .. old shard min_deadline=%" PRIdPTR,
shard->min_deadline);
}
@@ -426,7 +421,7 @@ void grpc_timer_cancel(grpc_timer* timer) {
timer_shard* shard = &g_shards[GPR_HASH_POINTER(timer, g_num_shards)];
gpr_mu_lock(&shard->mu);
- if (GRPC_TRACER_ON(grpc_timer_trace)) {
+ if (grpc_timer_trace.enabled()) {
gpr_log(GPR_DEBUG, "TIMER %p: CANCEL pending=%s", timer,
timer->pending ? "true" : "false");
}
@@ -467,7 +462,7 @@ static int refill_heap(timer_shard* shard, gpr_atm now) {
saturating_add(GPR_MAX(now, shard->queue_deadline_cap),
(gpr_atm)(deadline_delta * 1000.0));
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, " .. shard[%d]->queue_deadline_cap --> %" PRIdPTR,
(int)(shard - g_shards), shard->queue_deadline_cap);
}
@@ -475,7 +470,7 @@ static int refill_heap(timer_shard* shard, gpr_atm now) {
next = timer->next;
if (timer->deadline < shard->queue_deadline_cap) {
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, " .. add timer with deadline %" PRIdPTR " to heap",
timer->deadline);
}
@@ -492,7 +487,7 @@ static int refill_heap(timer_shard* shard, gpr_atm now) {
static grpc_timer* pop_one(timer_shard* shard, gpr_atm now) {
grpc_timer* timer;
for (;;) {
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, " .. shard[%d]: heap_empty=%s",
(int)(shard - g_shards),
grpc_timer_heap_is_empty(&shard->heap) ? "true" : "false");
@@ -502,13 +497,13 @@ static grpc_timer* pop_one(timer_shard* shard, gpr_atm now) {
if (!refill_heap(shard, now)) return nullptr;
}
timer = grpc_timer_heap_top(&shard->heap);
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG,
" .. check top timer deadline=%" PRIdPTR " now=%" PRIdPTR,
timer->deadline, now);
}
if (timer->deadline > now) return nullptr;
- if (GRPC_TRACER_ON(grpc_timer_trace)) {
+ if (grpc_timer_trace.enabled()) {
gpr_log(GPR_DEBUG, "TIMER %p: FIRE %" PRIdPTR "ms late via %s scheduler",
timer, now - timer->deadline,
timer->closure->scheduler->vtable->name);
@@ -532,7 +527,7 @@ static size_t pop_timers(timer_shard* shard, gpr_atm now,
}
*new_min_deadline = compute_min_deadline(shard);
gpr_mu_unlock(&shard->mu);
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, " .. shard[%d] popped %" PRIdPTR,
(int)(shard - g_shards), n);
}
@@ -555,7 +550,7 @@ static grpc_timer_check_result run_some_expired_timers(gpr_atm now,
gpr_mu_lock(&g_shared_mutables.mu);
result = GRPC_TIMERS_CHECKED_AND_EMPTY;
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, " .. shard[%d]->min_deadline = %" PRIdPTR,
(int)(g_shard_queue[0] - g_shards),
g_shard_queue[0]->min_deadline);
@@ -572,7 +567,7 @@ static grpc_timer_check_result run_some_expired_timers(gpr_atm now,
result = GRPC_TIMERS_FIRED;
}
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG,
" .. result --> %d"
", shard[%d]->min_deadline %" PRIdPTR " --> %" PRIdPTR
@@ -616,7 +611,7 @@ grpc_timer_check_result grpc_timer_check(grpc_millis* next) {
if (next != nullptr) {
*next = GPR_MIN(*next, min_timer);
}
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG,
"TIMER CHECK SKIP: now=%" PRIdPTR " min_timer=%" PRIdPTR, now,
min_timer);
@@ -630,7 +625,7 @@ grpc_timer_check_result grpc_timer_check(grpc_millis* next) {
: GRPC_ERROR_CREATE_FROM_STATIC_STRING("Shutting down timer system");
// tracing
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
char* next_str;
if (next == nullptr) {
next_str = gpr_strdup("NULL");
@@ -648,7 +643,7 @@ grpc_timer_check_result grpc_timer_check(grpc_millis* next) {
grpc_timer_check_result r =
run_some_expired_timers(now, next, shutdown_error);
// tracing
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
char* next_str;
if (next == nullptr) {
next_str = gpr_strdup("NULL");
diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc
index dfa381a1f1..0e1fa0c049 100644
--- a/src/core/lib/iomgr/timer_manager.cc
+++ b/src/core/lib/iomgr/timer_manager.cc
@@ -33,7 +33,7 @@ typedef struct completed_thread {
struct completed_thread* next;
} completed_thread;
-extern "C" grpc_tracer_flag grpc_timer_check_trace;
+extern grpc_core::TraceFlag grpc_timer_check_trace;
// global mutex
static gpr_mu g_mu;
@@ -81,7 +81,7 @@ static void start_timer_thread_and_unlock(void) {
++g_waiter_count;
++g_thread_count;
gpr_mu_unlock(&g_mu);
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, "Spawn timer thread");
}
gpr_thd_options opt = gpr_thd_options_default();
@@ -114,7 +114,7 @@ static void run_some_timers() {
// if there's no thread waiting with a timeout, kick an existing
// waiter so that the next deadline is not missed
if (!g_has_timed_waiter) {
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, "kick untimed waiter");
}
gpr_cv_signal(&g_cv_wait);
@@ -122,7 +122,7 @@ static void run_some_timers() {
gpr_mu_unlock(&g_mu);
}
// without our lock, flush the exec_ctx
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, "flush exec_ctx");
}
grpc_core::ExecCtx::Get()->Flush();
@@ -177,7 +177,7 @@ static bool wait_until(grpc_millis next) {
g_has_timed_waiter = true;
g_timed_waiter_deadline = next;
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
grpc_millis wait_time = next - grpc_core::ExecCtx::Get()->Now();
gpr_log(GPR_DEBUG, "sleep for a %" PRIdPTR " milliseconds",
wait_time);
@@ -187,15 +187,14 @@ static bool wait_until(grpc_millis next) {
}
}
- if (GRPC_TRACER_ON(grpc_timer_check_trace) &&
- next == GRPC_MILLIS_INF_FUTURE) {
+ if (grpc_timer_check_trace.enabled() && next == GRPC_MILLIS_INF_FUTURE) {
gpr_log(GPR_DEBUG, "sleep until kicked");
}
gpr_cv_wait(&g_cv_wait, &g_mu,
grpc_millis_to_timespec(next, GPR_CLOCK_REALTIME));
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, "wait ended: was_timed:%d kicked:%d",
my_timed_waiter_generation == g_timed_waiter_generation,
g_kicked);
@@ -224,9 +223,6 @@ static void timer_main_loop() {
for (;;) {
grpc_millis next = GRPC_MILLIS_INF_FUTURE;
grpc_core::ExecCtx::Get()->InvalidateNow();
- /* Calibrate g_start_time in exec_ctx.cc with a regular interval in case the
- * system clock has changed */
- grpc_exec_ctx_maybe_update_start_time();
// check timer state, updates next to the next time to run a check
switch (grpc_timer_check(&next)) {
@@ -243,7 +239,7 @@ static void timer_main_loop() {
Consequently, we can just sleep forever here and be happy at some
saved wakeup cycles. */
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, "timers not checked: expect another thread to");
}
next = GRPC_MILLIS_INF_FUTURE;
@@ -269,7 +265,7 @@ static void timer_thread_cleanup(completed_thread* ct) {
ct->next = g_completed_threads;
g_completed_threads = ct;
gpr_mu_unlock(&g_mu);
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, "End timer thread");
}
}
@@ -311,18 +307,18 @@ void grpc_timer_manager_init(void) {
static void stop_threads(void) {
gpr_mu_lock(&g_mu);
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, "stop timer threads: threaded=%d", g_threaded);
}
if (g_threaded) {
g_threaded = false;
gpr_cv_broadcast(&g_cv_wait);
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, "num timer threads: %d", g_thread_count);
}
while (g_thread_count > 0) {
gpr_cv_wait(&g_cv_shutdown, &g_mu, gpr_inf_future(GPR_CLOCK_REALTIME));
- if (GRPC_TRACER_ON(grpc_timer_check_trace)) {
+ if (grpc_timer_check_trace.enabled()) {
gpr_log(GPR_DEBUG, "num timer threads: %d", g_thread_count);
}
gc_completed_threads();
diff --git a/src/core/lib/iomgr/timer_uv.cc b/src/core/lib/iomgr/timer_uv.cc
index 1432eba51e..879890603c 100644
--- a/src/core/lib/iomgr/timer_uv.cc
+++ b/src/core/lib/iomgr/timer_uv.cc
@@ -29,11 +29,8 @@
#include <uv.h>
-extern "C" {
-grpc_tracer_flag grpc_timer_trace = GRPC_TRACER_INITIALIZER(false, "timer");
-grpc_tracer_flag grpc_timer_check_trace =
- GRPC_TRACER_INITIALIZER(false, "timer_check");
-}
+grpc_core::TraceFlag grpc_timer_trace(false, "timer");
+grpc_core::TraceFlag grpc_timer_check_trace(false, "timer_check");
static void timer_close_callback(uv_handle_t* handle) { gpr_free(handle); }
diff --git a/src/core/lib/security/context/security_context.cc b/src/core/lib/security/context/security_context.cc
index 7d9b4fbcb2..d4efdac583 100644
--- a/src/core/lib/security/context/security_context.cc
+++ b/src/core/lib/security/context/security_context.cc
@@ -29,10 +29,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_auth_context_refcount =
- GRPC_TRACER_INITIALIZER(false, "auth_context_refcount");
-#endif
+grpc_core::DebugOnlyTraceFlag grpc_trace_auth_context_refcount(
+ false, "auth_context_refcount");
/* --- grpc_call --- */
@@ -134,7 +132,7 @@ grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* ctx,
const char* file, int line,
const char* reason) {
if (ctx == nullptr) return nullptr;
- if (GRPC_TRACER_ON(grpc_trace_auth_context_refcount)) {
+ if (grpc_trace_auth_context_refcount.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&ctx->refcount.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"AUTH_CONTEXT:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", ctx, val,
@@ -152,7 +150,7 @@ grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* ctx) {
void grpc_auth_context_unref(grpc_auth_context* ctx, const char* file, int line,
const char* reason) {
if (ctx == nullptr) return;
- if (GRPC_TRACER_ON(grpc_trace_auth_context_refcount)) {
+ if (grpc_trace_auth_context_refcount.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&ctx->refcount.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"AUTH_CONTEXT:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", ctx, val,
diff --git a/src/core/lib/security/context/security_context.h b/src/core/lib/security/context/security_context.h
index 4f049c4a3b..5b27d1a42e 100644
--- a/src/core/lib/security/context/security_context.h
+++ b/src/core/lib/security/context/security_context.h
@@ -22,9 +22,7 @@
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/security/credentials/credentials.h"
-#ifndef NDEBUG
-extern grpc_tracer_flag grpc_trace_auth_context_refcount;
-#endif
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_auth_context_refcount;
#ifdef __cplusplus
extern "C" {
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.cc b/src/core/lib/security/credentials/jwt/jwt_credentials.cc
index df26b4e2c0..3eaedeea4e 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.cc
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.cc
@@ -167,7 +167,7 @@ static char* redact_private_key(const char* json_key) {
grpc_call_credentials* grpc_service_account_jwt_access_credentials_create(
const char* json_key, gpr_timespec token_lifetime, void* reserved) {
- if (GRPC_TRACER_ON(grpc_api_trace)) {
+ if (grpc_api_trace.enabled()) {
char* clean_json = redact_private_key(json_key);
gpr_log(GPR_INFO,
"grpc_service_account_jwt_access_credentials_create("
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
index f95df0f021..0fe368d3f2 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
@@ -461,7 +461,7 @@ grpc_call_credentials* grpc_google_refresh_token_credentials_create(
const char* json_refresh_token, void* reserved) {
grpc_auth_refresh_token token =
grpc_auth_refresh_token_create_from_string(json_refresh_token);
- if (GRPC_TRACER_ON(grpc_api_trace)) {
+ if (grpc_api_trace.enabled()) {
char* loggable_token = create_loggable_refresh_token(&token);
gpr_log(GPR_INFO,
"grpc_refresh_token_credentials_create(json_refresh_token=%s, "
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.cc b/src/core/lib/security/credentials/plugin/plugin_credentials.cc
index 27a762d9a3..a75ae033b9 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.cc
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc
@@ -31,8 +31,7 @@
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/validate_metadata.h"
-grpc_tracer_flag grpc_plugin_credentials_trace =
- GRPC_TRACER_INITIALIZER(false, "plugin_credentials");
+grpc_core::TraceFlag grpc_plugin_credentials_trace(false, "plugin_credentials");
static void plugin_destruct(grpc_call_credentials* creds) {
grpc_plugin_credentials* c = (grpc_plugin_credentials*)creds;
@@ -120,7 +119,7 @@ static void plugin_md_request_metadata_ready(void* request,
GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP);
grpc_plugin_credentials_pending_request* r =
(grpc_plugin_credentials_pending_request*)request;
- if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ if (grpc_plugin_credentials_trace.enabled()) {
gpr_log(GPR_INFO,
"plugin_credentials[%p]: request %p: plugin returned "
"asynchronously",
@@ -133,7 +132,7 @@ static void plugin_md_request_metadata_ready(void* request,
grpc_error* error =
process_plugin_result(r, md, num_md, status, error_details);
GRPC_CLOSURE_SCHED(r->on_request_metadata, error);
- } else if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ } else if (grpc_plugin_credentials_trace.enabled()) {
gpr_log(GPR_INFO,
"plugin_credentials[%p]: request %p: plugin was previously "
"cancelled",
@@ -167,7 +166,7 @@ static bool plugin_get_request_metadata(grpc_call_credentials* creds,
c->pending_requests = pending_request;
gpr_mu_unlock(&c->mu);
// Invoke the plugin. The callback holds a ref to us.
- if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ if (grpc_plugin_credentials_trace.enabled()) {
gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: invoking plugin",
c, pending_request);
}
@@ -180,7 +179,7 @@ static bool plugin_get_request_metadata(grpc_call_credentials* creds,
plugin_md_request_metadata_ready,
pending_request, creds_md, &num_creds_md,
&status, &error_details)) {
- if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ if (grpc_plugin_credentials_trace.enabled()) {
gpr_log(GPR_INFO,
"plugin_credentials[%p]: request %p: plugin will return "
"asynchronously",
@@ -195,7 +194,7 @@ static bool plugin_get_request_metadata(grpc_call_credentials* creds,
// asynchronously by plugin_cancel_get_request_metadata(), so return
// false. Otherwise, process the result.
if (pending_request->cancelled) {
- if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ if (grpc_plugin_credentials_trace.enabled()) {
gpr_log(GPR_INFO,
"plugin_credentials[%p]: request %p was cancelled, error "
"will be returned asynchronously",
@@ -203,7 +202,7 @@ static bool plugin_get_request_metadata(grpc_call_credentials* creds,
}
retval = false;
} else {
- if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ if (grpc_plugin_credentials_trace.enabled()) {
gpr_log(GPR_INFO,
"plugin_credentials[%p]: request %p: plugin returned "
"synchronously",
@@ -232,7 +231,7 @@ static void plugin_cancel_get_request_metadata(
c->pending_requests;
pending_request != nullptr; pending_request = pending_request->next) {
if (pending_request->md_array == md_array) {
- if (GRPC_TRACER_ON(grpc_plugin_credentials_trace)) {
+ if (grpc_plugin_credentials_trace.enabled()) {
gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", c,
pending_request);
}
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.h b/src/core/lib/security/credentials/plugin/plugin_credentials.h
index fc0955c695..e1467b0824 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.h
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.h
@@ -21,7 +21,7 @@
#include "src/core/lib/security/credentials/credentials.h"
-extern grpc_tracer_flag grpc_plugin_credentials_trace;
+extern grpc_core::TraceFlag grpc_plugin_credentials_trace;
struct grpc_plugin_credentials;
diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc
index 4ea40e7fa1..e5c089de9c 100644
--- a/src/core/lib/security/transport/secure_endpoint.cc
+++ b/src/core/lib/security/transport/secure_endpoint.cc
@@ -61,8 +61,7 @@ typedef struct {
gpr_refcount ref;
} secure_endpoint;
-grpc_tracer_flag grpc_trace_secure_endpoint =
- GRPC_TRACER_INITIALIZER(false, "secure_endpoint");
+grpc_core::TraceFlag grpc_trace_secure_endpoint(false, "secure_endpoint");
static void destroy(secure_endpoint* secure_ep) {
secure_endpoint* ep = secure_ep;
@@ -85,7 +84,7 @@ static void destroy(secure_endpoint* secure_ep) {
secure_endpoint_ref((ep), (reason), __FILE__, __LINE__)
static void secure_endpoint_unref(secure_endpoint* ep, const char* reason,
const char* file, int line) {
- if (GRPC_TRACER_ON(grpc_trace_secure_endpoint)) {
+ if (grpc_trace_secure_endpoint.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&ep->ref.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"SECENDP unref %p : %s %" PRIdPTR " -> %" PRIdPTR, ep, reason, val,
@@ -98,7 +97,7 @@ static void secure_endpoint_unref(secure_endpoint* ep, const char* reason,
static void secure_endpoint_ref(secure_endpoint* ep, const char* reason,
const char* file, int line) {
- if (GRPC_TRACER_ON(grpc_trace_secure_endpoint)) {
+ if (grpc_trace_secure_endpoint.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&ep->ref.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"SECENDP ref %p : %s %" PRIdPTR " -> %" PRIdPTR, ep, reason, val,
@@ -127,7 +126,7 @@ static void flush_read_staging_buffer(secure_endpoint* ep, uint8_t** cur,
}
static void call_read_cb(secure_endpoint* ep, grpc_error* error) {
- if (GRPC_TRACER_ON(grpc_trace_secure_endpoint)) {
+ if (grpc_trace_secure_endpoint.enabled()) {
size_t i;
for (i = 0; i < ep->read_buffer->count; i++) {
char* data = grpc_dump_slice(ep->read_buffer->slices[i],
@@ -263,7 +262,7 @@ static void endpoint_write(grpc_endpoint* secure_ep, grpc_slice_buffer* slices,
grpc_slice_buffer_reset_and_unref_internal(&ep->output_buffer);
- if (GRPC_TRACER_ON(grpc_trace_secure_endpoint)) {
+ if (grpc_trace_secure_endpoint.enabled()) {
for (i = 0; i < slices->count; i++) {
char* data =
grpc_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII);
diff --git a/src/core/lib/security/transport/secure_endpoint.h b/src/core/lib/security/transport/secure_endpoint.h
index db8233f6e6..92c457421b 100644
--- a/src/core/lib/security/transport/secure_endpoint.h
+++ b/src/core/lib/security/transport/secure_endpoint.h
@@ -29,7 +29,7 @@ extern "C" {
struct tsi_frame_protector;
struct tsi_zero_copy_grpc_protector;
-extern grpc_tracer_flag grpc_trace_secure_endpoint;
+extern grpc_core::TraceFlag grpc_trace_secure_endpoint;
/* Takes ownership of protector, zero_copy_protector, and to_wrap, and refs
* leftover_slices. If zero_copy_protector is not NULL, protector will never be
diff --git a/src/core/lib/security/transport/security_connector.cc b/src/core/lib/security/transport/security_connector.cc
index 0c99268578..fd139714da 100644
--- a/src/core/lib/security/transport/security_connector.cc
+++ b/src/core/lib/security/transport/security_connector.cc
@@ -44,10 +44,8 @@
#include "src/core/tsi/ssl_transport_security.h"
#include "src/core/tsi/transport_security_adapter.h"
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_security_connector_refcount =
- GRPC_TRACER_INITIALIZER(false, "security_connector_refcount");
-#endif
+grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount(
+ false, "security_connector_refcount");
/* -- Constants. -- */
@@ -197,7 +195,7 @@ grpc_security_connector* grpc_security_connector_ref(
grpc_security_connector* sc, const char* file, int line,
const char* reason) {
if (sc == nullptr) return nullptr;
- if (GRPC_TRACER_ON(grpc_trace_security_connector_refcount)) {
+ if (grpc_trace_security_connector_refcount.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"SECURITY_CONNECTOR:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", sc,
@@ -217,7 +215,7 @@ void grpc_security_connector_unref(grpc_security_connector* sc,
const char* file, int line,
const char* reason) {
if (sc == nullptr) return;
- if (GRPC_TRACER_ON(grpc_trace_security_connector_refcount)) {
+ if (grpc_trace_security_connector_refcount.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"SECURITY_CONNECTOR:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", sc,
diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h
index bb66cae422..78c9656a8b 100644
--- a/src/core/lib/security/transport/security_connector.h
+++ b/src/core/lib/security/transport/security_connector.h
@@ -33,9 +33,7 @@
extern "C" {
#endif
-#ifndef NDEBUG
-extern grpc_tracer_flag grpc_trace_security_connector_refcount;
-#endif
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount;
/* --- status enum. --- */
diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h
index be66b8ab00..a3205290cb 100644
--- a/src/core/lib/slice/slice_internal.h
+++ b/src/core/lib/slice/slice_internal.h
@@ -31,6 +31,8 @@ extern "C" {
grpc_slice grpc_slice_ref_internal(grpc_slice slice);
void grpc_slice_unref_internal(grpc_slice slice);
void grpc_slice_buffer_reset_and_unref_internal(grpc_slice_buffer* sb);
+void grpc_slice_buffer_partial_unref_internal(grpc_slice_buffer* sb,
+ size_t idx);
void grpc_slice_buffer_destroy_internal(grpc_slice_buffer* sb);
/* Check if a slice is interned */
diff --git a/src/core/lib/support/abstract.h b/src/core/lib/support/abstract.h
new file mode 100644
index 0000000000..5498769a7d
--- /dev/null
+++ b/src/core/lib/support/abstract.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_SUPPORT_ABSTRACT_H
+#define GRPC_CORE_LIB_SUPPORT_ABSTRACT_H
+
+// This is needed to support abstract base classes in the c core. Since gRPC
+// doesn't have a c++ runtime, it will hit a linker error on delete unless
+// we define a virtual operator delete. See this blog for more info:
+// https://eli.thegreenplace.net/2015/c-deleting-destructors-and-virtual-operator-delete/
+#define GRPC_ABSTRACT_BASE_CLASS \
+ static void operator delete(void* p) { abort(); }
+
+#endif /* GRPC_CORE_LIB_SUPPORT_ABSTRACT_H */
diff --git a/src/core/lib/support/cpu_posix.cc b/src/core/lib/support/cpu_posix.cc
index 503a96b4c8..bca14a0c12 100644
--- a/src/core/lib/support/cpu_posix.cc
+++ b/src/core/lib/support/cpu_posix.cc
@@ -18,21 +18,23 @@
#include <grpc/support/port_platform.h>
-#ifdef GPR_CPU_POSIX
+#if defined(GPR_CPU_POSIX)
#include <errno.h>
+#include <pthread.h>
#include <string.h>
#include <unistd.h>
+#include <grpc/support/alloc.h>
#include <grpc/support/cpu.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/useful.h>
-static __thread char magic_thread_local;
-
static long ncpus = 0;
+static pthread_key_t thread_id_key;
+
static void init_ncpus() {
ncpus = sysconf(_SC_NPROCESSORS_ONLN);
if (ncpus < 1 || ncpus > INT32_MAX) {
@@ -47,12 +49,32 @@ unsigned gpr_cpu_num_cores(void) {
return (unsigned)ncpus;
}
+static void delete_thread_id(void* value) {
+ if (value) {
+ gpr_free(value);
+ }
+}
+
+static void init_thread_id_key(void) {
+ pthread_key_create(&thread_id_key, delete_thread_id);
+}
+
unsigned gpr_cpu_current_cpu(void) {
/* NOTE: there's no way I know to return the actual cpu index portably...
most code that's using this is using it to shard across work queues though,
so here we use thread identity instead to achieve a similar though not
identical effect */
- return (unsigned)GPR_HASH_POINTER(&magic_thread_local, gpr_cpu_num_cores());
+ static gpr_once once = GPR_ONCE_INIT;
+ gpr_once_init(&once, init_thread_id_key);
+
+ unsigned int* thread_id =
+ static_cast<unsigned int*>(pthread_getspecific(thread_id_key));
+ if (thread_id == nullptr) {
+ thread_id = static_cast<unsigned int*>(gpr_malloc(sizeof(unsigned int)));
+ pthread_setspecific(thread_id_key, thread_id);
+ }
+
+ return (unsigned)GPR_HASH_POINTER(thread_id, gpr_cpu_num_cores());
}
#endif /* GPR_CPU_POSIX */
diff --git a/src/core/lib/support/manual_constructor.h b/src/core/lib/support/manual_constructor.h
index d753cf98a0..fda7653dbc 100644
--- a/src/core/lib/support/manual_constructor.h
+++ b/src/core/lib/support/manual_constructor.h
@@ -22,12 +22,147 @@
// manually construct a region of memory with some type
#include <stddef.h>
+#include <stdlib.h>
#include <new>
#include <type_traits>
#include <utility>
+#include <grpc/support/log.h>
+
namespace grpc_core {
+// this contains templated helpers needed to implement the ManualConstructors
+// in this file.
+namespace manual_ctor_impl {
+
+// is_one_of returns true it a class, Member, is present in a variadic list of
+// classes, List.
+template <class Member, class... List>
+class is_one_of;
+
+template <class Member, class... List>
+class is_one_of<Member, Member, List...> {
+ public:
+ static constexpr const bool value = true;
+};
+
+template <class Member, class A, class... List>
+class is_one_of<Member, A, List...> {
+ public:
+ static constexpr const bool value = is_one_of<Member, List...>::value;
+};
+
+template <class Member>
+class is_one_of<Member> {
+ public:
+ static constexpr const bool value = false;
+};
+
+// max_size_of returns sizeof(Type) for the largest type in the variadic list
+// of classes, Types.
+template <class... Types>
+class max_size_of;
+
+template <class A>
+class max_size_of<A> {
+ public:
+ static constexpr const size_t value = sizeof(A);
+};
+
+template <class A, class... B>
+class max_size_of<A, B...> {
+ public:
+ static constexpr const size_t value = sizeof(A) > max_size_of<B...>::value
+ ? sizeof(A)
+ : max_size_of<B...>::value;
+};
+
+// max_size_of returns alignof(Type) for the largest type in the variadic list
+// of classes, Types.
+template <class... Types>
+class max_align_of;
+
+template <class A>
+class max_align_of<A> {
+ public:
+ static constexpr const size_t value = alignof(A);
+};
+
+template <class A, class... B>
+class max_align_of<A, B...> {
+ public:
+ static constexpr const size_t value = alignof(A) > max_align_of<B...>::value
+ ? alignof(A)
+ : max_align_of<B...>::value;
+};
+
+} // namespace manual_ctor_impl
+
+template <class BaseType, class... DerivedTypes>
+class PolymorphicManualConstructor {
+ public:
+ // No constructor or destructor because one of the most useful uses of
+ // this class is as part of a union, and members of a union could not have
+ // constructors or destructors till C++11. And, anyway, the whole point of
+ // this class is to bypass constructor and destructor.
+
+ BaseType* get() { return reinterpret_cast<BaseType*>(&space_); }
+ const BaseType* get() const {
+ return reinterpret_cast<const BaseType*>(&space_);
+ }
+
+ BaseType* operator->() { return get(); }
+ const BaseType* operator->() const { return get(); }
+
+ BaseType& operator*() { return *get(); }
+ const BaseType& operator*() const { return *get(); }
+
+ template <class DerivedType>
+ void Init() {
+ FinishInit(new (&space_) DerivedType);
+ }
+
+ // Init() constructs the Type instance using the given arguments
+ // (which are forwarded to Type's constructor).
+ //
+ // Note that Init() with no arguments performs default-initialization,
+ // not zero-initialization (i.e it behaves the same as "new Type;", not
+ // "new Type();"), so it will leave non-class types uninitialized.
+ template <class DerivedType, typename... Ts>
+ void Init(Ts&&... args) {
+ FinishInit(new (&space_) DerivedType(std::forward<Ts>(args)...));
+ }
+
+ // Init() that is equivalent to copy and move construction.
+ // Enables usage like this:
+ // ManualConstructor<std::vector<int>> v;
+ // v.Init({1, 2, 3});
+ template <class DerivedType>
+ void Init(const DerivedType& x) {
+ FinishInit(new (&space_) DerivedType(x));
+ }
+ template <class DerivedType>
+ void Init(DerivedType&& x) {
+ FinishInit(new (&space_) DerivedType(std::move(x)));
+ }
+
+ void Destroy() { get()->~BaseType(); }
+
+ private:
+ template <class DerivedType>
+ void FinishInit(DerivedType* p) {
+ static_assert(
+ manual_ctor_impl::is_one_of<DerivedType, DerivedTypes...>::value,
+ "DerivedType must be one of the predeclared DerivedTypes");
+ GPR_ASSERT(reinterpret_cast<BaseType*>(static_cast<DerivedType*>(p)) == p);
+ }
+
+ typename std::aligned_storage<
+ grpc_core::manual_ctor_impl::max_size_of<DerivedTypes...>::value,
+ grpc_core::manual_ctor_impl::max_align_of<DerivedTypes...>::value>::type
+ space_;
+};
+
template <typename Type>
class ManualConstructor {
public:
diff --git a/src/core/lib/surface/alarm.cc b/src/core/lib/surface/alarm.cc
index 00d609b80d..9a13a7b323 100644
--- a/src/core/lib/surface/alarm.cc
+++ b/src/core/lib/surface/alarm.cc
@@ -27,10 +27,8 @@
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/surface/completion_queue.h"
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_alarm_refcount =
- GRPC_TRACER_INITIALIZER(false, "alarm_refcount");
-#endif
+grpc_core::DebugOnlyTraceFlag grpc_trace_alarm_refcount(false,
+ "alarm_refcount");
struct grpc_alarm {
gpr_refcount refs;
@@ -59,7 +57,7 @@ static void alarm_unref(grpc_alarm* alarm) {
#ifndef NDEBUG
static void alarm_ref_dbg(grpc_alarm* alarm, const char* reason,
const char* file, int line) {
- if (GRPC_TRACER_ON(grpc_trace_alarm_refcount)) {
+ if (grpc_trace_alarm_refcount.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&alarm->refs.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"Alarm:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", alarm, val,
@@ -71,7 +69,7 @@ static void alarm_ref_dbg(grpc_alarm* alarm, const char* reason,
static void alarm_unref_dbg(grpc_alarm* alarm, const char* reason,
const char* file, int line) {
- if (GRPC_TRACER_ON(grpc_trace_alarm_refcount)) {
+ if (grpc_trace_alarm_refcount.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&alarm->refs.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"Alarm:%p Unref %" PRIdPTR " -> %" PRIdPTR " %s", alarm, val,
@@ -102,7 +100,7 @@ grpc_alarm* grpc_alarm_create(void* reserved) {
grpc_alarm* alarm = (grpc_alarm*)gpr_malloc(sizeof(grpc_alarm));
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_alarm_refcount)) {
+ if (grpc_trace_alarm_refcount.enabled()) {
gpr_log(GPR_DEBUG, "Alarm:%p created (ref: 1)", alarm);
}
#endif
diff --git a/src/core/lib/surface/alarm_internal.h b/src/core/lib/surface/alarm_internal.h
index 136b60547f..2ee3a311f7 100644
--- a/src/core/lib/surface/alarm_internal.h
+++ b/src/core/lib/surface/alarm_internal.h
@@ -22,14 +22,14 @@
#include <grpc/support/log.h>
#include "src/core/lib/debug/trace.h"
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_alarm_refcount;
+
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NDEBUG
-extern grpc_tracer_flag grpc_trace_alarm_refcount;
-
#define GRPC_ALARM_REF(a, reason) alarm_ref_dbg(a, reason, __FILE__, __LINE__)
#define GRPC_ALARM_UNREF(a, reason) \
alarm_unref_dbg(a, reason, __FILE__, __LINE__)
diff --git a/src/core/lib/surface/api_trace.cc b/src/core/lib/surface/api_trace.cc
index 56973303da..7ab836a9ba 100644
--- a/src/core/lib/surface/api_trace.cc
+++ b/src/core/lib/surface/api_trace.cc
@@ -19,4 +19,4 @@
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/debug/trace.h"
-grpc_tracer_flag grpc_api_trace = GRPC_TRACER_INITIALIZER(false, "api");
+grpc_core::TraceFlag grpc_api_trace(false, "api");
diff --git a/src/core/lib/surface/api_trace.h b/src/core/lib/surface/api_trace.h
index 105abdf629..a4e11ce154 100644
--- a/src/core/lib/surface/api_trace.h
+++ b/src/core/lib/surface/api_trace.h
@@ -22,11 +22,7 @@
#include <grpc/support/log.h>
#include "src/core/lib/debug/trace.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern grpc_tracer_flag grpc_api_trace;
+extern grpc_core::TraceFlag grpc_api_trace;
/* Provide unwrapping macros because we're in C89 and variadic macros weren't
introduced until C99... */
@@ -47,12 +43,8 @@ extern grpc_tracer_flag grpc_api_trace;
/* Due to the limitations of C89's preprocessor, the arity of the var-arg list
'nargs' must be specified. */
#define GRPC_API_TRACE(fmt, nargs, args) \
- if (GRPC_TRACER_ON(grpc_api_trace)) { \
+ if (grpc_api_trace.enabled()) { \
gpr_log(GPR_INFO, fmt GRPC_API_TRACE_UNWRAP##nargs args); \
}
-#ifdef __cplusplus
-}
-#endif
-
#endif /* GRPC_CORE_LIB_SURFACE_API_TRACE_H */
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index 1caa717195..e4c8f01505 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -234,6 +234,7 @@ struct grpc_call {
struct {
grpc_status_code* status;
grpc_slice* status_details;
+ const char** error_string;
} client;
struct {
int* cancelled;
@@ -259,10 +260,8 @@ struct grpc_call {
gpr_atm recv_state;
};
-grpc_tracer_flag grpc_call_error_trace =
- GRPC_TRACER_INITIALIZER(false, "call_error");
-grpc_tracer_flag grpc_compression_trace =
- GRPC_TRACER_INITIALIZER(false, "compression");
+grpc_core::TraceFlag grpc_call_error_trace(false, "call_error");
+grpc_core::TraceFlag grpc_compression_trace(false, "compression");
#define CALL_STACK_FROM_CALL(call) ((grpc_call_stack*)((call) + 1))
#define CALL_FROM_CALL_STACK(call_stack) (((grpc_call*)(call_stack)) - 1)
@@ -280,10 +279,9 @@ static void cancel_with_error(grpc_call* c, status_source source,
grpc_error* error);
static void destroy_call(void* call_stack, grpc_error* error);
static void receiving_slice_ready(void* bctlp, grpc_error* error);
-static void get_final_status(grpc_call* call,
- void (*set_value)(grpc_status_code code,
- void* user_data),
- void* set_value_user_data, grpc_slice* details);
+static void get_final_status(
+ grpc_call* call, void (*set_value)(grpc_status_code code, void* user_data),
+ void* set_value_user_data, grpc_slice* details, const char** error_string);
static void set_status_value_directly(grpc_status_code status, void* dest);
static void set_status_from_error(grpc_call* call, status_source source,
grpc_error* error);
@@ -541,7 +539,7 @@ static void destroy_call(void* call, grpc_error* error) {
}
get_final_status(c, set_status_value_directly, &c->final_info.final_status,
- nullptr);
+ nullptr, c->final_info.error_string);
c->final_info.stats.latency =
gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time);
@@ -724,10 +722,11 @@ static void cancel_with_status(grpc_call* c, status_source source,
static bool get_final_status_from(
grpc_call* call, grpc_error* error, bool allow_ok_status,
void (*set_value)(grpc_status_code code, void* user_data),
- void* set_value_user_data, grpc_slice* details) {
+ void* set_value_user_data, grpc_slice* details, const char** error_string) {
grpc_status_code code;
grpc_slice slice = grpc_empty_slice();
- grpc_error_get_status(error, call->send_deadline, &code, &slice, nullptr);
+ grpc_error_get_status(error, call->send_deadline, &code, &slice, nullptr,
+ error_string);
if (code == GRPC_STATUS_OK && !allow_ok_status) {
return false;
}
@@ -739,16 +738,15 @@ static bool get_final_status_from(
return true;
}
-static void get_final_status(grpc_call* call,
- void (*set_value)(grpc_status_code code,
- void* user_data),
- void* set_value_user_data, grpc_slice* details) {
+static void get_final_status(
+ grpc_call* call, void (*set_value)(grpc_status_code code, void* user_data),
+ void* set_value_user_data, grpc_slice* details, const char** error_string) {
int i;
received_status status[STATUS_SOURCE_COUNT];
for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
status[i] = unpack_received_status(gpr_atm_acq_load(&call->status[i]));
}
- if (GRPC_TRACER_ON(grpc_call_error_trace)) {
+ if (grpc_call_error_trace.enabled()) {
gpr_log(GPR_DEBUG, "get_final_status %s", call->is_client ? "CLI" : "SVR");
for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
if (status[i].is_set) {
@@ -765,7 +763,8 @@ static void get_final_status(grpc_call* call,
if (status[i].is_set &&
grpc_error_has_clear_grpc_status(status[i].error)) {
if (get_final_status_from(call, status[i].error, allow_ok_status != 0,
- set_value, set_value_user_data, details)) {
+ set_value, set_value_user_data, details,
+ error_string)) {
return;
}
}
@@ -774,7 +773,8 @@ static void get_final_status(grpc_call* call,
for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
if (status[i].is_set) {
if (get_final_status_from(call, status[i].error, allow_ok_status != 0,
- set_value, set_value_user_data, details)) {
+ set_value, set_value_user_data, details,
+ error_string)) {
return;
}
}
@@ -1309,10 +1309,11 @@ static void post_batch_completion(batch_control* bctl) {
if (call->is_client) {
get_final_status(call, set_status_value_directly,
call->final_op.client.status,
- call->final_op.client.status_details);
+ call->final_op.client.status_details,
+ call->final_op.client.error_string);
} else {
get_final_status(call, set_cancelled_value,
- call->final_op.server.cancelled, nullptr);
+ call->final_op.server.cancelled, nullptr, nullptr);
}
GRPC_ERROR_UNREF(error);
@@ -1400,7 +1401,7 @@ static void receiving_slice_ready(void* bctlp, grpc_error* error) {
}
if (error != GRPC_ERROR_NONE) {
- if (GRPC_TRACER_ON(grpc_trace_operation_failures)) {
+ if (grpc_trace_operation_failures.enabled()) {
GRPC_LOG_IF_ERROR("receiving_slice_ready", GRPC_ERROR_REF(error));
}
grpc_byte_stream_destroy(call->receiving_stream);
@@ -1499,7 +1500,7 @@ static void validate_filtered_metadata(batch_control* bctl) {
GPR_ASSERT(call->stream_encodings_accepted_by_peer != 0);
if (!GPR_BITGET(call->stream_encodings_accepted_by_peer,
call->incoming_stream_compression_algorithm)) {
- if (GRPC_TRACER_ON(grpc_compression_trace)) {
+ if (grpc_compression_trace.enabled()) {
const char* algo_name = nullptr;
grpc_stream_compression_algorithm_name(
call->incoming_stream_compression_algorithm, &algo_name);
@@ -1542,7 +1543,7 @@ static void validate_filtered_metadata(batch_control* bctl) {
GPR_ASSERT(call->encodings_accepted_by_peer != 0);
if (!GPR_BITGET(call->encodings_accepted_by_peer,
call->incoming_compression_algorithm)) {
- if (GRPC_TRACER_ON(grpc_compression_trace)) {
+ if (grpc_compression_trace.enabled()) {
const char* algo_name = nullptr;
grpc_compression_algorithm_name(call->incoming_compression_algorithm,
&algo_name);
@@ -1954,6 +1955,8 @@ static grpc_call_error call_start_batch(grpc_call* call, const grpc_op* ops,
call->final_op.client.status = op->data.recv_status_on_client.status;
call->final_op.client.status_details =
op->data.recv_status_on_client.status_details;
+ call->final_op.client.error_string =
+ op->data.recv_status_on_client.error_string;
stream_op->recv_trailing_metadata = true;
stream_op->collect_stats = true;
stream_op_payload->recv_trailing_metadata.recv_trailing_metadata =
diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h
index 61cc6520da..49e391864f 100644
--- a/src/core/lib/surface/call.h
+++ b/src/core/lib/surface/call.h
@@ -96,8 +96,7 @@ void grpc_call_context_set(grpc_call* call, grpc_context_index elem,
void* grpc_call_context_get(grpc_call* call, grpc_context_index elem);
#define GRPC_CALL_LOG_BATCH(sev, call, ops, nops, tag) \
- if (GRPC_TRACER_ON(grpc_api_trace)) \
- grpc_call_log_batch(sev, call, ops, nops, tag)
+ if (grpc_api_trace.enabled()) grpc_call_log_batch(sev, call, ops, nops, tag)
uint8_t grpc_call_is_client(grpc_call* call);
@@ -106,8 +105,8 @@ uint8_t grpc_call_is_client(grpc_call* call);
grpc_compression_algorithm grpc_call_compression_for_level(
grpc_call* call, grpc_compression_level level);
-extern grpc_tracer_flag grpc_call_error_trace;
-extern grpc_tracer_flag grpc_compression_trace;
+extern grpc_core::TraceFlag grpc_call_error_trace;
+extern grpc_core::TraceFlag grpc_compression_trace;
#ifdef __cplusplus
}
diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc
index c84f35c508..958318f814 100644
--- a/src/core/lib/surface/completion_queue.cc
+++ b/src/core/lib/surface/completion_queue.cc
@@ -40,14 +40,9 @@
#include "src/core/lib/surface/call.h"
#include "src/core/lib/surface/event_string.h"
-grpc_tracer_flag grpc_trace_operation_failures =
- GRPC_TRACER_INITIALIZER(false, "op_failure");
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_pending_tags =
- GRPC_TRACER_INITIALIZER(false, "pending_tags");
-grpc_tracer_flag grpc_trace_cq_refcount =
- GRPC_TRACER_INITIALIZER(false, "cq_refcount");
-#endif
+grpc_core::TraceFlag grpc_trace_operation_failures(false, "op_failure");
+grpc_core::DebugOnlyTraceFlag grpc_trace_pending_tags(false, "pending_tags");
+grpc_core::DebugOnlyTraceFlag grpc_trace_cq_refcount(false, "cq_refcount");
// Specifies a cq thread local cache.
// The first event that occurs on a thread
@@ -325,18 +320,15 @@ static const cq_vtable g_cq_vtable[] = {
#define POLLSET_FROM_CQ(cq) \
((grpc_pollset*)(cq->vtable->data_size + (char*)DATA_FROM_CQ(cq)))
-grpc_tracer_flag grpc_cq_pluck_trace =
- GRPC_TRACER_INITIALIZER(true, "queue_pluck");
-grpc_tracer_flag grpc_cq_event_timeout_trace =
- GRPC_TRACER_INITIALIZER(true, "queue_timeout");
-
-#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \
- if (GRPC_TRACER_ON(grpc_api_trace) && \
- (GRPC_TRACER_ON(grpc_cq_pluck_trace) || \
- (event)->type != GRPC_QUEUE_TIMEOUT)) { \
- char* _ev = grpc_event_string(event); \
- gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \
- gpr_free(_ev); \
+grpc_core::TraceFlag grpc_cq_pluck_trace(true, "queue_pluck");
+grpc_core::TraceFlag grpc_cq_event_timeout_trace(true, "queue_timeout");
+
+#define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \
+ if (grpc_api_trace.enabled() && (grpc_cq_pluck_trace.enabled() || \
+ (event)->type != GRPC_QUEUE_TIMEOUT)) { \
+ char* _ev = grpc_event_string(event); \
+ gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \
+ gpr_free(_ev); \
}
static void on_pollset_shutdown_done(void* cq, grpc_error* error);
@@ -513,7 +505,7 @@ int grpc_get_cq_poll_num(grpc_completion_queue* cq) {
#ifndef NDEBUG
void grpc_cq_internal_ref(grpc_completion_queue* cq, const char* reason,
const char* file, int line) {
- if (GRPC_TRACER_ON(grpc_trace_cq_refcount)) {
+ if (grpc_trace_cq_refcount.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&cq->owning_refs.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"CQ:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", cq, val, val + 1,
@@ -533,7 +525,7 @@ static void on_pollset_shutdown_done(void* arg, grpc_error* error) {
#ifndef NDEBUG
void grpc_cq_internal_unref(grpc_completion_queue* cq, const char* reason,
const char* file, int line) {
- if (GRPC_TRACER_ON(grpc_trace_cq_refcount)) {
+ if (grpc_trace_cq_refcount.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&cq->owning_refs.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"CQ:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", cq, val, val - 1,
@@ -632,16 +624,14 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag,
void* done_arg, grpc_cq_completion* storage) {
GPR_TIMER_BEGIN("cq_end_op_for_next", 0);
- if (GRPC_TRACER_ON(grpc_api_trace) ||
- (GRPC_TRACER_ON(grpc_trace_operation_failures) &&
- 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_next(cq=%p, tag=%p, error=%s, "
"done=%p, done_arg=%p, storage=%p)",
6, (cq, tag, errmsg, done, done_arg, storage));
- if (GRPC_TRACER_ON(grpc_trace_operation_failures) &&
- error != GRPC_ERROR_NONE) {
+ if (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg);
}
}
@@ -719,16 +709,14 @@ static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag,
GPR_TIMER_BEGIN("cq_end_op_for_pluck", 0);
- if (GRPC_TRACER_ON(grpc_api_trace) ||
- (GRPC_TRACER_ON(grpc_trace_operation_failures) &&
- 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_pluck(cq=%p, tag=%p, error=%s, "
"done=%p, done_arg=%p, storage=%p)",
6, (cq, tag, errmsg, done, done_arg, storage));
- if (GRPC_TRACER_ON(grpc_trace_operation_failures) &&
- error != GRPC_ERROR_NONE) {
+ if (grpc_trace_operation_failures.enabled() && error != GRPC_ERROR_NONE) {
gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg);
}
}
@@ -829,7 +817,7 @@ class ExecCtxNext : public grpc_core::ExecCtx {
#ifndef NDEBUG
static void dump_pending_tags(grpc_completion_queue* cq) {
- if (!GRPC_TRACER_ON(grpc_trace_pending_tags)) return;
+ if (!grpc_trace_pending_tags.enabled()) return;
gpr_strvec v;
gpr_strvec_init(&v);
@@ -1098,7 +1086,7 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag,
GPR_TIMER_BEGIN("grpc_completion_queue_pluck", 0);
- if (GRPC_TRACER_ON(grpc_cq_pluck_trace)) {
+ if (grpc_cq_pluck_trace.enabled()) {
GRPC_API_TRACE(
"grpc_completion_queue_pluck("
"cq=%p, tag=%p, "
diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h
index 5ddafd9eb5..3a96ab59b0 100644
--- a/src/core/lib/surface/completion_queue.h
+++ b/src/core/lib/surface/completion_queue.h
@@ -27,14 +27,11 @@
/* These trace flags default to 1. The corresponding lines are only traced
if grpc_api_trace is also truthy */
-extern grpc_tracer_flag grpc_cq_pluck_trace;
-extern grpc_tracer_flag grpc_cq_event_timeout_trace;
-extern grpc_tracer_flag grpc_trace_operation_failures;
-
-#ifndef NDEBUG
-extern grpc_tracer_flag grpc_trace_pending_tags;
-extern grpc_tracer_flag grpc_trace_cq_refcount;
-#endif
+extern grpc_core::TraceFlag grpc_cq_pluck_trace;
+extern grpc_core::TraceFlag grpc_cq_event_timeout_trace;
+extern grpc_core::TraceFlag grpc_trace_operation_failures;
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_pending_tags;
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_cq_refcount;
#ifdef __cplusplus
extern "C" {
diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc
index b64e862b40..678f837cb7 100644
--- a/src/core/lib/surface/init.cc
+++ b/src/core/lib/surface/init.cc
@@ -124,30 +124,6 @@ void grpc_init(void) {
grpc_slice_intern_init();
grpc_mdctx_global_init();
grpc_channel_init_init();
- grpc_register_tracer(&grpc_api_trace);
- grpc_register_tracer(&grpc_trace_channel);
- grpc_register_tracer(&grpc_connectivity_state_trace);
- grpc_register_tracer(&grpc_trace_channel_stack_builder);
- grpc_register_tracer(&grpc_http1_trace);
- grpc_register_tracer(&grpc_cq_pluck_trace); // default on
- grpc_register_tracer(&grpc_call_combiner_trace);
- grpc_register_tracer(&grpc_combiner_trace);
- grpc_register_tracer(&grpc_server_channel_trace);
- grpc_register_tracer(&grpc_bdp_estimator_trace);
- grpc_register_tracer(&grpc_cq_event_timeout_trace); // default on
- grpc_register_tracer(&grpc_trace_operation_failures);
- grpc_register_tracer(&grpc_resource_quota_trace);
- grpc_register_tracer(&grpc_call_error_trace);
-#ifndef NDEBUG
- grpc_register_tracer(&grpc_trace_pending_tags);
- grpc_register_tracer(&grpc_trace_alarm_refcount);
- grpc_register_tracer(&grpc_trace_cq_refcount);
- grpc_register_tracer(&grpc_trace_closure);
- grpc_register_tracer(&grpc_trace_error_refcount);
- grpc_register_tracer(&grpc_trace_stream_refcount);
- grpc_register_tracer(&grpc_trace_fd_refcount);
- grpc_register_tracer(&grpc_trace_metadata);
-#endif
grpc_security_pre_init();
grpc_iomgr_init();
gpr_timers_global_init();
diff --git a/src/core/lib/surface/init_secure.cc b/src/core/lib/surface/init_secure.cc
index c8935c767d..75ed9faef0 100644
--- a/src/core/lib/surface/init_secure.cc
+++ b/src/core/lib/surface/init_secure.cc
@@ -24,6 +24,7 @@
#include <string.h>
#include "src/core/lib/debug/trace.h"
+#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/plugin/plugin_credentials.h"
#include "src/core/lib/security/transport/auth_filters.h"
@@ -33,18 +34,7 @@
#include "src/core/lib/surface/channel_init.h"
#include "src/core/tsi/transport_security_interface.h"
-#ifndef NDEBUG
-#include "src/core/lib/security/context/security_context.h"
-#endif
-
-void grpc_security_pre_init(void) {
- grpc_register_tracer(&grpc_trace_secure_endpoint);
- grpc_register_tracer(&tsi_tracing_enabled);
-#ifndef NDEBUG
- grpc_register_tracer(&grpc_trace_auth_context_refcount);
- grpc_register_tracer(&grpc_trace_security_connector_refcount);
-#endif
-}
+void grpc_security_pre_init(void) {}
static bool maybe_prepend_client_auth_filter(
grpc_channel_stack_builder* builder, void* arg) {
@@ -85,7 +75,4 @@ void grpc_register_security_filters(void) {
maybe_prepend_server_auth_filter, nullptr);
}
-void grpc_security_init() {
- grpc_security_register_handshaker_factories();
- grpc_register_tracer(&grpc_plugin_credentials_trace);
-}
+void grpc_security_init() { grpc_security_register_handshaker_factories(); }
diff --git a/src/core/lib/surface/lame_client.cc b/src/core/lib/surface/lame_client.cc
index 67188b46fc..d79f9a9ab2 100644
--- a/src/core/lib/surface/lame_client.cc
+++ b/src/core/lib/surface/lame_client.cc
@@ -25,7 +25,6 @@
#include "src/core/lib/support/atomic.h"
-extern "C" {
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/api_trace.h"
@@ -33,7 +32,6 @@ extern "C" {
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/lame_client.h"
#include "src/core/lib/transport/static_metadata.h"
-}
namespace grpc_core {
diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc
index 49f453569c..e003b5410b 100644
--- a/src/core/lib/surface/server.cc
+++ b/src/core/lib/surface/server.cc
@@ -59,8 +59,7 @@ typedef struct registered_method registered_method;
typedef enum { BATCH_CALL, REGISTERED_CALL } requested_call_type;
-grpc_tracer_flag grpc_server_channel_trace =
- GRPC_TRACER_INITIALIZER(false, "server_channel");
+grpc_core::TraceFlag grpc_server_channel_trace(false, "server_channel");
typedef struct requested_call {
gpr_mpscq_node request_link; /* must be first */
@@ -343,14 +342,8 @@ static void request_matcher_kill_requests(grpc_server* server,
grpc_error* error) {
requested_call* rc;
for (size_t i = 0; i < server->cq_count; i++) {
- /* Here we know:
- 1. no requests are being added (since the server is shut down)
- 2. no other threads are pulling (since the shut down process is single
- threaded)
- So, we can ignore the queue lock and just pop, with the guarantee that a
- NULL returned here truly means that the queue is empty */
- while ((rc = (requested_call*)gpr_mpscq_pop(
- &rm->requests_per_cq[i].queue)) != nullptr) {
+ while ((rc = (requested_call*)gpr_locked_mpscq_pop(
+ &rm->requests_per_cq[i])) != nullptr) {
fail_call(server, i, rc, GRPC_ERROR_REF(error));
}
}
@@ -425,7 +418,7 @@ static void destroy_channel(channel_data* chand, grpc_error* error) {
GRPC_CLOSURE_INIT(&chand->finish_destroy_channel_closure,
finish_destroy_channel, chand, grpc_schedule_on_exec_ctx);
- if (GRPC_TRACER_ON(grpc_server_channel_trace) && error != GRPC_ERROR_NONE) {
+ if (grpc_server_channel_trace.enabled() && error != GRPC_ERROR_NONE) {
const char* msg = grpc_error_string(error);
gpr_log(GPR_INFO, "Disconnected client: %s", msg);
}
diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h
index dfd777e8a5..3f53870075 100644
--- a/src/core/lib/surface/server.h
+++ b/src/core/lib/surface/server.h
@@ -31,7 +31,7 @@ extern "C" {
extern const grpc_channel_filter grpc_server_top_filter;
/** Lightweight tracing of server channel state */
-extern grpc_tracer_flag grpc_server_channel_trace;
+extern grpc_core::TraceFlag grpc_server_channel_trace;
/* Add a listener to the server: when the server starts, it will call start,
and when it shuts down, it will call destroy */
diff --git a/src/core/lib/transport/bdp_estimator.cc b/src/core/lib/transport/bdp_estimator.cc
index d2b6e5db25..5fcc62ec43 100644
--- a/src/core/lib/transport/bdp_estimator.cc
+++ b/src/core/lib/transport/bdp_estimator.cc
@@ -23,8 +23,7 @@
#include <grpc/support/useful.h>
-grpc_tracer_flag grpc_bdp_estimator_trace =
- GRPC_TRACER_INITIALIZER(false, "bdp_estimator");
+grpc_core::TraceFlag grpc_bdp_estimator_trace(false, "bdp_estimator");
namespace grpc_core {
@@ -44,7 +43,7 @@ grpc_millis BdpEstimator::CompletePing() {
double dt = (double)dt_ts.tv_sec + 1e-9 * (double)dt_ts.tv_nsec;
double bw = dt > 0 ? ((double)accumulator_ / dt) : 0;
int start_inter_ping_delay = inter_ping_delay_;
- if (GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
+ if (grpc_bdp_estimator_trace.enabled()) {
gpr_log(GPR_DEBUG,
"bdp[%s]:complete acc=%" PRId64 " est=%" PRId64
" dt=%lf bw=%lfMbs bw_est=%lfMbs",
@@ -55,7 +54,7 @@ grpc_millis BdpEstimator::CompletePing() {
if (accumulator_ > 2 * estimate_ / 3 && bw > bw_est_) {
estimate_ = GPR_MAX(accumulator_, estimate_ * 2);
bw_est_ = bw;
- if (GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
+ if (grpc_bdp_estimator_trace.enabled()) {
gpr_log(GPR_DEBUG, "bdp[%s]: estimate increased to %" PRId64, name_,
estimate_);
}
@@ -72,7 +71,7 @@ grpc_millis BdpEstimator::CompletePing() {
}
if (start_inter_ping_delay != inter_ping_delay_) {
stable_estimate_count_ = 0;
- if (GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
+ if (grpc_bdp_estimator_trace.enabled()) {
gpr_log(GPR_DEBUG, "bdp[%s]:update_inter_time to %dms", name_,
inter_ping_delay_);
}
diff --git a/src/core/lib/transport/bdp_estimator.h b/src/core/lib/transport/bdp_estimator.h
index 431d4b845c..e703af121c 100644
--- a/src/core/lib/transport/bdp_estimator.h
+++ b/src/core/lib/transport/bdp_estimator.h
@@ -31,7 +31,7 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/exec_ctx.h"
-extern grpc_tracer_flag grpc_bdp_estimator_trace;
+extern grpc_core::TraceFlag grpc_bdp_estimator_trace;
namespace grpc_core {
@@ -49,7 +49,7 @@ class BdpEstimator {
// grpc_bdp_estimator_add_incoming_bytes once a ping has been scheduled by a
// transport (but not necessarily started)
void SchedulePing() {
- if (GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
+ if (grpc_bdp_estimator_trace.enabled()) {
gpr_log(GPR_DEBUG, "bdp[%s]:sched acc=%" PRId64 " est=%" PRId64, name_,
accumulator_, estimate_);
}
@@ -62,7 +62,7 @@ class BdpEstimator {
// once
// the ping is on the wire
void StartPing() {
- if (GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
+ if (grpc_bdp_estimator_trace.enabled()) {
gpr_log(GPR_DEBUG, "bdp[%s]:start acc=%" PRId64 " est=%" PRId64, name_,
accumulator_, estimate_);
}
diff --git a/src/core/lib/transport/connectivity_state.cc b/src/core/lib/transport/connectivity_state.cc
index 51ee20d7b0..c42cc9c8d0 100644
--- a/src/core/lib/transport/connectivity_state.cc
+++ b/src/core/lib/transport/connectivity_state.cc
@@ -24,8 +24,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-grpc_tracer_flag grpc_connectivity_state_trace =
- GRPC_TRACER_INITIALIZER(false, "connectivity_state");
+grpc_core::TraceFlag grpc_connectivity_state_trace(false, "connectivity_state");
const char* grpc_connectivity_state_name(grpc_connectivity_state state) {
switch (state) {
@@ -77,7 +76,7 @@ grpc_connectivity_state grpc_connectivity_state_check(
grpc_connectivity_state cur =
(grpc_connectivity_state)gpr_atm_no_barrier_load(
&tracker->current_state_atm);
- if (GRPC_TRACER_ON(grpc_connectivity_state_trace)) {
+ if (grpc_connectivity_state_trace.enabled()) {
gpr_log(GPR_DEBUG, "CONWATCH: %p %s: get %s", tracker, tracker->name,
grpc_connectivity_state_name(cur));
}
@@ -89,7 +88,7 @@ grpc_connectivity_state grpc_connectivity_state_get(
grpc_connectivity_state cur =
(grpc_connectivity_state)gpr_atm_no_barrier_load(
&tracker->current_state_atm);
- if (GRPC_TRACER_ON(grpc_connectivity_state_trace)) {
+ if (grpc_connectivity_state_trace.enabled()) {
gpr_log(GPR_DEBUG, "CONWATCH: %p %s: get %s", tracker, tracker->name,
grpc_connectivity_state_name(cur));
}
@@ -110,7 +109,7 @@ bool grpc_connectivity_state_notify_on_state_change(
grpc_connectivity_state cur =
(grpc_connectivity_state)gpr_atm_no_barrier_load(
&tracker->current_state_atm);
- if (GRPC_TRACER_ON(grpc_connectivity_state_trace)) {
+ if (grpc_connectivity_state_trace.enabled()) {
if (current == nullptr) {
gpr_log(GPR_DEBUG, "CONWATCH: %p %s: unsubscribe notify=%p", tracker,
tracker->name, notify);
@@ -162,7 +161,7 @@ void grpc_connectivity_state_set(grpc_connectivity_state_tracker* tracker,
(grpc_connectivity_state)gpr_atm_no_barrier_load(
&tracker->current_state_atm);
grpc_connectivity_state_watcher* w;
- if (GRPC_TRACER_ON(grpc_connectivity_state_trace)) {
+ if (grpc_connectivity_state_trace.enabled()) {
const char* error_string = grpc_error_string(error);
gpr_log(GPR_DEBUG, "SET: %p %s: %s --> %s [%s] error=%p %s", tracker,
tracker->name, grpc_connectivity_state_name(cur),
@@ -189,7 +188,7 @@ void grpc_connectivity_state_set(grpc_connectivity_state_tracker* tracker,
while ((w = tracker->watchers) != nullptr) {
*w->current = state;
tracker->watchers = w->next;
- if (GRPC_TRACER_ON(grpc_connectivity_state_trace)) {
+ if (grpc_connectivity_state_trace.enabled()) {
gpr_log(GPR_DEBUG, "NOTIFY: %p %s: %p", tracker, tracker->name,
w->notify);
}
diff --git a/src/core/lib/transport/connectivity_state.h b/src/core/lib/transport/connectivity_state.h
index 83ce99e6d6..440bd7a9fa 100644
--- a/src/core/lib/transport/connectivity_state.h
+++ b/src/core/lib/transport/connectivity_state.h
@@ -47,7 +47,7 @@ typedef struct {
char* name;
} grpc_connectivity_state_tracker;
-extern grpc_tracer_flag grpc_connectivity_state_trace;
+extern grpc_core::TraceFlag grpc_connectivity_state_trace;
/** enum --> string conversion */
const char* grpc_connectivity_state_name(grpc_connectivity_state state);
diff --git a/src/core/lib/transport/error_utils.cc b/src/core/lib/transport/error_utils.cc
index 2db87b5d29..ffaf327081 100644
--- a/src/core/lib/transport/error_utils.cc
+++ b/src/core/lib/transport/error_utils.cc
@@ -18,6 +18,7 @@
#include "src/core/lib/transport/error_utils.h"
+#include <grpc/support/string_util.h>
#include "src/core/lib/iomgr/error_internal.h"
#include "src/core/lib/transport/status_conversion.h"
@@ -41,7 +42,8 @@ static grpc_error* recursively_find_error_with_field(grpc_error* error,
void grpc_error_get_status(grpc_error* error, grpc_millis deadline,
grpc_status_code* code, grpc_slice* slice,
- grpc_http2_error_code* http_error) {
+ grpc_http2_error_code* http_error,
+ const char** error_string) {
// Start with the parent error and recurse through the tree of children
// until we find the first one that has a status code.
grpc_error* found_error =
@@ -68,6 +70,10 @@ void grpc_error_get_status(grpc_error* error, grpc_millis deadline,
}
if (code != nullptr) *code = status;
+ if (error_string != NULL && status != GRPC_STATUS_OK) {
+ *error_string = gpr_strdup(grpc_error_string(error));
+ }
+
if (http_error != nullptr) {
if (grpc_error_get_int(found_error, GRPC_ERROR_INT_HTTP2_ERROR, &integer)) {
*http_error = (grpc_http2_error_code)integer;
diff --git a/src/core/lib/transport/error_utils.h b/src/core/lib/transport/error_utils.h
index 73ca7cf3ab..7d56282372 100644
--- a/src/core/lib/transport/error_utils.h
+++ b/src/core/lib/transport/error_utils.h
@@ -30,12 +30,14 @@ extern "C" {
/// A utility function to get the status code and message to be returned
/// to the application. If not set in the top-level message, looks
/// through child errors until it finds the first one with these attributes.
-/// All attributes are pulled from the same child error. If any of the
-/// attributes (code, msg, http_status) are unneeded, they can be passed as
+/// All attributes are pulled from the same child error. error_string will
+/// be populated with the entire error string. If any of the attributes (code,
+/// msg, http_status, error_string) are unneeded, they can be passed as
/// NULL.
void grpc_error_get_status(grpc_error* error, grpc_millis deadline,
grpc_status_code* code, grpc_slice* slice,
- grpc_http2_error_code* http_status);
+ grpc_http2_error_code* http_status,
+ const char** error_string);
/// A utility function to check whether there is a clear status code that
/// doesn't need to be guessed in \a error. This means that \a error or some
diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc
index 7596afa59b..5f0673e014 100644
--- a/src/core/lib/transport/metadata.cc
+++ b/src/core/lib/transport/metadata.cc
@@ -48,9 +48,9 @@
* used to determine which kind of element a pointer refers to.
*/
+grpc_core::DebugOnlyTraceFlag grpc_trace_metadata(false, "metadata");
+
#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_metadata =
- GRPC_TRACER_INITIALIZER(false, "metadata");
#define DEBUG_ARGS , const char *file, int line
#define FWD_DEBUG_ARGS , file, line
#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s), __FILE__, __LINE__)
@@ -149,7 +149,7 @@ static int is_mdelem_static(grpc_mdelem e) {
static void ref_md_locked(mdtab_shard* shard,
interned_metadata* md DEBUG_ARGS) {
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_metadata)) {
+ if (grpc_trace_metadata.enabled()) {
char* key_str = grpc_slice_to_c_string(md->key);
char* value_str = grpc_slice_to_c_string(md->value);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
@@ -252,7 +252,7 @@ grpc_mdelem grpc_mdelem_create(
allocated->value = grpc_slice_ref_internal(value);
gpr_atm_rel_store(&allocated->refcnt, 1);
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_metadata)) {
+ if (grpc_trace_metadata.enabled()) {
char* key_str = grpc_slice_to_c_string(allocated->key);
char* value_str = grpc_slice_to_c_string(allocated->value);
gpr_log(GPR_DEBUG, "ELM ALLOC:%p:%" PRIdPTR ": '%s' = '%s'",
@@ -306,7 +306,7 @@ grpc_mdelem grpc_mdelem_create(
shard->elems[idx] = md;
gpr_mu_init(&md->mu_user_data);
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_metadata)) {
+ if (grpc_trace_metadata.enabled()) {
char* key_str = grpc_slice_to_c_string(md->key);
char* value_str = grpc_slice_to_c_string(md->value);
gpr_log(GPR_DEBUG, "ELM NEW:%p:%" PRIdPTR ": '%s' = '%s'", (void*)md,
@@ -371,7 +371,7 @@ grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) {
case GRPC_MDELEM_STORAGE_INTERNED: {
interned_metadata* md = (interned_metadata*)GRPC_MDELEM_DATA(gmd);
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_metadata)) {
+ if (grpc_trace_metadata.enabled()) {
char* key_str = grpc_slice_to_c_string(md->key);
char* value_str = grpc_slice_to_c_string(md->value);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
@@ -393,7 +393,7 @@ grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) {
case GRPC_MDELEM_STORAGE_ALLOCATED: {
allocated_metadata* md = (allocated_metadata*)GRPC_MDELEM_DATA(gmd);
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_metadata)) {
+ if (grpc_trace_metadata.enabled()) {
char* key_str = grpc_slice_to_c_string(md->key);
char* value_str = grpc_slice_to_c_string(md->value);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
@@ -423,7 +423,7 @@ void grpc_mdelem_unref(grpc_mdelem gmd DEBUG_ARGS) {
case GRPC_MDELEM_STORAGE_INTERNED: {
interned_metadata* md = (interned_metadata*)GRPC_MDELEM_DATA(gmd);
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_metadata)) {
+ if (grpc_trace_metadata.enabled()) {
char* key_str = grpc_slice_to_c_string(md->key);
char* value_str = grpc_slice_to_c_string(md->value);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
@@ -449,7 +449,7 @@ void grpc_mdelem_unref(grpc_mdelem gmd DEBUG_ARGS) {
case GRPC_MDELEM_STORAGE_ALLOCATED: {
allocated_metadata* md = (allocated_metadata*)GRPC_MDELEM_DATA(gmd);
#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_metadata)) {
+ if (grpc_trace_metadata.enabled()) {
char* key_str = grpc_slice_to_c_string(md->key);
char* value_str = grpc_slice_to_c_string(md->value);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h
index 552eabf9b7..cf7fd0d43a 100644
--- a/src/core/lib/transport/metadata.h
+++ b/src/core/lib/transport/metadata.h
@@ -25,9 +25,7 @@
#include "src/core/lib/iomgr/exec_ctx.h"
-#ifndef NDEBUG
-extern grpc_tracer_flag grpc_trace_metadata;
-#endif
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_metadata;
#ifdef __cplusplus
extern "C" {
diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc
index d867123d6f..2e878b7f10 100644
--- a/src/core/lib/transport/transport.cc
+++ b/src/core/lib/transport/transport.cc
@@ -31,14 +31,12 @@
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/transport_impl.h"
-#ifndef NDEBUG
-grpc_tracer_flag grpc_trace_stream_refcount =
- GRPC_TRACER_INITIALIZER(false, "stream_refcount");
-#endif
+grpc_core::DebugOnlyTraceFlag grpc_trace_stream_refcount(false,
+ "stream_refcount");
#ifndef NDEBUG
void grpc_stream_ref(grpc_stream_refcount* refcount, const char* reason) {
- if (GRPC_TRACER_ON(grpc_trace_stream_refcount)) {
+ if (grpc_trace_stream_refcount.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count);
gpr_log(GPR_DEBUG, "%s %p:%p REF %" PRIdPTR "->%" PRIdPTR " %s",
refcount->object_type, refcount, refcount->destroy.cb_arg, val,
@@ -52,7 +50,7 @@ void grpc_stream_ref(grpc_stream_refcount* refcount) {
#ifndef NDEBUG
void grpc_stream_unref(grpc_stream_refcount* refcount, const char* reason) {
- if (GRPC_TRACER_ON(grpc_trace_stream_refcount)) {
+ if (grpc_trace_stream_refcount.enabled()) {
gpr_atm val = gpr_atm_no_barrier_load(&refcount->refs.count);
gpr_log(GPR_DEBUG, "%s %p:%p UNREF %" PRIdPTR "->%" PRIdPTR " %s",
refcount->object_type, refcount, refcount->destroy.cb_arg, val,
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index a6692ba1c2..c842e28a58 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -43,9 +43,7 @@ typedef struct grpc_transport grpc_transport;
for a stream. */
typedef struct grpc_stream grpc_stream;
-#ifndef NDEBUG
-extern grpc_tracer_flag grpc_trace_stream_refcount;
-#endif
+extern grpc_core::DebugOnlyTraceFlag grpc_trace_stream_refcount;
typedef struct grpc_stream_refcount {
gpr_refcount refs;
diff --git a/src/core/tsi/fake_transport_security.cc b/src/core/tsi/fake_transport_security.cc
index 4ea24c8ad2..b907636f9d 100644
--- a/src/core/tsi/fake_transport_security.cc
+++ b/src/core/tsi/fake_transport_security.cc
@@ -572,7 +572,7 @@ static tsi_result fake_handshaker_get_bytes_to_send_to_peer(
if (next_message_to_send > TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
next_message_to_send = TSI_FAKE_HANDSHAKE_MESSAGE_MAX;
}
- if (GRPC_TRACER_ON(tsi_tracing_enabled)) {
+ if (tsi_tracing_enabled.enabled()) {
gpr_log(GPR_INFO, "%s prepared %s.",
impl->is_client ? "Client" : "Server",
tsi_fake_handshake_message_to_string(impl->next_message_to_send));
@@ -584,7 +584,7 @@ static tsi_result fake_handshaker_get_bytes_to_send_to_peer(
if (!impl->is_client &&
impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
/* We're done. */
- if (GRPC_TRACER_ON(tsi_tracing_enabled)) {
+ if (tsi_tracing_enabled.enabled()) {
gpr_log(GPR_INFO, "Server is done.");
}
impl->result = TSI_OK;
@@ -622,7 +622,7 @@ static tsi_result fake_handshaker_process_bytes_from_peer(
tsi_fake_handshake_message_to_string(received_msg),
tsi_fake_handshake_message_to_string(expected_msg));
}
- if (GRPC_TRACER_ON(tsi_tracing_enabled)) {
+ if (tsi_tracing_enabled.enabled()) {
gpr_log(GPR_INFO, "%s received %s.", impl->is_client ? "Client" : "Server",
tsi_fake_handshake_message_to_string(received_msg));
}
@@ -630,7 +630,7 @@ static tsi_result fake_handshaker_process_bytes_from_peer(
impl->needs_incoming_message = 0;
if (impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
/* We're done. */
- if (GRPC_TRACER_ON(tsi_tracing_enabled)) {
+ if (tsi_tracing_enabled.enabled()) {
gpr_log(GPR_INFO, "%s is done.", impl->is_client ? "Client" : "Server");
}
impl->result = TSI_OK;
diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc
index f1fff043bd..f35caef640 100644
--- a/src/core/tsi/ssl_transport_security.cc
+++ b/src/core/tsi/ssl_transport_security.cc
@@ -175,7 +175,7 @@ static const char* ssl_error_string(int error) {
/* TODO(jboeuf): Remove when we are past the debugging phase with this code. */
static void ssl_log_where_info(const SSL* ssl, int where, int flag,
const char* msg) {
- if ((where & flag) && GRPC_TRACER_ON(tsi_tracing_enabled)) {
+ if ((where & flag) && tsi_tracing_enabled.enabled()) {
gpr_log(GPR_INFO, "%20.20s - %30.30s - %5.10s", msg,
SSL_state_string_long(ssl), SSL_state_string(ssl));
}
diff --git a/src/core/tsi/transport_security.cc b/src/core/tsi/transport_security.cc
index a2232bfab1..5abd2f0f68 100644
--- a/src/core/tsi/transport_security.cc
+++ b/src/core/tsi/transport_security.cc
@@ -26,7 +26,7 @@
/* --- Tracing. --- */
-grpc_tracer_flag tsi_tracing_enabled = GRPC_TRACER_INITIALIZER(false, "tsi");
+grpc_core::TraceFlag tsi_tracing_enabled(false, "tsi");
/* --- tsi_result common implementation. --- */
diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h
index c64b1ca51a..950154bf80 100644
--- a/src/core/tsi/transport_security.h
+++ b/src/core/tsi/transport_security.h
@@ -28,7 +28,7 @@
extern "C" {
#endif
-extern grpc_tracer_flag tsi_tracing_enabled;
+extern grpc_core::TraceFlag tsi_tracing_enabled;
/* Base for tsi_frame_protector implementations.
See transport_security_interface.h for documentation. */
diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h
index 54942a6b2a..0f3d468381 100644
--- a/src/core/tsi/transport_security_interface.h
+++ b/src/core/tsi/transport_security_interface.h
@@ -60,7 +60,7 @@ const char* tsi_result_to_string(tsi_result result);
/* --- tsi tracing --- */
-extern grpc_tracer_flag tsi_tracing_enabled;
+extern grpc_core::TraceFlag tsi_tracing_enabled;
/* -- tsi_zero_copy_grpc_protector object --
diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
index 9488ce29e9..e7d8939978 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
@@ -64,7 +64,7 @@ namespace Grpc.Core.Internal.Tests
public void CancelNotificationAfterStartDisposes()
{
var finishedTask = asyncCallServer.ServerSideCallAsync();
- fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true);
+ fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true);
AssertFinished(asyncCallServer, fakeCall, finishedTask);
}
@@ -76,8 +76,8 @@ namespace Grpc.Core.Internal.Tests
var moveNextTask = requestStream.MoveNext();
- fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true);
- fakeCall.ReceivedMessageHandler(true, null);
+ fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true);
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null);
Assert.IsFalse(moveNextTask.Result);
AssertFinished(asyncCallServer, fakeCall, finishedTask);
@@ -89,7 +89,7 @@ namespace Grpc.Core.Internal.Tests
var finishedTask = asyncCallServer.ServerSideCallAsync();
var requestStream = new ServerRequestStream<string, string>(asyncCallServer);
- fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true);
+ fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true);
// Check that starting a read after cancel notification has been processed is legal.
var moveNextTask = requestStream.MoveNext();
@@ -107,10 +107,10 @@ namespace Grpc.Core.Internal.Tests
// if a read completion's success==false, the request stream will silently finish
// and we rely on C core cancelling the call.
var moveNextTask = requestStream.MoveNext();
- fakeCall.ReceivedMessageHandler(false, null);
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, null);
Assert.IsFalse(moveNextTask.Result);
- fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true);
+ fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true);
AssertFinished(asyncCallServer, fakeCall, finishedTask);
}
@@ -120,7 +120,7 @@ namespace Grpc.Core.Internal.Tests
var finishedTask = asyncCallServer.ServerSideCallAsync();
var responseStream = new ServerResponseStream<string, string>(asyncCallServer);
- fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true);
+ fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true);
// TODO(jtattermusch): should we throw a different exception type instead?
Assert.Throws(typeof(InvalidOperationException), () => responseStream.WriteAsync("request1"));
@@ -134,10 +134,10 @@ namespace Grpc.Core.Internal.Tests
var responseStream = new ServerResponseStream<string, string>(asyncCallServer);
var writeTask = responseStream.WriteAsync("request1");
- fakeCall.SendCompletionHandler(false);
+ fakeCall.SendCompletionCallback.OnSendCompletion(false);
Assert.ThrowsAsync(typeof(IOException), async () => await writeTask);
- fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true);
+ fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true);
AssertFinished(asyncCallServer, fakeCall, finishedTask);
}
@@ -150,13 +150,13 @@ namespace Grpc.Core.Internal.Tests
var writeTask = responseStream.WriteAsync("request1");
var writeStatusTask = asyncCallServer.SendStatusFromServerAsync(Status.DefaultSuccess, new Metadata(), null);
- fakeCall.SendCompletionHandler(true);
- fakeCall.SendStatusFromServerHandler(true);
+ fakeCall.SendCompletionCallback.OnSendCompletion(true);
+ fakeCall.SendStatusFromServerCallback.OnSendStatusFromServerCompletion(true);
Assert.DoesNotThrowAsync(async () => await writeTask);
Assert.DoesNotThrowAsync(async () => await writeStatusTask);
- fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true);
+ fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true);
AssertFinished(asyncCallServer, fakeCall, finishedTask);
}
@@ -170,8 +170,8 @@ namespace Grpc.Core.Internal.Tests
asyncCallServer.SendStatusFromServerAsync(Status.DefaultSuccess, new Metadata(), null);
Assert.ThrowsAsync(typeof(InvalidOperationException), async () => await responseStream.WriteAsync("request1"));
- fakeCall.SendStatusFromServerHandler(true);
- fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true);
+ fakeCall.SendStatusFromServerCallback.OnSendStatusFromServerCompletion(true);
+ fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true);
AssertFinished(asyncCallServer, fakeCall, finishedTask);
}
diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
index b2b49f3a48..9aab54d2d0 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
@@ -73,7 +73,7 @@ namespace Grpc.Core.Internal.Tests
public void AsyncUnary_Success()
{
var resultTask = asyncCall.UnaryCallAsync("request1");
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
CreateResponsePayload(),
new Metadata());
@@ -85,7 +85,7 @@ namespace Grpc.Core.Internal.Tests
public void AsyncUnary_NonSuccessStatusCode()
{
var resultTask = asyncCall.UnaryCallAsync("request1");
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
CreateClientSideStatus(StatusCode.InvalidArgument),
null,
new Metadata());
@@ -97,7 +97,7 @@ namespace Grpc.Core.Internal.Tests
public void AsyncUnary_NullResponsePayload()
{
var resultTask = asyncCall.UnaryCallAsync("request1");
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
null,
new Metadata());
@@ -118,7 +118,7 @@ namespace Grpc.Core.Internal.Tests
public void ClientStreaming_NoRequest_Success()
{
var resultTask = asyncCall.ClientStreamingCallAsync();
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
CreateResponsePayload(),
new Metadata());
@@ -130,7 +130,7 @@ namespace Grpc.Core.Internal.Tests
public void ClientStreaming_NoRequest_NonSuccessStatusCode()
{
var resultTask = asyncCall.ClientStreamingCallAsync();
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
CreateClientSideStatus(StatusCode.InvalidArgument),
null,
new Metadata());
@@ -145,18 +145,18 @@ namespace Grpc.Core.Internal.Tests
var requestStream = new ClientRequestStream<string, string>(asyncCall);
var writeTask = requestStream.WriteAsync("request1");
- fakeCall.SendCompletionHandler(true);
+ fakeCall.SendCompletionCallback.OnSendCompletion(true);
writeTask.Wait();
var writeTask2 = requestStream.WriteAsync("request2");
- fakeCall.SendCompletionHandler(true);
+ fakeCall.SendCompletionCallback.OnSendCompletion(true);
writeTask2.Wait();
var completeTask = requestStream.CompleteAsync();
- fakeCall.SendCompletionHandler(true);
+ fakeCall.SendCompletionCallback.OnSendCompletion(true);
completeTask.Wait();
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
CreateResponsePayload(),
new Metadata());
@@ -171,12 +171,12 @@ namespace Grpc.Core.Internal.Tests
var requestStream = new ClientRequestStream<string, string>(asyncCall);
var writeTask = requestStream.WriteAsync("request1");
- fakeCall.SendCompletionHandler(false);
+ fakeCall.SendCompletionCallback.OnSendCompletion(false);
// The write will wait for call to finish to receive the status code.
Assert.IsFalse(writeTask.IsCompleted);
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
CreateClientSideStatus(StatusCode.Internal),
null,
new Metadata());
@@ -195,12 +195,12 @@ namespace Grpc.Core.Internal.Tests
var writeTask = requestStream.WriteAsync("request1");
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
CreateClientSideStatus(StatusCode.Internal),
null,
new Metadata());
- fakeCall.SendCompletionHandler(false);
+ fakeCall.SendCompletionCallback.OnSendCompletion(false);
var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode);
@@ -215,13 +215,13 @@ namespace Grpc.Core.Internal.Tests
var requestStream = new ClientRequestStream<string, string>(asyncCall);
var writeTask = requestStream.WriteAsync("request1");
- fakeCall.SendCompletionHandler(false);
+ fakeCall.SendCompletionCallback.OnSendCompletion(false);
// Until the delayed write completion has been triggered,
// we still act as if there was an active write.
Assert.Throws(typeof(InvalidOperationException), () => requestStream.WriteAsync("request2"));
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
CreateClientSideStatus(StatusCode.Internal),
null,
new Metadata());
@@ -242,7 +242,7 @@ namespace Grpc.Core.Internal.Tests
var resultTask = asyncCall.ClientStreamingCallAsync();
var requestStream = new ClientRequestStream<string, string>(asyncCall);
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
CreateResponsePayload(),
new Metadata());
@@ -260,7 +260,7 @@ namespace Grpc.Core.Internal.Tests
var resultTask = asyncCall.ClientStreamingCallAsync();
var requestStream = new ClientRequestStream<string, string>(asyncCall);
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
new ClientSideStatus(new Status(StatusCode.OutOfRange, ""), new Metadata()),
CreateResponsePayload(),
new Metadata());
@@ -282,9 +282,9 @@ namespace Grpc.Core.Internal.Tests
Assert.Throws(typeof(InvalidOperationException), () => requestStream.WriteAsync("request1"));
- fakeCall.SendCompletionHandler(true);
+ fakeCall.SendCompletionCallback.OnSendCompletion(true);
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
CreateResponsePayload(),
new Metadata());
@@ -298,7 +298,7 @@ namespace Grpc.Core.Internal.Tests
var resultTask = asyncCall.ClientStreamingCallAsync();
var requestStream = new ClientRequestStream<string, string>(asyncCall);
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
new ClientSideStatus(Status.DefaultSuccess, new Metadata()),
CreateResponsePayload(),
new Metadata());
@@ -319,7 +319,7 @@ namespace Grpc.Core.Internal.Tests
var writeTask = requestStream.WriteAsync("request1");
Assert.ThrowsAsync(typeof(TaskCanceledException), async () => await writeTask);
- fakeCall.UnaryResponseClientHandler(true,
+ fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true,
CreateClientSideStatus(StatusCode.Cancelled),
null,
new Metadata());
@@ -342,11 +342,11 @@ namespace Grpc.Core.Internal.Tests
var responseStream = new ClientResponseStream<string, string>(asyncCall);
var readTask = responseStream.MoveNext();
- fakeCall.ReceivedResponseHeadersHandler(true, new Metadata());
+ fakeCall.ReceivedResponseHeadersCallback.OnReceivedResponseHeaders(true, new Metadata());
Assert.AreEqual(0, asyncCall.ResponseHeadersAsync.Result.Count);
- fakeCall.ReceivedMessageHandler(true, null);
- fakeCall.ReceivedStatusOnClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null);
+ fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask);
}
@@ -359,8 +359,8 @@ namespace Grpc.Core.Internal.Tests
var readTask = responseStream.MoveNext();
// try alternative order of completions
- fakeCall.ReceivedStatusOnClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
- fakeCall.ReceivedMessageHandler(true, null);
+ fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null);
AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask);
}
@@ -372,8 +372,8 @@ namespace Grpc.Core.Internal.Tests
var responseStream = new ClientResponseStream<string, string>(asyncCall);
var readTask = responseStream.MoveNext();
- fakeCall.ReceivedMessageHandler(false, null); // after a failed read, we rely on C core to deliver appropriate status code.
- fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.Internal));
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, null); // after a failed read, we rely on C core to deliver appropriate status code.
+ fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Internal));
AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.Internal);
}
@@ -385,18 +385,18 @@ namespace Grpc.Core.Internal.Tests
var responseStream = new ClientResponseStream<string, string>(asyncCall);
var readTask1 = responseStream.MoveNext();
- fakeCall.ReceivedMessageHandler(true, CreateResponsePayload());
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateResponsePayload());
Assert.IsTrue(readTask1.Result);
Assert.AreEqual("response1", responseStream.Current);
var readTask2 = responseStream.MoveNext();
- fakeCall.ReceivedMessageHandler(true, CreateResponsePayload());
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateResponsePayload());
Assert.IsTrue(readTask2.Result);
Assert.AreEqual("response1", responseStream.Current);
var readTask3 = responseStream.MoveNext();
- fakeCall.ReceivedStatusOnClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
- fakeCall.ReceivedMessageHandler(true, null);
+ fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null);
AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask3);
}
@@ -409,12 +409,12 @@ namespace Grpc.Core.Internal.Tests
var responseStream = new ClientResponseStream<string, string>(asyncCall);
var writeTask1 = requestStream.CompleteAsync();
- fakeCall.SendCompletionHandler(true);
+ fakeCall.SendCompletionCallback.OnSendCompletion(true);
Assert.DoesNotThrowAsync(async () => await writeTask1);
var readTask = responseStream.MoveNext();
- fakeCall.ReceivedMessageHandler(true, null);
- fakeCall.ReceivedStatusOnClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null);
+ fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask);
}
@@ -427,8 +427,8 @@ namespace Grpc.Core.Internal.Tests
var responseStream = new ClientResponseStream<string, string>(asyncCall);
var readTask = responseStream.MoveNext();
- fakeCall.ReceivedMessageHandler(true, null);
- fakeCall.ReceivedStatusOnClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null);
+ fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask);
@@ -445,8 +445,8 @@ namespace Grpc.Core.Internal.Tests
var responseStream = new ClientResponseStream<string, string>(asyncCall);
var readTask = responseStream.MoveNext();
- fakeCall.ReceivedMessageHandler(true, null);
- fakeCall.ReceivedStatusOnClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null);
+ fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()));
AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask);
@@ -461,14 +461,14 @@ namespace Grpc.Core.Internal.Tests
var responseStream = new ClientResponseStream<string, string>(asyncCall);
var writeTask = requestStream.WriteAsync("request1");
- fakeCall.SendCompletionHandler(false);
+ fakeCall.SendCompletionCallback.OnSendCompletion(false);
// The write will wait for call to finish to receive the status code.
Assert.IsFalse(writeTask.IsCompleted);
var readTask = responseStream.MoveNext();
- fakeCall.ReceivedMessageHandler(true, null);
- fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.PermissionDenied));
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null);
+ fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.PermissionDenied));
var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
Assert.AreEqual(StatusCode.PermissionDenied, ex.Status.StatusCode);
@@ -486,9 +486,9 @@ namespace Grpc.Core.Internal.Tests
var writeTask = requestStream.WriteAsync("request1");
var readTask = responseStream.MoveNext();
- fakeCall.ReceivedMessageHandler(true, null);
- fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.PermissionDenied));
- fakeCall.SendCompletionHandler(false);
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null);
+ fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.PermissionDenied));
+ fakeCall.SendCompletionCallback.OnSendCompletion(false);
var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
Assert.AreEqual(StatusCode.PermissionDenied, ex.Status.StatusCode);
@@ -510,8 +510,8 @@ namespace Grpc.Core.Internal.Tests
Assert.ThrowsAsync(typeof(TaskCanceledException), async () => await writeTask);
var readTask = responseStream.MoveNext();
- fakeCall.ReceivedMessageHandler(true, null);
- fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.Cancelled));
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null);
+ fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled));
AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.Cancelled);
}
@@ -526,13 +526,13 @@ namespace Grpc.Core.Internal.Tests
Assert.IsTrue(fakeCall.IsCancelled);
var readTask1 = responseStream.MoveNext();
- fakeCall.ReceivedMessageHandler(true, CreateResponsePayload());
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateResponsePayload());
Assert.IsTrue(readTask1.Result);
Assert.AreEqual("response1", responseStream.Current);
var readTask2 = responseStream.MoveNext();
- fakeCall.ReceivedMessageHandler(true, null);
- fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.Cancelled));
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null);
+ fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled));
AssertStreamingResponseError(asyncCall, fakeCall, readTask2, StatusCode.Cancelled);
}
@@ -547,13 +547,13 @@ namespace Grpc.Core.Internal.Tests
asyncCall.Cancel();
Assert.IsTrue(fakeCall.IsCancelled);
- fakeCall.ReceivedMessageHandler(true, CreateResponsePayload());
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateResponsePayload());
Assert.IsTrue(readTask1.Result);
Assert.AreEqual("response1", responseStream.Current);
var readTask2 = responseStream.MoveNext();
- fakeCall.ReceivedMessageHandler(true, null);
- fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.Cancelled));
+ fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null);
+ fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled));
AssertStreamingResponseError(asyncCall, fakeCall, readTask2, StatusCode.Cancelled);
}
diff --git a/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs b/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs
index c3a27167f9..581ac3384b 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs
@@ -31,43 +31,43 @@ namespace Grpc.Core.Internal.Tests
/// </summary>
internal class FakeNativeCall : INativeCall
{
- public UnaryResponseClientHandler UnaryResponseClientHandler
+ public IUnaryResponseClientCallback UnaryResponseClientCallback
{
get;
set;
}
- public ReceivedStatusOnClientHandler ReceivedStatusOnClientHandler
+ public IReceivedStatusOnClientCallback ReceivedStatusOnClientCallback
{
get;
set;
}
- public ReceivedMessageHandler ReceivedMessageHandler
+ public IReceivedMessageCallback ReceivedMessageCallback
{
get;
set;
}
- public ReceivedResponseHeadersHandler ReceivedResponseHeadersHandler
+ public IReceivedResponseHeadersCallback ReceivedResponseHeadersCallback
{
get;
set;
}
- public SendCompletionHandler SendCompletionHandler
+ public ISendCompletionCallback SendCompletionCallback
{
get;
set;
}
- public SendCompletionHandler SendStatusFromServerHandler
+ public ISendStatusFromServerCompletionCallback SendStatusFromServerCallback
{
get;
set;
}
- public ReceivedCloseOnServerHandler ReceivedCloseOnServerHandler
+ public IReceivedCloseOnServerCallback ReceivedCloseOnServerCallback
{
get;
set;
@@ -100,9 +100,9 @@ namespace Grpc.Core.Internal.Tests
return "PEER";
}
- public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
+ public void StartUnary(IUnaryResponseClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
- UnaryResponseClientHandler = callback;
+ UnaryResponseClientCallback = callback;
}
public void StartUnary(BatchContextSafeHandle ctx, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
@@ -110,55 +110,55 @@ namespace Grpc.Core.Internal.Tests
throw new NotImplementedException();
}
- public void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
+ public void StartClientStreaming(IUnaryResponseClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
- UnaryResponseClientHandler = callback;
+ UnaryResponseClientCallback = callback;
}
- public void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
+ public void StartServerStreaming(IReceivedStatusOnClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
- ReceivedStatusOnClientHandler = callback;
+ ReceivedStatusOnClientCallback = callback;
}
- public void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
+ public void StartDuplexStreaming(IReceivedStatusOnClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
- ReceivedStatusOnClientHandler = callback;
+ ReceivedStatusOnClientCallback = callback;
}
- public void StartReceiveMessage(ReceivedMessageHandler callback)
+ public void StartReceiveMessage(IReceivedMessageCallback callback)
{
- ReceivedMessageHandler = callback;
+ ReceivedMessageCallback = callback;
}
- public void StartReceiveInitialMetadata(ReceivedResponseHeadersHandler callback)
+ public void StartReceiveInitialMetadata(IReceivedResponseHeadersCallback callback)
{
- ReceivedResponseHeadersHandler = callback;
+ ReceivedResponseHeadersCallback = callback;
}
- public void StartSendInitialMetadata(SendCompletionHandler callback, MetadataArraySafeHandle metadataArray)
+ public void StartSendInitialMetadata(ISendCompletionCallback callback, MetadataArraySafeHandle metadataArray)
{
- SendCompletionHandler = callback;
+ SendCompletionCallback = callback;
}
- public void StartSendMessage(SendCompletionHandler callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata)
+ public void StartSendMessage(ISendCompletionCallback callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata)
{
- SendCompletionHandler = callback;
+ SendCompletionCallback = callback;
}
- public void StartSendCloseFromClient(SendCompletionHandler callback)
+ public void StartSendCloseFromClient(ISendCompletionCallback callback)
{
- SendCompletionHandler = callback;
+ SendCompletionCallback = callback;
}
- public void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
+ public void StartSendStatusFromServer(ISendStatusFromServerCompletionCallback callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
byte[] optionalPayload, WriteFlags writeFlags)
{
- SendStatusFromServerHandler = callback;
+ SendStatusFromServerCallback = callback;
}
- public void StartServerSide(ReceivedCloseOnServerHandler callback)
+ public void StartServerSide(IReceivedCloseOnServerCallback callback)
{
- ReceivedCloseOnServerHandler = callback;
+ ReceivedCloseOnServerCallback = callback;
}
public void Dispose()
diff --git a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
index 7529c44c4e..43f816bb1c 100644
--- a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
+++ b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
@@ -63,7 +63,7 @@ namespace Grpc.Core.Tests
[Ignore("Prevent running on Jenkins")]
public void NativeCallbackBenchmark()
{
- OpCompletionDelegate handler = Handler;
+ NativeCallbackTestDelegate handler = Handler;
counter = 0;
BenchmarkUtil.RunBenchmark(
@@ -91,7 +91,7 @@ namespace Grpc.Core.Tests
10000, 10000,
() =>
{
- Native.grpcsharp_test_callback(new OpCompletionDelegate(Handler));
+ Native.grpcsharp_test_callback(new NativeCallbackTestDelegate(Handler));
});
Assert.AreNotEqual(0, counter);
}
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs
index 1803920662..f9925a8a76 100644
--- a/src/csharp/Grpc.Core/Channel.cs
+++ b/src/csharp/Grpc.Core/Channel.cs
@@ -127,6 +127,20 @@ namespace Grpc.Core
}
}
+ // cached handler for watch connectivity state
+ static readonly BatchCompletionDelegate WatchConnectivityStateHandler = (success, ctx, state) =>
+ {
+ var tcs = (TaskCompletionSource<object>) state;
+ if (success)
+ {
+ tcs.SetResult(null);
+ }
+ else
+ {
+ tcs.SetCanceled();
+ }
+ };
+
/// <summary>
/// Returned tasks completes once channel state has become different from
/// given lastObservedState.
@@ -138,18 +152,8 @@ namespace Grpc.Core
"Shutdown is a terminal state. No further state changes can occur.");
var tcs = new TaskCompletionSource<object>();
var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture;
- var handler = new BatchCompletionDelegate((success, ctx) =>
- {
- if (success)
- {
- tcs.SetResult(null);
- }
- else
- {
- tcs.SetCanceled();
- }
- });
- handle.WatchConnectivityState(lastObservedState, deadlineTimespec, completionQueue, handler);
+ // pass "tcs" as "state" for WatchConnectivityStateHandler.
+ handle.WatchConnectivityState(lastObservedState, deadlineTimespec, completionQueue, WatchConnectivityStateHandler, tcs);
return tcs.Task;
}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 09fb722c81..aa2161267a 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -27,7 +27,7 @@ namespace Grpc.Core.Internal
/// <summary>
/// Manages client side native call lifecycle.
/// </summary>
- internal class AsyncCall<TRequest, TResponse> : AsyncCallBase<TRequest, TResponse>
+ internal class AsyncCall<TRequest, TResponse> : AsyncCallBase<TRequest, TResponse>, IUnaryResponseClientCallback, IReceivedStatusOnClientCallback, IReceivedResponseHeadersCallback
{
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<AsyncCall<TRequest, TResponse>>();
@@ -138,7 +138,7 @@ namespace Grpc.Core.Internal
unaryResponseTcs = new TaskCompletionSource<TResponse>();
using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers))
{
- call.StartUnary(HandleUnaryResponse, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags);
+ call.StartUnary(UnaryResponseClientCallback, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags);
}
return unaryResponseTcs.Task;
}
@@ -162,7 +162,7 @@ namespace Grpc.Core.Internal
unaryResponseTcs = new TaskCompletionSource<TResponse>();
using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers))
{
- call.StartClientStreaming(HandleUnaryResponse, metadataArray, details.Options.Flags);
+ call.StartClientStreaming(UnaryResponseClientCallback, metadataArray, details.Options.Flags);
}
return unaryResponseTcs.Task;
@@ -188,9 +188,9 @@ namespace Grpc.Core.Internal
streamingResponseCallFinishedTcs = new TaskCompletionSource<object>();
using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers))
{
- call.StartServerStreaming(HandleFinished, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags);
+ call.StartServerStreaming(ReceivedStatusOnClientCallback, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags);
}
- call.StartReceiveInitialMetadata(HandleReceivedResponseHeaders);
+ call.StartReceiveInitialMetadata(ReceivedResponseHeadersCallback);
}
}
@@ -210,9 +210,9 @@ namespace Grpc.Core.Internal
streamingResponseCallFinishedTcs = new TaskCompletionSource<object>();
using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers))
{
- call.StartDuplexStreaming(HandleFinished, metadataArray, details.Options.Flags);
+ call.StartDuplexStreaming(ReceivedStatusOnClientCallback, metadataArray, details.Options.Flags);
}
- call.StartReceiveInitialMetadata(HandleReceivedResponseHeaders);
+ call.StartReceiveInitialMetadata(ReceivedResponseHeadersCallback);
}
}
@@ -256,7 +256,7 @@ namespace Grpc.Core.Internal
halfcloseRequested = true;
return TaskUtils.CompletedTask;
}
- call.StartSendCloseFromClient(HandleSendFinished);
+ call.StartSendCloseFromClient(SendCompletionCallback);
halfcloseRequested = true;
streamingWriteTcs = new TaskCompletionSource<object>();
@@ -516,5 +516,26 @@ namespace Grpc.Core.Internal
streamingResponseCallFinishedTcs.SetResult(null);
}
+
+ IUnaryResponseClientCallback UnaryResponseClientCallback => this;
+
+ void IUnaryResponseClientCallback.OnUnaryResponseClient(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders)
+ {
+ HandleUnaryResponse(success, receivedStatus, receivedMessage, responseHeaders);
+ }
+
+ IReceivedStatusOnClientCallback ReceivedStatusOnClientCallback => this;
+
+ void IReceivedStatusOnClientCallback.OnReceivedStatusOnClient(bool success, ClientSideStatus receivedStatus)
+ {
+ HandleFinished(success, receivedStatus);
+ }
+
+ IReceivedResponseHeadersCallback ReceivedResponseHeadersCallback => this;
+
+ void IReceivedResponseHeadersCallback.OnReceivedResponseHeaders(bool success, Metadata responseHeaders)
+ {
+ HandleReceivedResponseHeaders(success, responseHeaders);
+ }
}
}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index f379c85e00..3273c26b88 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -35,7 +35,7 @@ namespace Grpc.Core.Internal
/// Base for handling both client side and server side calls.
/// Manages native call lifecycle and provides convenience methods.
/// </summary>
- internal abstract class AsyncCallBase<TWrite, TRead>
+ internal abstract class AsyncCallBase<TWrite, TRead> : IReceivedMessageCallback, ISendCompletionCallback
{
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<AsyncCallBase<TWrite, TRead>>();
protected static readonly Status DeserializeResponseFailureStatus = new Status(StatusCode.Internal, "Failed to deserialize response message.");
@@ -126,7 +126,7 @@ namespace Grpc.Core.Internal
return earlyResult;
}
- call.StartSendMessage(HandleSendFinished, payload, writeFlags, !initialMetadataSent);
+ call.StartSendMessage(SendCompletionCallback, payload, writeFlags, !initialMetadataSent);
initialMetadataSent = true;
streamingWritesCounter++;
@@ -154,7 +154,7 @@ namespace Grpc.Core.Internal
GrpcPreconditions.CheckState(streamingReadTcs == null, "Only one read can be pending at a time");
GrpcPreconditions.CheckState(!disposed);
- call.StartReceiveMessage(HandleReadFinished);
+ call.StartReceiveMessage(ReceivedMessageCallback);
streamingReadTcs = new TaskCompletionSource<TRead>();
return streamingReadTcs.Task;
}
@@ -342,5 +342,19 @@ namespace Grpc.Core.Internal
}
origTcs.SetResult(msg);
}
+
+ protected ISendCompletionCallback SendCompletionCallback => this;
+
+ void ISendCompletionCallback.OnSendCompletion(bool success)
+ {
+ HandleSendFinished(success);
+ }
+
+ IReceivedMessageCallback ReceivedMessageCallback => this;
+
+ void IReceivedMessageCallback.OnReceivedMessage(bool success, byte[] receivedMessage)
+ {
+ HandleReadFinished(success, receivedMessage);
+ }
}
}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index 271a6ffadf..11acb27533 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -31,7 +31,7 @@ namespace Grpc.Core.Internal
/// <summary>
/// Manages server side native call lifecycle.
/// </summary>
- internal class AsyncCallServer<TRequest, TResponse> : AsyncCallBase<TResponse, TRequest>
+ internal class AsyncCallServer<TRequest, TResponse> : AsyncCallBase<TResponse, TRequest>, IReceivedCloseOnServerCallback, ISendStatusFromServerCompletionCallback
{
readonly TaskCompletionSource<object> finishedServersideTcs = new TaskCompletionSource<object>();
readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
@@ -70,7 +70,7 @@ namespace Grpc.Core.Internal
started = true;
- call.StartServerSide(HandleFinishedServerside);
+ call.StartServerSide(ReceiveCloseOnServerCallback);
return finishedServersideTcs.Task;
}
}
@@ -114,7 +114,7 @@ namespace Grpc.Core.Internal
using (var metadataArray = MetadataArraySafeHandle.Create(headers))
{
- call.StartSendInitialMetadata(HandleSendFinished, metadataArray);
+ call.StartSendInitialMetadata(SendCompletionCallback, metadataArray);
}
this.initialMetadataSent = true;
@@ -127,10 +127,10 @@ namespace Grpc.Core.Internal
/// Sends call result status, indicating we are done with writes.
/// Sending a status different from StatusCode.OK will also implicitly cancel the call.
/// </summary>
- public Task SendStatusFromServerAsync(Status status, Metadata trailers, Tuple<TResponse, WriteFlags> optionalWrite)
+ public Task SendStatusFromServerAsync(Status status, Metadata trailers, ResponseWithFlags? optionalWrite)
{
- byte[] payload = optionalWrite != null ? UnsafeSerialize(optionalWrite.Item1) : null;
- var writeFlags = optionalWrite != null ? optionalWrite.Item2 : default(WriteFlags);
+ byte[] payload = optionalWrite.HasValue ? UnsafeSerialize(optionalWrite.Value.Response) : null;
+ var writeFlags = optionalWrite.HasValue ? optionalWrite.Value.WriteFlags : default(WriteFlags);
lock (myLock)
{
@@ -140,13 +140,13 @@ namespace Grpc.Core.Internal
using (var metadataArray = MetadataArraySafeHandle.Create(trailers))
{
- call.StartSendStatusFromServer(HandleSendStatusFromServerFinished, status, metadataArray, !initialMetadataSent,
+ call.StartSendStatusFromServer(SendStatusFromServerCompletionCallback, status, metadataArray, !initialMetadataSent,
payload, writeFlags);
}
halfcloseRequested = true;
initialMetadataSent = true;
sendStatusFromServerTcs = new TaskCompletionSource<object>();
- if (optionalWrite != null)
+ if (optionalWrite.HasValue)
{
streamingWritesCounter++;
}
@@ -227,5 +227,31 @@ namespace Grpc.Core.Internal
finishedServersideTcs.SetResult(null);
}
+
+ IReceivedCloseOnServerCallback ReceiveCloseOnServerCallback => this;
+
+ void IReceivedCloseOnServerCallback.OnReceivedCloseOnServer(bool success, bool cancelled)
+ {
+ HandleFinishedServerside(success, cancelled);
+ }
+
+ ISendStatusFromServerCompletionCallback SendStatusFromServerCompletionCallback => this;
+
+ void ISendStatusFromServerCompletionCallback.OnSendStatusFromServerCompletion(bool success)
+ {
+ HandleSendStatusFromServerFinished(success);
+ }
+
+ public struct ResponseWithFlags
+ {
+ public ResponseWithFlags(TResponse response, WriteFlags writeFlags)
+ {
+ this.Response = response;
+ this.WriteFlags = writeFlags;
+ }
+
+ public TResponse Response { get; }
+ public WriteFlags WriteFlags { get; }
+ }
}
}
diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
index cd5e3d8911..1e6f1fba37 100644
--- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
@@ -20,15 +20,25 @@ using System;
using System.Runtime.InteropServices;
using System.Text;
using Grpc.Core;
+using Grpc.Core.Logging;
+using Grpc.Core.Utils;
namespace Grpc.Core.Internal
{
+ internal interface IOpCompletionCallback
+ {
+ void OnComplete(bool success);
+ }
+
/// <summary>
/// grpcsharp_batch_context
/// </summary>
- internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid
+ internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback
{
static readonly NativeMethods Native = NativeMethods.Get();
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<BatchContextSafeHandle>();
+
+ CompletionCallbackData completionCallbackData;
private BatchContextSafeHandle()
{
@@ -47,19 +57,26 @@ namespace Grpc.Core.Internal
}
}
+ public void SetCompletionCallback(BatchCompletionDelegate callback, object state)
+ {
+ GrpcPreconditions.CheckState(completionCallbackData.Callback == null);
+ GrpcPreconditions.CheckNotNull(callback, nameof(callback));
+ completionCallbackData = new CompletionCallbackData(callback, state);
+ }
+
// Gets data of recv_initial_metadata completion.
public Metadata GetReceivedInitialMetadata()
{
IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_initial_metadata(this);
return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
}
-
+
// Gets data of recv_status_on_client completion.
public ClientSideStatus GetReceivedStatusOnClient()
{
UIntPtr detailsLength;
IntPtr detailsPtr = Native.grpcsharp_batch_context_recv_status_on_client_details(this, out detailsLength);
- string details = MarshalUtils.PtrToStringUTF8(detailsPtr, (int) detailsLength.ToUInt32());
+ string details = MarshalUtils.PtrToStringUTF8(detailsPtr, (int)detailsLength.ToUInt32());
var status = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details);
IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this);
@@ -86,11 +103,40 @@ namespace Grpc.Core.Internal
{
return Native.grpcsharp_batch_context_recv_close_on_server_cancelled(this) != 0;
}
-
+
protected override bool ReleaseHandle()
{
Native.grpcsharp_batch_context_destroy(handle);
return true;
}
+
+ void IOpCompletionCallback.OnComplete(bool success)
+ {
+ try
+ {
+ completionCallbackData.Callback(success, this, completionCallbackData.State);
+ }
+ catch (Exception e)
+ {
+ Logger.Error(e, "Exception occured while invoking batch completion delegate.");
+ }
+ finally
+ {
+ completionCallbackData = default(CompletionCallbackData);
+ Dispose();
+ }
+ }
+
+ struct CompletionCallbackData
+ {
+ public CompletionCallbackData(BatchCompletionDelegate callback, object state)
+ {
+ this.Callback = callback;
+ this.State = state;
+ }
+
+ public BatchCompletionDelegate Callback { get; }
+ public object State { get; }
+ }
}
}
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index 3a7f97707b..d6a5ba586b 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -32,6 +32,23 @@ namespace Grpc.Core.Internal
public static readonly CallSafeHandle NullInstance = new CallSafeHandle();
static readonly NativeMethods Native = NativeMethods.Get();
+ // Completion handlers are pre-allocated to avoid unneccessary delegate allocations.
+ // The "state" field is used to store the actual callback to invoke.
+ static readonly BatchCompletionDelegate CompletionHandler_IUnaryResponseClientCallback =
+ (success, context, state) => ((IUnaryResponseClientCallback)state).OnUnaryResponseClient(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata());
+ static readonly BatchCompletionDelegate CompletionHandler_IReceivedStatusOnClientCallback =
+ (success, context, state) => ((IReceivedStatusOnClientCallback)state).OnReceivedStatusOnClient(success, context.GetReceivedStatusOnClient());
+ static readonly BatchCompletionDelegate CompletionHandler_IReceivedMessageCallback =
+ (success, context, state) => ((IReceivedMessageCallback)state).OnReceivedMessage(success, context.GetReceivedMessage());
+ static readonly BatchCompletionDelegate CompletionHandler_IReceivedResponseHeadersCallback =
+ (success, context, state) => ((IReceivedResponseHeadersCallback)state).OnReceivedResponseHeaders(success, context.GetReceivedInitialMetadata());
+ static readonly BatchCompletionDelegate CompletionHandler_ISendCompletionCallback =
+ (success, context, state) => ((ISendCompletionCallback)state).OnSendCompletion(success);
+ static readonly BatchCompletionDelegate CompletionHandler_ISendStatusFromServerCompletionCallback =
+ (success, context, state) => ((ISendStatusFromServerCompletionCallback)state).OnSendStatusFromServerCompletion(success);
+ static readonly BatchCompletionDelegate CompletionHandler_IReceivedCloseOnServerCallback =
+ (success, context, state) => ((IReceivedCloseOnServerCallback)state).OnReceivedCloseOnServer(success, context.GetReceivedCloseOnServerCancelled());
+
const uint GRPC_WRITE_BUFFER_HINT = 1;
CompletionQueueSafeHandle completionQueue;
@@ -49,12 +66,12 @@ namespace Grpc.Core.Internal
Native.grpcsharp_call_set_credentials(this, credentials).CheckOk();
}
- public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
+ public void StartUnary(IUnaryResponseClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
- completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
+ completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IUnaryResponseClientCallback, callback);
Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, metadataArray, callFlags)
.CheckOk();
}
@@ -66,106 +83,106 @@ namespace Grpc.Core.Internal
.CheckOk();
}
- public void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
+ public void StartClientStreaming(IUnaryResponseClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
- completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
+ completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IUnaryResponseClientCallback, callback);
Native.grpcsharp_call_start_client_streaming(this, ctx, metadataArray, callFlags).CheckOk();
}
}
- public void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
+ public void StartServerStreaming(IReceivedStatusOnClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
- completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
+ completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IReceivedStatusOnClientCallback, callback);
Native.grpcsharp_call_start_server_streaming(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, metadataArray, callFlags).CheckOk();
}
}
- public void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
+ public void StartDuplexStreaming(IReceivedStatusOnClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
- completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
+ completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IReceivedStatusOnClientCallback, callback);
Native.grpcsharp_call_start_duplex_streaming(this, ctx, metadataArray, callFlags).CheckOk();
}
}
- public void StartSendMessage(SendCompletionHandler callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata)
+ public void StartSendMessage(ISendCompletionCallback callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
- completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
+ completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_ISendCompletionCallback, callback);
Native.grpcsharp_call_send_message(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, sendEmptyInitialMetadata ? 1 : 0).CheckOk();
}
}
- public void StartSendCloseFromClient(SendCompletionHandler callback)
+ public void StartSendCloseFromClient(ISendCompletionCallback callback)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
- completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
+ completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_ISendCompletionCallback, callback);
Native.grpcsharp_call_send_close_from_client(this, ctx).CheckOk();
}
}
- public void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
+ public void StartSendStatusFromServer(ISendStatusFromServerCompletionCallback callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
byte[] optionalPayload, WriteFlags writeFlags)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero;
- completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
+ completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_ISendStatusFromServerCompletionCallback, callback);
var statusDetailBytes = MarshalUtils.GetBytesUTF8(status.Detail);
Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, statusDetailBytes, new UIntPtr((ulong)statusDetailBytes.Length), metadataArray, sendEmptyInitialMetadata ? 1 : 0,
optionalPayload, optionalPayloadLength, writeFlags).CheckOk();
}
}
- public void StartReceiveMessage(ReceivedMessageHandler callback)
+ public void StartReceiveMessage(IReceivedMessageCallback callback)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
- completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedMessage()));
+ completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IReceivedMessageCallback, callback);
Native.grpcsharp_call_recv_message(this, ctx).CheckOk();
}
}
- public void StartReceiveInitialMetadata(ReceivedResponseHeadersHandler callback)
+ public void StartReceiveInitialMetadata(IReceivedResponseHeadersCallback callback)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
- completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedInitialMetadata()));
+ completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IReceivedResponseHeadersCallback, callback);
Native.grpcsharp_call_recv_initial_metadata(this, ctx).CheckOk();
}
}
- public void StartServerSide(ReceivedCloseOnServerHandler callback)
+ public void StartServerSide(IReceivedCloseOnServerCallback callback)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
- completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedCloseOnServerCancelled()));
+ completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IReceivedCloseOnServerCallback, callback);
Native.grpcsharp_call_start_serverside(this, ctx).CheckOk();
}
}
- public void StartSendInitialMetadata(SendCompletionHandler callback, MetadataArraySafeHandle metadataArray)
+ public void StartSendInitialMetadata(ISendCompletionCallback callback, MetadataArraySafeHandle metadataArray)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
- completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
+ completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_ISendCompletionCallback, callback);
Native.grpcsharp_call_send_initial_metadata(this, ctx, metadataArray).CheckOk();
}
}
diff --git a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
index f826a17bad..1eeb0e3d97 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
@@ -64,10 +64,10 @@ namespace Grpc.Core.Internal
return Native.grpcsharp_channel_check_connectivity_state(this, tryToConnect ? 1 : 0);
}
- public void WatchConnectivityState(ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchCompletionDelegate callback)
+ public void WatchConnectivityState(ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchCompletionDelegate callback, object callbackState)
{
var ctx = BatchContextSafeHandle.Create();
- cq.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
+ cq.CompletionRegistry.RegisterBatchCompletion(ctx, callback, callbackState);
Native.grpcsharp_channel_watch_connectivity_state(this, lastObservedState, deadline, cq, ctx);
}
diff --git a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
index 3ce08e9a75..b68655b33c 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
@@ -19,15 +19,15 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Runtime.InteropServices;
+using System.Threading;
using Grpc.Core.Logging;
using Grpc.Core.Utils;
namespace Grpc.Core.Internal
{
- internal delegate void OpCompletionDelegate(bool success);
-
- internal delegate void BatchCompletionDelegate(bool success, BatchContextSafeHandle ctx);
+ internal delegate void BatchCompletionDelegate(bool success, BatchContextSafeHandle ctx, object state);
internal delegate void RequestCallCompletionDelegate(bool success, RequestCallContextSafeHandle ctx);
@@ -36,7 +36,8 @@ namespace Grpc.Core.Internal
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<CompletionRegistry>();
readonly GrpcEnvironment environment;
- readonly ConcurrentDictionary<IntPtr, OpCompletionDelegate> dict = new ConcurrentDictionary<IntPtr, OpCompletionDelegate>(new IntPtrComparer());
+ readonly Dictionary<IntPtr, IOpCompletionCallback> dict = new Dictionary<IntPtr, IOpCompletionCallback>(new IntPtrComparer());
+ SpinLock spinLock = new SpinLock(Debugger.IsAttached);
IntPtr lastRegisteredKey; // only for testing
public CompletionRegistry(GrpcEnvironment environment)
@@ -44,77 +45,61 @@ namespace Grpc.Core.Internal
this.environment = environment;
}
- public void Register(IntPtr key, OpCompletionDelegate callback)
+ public void Register(IntPtr key, IOpCompletionCallback callback)
{
environment.DebugStats.PendingBatchCompletions.Increment();
- GrpcPreconditions.CheckState(dict.TryAdd(key, callback));
- this.lastRegisteredKey = key;
- }
- public void RegisterBatchCompletion(BatchContextSafeHandle ctx, BatchCompletionDelegate callback)
- {
- OpCompletionDelegate opCallback = ((success) => HandleBatchCompletion(success, ctx, callback));
- Register(ctx.Handle, opCallback);
- }
+ bool lockTaken = false;
+ try
+ {
+ spinLock.Enter(ref lockTaken);
- public void RegisterRequestCallCompletion(RequestCallContextSafeHandle ctx, RequestCallCompletionDelegate callback)
- {
- OpCompletionDelegate opCallback = ((success) => HandleRequestCallCompletion(success, ctx, callback));
- Register(ctx.Handle, opCallback);
+ dict.Add(key, callback);
+ this.lastRegisteredKey = key;
+ }
+ finally
+ {
+ if (lockTaken) spinLock.Exit();
+ }
}
- public OpCompletionDelegate Extract(IntPtr key)
+ public void RegisterBatchCompletion(BatchContextSafeHandle ctx, BatchCompletionDelegate callback, object state)
{
- OpCompletionDelegate value;
- GrpcPreconditions.CheckState(dict.TryRemove(key, out value));
- environment.DebugStats.PendingBatchCompletions.Decrement();
- return value;
+ ctx.SetCompletionCallback(callback, state);
+ Register(ctx.Handle, ctx);
}
- /// <summary>
- /// For testing purposes only.
- /// </summary>
- public IntPtr LastRegisteredKey
+ public void RegisterRequestCallCompletion(RequestCallContextSafeHandle ctx, RequestCallCompletionDelegate callback)
{
- get { return this.lastRegisteredKey; }
+ ctx.CompletionCallback = callback;
+ Register(ctx.Handle, ctx);
}
- private static void HandleBatchCompletion(bool success, BatchContextSafeHandle ctx, BatchCompletionDelegate callback)
+ public IOpCompletionCallback Extract(IntPtr key)
{
+ IOpCompletionCallback value = null;
+ bool lockTaken = false;
try
{
- callback(success, ctx);
- }
- catch (Exception e)
- {
- Logger.Error(e, "Exception occured while invoking batch completion delegate.");
+ spinLock.Enter(ref lockTaken);
+
+ value = dict[key];
+ dict.Remove(key);
}
finally
{
- if (ctx != null)
- {
- ctx.Dispose();
- }
+ if (lockTaken) spinLock.Exit();
}
+ environment.DebugStats.PendingBatchCompletions.Decrement();
+ return value;
}
- private static void HandleRequestCallCompletion(bool success, RequestCallContextSafeHandle ctx, RequestCallCompletionDelegate callback)
+ /// <summary>
+ /// For testing purposes only. NOT threadsafe.
+ /// </summary>
+ public IntPtr LastRegisteredKey
{
- try
- {
- callback(success, ctx);
- }
- catch (Exception e)
- {
- Logger.Error(e, "Exception occured while invoking request call completion delegate.");
- }
- finally
- {
- if (ctx != null)
- {
- ctx.Dispose();
- }
- }
+ get { return this.lastRegisteredKey; }
}
/// <summary>
diff --git a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
index 3c94b602c0..bd0229a9dd 100644
--- a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
+++ b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
@@ -68,8 +68,8 @@ namespace Grpc.Core.Internal
GrpcPreconditions.CheckArgument(poolSize >= completionQueueCount,
"Thread pool size cannot be smaller than the number of completion queues used.");
- this.runCompletionQueueEventCallbackSuccess = new WaitCallback((callback) => RunCompletionQueueEventCallback((OpCompletionDelegate) callback, true));
- this.runCompletionQueueEventCallbackFailure = new WaitCallback((callback) => RunCompletionQueueEventCallback((OpCompletionDelegate) callback, false));
+ this.runCompletionQueueEventCallbackSuccess = new WaitCallback((callback) => RunCompletionQueueEventCallback((IOpCompletionCallback) callback, true));
+ this.runCompletionQueueEventCallbackFailure = new WaitCallback((callback) => RunCompletionQueueEventCallback((IOpCompletionCallback) callback, false));
}
public void Start()
@@ -176,10 +176,10 @@ namespace Grpc.Core.Internal
try
{
var callback = cq.CompletionRegistry.Extract(tag);
- // Use cached delegates to avoid unnecessary allocations
+ queuedContinuationCounter.Increment();
if (!inlineHandlers)
{
- queuedContinuationCounter.Increment();
+ // Use cached delegates to avoid unnecessary allocations
ThreadPool.QueueUserWorkItem(success ? runCompletionQueueEventCallbackSuccess : runCompletionQueueEventCallbackFailure, callback);
}
else
@@ -225,11 +225,11 @@ namespace Grpc.Core.Internal
return list.AsReadOnly();
}
- private void RunCompletionQueueEventCallback(OpCompletionDelegate callback, bool success)
+ private void RunCompletionQueueEventCallback(IOpCompletionCallback callback, bool success)
{
try
{
- callback(success);
+ callback.OnComplete(success);
}
catch (Exception e)
{
diff --git a/src/csharp/Grpc.Core/Internal/INativeCall.cs b/src/csharp/Grpc.Core/Internal/INativeCall.cs
index f9c06583c8..5c35b2ba46 100644
--- a/src/csharp/Grpc.Core/Internal/INativeCall.cs
+++ b/src/csharp/Grpc.Core/Internal/INativeCall.cs
@@ -20,18 +20,41 @@ using Grpc.Core;
namespace Grpc.Core.Internal
{
- internal delegate void UnaryResponseClientHandler(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders);
+ internal interface IUnaryResponseClientCallback
+ {
+ void OnUnaryResponseClient(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders);
+ }
// Received status for streaming response calls.
- internal delegate void ReceivedStatusOnClientHandler(bool success, ClientSideStatus receivedStatus);
+ internal interface IReceivedStatusOnClientCallback
+ {
+ void OnReceivedStatusOnClient(bool success, ClientSideStatus receivedStatus);
+ }
- internal delegate void ReceivedMessageHandler(bool success, byte[] receivedMessage);
+ internal interface IReceivedMessageCallback
+ {
+ void OnReceivedMessage(bool success, byte[] receivedMessage);
+ }
- internal delegate void ReceivedResponseHeadersHandler(bool success, Metadata responseHeaders);
+ internal interface IReceivedResponseHeadersCallback
+ {
+ void OnReceivedResponseHeaders(bool success, Metadata responseHeaders);
+ }
- internal delegate void SendCompletionHandler(bool success);
+ internal interface ISendCompletionCallback
+ {
+ void OnSendCompletion(bool success);
+ }
- internal delegate void ReceivedCloseOnServerHandler(bool success, bool cancelled);
+ internal interface ISendStatusFromServerCompletionCallback
+ {
+ void OnSendStatusFromServerCompletion(bool success);
+ }
+
+ internal interface IReceivedCloseOnServerCallback
+ {
+ void OnReceivedCloseOnServer(bool success, bool cancelled);
+ }
/// <summary>
/// Abstraction of a native call object.
@@ -44,28 +67,28 @@ namespace Grpc.Core.Internal
string GetPeer();
- void StartUnary(UnaryResponseClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
+ void StartUnary(IUnaryResponseClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
void StartUnary(BatchContextSafeHandle ctx, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
- void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
+ void StartClientStreaming(IUnaryResponseClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
- void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
+ void StartServerStreaming(IReceivedStatusOnClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
- void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
+ void StartDuplexStreaming(IReceivedStatusOnClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags);
- void StartReceiveMessage(ReceivedMessageHandler callback);
+ void StartReceiveMessage(IReceivedMessageCallback callback);
- void StartReceiveInitialMetadata(ReceivedResponseHeadersHandler callback);
+ void StartReceiveInitialMetadata(IReceivedResponseHeadersCallback callback);
- void StartSendInitialMetadata(SendCompletionHandler callback, MetadataArraySafeHandle metadataArray);
+ void StartSendInitialMetadata(ISendCompletionCallback callback, MetadataArraySafeHandle metadataArray);
- void StartSendMessage(SendCompletionHandler callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
+ void StartSendMessage(ISendCompletionCallback callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
- void StartSendCloseFromClient(SendCompletionHandler callback);
+ void StartSendCloseFromClient(ISendCompletionCallback callback);
- void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, byte[] optionalPayload, WriteFlags writeFlags);
+ void StartSendStatusFromServer(ISendStatusFromServerCompletionCallback callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, byte[] optionalPayload, WriteFlags writeFlags);
- void StartServerSide(ReceivedCloseOnServerHandler callback);
+ void StartServerSide(IReceivedCloseOnServerCallback callback);
}
}
diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
index 22faa19d9b..d517252cfe 100644
--- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
@@ -29,6 +29,8 @@ using Grpc.Core.Utils;
namespace Grpc.Core.Internal
{
+ internal delegate void NativeCallbackTestDelegate(bool success);
+
/// <summary>
/// Provides access to all native methods provided by <c>NativeExtension</c>.
/// An extra level of indirection is added to P/Invoke calls to allow intelligent loading
@@ -420,7 +422,7 @@ namespace Grpc.Core.Internal
public delegate Timespec gprsharp_convert_clock_type_delegate(Timespec t, ClockType targetClock);
public delegate int gprsharp_sizeof_timespec_delegate();
- public delegate CallError grpcsharp_test_callback_delegate([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback);
+ public delegate CallError grpcsharp_test_callback_delegate([MarshalAs(UnmanagedType.FunctionPtr)] NativeCallbackTestDelegate callback);
public delegate IntPtr grpcsharp_test_nop_delegate(IntPtr ptr);
public delegate void grpcsharp_test_override_method_delegate(string methodName, string variant);
}
diff --git a/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs
index b7af0c102d..09f5c3e452 100644
--- a/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs
@@ -19,15 +19,17 @@
using System;
using System.Runtime.InteropServices;
using Grpc.Core;
+using Grpc.Core.Logging;
namespace Grpc.Core.Internal
{
/// <summary>
/// grpcsharp_request_call_context
/// </summary>
- internal class RequestCallContextSafeHandle : SafeHandleZeroIsInvalid
+ internal class RequestCallContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback
{
static readonly NativeMethods Native = NativeMethods.Get();
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<RequestCallContextSafeHandle>();
private RequestCallContextSafeHandle()
{
@@ -46,6 +48,8 @@ namespace Grpc.Core.Internal
}
}
+ public RequestCallCompletionDelegate CompletionCallback { get; set; }
+
// Gets data of server_rpc_new completion.
public ServerRpcNew GetServerRpcNew(Server server)
{
@@ -72,5 +76,22 @@ namespace Grpc.Core.Internal
Native.grpcsharp_request_call_context_destroy(handle);
return true;
}
+
+ void IOpCompletionCallback.OnComplete(bool success)
+ {
+ try
+ {
+ CompletionCallback(success, this);
+ }
+ catch (Exception e)
+ {
+ Logger.Error(e, "Exception occured while invoking request call completion delegate.");
+ }
+ finally
+ {
+ CompletionCallback = null;
+ Dispose();
+ }
+ }
}
}
diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
index 6019f8e793..98995a0862 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
@@ -60,7 +60,7 @@ namespace Grpc.Core.Internal
var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall);
Status status;
- Tuple<TResponse,WriteFlags> responseTuple = null;
+ AsyncCallServer<TRequest,TResponse>.ResponseWithFlags? responseWithFlags = null;
var context = HandlerUtils.NewContext(newRpc, responseStream, asyncCall.CancellationToken);
try
{
@@ -68,7 +68,7 @@ namespace Grpc.Core.Internal
var request = requestStream.Current;
var response = await handler(request, context).ConfigureAwait(false);
status = context.Status;
- responseTuple = Tuple.Create(response, HandlerUtils.GetWriteFlags(context.WriteOptions));
+ responseWithFlags = new AsyncCallServer<TRequest, TResponse>.ResponseWithFlags(response, HandlerUtils.GetWriteFlags(context.WriteOptions));
}
catch (Exception e)
{
@@ -80,7 +80,7 @@ namespace Grpc.Core.Internal
}
try
{
- await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, responseTuple).ConfigureAwait(false);
+ await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, responseWithFlags).ConfigureAwait(false);
}
catch (Exception)
{
@@ -177,13 +177,13 @@ namespace Grpc.Core.Internal
var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall);
Status status;
- Tuple<TResponse,WriteFlags> responseTuple = null;
+ AsyncCallServer<TRequest, TResponse>.ResponseWithFlags? responseWithFlags = null;
var context = HandlerUtils.NewContext(newRpc, responseStream, asyncCall.CancellationToken);
try
{
var response = await handler(requestStream, context).ConfigureAwait(false);
status = context.Status;
- responseTuple = Tuple.Create(response, HandlerUtils.GetWriteFlags(context.WriteOptions));
+ responseWithFlags = new AsyncCallServer<TRequest, TResponse>.ResponseWithFlags(response, HandlerUtils.GetWriteFlags(context.WriteOptions));
}
catch (Exception e)
{
@@ -196,7 +196,7 @@ namespace Grpc.Core.Internal
try
{
- await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, responseTuple).ConfigureAwait(false);
+ await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, responseWithFlags).ConfigureAwait(false);
}
catch (Exception)
{
diff --git a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
index 63000e9a22..a308890cde 100644
--- a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
@@ -59,13 +59,15 @@ namespace Grpc.Core.Internal
{
Native.grpcsharp_server_start(this);
}
-
+
public void ShutdownAndNotify(BatchCompletionDelegate callback, CompletionQueueSafeHandle completionQueue)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
- completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
+ // TODO(jtattermusch): delegate allocation by caller can be avoided by utilizing the "state" object,
+ // but server shutdown isn't worth optimizing right now.
+ completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, callback, null);
Native.grpcsharp_server_shutdown_and_notify_callback(this, completionQueue, ctx);
}
}
diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs
index 77ad876bdf..71c7f108f3 100644
--- a/src/csharp/Grpc.Core/Server.cs
+++ b/src/csharp/Grpc.Core/Server.cs
@@ -387,7 +387,7 @@ namespace Grpc.Core
/// <summary>
/// Handles native callback.
/// </summary>
- private void HandleServerShutdown(bool success, BatchContextSafeHandle ctx)
+ private void HandleServerShutdown(bool success, BatchContextSafeHandle ctx, object state)
{
shutdownTcs.SetResult(null);
}
diff --git a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
index 60696b62d9..48905a2715 100644
--- a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
@@ -72,7 +72,7 @@ namespace Grpc.IntegrationTesting
Logger.Warning("ClientConfig.CoreList is not supported for C#. Ignoring the value");
}
- var channels = CreateChannels(config.ClientChannels, config.ServerTargets, config.SecurityParams);
+ var channels = CreateChannels(config.ClientChannels, config.ServerTargets, config.SecurityParams, config.ChannelArgs);
return new ClientRunnerImpl(channels,
config.ClientType,
@@ -84,19 +84,20 @@ namespace Grpc.IntegrationTesting
() => GetNextProfiler());
}
- private static List<Channel> CreateChannels(int clientChannels, IEnumerable<string> serverTargets, SecurityParams securityParams)
+ private static List<Channel> CreateChannels(int clientChannels, IEnumerable<string> serverTargets, SecurityParams securityParams, IEnumerable<ChannelArg> channelArguments)
{
GrpcPreconditions.CheckArgument(clientChannels > 0, "clientChannels needs to be at least 1.");
GrpcPreconditions.CheckArgument(serverTargets.Count() > 0, "at least one serverTarget needs to be specified.");
var credentials = securityParams != null ? TestCredentials.CreateSslCredentials() : ChannelCredentials.Insecure;
- List<ChannelOption> channelOptions = null;
+ var channelOptions = new List<ChannelOption>();
if (securityParams != null && securityParams.ServerHostOverride != "")
{
- channelOptions = new List<ChannelOption>
- {
- new ChannelOption(ChannelOptions.SslTargetNameOverride, securityParams.ServerHostOverride)
- };
+ channelOptions.Add(new ChannelOption(ChannelOptions.SslTargetNameOverride, securityParams.ServerHostOverride));
+ }
+ foreach (var channelArgument in channelArguments)
+ {
+ channelOptions.Add(channelArgument.ToChannelOption());
}
var result = new List<Channel>();
diff --git a/src/csharp/Grpc.IntegrationTesting/ControlExtensions.cs b/src/csharp/Grpc.IntegrationTesting/ControlExtensions.cs
new file mode 100644
index 0000000000..67f5faed20
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/ControlExtensions.cs
@@ -0,0 +1,43 @@
+#region Copyright notice and license
+
+// Copyright 2016 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using Grpc.Core;
+using Grpc.Testing;
+
+namespace Grpc.IntegrationTesting
+{
+ /// <summary>
+ /// Helpers for Control.cs
+ /// </summary>
+ public static class ControlExtensions
+ {
+ public static ChannelOption ToChannelOption(this ChannelArg channelArgument)
+ {
+ switch (channelArgument.ValueCase)
+ {
+ case ChannelArg.ValueOneofCase.StrValue:
+ return new ChannelOption(channelArgument.Name, channelArgument.StrValue);
+ case ChannelArg.ValueOneofCase.IntValue:
+ return new ChannelOption(channelArgument.Name, channelArgument.IntValue);
+ default:
+ throw new ArgumentException("Unsupported channel argument value.");
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs b/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
index 45bff3aaf8..e1b47744d5 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
@@ -78,7 +78,8 @@ namespace Grpc.IntegrationTesting
throw new ArgumentException("Unsupported ServerType");
}
- var server = new Server
+ var channelOptions = new List<ChannelOption>(config.ChannelArgs.Select((arg) => arg.ToChannelOption()));
+ var server = new Server(channelOptions)
{
Services = { service },
Ports = { new ServerPort("[::]", config.Port, credentials) }
diff --git a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs
new file mode 100644
index 0000000000..2d1c33e9a0
--- /dev/null
+++ b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs
@@ -0,0 +1,78 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Grpc.Microbenchmarks
+{
+ public class CompletionRegistryBenchmark
+ {
+ GrpcEnvironment environment;
+
+ public void Init()
+ {
+ environment = GrpcEnvironment.AddRef();
+ }
+
+ public void Cleanup()
+ {
+ GrpcEnvironment.ReleaseAsync().Wait();
+ }
+
+ public void Run(int threadCount, int iterations, bool useSharedRegistry)
+ {
+ Console.WriteLine(string.Format("CompletionRegistryBenchmark: threads={0}, iterations={1}, useSharedRegistry={2}", threadCount, iterations, useSharedRegistry));
+ CompletionRegistry sharedRegistry = useSharedRegistry ? new CompletionRegistry(environment) : null;
+ var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, sharedRegistry));
+ threadedBenchmark.Run();
+ // TODO: parametrize by number of pending completions
+ }
+
+ private void ThreadBody(int iterations, CompletionRegistry optionalSharedRegistry)
+ {
+ var completionRegistry = optionalSharedRegistry ?? new CompletionRegistry(environment);
+ var ctx = BatchContextSafeHandle.Create();
+
+ var stopwatch = Stopwatch.StartNew();
+ for (int i = 0; i < iterations; i++)
+ {
+ completionRegistry.Register(ctx.Handle, ctx);
+ var callback = completionRegistry.Extract(ctx.Handle);
+ // NOTE: we are not calling the callback to avoid disposing ctx.
+ }
+ stopwatch.Stop();
+ Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds);
+
+ ctx.Dispose();
+ }
+
+ private class NopCompletionCallback : IOpCompletionCallback
+ {
+ public void OnComplete(bool success)
+ {
+
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Microbenchmarks/GCStats.cs b/src/csharp/Grpc.Microbenchmarks/GCStats.cs
new file mode 100644
index 0000000000..ca7051ec4e
--- /dev/null
+++ b/src/csharp/Grpc.Microbenchmarks/GCStats.cs
@@ -0,0 +1,69 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using Grpc.Core;
+using Grpc.Core.Internal;
+
+namespace Grpc.Microbenchmarks
+{
+ internal class GCStats
+ {
+ readonly object myLock = new object();
+ GCStatsSnapshot lastSnapshot;
+
+ public GCStats()
+ {
+ lastSnapshot = new GCStatsSnapshot(GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2));
+ }
+
+ public GCStatsSnapshot GetSnapshot(bool reset = false)
+ {
+ lock (myLock)
+ {
+ var newSnapshot = new GCStatsSnapshot(GC.CollectionCount(0) - lastSnapshot.Gen0,
+ GC.CollectionCount(1) - lastSnapshot.Gen1,
+ GC.CollectionCount(2) - lastSnapshot.Gen2);
+ if (reset)
+ {
+ lastSnapshot = newSnapshot;
+ }
+ return newSnapshot;
+ }
+ }
+ }
+
+ public class GCStatsSnapshot
+ {
+ public GCStatsSnapshot(int gen0, int gen1, int gen2)
+ {
+ this.Gen0 = gen0;
+ this.Gen1 = gen1;
+ this.Gen2 = gen2;
+ }
+
+ public int Gen0 { get; }
+ public int Gen1 { get; }
+ public int Gen2 { get; }
+
+ public override string ToString()
+ {
+ return string.Format("[GCCollectionCount: gen0 {0}, gen1 {1}, gen2 {2}]", Gen0, Gen1, Gen2);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj
index 108357e4eb..8a629f9748 100644
--- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj
+++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj
@@ -15,6 +15,10 @@
<ProjectReference Include="../Grpc.Core/Grpc.Core.csproj" />
</ItemGroup>
+ <ItemGroup>
+ <PackageReference Include="CommandLineParser" Version="2.1.1-beta" />
+ </ItemGroup>
+
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
diff --git a/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs
new file mode 100644
index 0000000000..787b5508fb
--- /dev/null
+++ b/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs
@@ -0,0 +1,64 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Grpc.Microbenchmarks
+{
+ public class PInvokeByteArrayBenchmark
+ {
+ static readonly NativeMethods Native = NativeMethods.Get();
+
+ public void Init()
+ {
+ }
+
+ public void Cleanup()
+ {
+ }
+
+ public void Run(int threadCount, int iterations, int payloadSize)
+ {
+ Console.WriteLine(string.Format("PInvokeByteArrayBenchmark: threads={0}, iterations={1}, payloadSize={2}", threadCount, iterations, payloadSize));
+ var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, payloadSize));
+ threadedBenchmark.Run();
+ }
+
+ private void ThreadBody(int iterations, int payloadSize)
+ {
+ var payload = new byte[payloadSize];
+
+ var stopwatch = Stopwatch.StartNew();
+ for (int i = 0; i < iterations; i++)
+ {
+ var gcHandle = GCHandle.Alloc(payload, GCHandleType.Pinned);
+ var payloadPtr = gcHandle.AddrOfPinnedObject();
+ Native.grpcsharp_test_nop(payloadPtr);
+ gcHandle.Free();
+ }
+ stopwatch.Stop();
+ Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Microbenchmarks/Program.cs b/src/csharp/Grpc.Microbenchmarks/Program.cs
index d07d4187c4..a64c2979ab 100644
--- a/src/csharp/Grpc.Microbenchmarks/Program.cs
+++ b/src/csharp/Grpc.Microbenchmarks/Program.cs
@@ -20,14 +20,84 @@ using System;
using Grpc.Core;
using Grpc.Core.Internal;
using Grpc.Core.Logging;
+using CommandLine;
+using CommandLine.Text;
namespace Grpc.Microbenchmarks
{
class Program
{
+ public enum MicrobenchmarkType
+ {
+ CompletionRegistry,
+ PInvokeByteArray,
+ SendMessage
+ }
+
+ private class BenchmarkOptions
+ {
+ [Option("benchmark", Required = true, HelpText = "Benchmark to run")]
+ public MicrobenchmarkType Benchmark { get; set; }
+ }
+
public static void Main(string[] args)
{
GrpcEnvironment.SetLogger(new ConsoleLogger());
+ var parserResult = Parser.Default.ParseArguments<BenchmarkOptions>(args)
+ .WithNotParsed(errors => {
+ Console.WriteLine("Supported benchmarks:");
+ foreach (var enumValue in Enum.GetValues(typeof(MicrobenchmarkType)))
+ {
+ Console.WriteLine(" " + enumValue);
+ }
+ Environment.Exit(1);
+ })
+ .WithParsed(options =>
+ {
+ switch (options.Benchmark)
+ {
+ case MicrobenchmarkType.CompletionRegistry:
+ RunCompletionRegistryBenchmark();
+ break;
+ case MicrobenchmarkType.PInvokeByteArray:
+ RunPInvokeByteArrayBenchmark();
+ break;
+ case MicrobenchmarkType.SendMessage:
+ RunSendMessageBenchmark();
+ break;
+ default:
+ throw new ArgumentException("Unsupported benchmark.");
+ }
+ });
+ }
+
+ static void RunCompletionRegistryBenchmark()
+ {
+ var benchmark = new CompletionRegistryBenchmark();
+ benchmark.Init();
+ foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12})
+ {
+ foreach (bool useSharedRegistry in new bool[] {false, true})
+ {
+ benchmark.Run(threadCount, 4 * 1000 * 1000, useSharedRegistry);
+ }
+ }
+ benchmark.Cleanup();
+ }
+
+ static void RunPInvokeByteArrayBenchmark()
+ {
+ var benchmark = new PInvokeByteArrayBenchmark();
+ benchmark.Init();
+ foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12})
+ {
+ benchmark.Run(threadCount, 4 * 1000 * 1000, 0);
+ }
+ benchmark.Cleanup();
+ }
+
+ static void RunSendMessageBenchmark()
+ {
var benchmark = new SendMessageBenchmark();
benchmark.Init();
foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12})
diff --git a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs
index de67874580..9cff97eb88 100644
--- a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs
+++ b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs
@@ -59,16 +59,16 @@ namespace Grpc.Microbenchmarks
var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry);
var call = CreateFakeCall(cq);
- var sendCompletionHandler = new SendCompletionHandler((success) => { });
+ var sendCompletionCallback = new NopSendCompletionCallback();
var payload = new byte[payloadSize];
var writeFlags = default(WriteFlags);
var stopwatch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
- call.StartSendMessage(sendCompletionHandler, payload, writeFlags, false);
+ call.StartSendMessage(sendCompletionCallback, payload, writeFlags, false);
var callback = completionRegistry.Extract(completionRegistry.LastRegisteredKey);
- callback(true);
+ callback.OnComplete(true);
}
stopwatch.Stop();
Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds);
@@ -87,5 +87,13 @@ namespace Grpc.Microbenchmarks
}
return call;
}
+
+ private class NopSendCompletionCallback : ISendCompletionCallback
+ {
+ public void OnSendCompletion(bool success)
+ {
+ // NOP
+ }
+ }
}
}
diff --git a/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs
index feac8d1690..95b9aaaf3f 100644
--- a/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs
+++ b/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs
@@ -46,6 +46,7 @@ namespace Grpc.Microbenchmarks
public void Run()
{
Console.WriteLine("Running threads.");
+ var gcStats = new GCStats();
var threads = new List<Thread>();
for (int i = 0; i < runners.Count; i++)
{
@@ -58,7 +59,7 @@ namespace Grpc.Microbenchmarks
{
thread.Join();
}
- Console.WriteLine("All threads finished.");
+ Console.WriteLine("All threads finished (GC Stats Delta: " + gcStats.GetSnapshot() + ")");
}
}
}
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index c9f9ac27d9..558ce42129 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -424,6 +424,21 @@ class ServerCredentials(object):
self._credentials = credentials
+class ServerCertificateConfiguration(object):
+ """A certificate configuration for use with an SSL-enabled Server.
+
+ Instances of this class can be returned in the certificate configuration
+ fetching callback.
+
+ This class has no supported interface -- it exists to define the
+ type of its instances and its instances exist to be passed to
+ other functions.
+ """
+
+ def __init__(self, certificate_configuration):
+ self._certificate_configuration = certificate_configuration
+
+
######################## Multi-Callable Interfaces ###########################
@@ -1252,6 +1267,61 @@ def ssl_server_credentials(private_key_certificate_chain_pairs,
], require_client_auth))
+def ssl_server_certificate_configuration(private_key_certificate_chain_pairs,
+ root_certificates=None):
+ """Creates a ServerCertificateConfiguration for use with a Server.
+
+ Args:
+ private_key_certificate_chain_pairs: A collection of pairs of
+ the form [PEM-encoded private key, PEM-encoded certificate
+ chain].
+ root_certificates: An optional byte string of PEM-encoded client root
+ certificates that the server will use to verify client authentication.
+
+ Returns:
+ A ServerCertificateConfiguration that can be returned in the certificate
+ configuration fetching callback.
+ """
+ if len(private_key_certificate_chain_pairs) == 0:
+ raise ValueError(
+ 'At least one private key-certificate chain pair is required!')
+ else:
+ return ServerCertificateConfiguration(
+ _cygrpc.server_certificate_config_ssl(root_certificates, [
+ _cygrpc.SslPemKeyCertPair(key, pem)
+ for key, pem in private_key_certificate_chain_pairs
+ ]))
+
+
+def dynamic_ssl_server_credentials(initial_certificate_configuration,
+ certificate_configuration_fetcher,
+ require_client_authentication=False):
+ """Creates a ServerCredentials for use with an SSL-enabled Server.
+
+ Args:
+ initial_certificate_configuration (ServerCertificateConfiguration): The
+ certificate configuration with which the server will be initialized.
+ certificate_configuration_fetcher (callable): A callable that takes no
+ arguments and should return a ServerCertificateConfiguration to
+ replace the server's current certificate, or None for no change
+ (i.e., the server will continue its current certificate
+ config). The library will call this callback on *every* new
+ client connection before starting the TLS handshake with the
+ client, thus allowing the user application to optionally
+ return a new ServerCertificateConfiguration that the server will then
+ use for the handshake.
+ require_client_authentication: A boolean indicating whether or not to
+ require clients to be authenticated.
+
+ Returns:
+ A ServerCredentials.
+ """
+ return ServerCredentials(
+ _cygrpc.server_credentials_ssl_dynamic_cert_config(
+ initial_certificate_configuration,
+ certificate_configuration_fetcher, require_client_authentication))
+
+
def channel_ready_future(channel):
"""Creates a Future that tracks when a Channel is ready.
@@ -1334,7 +1404,8 @@ __all__ = ('FutureTimeoutError', 'FutureCancelledError', 'Future',
'ChannelConnectivity', 'StatusCode', 'RpcError', 'RpcContext',
'Call', 'ChannelCredentials', 'CallCredentials',
'AuthMetadataContext', 'AuthMetadataPluginCallback',
- 'AuthMetadataPlugin', 'ServerCredentials', 'UnaryUnaryMultiCallable',
+ 'AuthMetadataPlugin', 'ServerCertificateConfiguration',
+ 'ServerCredentials', 'UnaryUnaryMultiCallable',
'UnaryStreamMultiCallable', 'StreamUnaryMultiCallable',
'StreamStreamMultiCallable', 'Channel', 'ServicerContext',
'RpcMethodHandler', 'HandlerCallDetails', 'GenericRpcHandler',
@@ -1344,8 +1415,9 @@ __all__ = ('FutureTimeoutError', 'FutureCancelledError', 'Future',
'method_handlers_generic_handler', 'ssl_channel_credentials',
'metadata_call_credentials', 'access_token_call_credentials',
'composite_call_credentials', 'composite_channel_credentials',
- 'ssl_server_credentials', 'channel_ready_future', 'insecure_channel',
- 'secure_channel', 'server',)
+ 'ssl_server_credentials', 'ssl_server_certificate_configuration',
+ 'dynamic_ssl_server_credentials', 'channel_ready_future',
+ 'insecure_channel', 'secure_channel', 'server',)
############################### Extension Shims ################################
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
index 41975cbe9e..bc0f185c77 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
@@ -28,12 +28,27 @@ cdef class CallCredentials:
cdef list references
+cdef class ServerCertificateConfig:
+
+ cdef grpc_ssl_server_certificate_config *c_cert_config
+ cdef const char *c_pem_root_certs
+ cdef grpc_ssl_pem_key_cert_pair *c_ssl_pem_key_cert_pairs
+ cdef size_t c_ssl_pem_key_cert_pairs_count
+ cdef list references
+
+
cdef class ServerCredentials:
cdef grpc_server_credentials *c_credentials
cdef grpc_ssl_pem_key_cert_pair *c_ssl_pem_key_cert_pairs
cdef size_t c_ssl_pem_key_cert_pairs_count
cdef list references
+ # the cert config related state is used only if this credentials is
+ # created with cert config/fetcher
+ cdef object initial_cert_config
+ cdef object cert_config_fetcher
+ # whether C-core has asked for the initial_cert_config
+ cdef bint initial_cert_config_fetched
cdef class CredentialsMetadataPlugin:
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
index 0fabda19ce..bdba40b4f1 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
@@ -14,6 +14,7 @@
cimport cpython
+import grpc
import threading
import traceback
@@ -58,12 +59,30 @@ cdef class CallCredentials:
grpc_shutdown()
+cdef class ServerCertificateConfig:
+
+ def __cinit__(self):
+ grpc_init()
+ self.c_cert_config = NULL
+ self.c_pem_root_certs = NULL
+ self.c_ssl_pem_key_cert_pairs = NULL
+ self.references = []
+
+ def __dealloc__(self):
+ grpc_ssl_server_certificate_config_destroy(self.c_cert_config)
+ gpr_free(self.c_ssl_pem_key_cert_pairs)
+ grpc_shutdown()
+
+
cdef class ServerCredentials:
def __cinit__(self):
grpc_init()
self.c_credentials = NULL
self.references = []
+ self.initial_cert_config = None
+ self.cert_config_fetcher = None
+ self.initial_cert_config_fetched = False
def __dealloc__(self):
if self.c_credentials != NULL:
@@ -254,34 +273,86 @@ def call_credentials_metadata_plugin(CredentialsMetadataPlugin plugin):
credentials.references.append(plugin)
return credentials
-def server_credentials_ssl(pem_root_certs, pem_key_cert_pairs,
- bint force_client_auth):
- pem_root_certs = str_to_bytes(pem_root_certs)
+cdef const char* _get_c_pem_root_certs(pem_root_certs):
cdef char *c_pem_root_certs = NULL
- if pem_root_certs is not None:
+ if pem_root_certs is not None:
c_pem_root_certs = pem_root_certs
- pem_key_cert_pairs = list(pem_key_cert_pairs)
+ return c_pem_root_certs
+
+cdef grpc_ssl_pem_key_cert_pair* _create_c_ssl_pem_key_cert_pairs(pem_key_cert_pairs):
+ # return a malloc'ed grpc_ssl_pem_key_cert_pair from a _list_ of SslPemKeyCertPair
for pair in pem_key_cert_pairs:
if not isinstance(pair, SslPemKeyCertPair):
raise TypeError("expected pem_key_cert_pairs to be sequence of "
"SslPemKeyCertPair")
+ cdef size_t c_ssl_pem_key_cert_pairs_count = len(pem_key_cert_pairs)
+ cdef grpc_ssl_pem_key_cert_pair* c_ssl_pem_key_cert_pairs = NULL
+ with nogil:
+ c_ssl_pem_key_cert_pairs = (
+ <grpc_ssl_pem_key_cert_pair *>gpr_malloc(
+ sizeof(grpc_ssl_pem_key_cert_pair) * c_ssl_pem_key_cert_pairs_count))
+ for i in range(c_ssl_pem_key_cert_pairs_count):
+ c_ssl_pem_key_cert_pairs[i] = (
+ (<SslPemKeyCertPair>pem_key_cert_pairs[i]).c_pair)
+ return c_ssl_pem_key_cert_pairs
+
+def server_credentials_ssl(pem_root_certs, pem_key_cert_pairs,
+ bint force_client_auth):
+ pem_root_certs = str_to_bytes(pem_root_certs)
+ pem_key_cert_pairs = list(pem_key_cert_pairs)
cdef ServerCredentials credentials = ServerCredentials()
- credentials.references.append(pem_key_cert_pairs)
credentials.references.append(pem_root_certs)
+ credentials.references.append(pem_key_cert_pairs)
+ cdef char * c_pem_root_certs = _get_c_pem_root_certs(pem_root_certs)
credentials.c_ssl_pem_key_cert_pairs_count = len(pem_key_cert_pairs)
- with nogil:
- credentials.c_ssl_pem_key_cert_pairs = (
- <grpc_ssl_pem_key_cert_pair *>gpr_malloc(
- sizeof(grpc_ssl_pem_key_cert_pair) *
- credentials.c_ssl_pem_key_cert_pairs_count
- ))
- for i in range(credentials.c_ssl_pem_key_cert_pairs_count):
- credentials.c_ssl_pem_key_cert_pairs[i] = (
- (<SslPemKeyCertPair>pem_key_cert_pairs[i]).c_pair)
- credentials.c_credentials = grpc_ssl_server_credentials_create(
- c_pem_root_certs, credentials.c_ssl_pem_key_cert_pairs,
- credentials.c_ssl_pem_key_cert_pairs_count,
- GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY if force_client_auth else GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
- NULL)
+ credentials.c_ssl_pem_key_cert_pairs = _create_c_ssl_pem_key_cert_pairs(pem_key_cert_pairs)
+ cdef grpc_ssl_server_certificate_config *c_cert_config = NULL
+ c_cert_config = grpc_ssl_server_certificate_config_create(
+ c_pem_root_certs, credentials.c_ssl_pem_key_cert_pairs,
+ credentials.c_ssl_pem_key_cert_pairs_count)
+ cdef grpc_ssl_server_credentials_options* c_options = NULL
+ # C-core assumes ownership of c_cert_config
+ c_options = grpc_ssl_server_credentials_create_options_using_config(
+ GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+ if force_client_auth else
+ GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
+ c_cert_config)
+ # C-core assumes ownership of c_options
+ credentials.c_credentials = grpc_ssl_server_credentials_create_with_options(c_options)
return credentials
+def server_certificate_config_ssl(pem_root_certs, pem_key_cert_pairs):
+ pem_root_certs = str_to_bytes(pem_root_certs)
+ pem_key_cert_pairs = list(pem_key_cert_pairs)
+ cdef ServerCertificateConfig cert_config = ServerCertificateConfig()
+ cert_config.references.append(pem_root_certs)
+ cert_config.references.append(pem_key_cert_pairs)
+ cert_config.c_pem_root_certs = _get_c_pem_root_certs(pem_root_certs)
+ cert_config.c_ssl_pem_key_cert_pairs_count = len(pem_key_cert_pairs)
+ cert_config.c_ssl_pem_key_cert_pairs = _create_c_ssl_pem_key_cert_pairs(pem_key_cert_pairs)
+ 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 cert_config
+
+def server_credentials_ssl_dynamic_cert_config(initial_cert_config,
+ cert_config_fetcher,
+ bint force_client_auth):
+ if not isinstance(initial_cert_config, grpc.ServerCertificateConfiguration):
+ raise TypeError(
+ 'initial_cert_config must be a grpc.ServerCertificateConfiguration')
+ if not callable(cert_config_fetcher):
+ raise TypeError('cert_config_fetcher must be callable')
+ cdef ServerCredentials credentials = ServerCredentials()
+ credentials.initial_cert_config = initial_cert_config
+ credentials.cert_config_fetcher = cert_config_fetcher
+ cdef grpc_ssl_server_credentials_options* c_options = NULL
+ c_options = grpc_ssl_server_credentials_create_options_using_config_fetcher(
+ GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+ if force_client_auth else
+ GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
+ _server_cert_config_fetcher_wrapper,
+ <void*>credentials)
+ # C-core assumes ownership of c_options
+ credentials.c_credentials = grpc_ssl_server_credentials_create_with_options(c_options)
+ return credentials
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index f115106e60..660263fc09 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -391,6 +391,42 @@ cdef extern from "grpc/grpc_security.h":
GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY
GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+ ctypedef enum grpc_ssl_certificate_config_reload_status:
+ GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED
+ GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW
+ GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL
+
+ ctypedef struct grpc_ssl_server_certificate_config:
+ # We don't care about the internals
+ pass
+
+ ctypedef struct grpc_ssl_server_credentials_options:
+ # We don't care about the internals
+ pass
+
+ grpc_ssl_server_certificate_config * grpc_ssl_server_certificate_config_create(
+ const char *pem_root_certs,
+ const grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
+ size_t num_key_cert_pairs)
+
+ void grpc_ssl_server_certificate_config_destroy(grpc_ssl_server_certificate_config *config)
+
+ ctypedef grpc_ssl_certificate_config_reload_status (*grpc_ssl_server_certificate_config_callback)(
+ void *user_data,
+ grpc_ssl_server_certificate_config **config)
+
+ grpc_ssl_server_credentials_options *grpc_ssl_server_credentials_create_options_using_config(
+ grpc_ssl_client_certificate_request_type client_certificate_request,
+ grpc_ssl_server_certificate_config *certificate_config)
+
+ grpc_ssl_server_credentials_options* grpc_ssl_server_credentials_create_options_using_config_fetcher(
+ grpc_ssl_client_certificate_request_type client_certificate_request,
+ grpc_ssl_server_certificate_config_callback cb,
+ void *user_data)
+
+ grpc_server_credentials *grpc_ssl_server_credentials_create_with_options(
+ grpc_ssl_server_credentials_options *options)
+
ctypedef struct grpc_ssl_pem_key_cert_pair:
const char *private_key
const char *certificate_chain "cert_chain"
@@ -440,10 +476,6 @@ cdef extern from "grpc/grpc_security.h":
# We don't care about the internals (and in fact don't know them)
pass
- grpc_server_credentials *grpc_ssl_server_credentials_create(
- const char *pem_root_certs,
- grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
- size_t num_key_cert_pairs, int force_client_auth, void *reserved)
void grpc_server_credentials_release(grpc_server_credentials *creds) nogil
int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
index b8db27469f..5f3405936c 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
@@ -14,8 +14,46 @@
cimport cpython
+import logging
import time
+import grpc
+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 = <ServerCredentials>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:
+ logging.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):
+ logging.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] = <grpc_ssl_server_certificate_config*>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:
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index bb7d990078..330c4185c6 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -80,7 +80,6 @@ CORE_SOURCE_FILES = [
'src/core/lib/http/httpcli.cc',
'src/core/lib/http/parser.cc',
'src/core/lib/iomgr/call_combiner.cc',
- 'src/core/lib/iomgr/closure.cc',
'src/core/lib/iomgr/combiner.cc',
'src/core/lib/iomgr/endpoint.cc',
'src/core/lib/iomgr/endpoint_pair_posix.cc',
diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py
index 01d796f4e6..7a2e6f5027 100644
--- a/src/python/grpcio_health_checking/setup.py
+++ b/src/python/grpcio_health_checking/setup.py
@@ -60,17 +60,8 @@ INSTALL_REQUIRES = ('protobuf>=3.3.0',
'grpcio>={version}'.format(version=grpc_version.VERSION),)
try:
- # ensure we can load the _pb2_grpc module:
- from grpc_health.v1 import health_pb2_grpc as _pb2_grpc
- # if we can find the _pb2_grpc module, the package has already been built.
- SETUP_REQUIRES = ()
- COMMAND_CLASS = {
- # wire up commands to no-op not to break the external dependencies
- 'preprocess': _NoOpCommand,
- 'build_package_protos': _NoOpCommand,
- }
-except ImportError: # we are in the build environment
import health_commands as _health_commands
+ # we are in the build environment, otherwise the above import fails
SETUP_REQUIRES = (
'grpcio-tools=={version}'.format(version=grpc_version.VERSION),)
COMMAND_CLASS = {
@@ -78,6 +69,13 @@ except ImportError: # we are in the build environment
'preprocess': _health_commands.CopyProtoModules,
'build_package_protos': _health_commands.BuildPackageProtos,
}
+except ImportError:
+ SETUP_REQUIRES = ()
+ COMMAND_CLASS = {
+ # wire up commands to no-op not to break the external dependencies
+ 'preprocess': _NoOpCommand,
+ 'build_package_protos': _NoOpCommand,
+ }
setuptools.setup(
name='grpcio-health-checking',
diff --git a/src/python/grpcio_reflection/setup.py b/src/python/grpcio_reflection/setup.py
index ad9e86990f..25312c7c0a 100644
--- a/src/python/grpcio_reflection/setup.py
+++ b/src/python/grpcio_reflection/setup.py
@@ -61,17 +61,8 @@ INSTALL_REQUIRES = ('protobuf>=3.3.0',
'grpcio>={version}'.format(version=grpc_version.VERSION),)
try:
- # ensure we can load the _pb2_grpc module:
- from grpc_reflection.v1alpha import reflection_pb2_grpc as _pb2_grpc
- # if we can find the _pb2_grpc module, the package has already been built.
- SETUP_REQUIRES = ()
- COMMAND_CLASS = {
- # wire up commands to no-op not to break the external dependencies
- 'preprocess': _NoOpCommand,
- 'build_package_protos': _NoOpCommand,
- }
-except ImportError: # we are in the build environment
import reflection_commands as _reflection_commands
+ # we are in the build environment, otherwise the above import fails
SETUP_REQUIRES = (
'grpcio-tools=={version}'.format(version=grpc_version.VERSION),)
COMMAND_CLASS = {
@@ -79,6 +70,13 @@ except ImportError: # we are in the build environment
'preprocess': _reflection_commands.CopyProtoModules,
'build_package_protos': _reflection_commands.BuildPackageProtos,
}
+except ImportError:
+ SETUP_REQUIRES = ()
+ COMMAND_CLASS = {
+ # wire up commands to no-op not to break the external dependencies
+ 'preprocess': _NoOpCommand,
+ 'build_package_protos': _NoOpCommand,
+ }
setuptools.setup(
name='grpcio-reflection',
diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py
index e520c08290..383b5f033d 100644
--- a/src/python/grpcio_tests/tests/interop/client.py
+++ b/src/python/grpcio_tests/tests/interop/client.py
@@ -29,37 +29,40 @@ def _args():
parser = argparse.ArgumentParser()
parser.add_argument(
'--server_host',
- help='the host to which to connect',
+ default="localhost",
type=str,
- default="localhost")
+ help='the host to which to connect')
parser.add_argument(
- '--server_port', help='the port to which to connect', type=int)
+ '--server_port',
+ type=int,
+ required=True,
+ help='the port to which to connect')
parser.add_argument(
'--test_case',
- help='the test case to execute',
+ default='large_unary',
type=str,
- default="large_unary")
+ help='the test case to execute')
parser.add_argument(
'--use_tls',
- help='require a secure connection',
default=False,
- type=resources.parse_bool)
+ type=resources.parse_bool,
+ help='require a secure connection')
parser.add_argument(
'--use_test_ca',
- help='replace platform root CAs with ca.pem',
default=False,
- type=resources.parse_bool)
+ type=resources.parse_bool,
+ help='replace platform root CAs with ca.pem')
parser.add_argument(
'--server_host_override',
default="foo.test.google.fr",
- help='the server host to which to claim to connect',
- type=str)
+ type=str,
+ help='the server host to which to claim to connect')
parser.add_argument(
- '--oauth_scope', help='scope for OAuth tokens', type=str)
+ '--oauth_scope', type=str, help='scope for OAuth tokens')
parser.add_argument(
'--default_service_account',
- help='email address of the default service account',
- type=str)
+ type=str,
+ help='email address of the default service account')
return parser.parse_args()
diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py
index 8ad1f5f7cd..eeb41a21d2 100644
--- a/src/python/grpcio_tests/tests/interop/server.py
+++ b/src/python/grpcio_tests/tests/interop/server.py
@@ -29,12 +29,13 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24
def serve():
parser = argparse.ArgumentParser()
- parser.add_argument('--port', help='the port on which to serve', type=int)
+ parser.add_argument(
+ '--port', type=int, required=True, help='the port on which to serve')
parser.add_argument(
'--use_tls',
- help='require a secure connection',
default=False,
- type=resources.parse_bool)
+ type=resources.parse_bool,
+ help='require a secure connection')
args = parser.parse_args()
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index 8512d5b96f..e277a3ea1d 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -46,6 +46,10 @@
"unit._reconnect_test.ReconnectTest",
"unit._resource_exhausted_test.ResourceExhaustedTest",
"unit._rpc_test.RPCTest",
+ "unit._server_ssl_cert_config_test.ServerSSLCertConfigFetcherParamsChecks",
+ "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestCertConfigReuse",
+ "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestWithClientAuth",
+ "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestWithoutClientAuth",
"unit._thread_cleanup_test.CleanupThreadTest",
"unit.beta._beta_features_test.BetaFeaturesTest",
"unit.beta._beta_features_test.ContextManagementAndLifecycleTest",
diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py
index a3351aab50..b14e8d5c75 100644
--- a/src/python/grpcio_tests/tests/unit/_api_test.py
+++ b/src/python/grpcio_tests/tests/unit/_api_test.py
@@ -30,18 +30,20 @@ class AllTest(unittest.TestCase):
'ChannelConnectivity', 'StatusCode', 'RpcError', 'RpcContext',
'Call', 'ChannelCredentials', 'CallCredentials',
'AuthMetadataContext', 'AuthMetadataPluginCallback',
- 'AuthMetadataPlugin', 'ServerCredentials',
- 'UnaryUnaryMultiCallable', 'UnaryStreamMultiCallable',
- 'StreamUnaryMultiCallable', 'StreamStreamMultiCallable', 'Channel',
- 'ServicerContext', 'RpcMethodHandler', 'HandlerCallDetails',
- 'GenericRpcHandler', 'ServiceRpcHandler', 'Server',
- 'unary_unary_rpc_method_handler', 'unary_stream_rpc_method_handler',
+ 'AuthMetadataPlugin', 'ServerCertificateConfiguration',
+ 'ServerCredentials', 'UnaryUnaryMultiCallable',
+ 'UnaryStreamMultiCallable', 'StreamUnaryMultiCallable',
+ 'StreamStreamMultiCallable', 'Channel', 'ServicerContext',
+ 'RpcMethodHandler', 'HandlerCallDetails', 'GenericRpcHandler',
+ 'ServiceRpcHandler', 'Server', 'unary_unary_rpc_method_handler',
+ 'unary_stream_rpc_method_handler',
'stream_unary_rpc_method_handler',
'stream_stream_rpc_method_handler',
'method_handlers_generic_handler', 'ssl_channel_credentials',
'metadata_call_credentials', 'access_token_call_credentials',
'composite_call_credentials', 'composite_channel_credentials',
- 'ssl_server_credentials', 'channel_ready_future',
+ 'ssl_server_credentials', 'ssl_server_certificate_configuration',
+ 'dynamic_ssl_server_credentials', 'channel_ready_future',
'insecure_channel', 'secure_channel', 'server',)
six.assertCountEqual(self, expected_grpc_code_elements,
diff --git a/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py
new file mode 100644
index 0000000000..005d16ea75
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py
@@ -0,0 +1,519 @@
+# 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.
+"""Tests server certificate rotation.
+
+Here we test various aspects of gRPC Python, and in some cases gRPC
+Core by extension, support for server certificate rotation.
+
+* ServerSSLCertReloadTestWithClientAuth: test ability to rotate
+ server's SSL cert for use in future channels with clients while not
+ affecting any existing channel. The server requires client
+ authentication.
+
+* ServerSSLCertReloadTestWithoutClientAuth: like
+ ServerSSLCertReloadTestWithClientAuth except that the server does
+ not authenticate the client.
+
+* ServerSSLCertReloadTestCertConfigReuse: tests gRPC Python's ability
+ to deal with user's reuse of ServerCertificateConfiguration instances.
+"""
+
+import abc
+import collections
+import os
+import six
+import threading
+import unittest
+
+from concurrent import futures
+
+import grpc
+from tests.unit import resources
+from tests.testing import _application_common
+from tests.testing import _server_application
+from tests.testing.proto import services_pb2_grpc
+
+CA_1_PEM = resources.cert_hier_1_root_ca_cert()
+CA_2_PEM = resources.cert_hier_2_root_ca_cert()
+
+CLIENT_KEY_1_PEM = resources.cert_hier_1_client_1_key()
+CLIENT_CERT_CHAIN_1_PEM = (resources.cert_hier_1_client_1_cert() +
+ resources.cert_hier_1_intermediate_ca_cert())
+
+CLIENT_KEY_2_PEM = resources.cert_hier_2_client_1_key()
+CLIENT_CERT_CHAIN_2_PEM = (resources.cert_hier_2_client_1_cert() +
+ resources.cert_hier_2_intermediate_ca_cert())
+
+SERVER_KEY_1_PEM = resources.cert_hier_1_server_1_key()
+SERVER_CERT_CHAIN_1_PEM = (resources.cert_hier_1_server_1_cert() +
+ resources.cert_hier_1_intermediate_ca_cert())
+
+SERVER_KEY_2_PEM = resources.cert_hier_2_server_1_key()
+SERVER_CERT_CHAIN_2_PEM = (resources.cert_hier_2_server_1_cert() +
+ resources.cert_hier_2_intermediate_ca_cert())
+
+# for use with the CertConfigFetcher. Roughly a simple custom mock
+# implementation
+Call = collections.namedtuple('Call', ['did_raise', 'returned_cert_config'])
+
+
+def _create_client_stub(
+ port,
+ expect_success,
+ root_certificates=None,
+ private_key=None,
+ certificate_chain=None,):
+ channel = grpc.secure_channel('localhost:{}'.format(port),
+ grpc.ssl_channel_credentials(
+ root_certificates=root_certificates,
+ private_key=private_key,
+ certificate_chain=certificate_chain))
+ if expect_success:
+ # per Nathaniel: there's some robustness issue if we start
+ # using a channel without waiting for it to be actually ready
+ grpc.channel_ready_future(channel).result(timeout=10)
+ return services_pb2_grpc.FirstServiceStub(channel)
+
+
+class CertConfigFetcher(object):
+
+ def __init__(self):
+ self._lock = threading.Lock()
+ self._calls = []
+ self._should_raise = False
+ self._cert_config = None
+
+ def reset(self):
+ with self._lock:
+ self._calls = []
+ self._should_raise = False
+ self._cert_config = None
+
+ def configure(self, should_raise, cert_config):
+ assert not (should_raise and cert_config), (
+ "should not specify both should_raise and a cert_config at the same time"
+ )
+ with self._lock:
+ self._should_raise = should_raise
+ self._cert_config = cert_config
+
+ def getCalls(self):
+ with self._lock:
+ return self._calls
+
+ def __call__(self):
+ with self._lock:
+ if self._should_raise:
+ self._calls.append(Call(True, None))
+ raise ValueError('just for fun, should not affect the test')
+ else:
+ self._calls.append(Call(False, self._cert_config))
+ return self._cert_config
+
+
+class _ServerSSLCertReloadTest(
+ six.with_metaclass(abc.ABCMeta, unittest.TestCase)):
+
+ def __init__(self, *args, **kwargs):
+ super(_ServerSSLCertReloadTest, self).__init__(*args, **kwargs)
+ self.server = None
+ self.port = None
+
+ @abc.abstractmethod
+ def require_client_auth(self):
+ raise NotImplementedError()
+
+ def setUp(self):
+ self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+ services_pb2_grpc.add_FirstServiceServicer_to_server(
+ _server_application.FirstServiceServicer(), self.server)
+ switch_cert_on_client_num = 10
+ initial_cert_config = grpc.ssl_server_certificate_configuration(
+ [(SERVER_KEY_1_PEM, SERVER_CERT_CHAIN_1_PEM)],
+ root_certificates=CA_2_PEM)
+ self.cert_config_fetcher = CertConfigFetcher()
+ server_credentials = grpc.dynamic_ssl_server_credentials(
+ initial_cert_config,
+ self.cert_config_fetcher,
+ require_client_authentication=self.require_client_auth())
+ self.port = self.server.add_secure_port('[::]:0', server_credentials)
+ self.server.start()
+
+ def tearDown(self):
+ if self.server:
+ self.server.stop(None)
+
+ def _perform_rpc(self, client_stub, expect_success):
+ # we don't care about the actual response of the rpc; only
+ # whether we can perform it or not, and if not, the status
+ # code must be UNAVAILABLE
+ request = _application_common.UNARY_UNARY_REQUEST
+ if expect_success:
+ response = client_stub.UnUn(request)
+ self.assertEqual(response, _application_common.UNARY_UNARY_RESPONSE)
+ else:
+ with self.assertRaises(grpc.RpcError) as exception_context:
+ client_stub.UnUn(request)
+ self.assertEqual(exception_context.exception.code(),
+ grpc.StatusCode.UNAVAILABLE)
+
+ def _do_one_shot_client_rpc(self,
+ expect_success,
+ root_certificates=None,
+ private_key=None,
+ certificate_chain=None):
+ client_stub = _create_client_stub(
+ self.port,
+ expect_success,
+ root_certificates=root_certificates,
+ private_key=private_key,
+ certificate_chain=certificate_chain)
+ self._perform_rpc(client_stub, expect_success)
+ del client_stub
+
+ def _test(self):
+ # things should work...
+ self.cert_config_fetcher.configure(False, None)
+ self._do_one_shot_client_rpc(
+ True,
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ self.assertIsNone(actual_calls[0].returned_cert_config)
+
+ # client should reject server...
+ # fails because client trusts ca2 and so will reject server
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, None)
+ self._do_one_shot_client_rpc(
+ False,
+ root_certificates=CA_2_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertGreaterEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ for i, call in enumerate(actual_calls):
+ self.assertFalse(call.did_raise, 'i= {}'.format(i))
+ self.assertIsNone(call.returned_cert_config, 'i= {}'.format(i))
+
+ # should work again...
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(True, None)
+ self._do_one_shot_client_rpc(
+ True,
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertEqual(len(actual_calls), 1)
+ self.assertTrue(actual_calls[0].did_raise)
+ self.assertIsNone(actual_calls[0].returned_cert_config)
+
+ # if with_client_auth, then client should be rejected by
+ # server because client uses key/cert1, but server trusts ca2,
+ # so server will reject
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, None)
+ self._do_one_shot_client_rpc(
+ not self.require_client_auth(),
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_1_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_1_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertGreaterEqual(len(actual_calls), 1)
+ for i, call in enumerate(actual_calls):
+ self.assertFalse(call.did_raise, 'i= {}'.format(i))
+ self.assertIsNone(call.returned_cert_config, 'i= {}'.format(i))
+
+ # should work again...
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, None)
+ self._do_one_shot_client_rpc(
+ True,
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ self.assertIsNone(actual_calls[0].returned_cert_config)
+
+ # now create the "persistent" clients
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, None)
+ persistent_client_stub_A = _create_client_stub(
+ self.port,
+ True,
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ self._perform_rpc(persistent_client_stub_A, True)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ self.assertIsNone(actual_calls[0].returned_cert_config)
+
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, None)
+ persistent_client_stub_B = _create_client_stub(
+ self.port,
+ True,
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ self._perform_rpc(persistent_client_stub_B, True)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ self.assertIsNone(actual_calls[0].returned_cert_config)
+
+ # moment of truth!! client should reject server because the
+ # server switch cert...
+ cert_config = grpc.ssl_server_certificate_configuration(
+ [(SERVER_KEY_2_PEM, SERVER_CERT_CHAIN_2_PEM)],
+ root_certificates=CA_1_PEM)
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, cert_config)
+ self._do_one_shot_client_rpc(
+ False,
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertGreaterEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ for i, call in enumerate(actual_calls):
+ self.assertFalse(call.did_raise, 'i= {}'.format(i))
+ self.assertEqual(call.returned_cert_config, cert_config,
+ 'i= {}'.format(i))
+
+ # now should work again...
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, None)
+ self._do_one_shot_client_rpc(
+ True,
+ root_certificates=CA_2_PEM,
+ private_key=CLIENT_KEY_1_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_1_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ self.assertIsNone(actual_calls[0].returned_cert_config)
+
+ # client should be rejected by server if with_client_auth
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, None)
+ self._do_one_shot_client_rpc(
+ not self.require_client_auth(),
+ root_certificates=CA_2_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertGreaterEqual(len(actual_calls), 1)
+ for i, call in enumerate(actual_calls):
+ self.assertFalse(call.did_raise, 'i= {}'.format(i))
+ self.assertIsNone(call.returned_cert_config, 'i= {}'.format(i))
+
+ # here client should reject server...
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, None)
+ self._do_one_shot_client_rpc(
+ False,
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertGreaterEqual(len(actual_calls), 1)
+ for i, call in enumerate(actual_calls):
+ self.assertFalse(call.did_raise, 'i= {}'.format(i))
+ self.assertIsNone(call.returned_cert_config, 'i= {}'.format(i))
+
+ # persistent clients should continue to work
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, None)
+ self._perform_rpc(persistent_client_stub_A, True)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertEqual(len(actual_calls), 0)
+
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, None)
+ self._perform_rpc(persistent_client_stub_B, True)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertEqual(len(actual_calls), 0)
+
+
+class ServerSSLCertConfigFetcherParamsChecks(unittest.TestCase):
+
+ def test_check_on_initial_config(self):
+ with self.assertRaises(TypeError):
+ grpc.dynamic_ssl_server_credentials(None, str)
+ with self.assertRaises(TypeError):
+ grpc.dynamic_ssl_server_credentials(1, str)
+
+ def test_check_on_config_fetcher(self):
+ cert_config = grpc.ssl_server_certificate_configuration(
+ [(SERVER_KEY_2_PEM, SERVER_CERT_CHAIN_2_PEM)],
+ root_certificates=CA_1_PEM)
+ with self.assertRaises(TypeError):
+ grpc.dynamic_ssl_server_credentials(cert_config, None)
+ with self.assertRaises(TypeError):
+ grpc.dynamic_ssl_server_credentials(cert_config, 1)
+
+
+class ServerSSLCertReloadTestWithClientAuth(_ServerSSLCertReloadTest):
+
+ def require_client_auth(self):
+ return True
+
+ test = _ServerSSLCertReloadTest._test
+
+
+class ServerSSLCertReloadTestWithoutClientAuth(_ServerSSLCertReloadTest):
+
+ def require_client_auth(self):
+ return False
+
+ test = _ServerSSLCertReloadTest._test
+
+
+class ServerSSLCertReloadTestCertConfigReuse(_ServerSSLCertReloadTest):
+ """Ensures that `ServerCertificateConfiguration` instances can be reused.
+
+ Because gRPC Core takes ownership of the
+ `grpc_ssl_server_certificate_config` encapsulated by
+ `ServerCertificateConfiguration`, this test reuses the same
+ `ServerCertificateConfiguration` instances multiple times to make sure
+ gRPC Python takes care of maintaining the validity of
+ `ServerCertificateConfiguration` instances, so that such instances can be
+ re-used by user application.
+ """
+
+ def require_client_auth(self):
+ return True
+
+ def setUp(self):
+ self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+ services_pb2_grpc.add_FirstServiceServicer_to_server(
+ _server_application.FirstServiceServicer(), self.server)
+ self.cert_config_A = grpc.ssl_server_certificate_configuration(
+ [(SERVER_KEY_1_PEM, SERVER_CERT_CHAIN_1_PEM)],
+ root_certificates=CA_2_PEM)
+ self.cert_config_B = grpc.ssl_server_certificate_configuration(
+ [(SERVER_KEY_2_PEM, SERVER_CERT_CHAIN_2_PEM)],
+ root_certificates=CA_1_PEM)
+ self.cert_config_fetcher = CertConfigFetcher()
+ server_credentials = grpc.dynamic_ssl_server_credentials(
+ self.cert_config_A,
+ self.cert_config_fetcher,
+ require_client_authentication=True)
+ self.port = self.server.add_secure_port('[::]:0', server_credentials)
+ self.server.start()
+
+ def test_cert_config_reuse(self):
+
+ # succeed with A
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, self.cert_config_A)
+ self._do_one_shot_client_rpc(
+ True,
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ self.assertEqual(actual_calls[0].returned_cert_config,
+ self.cert_config_A)
+
+ # fail with A
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, self.cert_config_A)
+ self._do_one_shot_client_rpc(
+ False,
+ root_certificates=CA_2_PEM,
+ private_key=CLIENT_KEY_1_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_1_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertGreaterEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ for i, call in enumerate(actual_calls):
+ self.assertFalse(call.did_raise, 'i= {}'.format(i))
+ self.assertEqual(call.returned_cert_config, self.cert_config_A,
+ 'i= {}'.format(i))
+
+ # succeed again with A
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, self.cert_config_A)
+ self._do_one_shot_client_rpc(
+ True,
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ self.assertEqual(actual_calls[0].returned_cert_config,
+ self.cert_config_A)
+
+ # succeed with B
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, self.cert_config_B)
+ self._do_one_shot_client_rpc(
+ True,
+ root_certificates=CA_2_PEM,
+ private_key=CLIENT_KEY_1_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_1_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ self.assertEqual(actual_calls[0].returned_cert_config,
+ self.cert_config_B)
+
+ # fail with B
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, self.cert_config_B)
+ self._do_one_shot_client_rpc(
+ False,
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertGreaterEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ for i, call in enumerate(actual_calls):
+ self.assertFalse(call.did_raise, 'i= {}'.format(i))
+ self.assertEqual(call.returned_cert_config, self.cert_config_B,
+ 'i= {}'.format(i))
+
+ # succeed again with B
+ self.cert_config_fetcher.reset()
+ self.cert_config_fetcher.configure(False, self.cert_config_B)
+ self._do_one_shot_client_rpc(
+ True,
+ root_certificates=CA_2_PEM,
+ private_key=CLIENT_KEY_1_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_1_PEM)
+ actual_calls = self.cert_config_fetcher.getCalls()
+ self.assertEqual(len(actual_calls), 1)
+ self.assertFalse(actual_calls[0].did_raise)
+ self.assertEqual(actual_calls[0].returned_cert_config,
+ self.cert_config_B)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/credentials/README b/src/python/grpcio_tests/tests/unit/credentials/README
deleted file mode 100644
index cb20dcb49f..0000000000
--- a/src/python/grpcio_tests/tests/unit/credentials/README
+++ /dev/null
@@ -1 +0,0 @@
-These are test keys *NOT* to be used in production.
diff --git a/src/python/grpcio_tests/tests/unit/credentials/README.md b/src/python/grpcio_tests/tests/unit/credentials/README.md
new file mode 100644
index 0000000000..100b43c1aa
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/README.md
@@ -0,0 +1,15 @@
+These are test keys *NOT* to be used in production.
+
+The `certificate_hierarchy_1` and `certificate_hierarchy_2` contain
+two disjoint but similarly organized certificate hierarchies. Each
+contains:
+
+* The respective root CA cert in `certs/ca.cert.pem`
+
+* The intermediate CA cert in
+ `intermediate/certs/intermediate.cert.pem`, signed by the root CA
+
+* A client cert and a server cert--both signed by the intermediate
+ CA--in `intermediate/certs/client.cert.pem` and
+ `intermediate/certs/localhost-1.cert.pem`; the corresponding keys
+ are in `intermediate/private`
diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/certs/ca.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/certs/ca.cert.pem
new file mode 100644
index 0000000000..604b86fdff
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/certs/ca.cert.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFZDCCA0ygAwIBAgIJAKfkDFZ6+Ly/MA0GCSqGSIb3DQEBCwUAMD8xCzAJBgNV
+BAYTAnVzMQ4wDAYDVQQIDAVkdW1teTEOMAwGA1UECgwFZHVtbXkxEDAOBgNVBAMM
+B3Jvb3QgY2EwHhcNMTcxMTAyMDAzNzA1WhcNMzcxMDI4MDAzNzA1WjA/MQswCQYD
+VQQGEwJ1czEOMAwGA1UECAwFZHVtbXkxDjAMBgNVBAoMBWR1bW15MRAwDgYDVQQD
+DAdyb290IGNhMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxlSUuSbi
+o66tT2ZCqu9wNqSX8VhAJkmrAT5y6m2V0VlQ8Gz7ddynW5UVSmtvDNTebZ15FrvO
+6Ng7QnwXXNs/dEzl6oMe6AKDZpuWScVkiqH1UYWBkMLRygWCTEYpSTWTpZWk1zxj
+DJ2LlIoO1X/ufLyLOfy2a2XEz8ICzJePmqVca6fmfEtCTj1/8FcwCBF6YlUWVzlR
+wewjanQo/lorTYbub+Q6LGxPXZ8W0qoKZzLDSD9cnj4pcJzGGFeu9KkNaW4rldZG
+t7mTGQqIRc98dDRc9Jb7PqL8tMPLidw1KErUi05ofxggc5vqNnj4xBl6aX6b/EYN
+rBLzO2e0FazX6TwNKwwg68vbOanpDq5LVmIUH8bY1zNZ+JPBGO9pXlAA0YwLx86r
+R7YhQ431ZpJ2KGnYjVhYnZ2L3NjV3UYX3x5Z3OrDj9hybhucJB48DMQ1+loEabwK
+fSUJtcSPc8dCIibxVKidBFgaTPXtHy2MPXuhMhR7PCtMpE7RPUoYmdZLr9FNN1ty
+/RAbwBfuhGLbRI2qqJgbOzHJHaOY/FtShfooLz7lt4LIjPTARaNsulG2rbv+m3z9
+mhNjL+peV8gni/xyOYYTbdzZagLrtSHeTWsITvmVt0flMHkjHyv35rw23+hBlSjp
+6+S+0MmwuwxqBBccBSlZ9t3Xh1N+vFkb2UkCAwEAAaNjMGEwHQYDVR0OBBYEFJWE
+tQwTbTCgZWNN08VSxjdNA0oaMB8GA1UdIwQYMBaAFJWEtQwTbTCgZWNN08VSxjdN
+A0oaMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
+CwUAA4ICAQCNjPv/e3ozX1PuN5Tluf0yOmKCxKVCK3Pp98WkDzH4Rp1urEeYrGJL
+vBNcl17avOJ0e+zTVYPXFviFbsBsU/zaf+TqEujXabsdL+nvvCJ2mMqYn4wyDFjS
+zDNbGH6O0ENZz5NSY0/UGSOHYrYnYB94QRFLbbf0Y3PmBS2eRNjIUnv7ytPZNMi/
+piM+QhPb0Ebyk0rHQZ0RAJaC/wsEtqP8TGV/fx+AzG7zW/zxgPTrgIThy138tLQ+
+xCVDP9H2c17nVP6vjYzKnMZ94uGrGqUzV9vU7EqYl0uZflIf98pLfdKHnQ3heqds
+8KQPNKRxVvcc92qv2pQY951wb1fkhLutjHn7TUvrenyAngz+Vs19NxbqLPys1CTw
+iaL7vZ8VE/aEDm1tjt5SLM474tpATjk1+qMRaWnii8J5rTodYHP+Zu2GxyIrMiGq
+tfNZMYI0tETK1XmEo75E/3s9pmIeQNGKLFp+qL7xrVyN/2ffNv0at8kkqXluunK9
+/Ki0gKYlGFm4Eu8t/nHMqhBx/njYg6pLDuarLW6ftUV7aHd7qKcCWOWqK6gnH/vX
+3Apv31eltZBBVN69p3CFy2oMnjrom2Yn/DUXFwrJLBiNJ1dd1JyDxpqpJ74ZQy+/
+pSRWMTRM5SuC7lYARx5rYPmp6cZJWyWRH/3r7bwS699/W965pa5nug==
+-----END CERTIFICATE-----
diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/client.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/client.cert.pem
new file mode 100644
index 0000000000..44bc562599
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/client.cert.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIExzCCAq+gAwIBAgICEAMwDQYJKoZIhvcNAQELBQAwRzELMAkGA1UEBhMCdXMx
+DjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEYMBYGA1UEAwwPaW50ZXJt
+ZWRpYXRlIGNhMB4XDTE3MTEwMjAwMzcwNloXDTI3MTAzMTAwMzcwNlowPjELMAkG
+A1UEBhMCdXMxDjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEPMA0GA1UE
+AwwGY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwquL6gtP
+R7P9xJK76FTj8fI5TSJa3cAMt1p6CmessjHQq7nQ6DWLGVi4XIt9Sc/1C3rXupOe
+90Ok4L0tsuVZH78Wn0EBmBH7S4IbhU9P+aJ9mcigepj1lnxWqoVblgeJYKMOOwAf
+pAKUNMWDSm+nCfwE+R5d8d8cfA41Awq1jTRjOVpiJq6aoKfs791a1ZkZde3kFrNV
+AVjC06GgA1lZd3sHf94hmLeC+xJztRXVE9e+7dcc7nFDH0t5DIKYBAklsHg77mZa
+3IK4aOZew7Lm6diPoMnAzXh2rWpJU6RrEE29gIkJBsF8CL1Ndg9MzssCg6KBjoai
+Vt5dJ+4TSEGCOwIDAQABo4HFMIHCMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQD
+AgWgMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBDbGllbnQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFPeuKDCswk8jaH9tl6X+uXjo+WM1MB8GA1UdIwQY
+MBaAFCoqYgmKh3CUafVp+paXxfz+He+FMA4GA1UdDwEB/wQEAwIF4DAdBgNVHSUE
+FjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDQYJKoZIhvcNAQELBQADggIBADYAp8XS
+UjMEpX/zVjRWpAAT4HNEJylCV1QNyhBIAyx38A6xJYuFIx966Htd6W9/Rw4sUY6y
+F4pOmnLCRxIPqFzzMYcBHSpynlcu5G7zqIod3wYIk7BNlB0AzkZn6yD8bM1y5Plf
+myzQVDEGggrDtaW2EehhNIB+wOmbRGITjIcZUEr8V4BlLXkCqOuxauxl82d5/k2w
+LAhjOb9d1VW6RT8+Lcn6drhHZdvtSCe8Z27BcXhaQLL8366mhbigKYJt5adD0KOx
+pl0MQcoL1Rth5cJEj+1/lgUaxcnvh7TaIIGEx0h3olQXsTxSTypU/nww2Ic41xdG
+xl3xvHsxe20IvOOAMRfS/LPW7MCtQ3k0BqB/rAQvmB0r5YITLlMJuBqg+zjYrG/j
+s5szSGAz9r0leFuPraeuZA41d9UBTAJMoVrrQZ4xVHMXQi1oz9E9KlIdbO9+spvC
+ulfO+D+Z4a9trYSWhnQL2dSHT0+kHqJ/8GipiUNP/yAC76dRpDVR3xtYNr73iw0j
+hyDsVjihTD8JBebs3axnt+Bc+FwoCCd6CVcsggfGUNhu/N5LS78b13PcaRzrUNjU
+Eh+8cJvMLst+UQzePlyazzpn7jjN3KsBzWUkbnXCtUs2qRMn8f2gZqliDo7JSFvy
+WtBSCYpikOivuJSQUlrHQ8NaXeddyWQzLY79
+-----END CERTIFICATE-----
diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/intermediate.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/intermediate.cert.pem
new file mode 100644
index 0000000000..98e13669c0
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/intermediate.cert.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFaDCCA1CgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzELMAkGA1UEBhMCdXMx
+DjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEQMA4GA1UEAwwHcm9vdCBj
+YTAeFw0xNzExMDIwMDM3MDZaFw0yNzEwMzEwMDM3MDZaMEcxCzAJBgNVBAYTAnVz
+MQ4wDAYDVQQIDAVkdW1teTEOMAwGA1UECgwFZHVtbXkxGDAWBgNVBAMMD2ludGVy
+bWVkaWF0ZSBjYTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOOxzve7
+CG2P9SvKfXkJVTXkj4y79JSZ77Kud/TiPfDbHTqZWKuLTXkOCkCCxfpuJvWXnnj5
+1AeLCdKx9hEwJQeU23EXDt1K+RsRyl09SXtPNnJnqHD1mUHRQR28vGX5ctrQzK8J
+Sa6/mHW4bX8ol100npbgVMDnM4IDfLYcsv4BXMICGkSHOW6Gn0zJaeHzRVPpmnK/
+0k/GQAcIrU2sZ39kVlVQkWq3HJC28cNL/P04hjh4gAf0evo/k9VrEtxPWYMfiPDt
+kOAKueoPv/VTA/zL5t8lyzfhrhxvsJxFg/klapPXK0gLLbhsHyOhnkbrzvmSR4Rw
+xubYJ2dDK0DKx+BIZqlFznjP9BvOtvtuVVMyqg9cfgc7J/OjvAguO0f93MLSfIWP
+uISqv7Llt/Blvy/xI5owvOKVc/hm3d+5pqjWBC1HkVwo4qugpWmM49dFWl4kc4c7
+ayYUjTmcgoj1ZR89w4Off/bPd1A6gXqSkw2VQfgFF+uOos84fP1V+zPWhp3UDY3P
+bFeJtuTdv1gR5w1jCIq6xVJ+UsyDZBaYP7yBBRiNzS1/yXJpnXrvHmDfUeQHLBPR
+N0nbMjqXJ1dVpZwydiI0Qx9DnJtOaq/spUreXr8+PU2jeQdCCAN21MB1umr2gZBJ
+8MZBStTgE7SDByfGmGfp7B5/s/r4O/rNc4WzAgMBAAGjZjBkMB0GA1UdDgQWBBQq
+KmIJiodwlGn1afqWl8X8/h3vhTAfBgNVHSMEGDAWgBSVhLUME20woGVjTdPFUsY3
+TQNKGjASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
+9w0BAQsFAAOCAgEAvzLu/Jc8DlfCltVufC54UZ8DVwUfxdGapNBGv4icrs1wMV3S
+xqdaLO+vSp9NeEufi724+/hj4URapW9kSt2TMD7BNJ61QSATZFJajxTFgGa0Zz95
+RBDw8/b5Arz/2pOF4VX+FJ+wqHvoH/2A0T+fwz8hLORhxZHv/cUN6kif4FKCwryQ
+s89e694kXkEiJfquvu7DR9hYCLOJwzMOOJiTnjz3hlQg4WGu7Z8ZvqzCM+how1hr
+nYbUx6a+HfoUf79AHJB0N1EsEEetJ+omvTdrrayCvy1bHA3QgHlJ28QZIJ7MzX9E
+n11/xQ95iTuSp8iWurzjTjbrm7eHnGUh+5QubYLXOzbqKzNZu72w0uvWv6ptIudU
+usttltiwW8H9kP0ArWTcZDPhhPfS9impFlhiPDk1wUv2/7g+Zz1OaOb7IiSH0s8y
+FG72AB8ucJ5dNa/2q5dJiM8Gm5CbiVw5RXTBjlfTTkNeM6LBI3dRghpPdU7Kbfhn
+xYs9vnRZeRMJHrcodLuwVcpY/gyeJ0k5LD6eIPCJmatkYZ122isYyMX8lL2P5aR+
+7d2hhqcOCproOrtThjp6nW2jWTB+R/O2+s6mhKSPgfbY2cdky1Y9FSJxSNayb9B8
+eQ+A29iOHrGVAA0R/rvw119rLAYxjXzToM28owx7IyXKrBaU4RMv5yokgag=
+-----END CERTIFICATE-----
diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/localhost-1.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/localhost-1.cert.pem
new file mode 100644
index 0000000000..f15f1cf5c2
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/localhost-1.cert.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIFFzCCAv+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwRzELMAkGA1UEBhMCdXMx
+DjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEYMBYGA1UEAwwPaW50ZXJt
+ZWRpYXRlIGNhMB4XDTE3MTEwMjAwMzcwNloXDTI3MTAzMTAwMzcwNlowTTELMAkG
+A1UEBhMCdXMxDjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEKMAgGA1UE
+CwwBMTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEArRAy0Nim9P883BAisXdFoKmgHGTtcLH/SzwkkPWTFHz0rHU1Klwz
+w8u3OkRyvgoQp7DqkohboNMDwg5VrOOcfKwtM2GZ5jixo+YKvJ25oj8Jfr+40baz
+nyWTmOcfoviKrb7u2T9BPEEz5og+lXRDAsTFATGaQDX2LN3Dd9KIw+7sWY+gc3Zi
+13HHaWYhtmfJjzFbH1vDxHKCdSdgtPyEhqcJ4OC6wbgp/mQ01VlPAr08kRfkC8mT
+TS7atqc410irKViF3sWi4YNPf7LuBrjo75FIIOp+sQgZE6xwOuZ/9bT2Zx/IUtCC
+TqzVgZI0s5NVlINtWR6eyyxQ1uDKTs4xrQIDAQABo4IBBTCCAQEwCQYDVR0TBAIw
+ADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4QgENBCYWJE9wZW5TU0wgR2Vu
+ZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUDE8pwi7aELJjvyNT
+ed81/KIgGfowaAYDVR0jBGEwX4AUKipiCYqHcJRp9Wn6lpfF/P4d74WhQ6RBMD8x
+CzAJBgNVBAYTAnVzMQ4wDAYDVQQIDAVkdW1teTEOMAwGA1UECgwFZHVtbXkxEDAO
+BgNVBAMMB3Jvb3QgY2GCAhAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr
+BgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEA2cvXxJw120Z9oWXyGwR6CH7TcXoy
+1i77B1M5j0Krvkjh2/MkEU+JxpZcrhAgZODK9wMPeIUIpJNw2t6Hg+vigpInu7pY
+MXR4IA5XLnhGV/hueXa0JLia5FG1TISxr4piW6Jd9P2pOt3ECm3Url/F0OeFF/74
+jGaAlWkbhqWJ9M7Gd4QP2wUNm0P4CwAqS9DC6dnMz+JXTakEUirOpmq7U8UKT+5N
+QS1K4WuH671n4MiYye3+UoRYt4zPjOzN+QxzvAMtkUBspPmWD6txmD5tKUYDECqn
+0sSbY6ytD30OTHIbICFp40arOffmEEJSriL+uQNPPmvqMxX1G2kUFGm15NLPs8Xa
+J7ChrAaJzssN5J3myZUbDfCuxmTkWg+hGvGmxLraVNWc3fzKFmdszSkXrGIdf2HR
+gZeFI3w6M4Ktx3KctXlsjwqQTYZI/WwLOEpsrHQBPBLQhISyNw4xjZ4MxK8SFZuQ
+IiGps/do0eEgeQ+o3gD1dIXt8YxFIxrgk0pzJONpXGgv/cZrukbLNTBdkTSkIwtx
+TXKdiJbO17H24MvW+UxFdsIoJXmfQZWdQC3p+Dl0iP+K80aI6WbaysmToHuOi216
+e49nmiM72Izul2zmBi7Cq2nRQbHAETsFfqC34FzJlx0aP8WS953IBD0jNi1BB+AX
+BxwiZ1rPjeMvekI=
+-----END CERTIFICATE-----
diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/client.key.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/client.key.pem
new file mode 100644
index 0000000000..d8a21632ab
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/client.key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAwquL6gtPR7P9xJK76FTj8fI5TSJa3cAMt1p6CmessjHQq7nQ
+6DWLGVi4XIt9Sc/1C3rXupOe90Ok4L0tsuVZH78Wn0EBmBH7S4IbhU9P+aJ9mcig
+epj1lnxWqoVblgeJYKMOOwAfpAKUNMWDSm+nCfwE+R5d8d8cfA41Awq1jTRjOVpi
+Jq6aoKfs791a1ZkZde3kFrNVAVjC06GgA1lZd3sHf94hmLeC+xJztRXVE9e+7dcc
+7nFDH0t5DIKYBAklsHg77mZa3IK4aOZew7Lm6diPoMnAzXh2rWpJU6RrEE29gIkJ
+BsF8CL1Ndg9MzssCg6KBjoaiVt5dJ+4TSEGCOwIDAQABAoIBABECKAFU56JeKYfp
+Qh20fQ4Amd0RaVsCkpnaf9s037PaAl9eptADDZozVDhRv6qZTtGn8/1LNJJqCJfS
+L5H30+egLHvRlDATMh+QyJLHMTegaNTs4IiVoK97QZ84c54SHoCg/ndNNXaA+y35
+K9VvF+sZZ93UN2UQl06Hdz5Cy0YA7L5HIIH3Ezk0ArAw4AarLil5mv4yEz2ApZhm
+Tw4I4yNfxB7tZeP+ekNg0XXRL1quA0tGblp+A5fAFfVMDplqqB2d3/KxPR9FSEOi
+4PzBZ5Mq2wQBPIaNog5um9qkw6VKxjl5sQGhP1GGTA8iZqR9iM2+xh57xdCZm3g3
+jcr+aPECgYEA42mXTsF/4oBQtU6hh/sOCMWHhxAPstKpQHFMKGYLHKEJ/V1qq0Sd
+d0kswAYCmH5G9ookzu5p7pNf0hUUHO5EwelpSZ3FEmtIM+oBwSnDk3vGuadYXN5X
+fPuVUla65B1F9SSwapYNBUAiRgrY69Knca2rkTSdcZQaBuWmo684UQcCgYEA2yRE
+P23I/9N6AVhKB/zTRtil1AxnTW8o+j7AE4q1o+xly7DS7DT34INaLKLiuG6ylV1F
+UoTiqmWqH3A7m3o3Id2AnVf/oDoKV78LCXRF3dJJWvzrPdob2fLlwyjgqXYvmD3O
+UH/OFY2blYcAHOYib1Y1AAhHPlXiHA52BYZtnC0CgYAVjjitWmII0ijURrPA8+cM
+pcyG3NrgFF++n/6cBbAf8pPD1Er8GPDkEaeQPAGa+r03OTjr9GVOG+IFQ8I4S81w
+o/M66x129XxOj2vDJ3ZGUIExr88MXnbkfeRVfasRXET5S5T9RWPOj5mwEe8lyz3b
+5J5SkS4rSeJ9rN7yvPUVmQKBgAvrrB67LRzldxSNpfFLSn7nGBYx2oi2zEbYlQA7
+ImhZWqw64S5iLz2yR3x4G9cmhmZjnXrAqcfVIez14PgzLL6V2wI0ID6qCZf+V25b
+OdW4M69UZMOHks5HTUJRfe8Z87rXWdq9KQu5GUaIAnSP/D2MNfPbf2yfpV4bV0Yz
+qtC9AoGAD3/XXaeGCdV5DPomEmehp84JXU2q/YECRvph46tr4jArG67PCvx2m84B
++W6my4Yi7QJcW4gC0gsdAuxbJl4Y7MCZBnTtNIRCRnHEIciKITJ/+brFln5QUgyn
+WnXEPN8q7VjSVXGrljFuLWkzi2Vh8iZDgourNfW+iYDGCJjx1H0=
+-----END RSA PRIVATE KEY-----
diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/localhost-1.key.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/localhost-1.key.pem
new file mode 100644
index 0000000000..aa83f1a4a2
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/localhost-1.key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEArRAy0Nim9P883BAisXdFoKmgHGTtcLH/SzwkkPWTFHz0rHU1
+Klwzw8u3OkRyvgoQp7DqkohboNMDwg5VrOOcfKwtM2GZ5jixo+YKvJ25oj8Jfr+4
+0baznyWTmOcfoviKrb7u2T9BPEEz5og+lXRDAsTFATGaQDX2LN3Dd9KIw+7sWY+g
+c3Zi13HHaWYhtmfJjzFbH1vDxHKCdSdgtPyEhqcJ4OC6wbgp/mQ01VlPAr08kRfk
+C8mTTS7atqc410irKViF3sWi4YNPf7LuBrjo75FIIOp+sQgZE6xwOuZ/9bT2Zx/I
+UtCCTqzVgZI0s5NVlINtWR6eyyxQ1uDKTs4xrQIDAQABAoIBAC56mDswxH4uAmlT
+yA2Da+a/R6n4jTBkDZ1mFKf93Dd3a7rZa6Lpylk+YAI9GdfiGiD/SbB7AKjLo0m9
+0dKx+ngdQbJ39v42obbT9HQ9o/poFaO91+QyvkDytZYuFHgPaidJjRo5e8qz9D1o
+v+4hoFGhCQvOB5BRLcFU+cc3etWr5t61sNL/kKCWEDd+MWWsOCHpdhEoWC+o25pC
+bhD3FG5xoz+8zL7WdNfke/4twfKoBJ/kq89bfIkl8eKpg387WBQY44RJF7/zVr7a
+9dsUuW2y/wVXslCHChjSrxhRlOyy5ssv3EgKh8gPkZ+oeKuONqAGw27nyKyvpjxS
+i62K+WECgYEA4oKpIS2D77RCC6rpYIK6KYfbUcNSOtHFvcbf0RH9Oi8vSRYum2ZA
+/ITdWSFgWkhT6iOSPuvZlu/EvueWDgNgW1ZVsTMFeapz1+Jwk7JRoBKF1dUEwELh
+jdAswdh0MLbgBYs6NXtVVkeK2ocgZtosmt1PUktl566NlyIyhOjH6vkCgYEAw5g0
+cteTpz+noKsfWcbnjyesuQy0caICfZIE01nKv9rKTF8BtCO6Qxj10iM2o00jW7Vl
+tZa/igjuqvozXAHBI3xegtrWV05urkjj3FB/Pyuqsx3wxhAdSNchQjdTjwUBQEzp
+3ztGSlDTRPpijnpW28lg8Kkr3weryaHvl0xM1VUCgYBqnTN8QU8rgT3g/gYw/fcf
+2ylY98V5mAkqBTSN1JjLTTBFh2JSlLOb5/HDpRkUBZ0xxKJuaVaWW67QaHLRj7dH
+5oAZErnOBXPXNmbkrfcLkAxclJJS6Gf/9u9KIla2Iy2YjmrMh4uoO65Yo2eV4bVD
+A031nzWM8jUE4PzEYEjRCQKBgHDdTj6KiQg0Yg0DUabjcNEZasCpRSJhAyDkdmZi
+5OzKWnuxQvFowF1hdM/aQ/f9Vg7gYJ1lLIeBWf9NOv+3f3RzmrHVh2N/vbxSETIb
+PSH9l5WeDEauG8fhY66q8EuR7sPk3ftTX98YPqEJ/n8Ktz5COO8GH2umKInEKNXc
+UGW1AoGAfENy7vInNv0tzFWPSYdFgesvzo7e8mXyVO8hCyWvY3rxW2on7qfLF3Z9
+fHjd7P9gULja0n1kvmxwUC3u20RrvpY59F4hfi+ji2EiubS9Yhszd2e1CLeRMkln
+ojDjnflN32ZbWVHX/i6g3Dabq9JOD0FsOaOlriLMuofdA6jTUFE=
+-----END RSA PRIVATE KEY-----
diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/certs/ca.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/certs/ca.cert.pem
new file mode 100644
index 0000000000..212b5862cb
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/certs/ca.cert.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFZDCCA0ygAwIBAgIJALhSfZ8i0rWTMA0GCSqGSIb3DQEBCwUAMD8xCzAJBgNV
+BAYTAnVzMQ4wDAYDVQQIDAVkdW1teTEOMAwGA1UECgwFZHVtbXkxEDAOBgNVBAMM
+B3Jvb3QgY2EwHhcNMTcxMTAyMDAzNzU4WhcNMzcxMDI4MDAzNzU4WjA/MQswCQYD
+VQQGEwJ1czEOMAwGA1UECAwFZHVtbXkxDjAMBgNVBAoMBWR1bW15MRAwDgYDVQQD
+DAdyb290IGNhMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArHaQ3uyp
+wVaVPZDYvy/EJbnP7KbZNPBvKpQCDEqg9B2TPaC8WVjiqT6I88c+KcGuB8nADJdk
+o10iZC5AwbrXK4ELSCOvBpxYI5sjoFcv3lZ/oe4e650QO2L/ADmtwLaLYK6rZkwW
+Sd90yCGF7ZOTZTJZDwmWEl+ohi+2ow6sRMHKcSKUNfx9G5BB7TOzoqUxqH+moEds
+YpjVMEcKzQi2FmbRd+8Dlg2eGqA2V4faprGQwoYz8NqJZGa/KPpRvXE2VjSTDN6b
+rJ7mmui6eYN53mZEBRYogyoQHdFXhK02FgyoPEgR/wQlLLbQ+xxOcv02YsOljtza
+hl5LjeNUYPMjyhef0QpONp+5NcFhZf38DsSq5EWZLLxPScxwl0lBQkJTjo5ARuFl
+Mrv50RYrLwv4ImsiO2ftE7gAX4vNsgcixnCHd6rNzoGimf1+DSvDVJ9ujWo7HPN3
+7ONuoyjsU4mUJJpYXs8zHx5WSxaYiPJRcmG3LjcU5/A+Fs7bkqSrlEjJsG29xDrO
+vKR7hH+m6MwcIcXSh9wjjAIvHxAALdU9xaYE3hmVkoxew1mRBsYq34h2vpwGOY5r
+0njRQyGGZnVa8qkQd6P3U5fcvLOM8v9QImZqRDS2jAGZXYruo/RIgJpklVX7ZY0+
+CnGdz4YxgLyOBJCDu3aEgL1oON3mg2SsrVMCAwEAAaNjMGEwHQYDVR0OBBYEFOBO
+9R6yEY6KOE+aSClwD2BQtWXKMB8GA1UdIwQYMBaAFOBO9R6yEY6KOE+aSClwD2BQ
+tWXKMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
+CwUAA4ICAQBElio7lLZ2eNt0tDPVSkChksc0IJ2/DpjYjqJzqxF/jZ2oToaAn2Er
+9iHl8ggTLB5WrTQxO1ev7qOwQsk9hrgvZ+EQCBTbyDyfNwVjgftH5jdQGdbyrnuJ
+yaks1mnd8is5ZZQmmQSd7GVOMTYi/7yH0xI4DHQ386dwnf5eKdoOI7yrVufEMxRx
+tB3Wv8KrX4z47zsIO28H/O0T26oUkrd4PEqFwDa5HQr6iG7QQgoGD/DPLgbBudlO
+kEos9fmXxiX60RLziKCE/DAxI3YWPvG3WhIWnVj22Oz6apz2pYWpOKwlaihNYrhq
+8xc02vIFwKh+t7D+wF4KHfduyMJ/wKVc5dzpNbTgkZePPKSB7QgbsMeRqbdPoXQF
+pMuzfj8VCWzpqBeHqE/adSCZhzeTrnyiYavF4T2vkSC5KJu+MHmbZ3nU9bcnnEy+
+24oEv9cEAiYNkvftbD+5ByEtkcBB2uT47sbiGrAeco+GxFGUVqi1IjObqrkIrPzV
+OjQhTZV6qgYCOuniJiGfoiMeHqdaDybpqo1bIrxSlvGRNcVoOsKt2/KP1DzW4ARZ
+hoRvayU2apHz/T5TAailqAW2MsrjGRaVHQTmeZKag8CKtAcjWzui0J2DnfXxUMn8
+R3ruFu3xJduOT1VghT9L9udvX9YhPCIKVL9+B5eFX9eMV6N7hUnVug==
+-----END CERTIFICATE-----
diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/client.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/client.cert.pem
new file mode 100644
index 0000000000..b6f4280168
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/client.cert.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIExzCCAq+gAwIBAgICEAMwDQYJKoZIhvcNAQELBQAwRzELMAkGA1UEBhMCdXMx
+DjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEYMBYGA1UEAwwPaW50ZXJt
+ZWRpYXRlIGNhMB4XDTE3MTEwMjAwMzgwMFoXDTI3MTAzMTAwMzgwMFowPjELMAkG
+A1UEBhMCdXMxDjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEPMA0GA1UE
+AwwGY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyxZFTLqv
+Gd9SpFAykyRyLQgHcR5hgD55mz+9fl1OfnMoAc7yTdPVLksDLmeFUlxcvCtLHysJ
+klIBX62c6LzbsVcfLg/DPJlQxFnkhJCRKen4fp7x9h62qqJkDFVXsiEFza9L1lsN
+4OwqU8i4RRgZ/xggM/s/wVBtynioeW9QADNmKZ1n6HVKkYwdOynbFSggYfFrL3HL
+54bC9roZUETin0G5wZ9QU+srgivT0a/KC3ourBYHXAI40iHuuOBf3syDVJ6xId/r
+3UO3qkiQ5q7pwglg+8Nx7Q3CFtGZY3ewxSSSDo6BOyweGYMsBaxMO3EyTqecyfXn
+3n4XPqwmDalWYQIDAQABo4HFMIHCMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQD
+AgWgMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBDbGllbnQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFP2bodoNQ1tCNEOALPnygGMUfNI+MB8GA1UdIwQY
+MBaAFOWzLd7eBJwSNbzRqNsD7MQDCHg/MA4GA1UdDwEB/wQEAwIF4DAdBgNVHSUE
+FjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDQYJKoZIhvcNAQELBQADggIBAHqUuCLt
+olOdR9p/g+KgGPnKuVgMn15Wc2VLCrbbl2P0fuCcNWmnBKqHHgQ1EJEpgnQ2N8m6
+tOGucX7IAzlZj36RP4lN3gZqFRSO/OiTOUYpE6Uv1hYRxeMzAYo5sBdCiiypjV9z
+H0Ew5NuWRf2/0nFWoywB9ktHcfD8lRFI3o8zUFXmE2JSUPQtKhW3tBkPPjYBlgzD
+RD8cq8dVK9P7i3tUENP+MNHJToNLFBqfA9De6bKnhCWHhZkfB0VeeSm4Ja9HkCg/
+DB+PAKMfbLCH5T8gCpEWxNlvj09r9mn37fNjtJPO/goAcNZNO2AURmb/ZQ4ggdry
+xb6lm832qplMUMWx//Ore0faEodlEc5d2kEtmcjj79gAypcLmm74q7CPt7xmniyd
+XvNT33S2tkh4dSirpCVwq0xyqOP3ZqTsTjudTveTBaTZNhTbCjDbaV7ga47TcH9/
++OZ3fQKjt2LAC6162wgEFZf10nUgaAXvSlI74gru93vEwWd8Pd3sWfGwuAFX3oKI
+JuwL2kxEuoZQmeRiVJu6KQb+Im7d5CIoWViDmfxcSDJfdtSePTqmDURIx87fw14Z
+XBWJP4PiK5PRmG/L0cGiDckmDKm/MuD13Z2I/NMl81GNY/q3WY2O7BmddPpAG5dr
+sc5hOqA9+jX08XbxKnfBPYllK5skYMkFH5tN
+-----END CERTIFICATE-----
diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/intermediate.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/intermediate.cert.pem
new file mode 100644
index 0000000000..4305e5333f
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/intermediate.cert.pem
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFaDCCA1CgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzELMAkGA1UEBhMCdXMx
+DjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEQMA4GA1UEAwwHcm9vdCBj
+YTAeFw0xNzExMDIwMDM3NTlaFw0yNzEwMzEwMDM3NTlaMEcxCzAJBgNVBAYTAnVz
+MQ4wDAYDVQQIDAVkdW1teTEOMAwGA1UECgwFZHVtbXkxGDAWBgNVBAMMD2ludGVy
+bWVkaWF0ZSBjYTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKuM2iFz
+CCKmbs4uLj/8wjtxf+jFmkwzN4Pps4hqJ3NJqWB326LhzWyqM4WiTAJWE02wSJbS
+16RPfbjkVC77OI4+PUdwqxU9vNAP/95w0h6hBSFtkysuT5VVUt5jiY7wnUKgqTCi
+MYhYOl+HEP32O4cnxAazkUKKvtyrd4/PvejJ9zz+iYexRnaaGfOFR3co7jQ5QKar
+oK4UgJC3mVDZQEMBV0oljkpgVQMAVb4XQU7e+o25JOUkOoK6LdK/b/95khR0jTyD
+OBLqd4mCEzxNi+jZ0jLTLPk0c+DnGmRfoNUxnFb40R8QnEIEKwf+JKyl6p89oqOl
+pvIZFLZlUWIS4qL+993l1SCqPkWJOAdTg+s/Zh6DeAOhrUn9/wk0aQwZrK7wQQLJ
+4GGhxC/FfuUGsLqZszAVkP8jDEWnzhN2rw3V+C7v6lj4qHhUwqGHuYzCx2Hxl+B8
+UyBmZb9gXKVUtAvaZjaL2PDj1ZAxT0KVMlw1ZVrZu45OsHNQuBx/4uIAt6Rga8yt
+av1lsq+hFqwI4bU/oZC/oPMacOsB4qEkAA1101WjMc5bg6JOPWobwIqmUXQR1WJE
+j30e99HCpk1Cc2+9sUCzNu8KvU5kUY2K90zwqProvj5IfMuDetAVXsEjgW+ZqSho
+UMIpJ2M/hzAFl8Z5IRlG+YNfZNXl0FqJ5LzLAgMBAAGjZjBkMB0GA1UdDgQWBBTl
+sy3e3gScEjW80ajbA+zEAwh4PzAfBgNVHSMEGDAWgBTgTvUeshGOijhPmkgpcA9g
+ULVlyjASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
+9w0BAQsFAAOCAgEAOS7DtliOUPcVosRfyx9dHcSUc3O+uY8uKjSHhdIrxDJm4lwP
+Q6lKg5j8CdMVb+sDQmyBkqQIA/6E13corP6R283jO6W8D4A8kjOiQWpXfjW6OcP3
+4rrDEWhCdeLFSNJIYOFkr2qWJpI/k0VpyDnmY0YluS5WbNjg6zTzGelzhFbV7/S1
+cteNAZD0vHD8NmbLVDJjjIY3E/iwzoUzBncLYbDwqyVS1g6utWdSy8LEJxzzqqWJ
+pBKlNYILAdh8efBgvotafaxsn2nfjmVmekPn3KcQZuE4Kzv1EQ2PrHpGeJKwh6up
+YBL2tav5cAki8bWoGPr2oGmWUf9L2tB57SdWdaY60ifzmQaeGiWPZBSmAz7PRSrz
+sR9SMIkBfYVRxXgWwlvr8JYnd2h/Ef5K9fI32nGfje+7/0kPEjNyjehri7sV4Sjt
+zzkDiFO+JklrRuLBPMFYOokq6Pcko32FKlE82pe8QkMDS8Sk//9PqCTK9ceB7y6E
+NYLNBW/X9SAw/TR5kdRinHHgHyEug7N4+DCU3lU1wl72ZjoiGE7V6c2AssFC2VcE
+E+WYxJT1ROJ1/5+U6BKdaIpTwMtRIFRomOEI66iOwOSEwqLIztkqxwpQ7THraWKm
+2W5e54u/efapIDcQFnP3E8r7TD0PdIeU6mD28o0+WiK3uL/OZpvyKaHPeFU=
+-----END CERTIFICATE-----
diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/localhost-1.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/localhost-1.cert.pem
new file mode 100644
index 0000000000..2850e42fe9
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/localhost-1.cert.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIFFzCCAv+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwRzELMAkGA1UEBhMCdXMx
+DjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEYMBYGA1UEAwwPaW50ZXJt
+ZWRpYXRlIGNhMB4XDTE3MTEwMjAwMzc1OVoXDTI3MTAzMTAwMzc1OVowTTELMAkG
+A1UEBhMCdXMxDjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEKMAgGA1UE
+CwwBMTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAycY/7H1xk3/XHZRopULV7YsOzPIrMG25zoACbpDZxjS0I+2r1c7V
+wnvE8TszAkloLi+Skku5CYC7IvVEEEuKuIuV+8M48FJEwlCPge8LPiy18C+npCEd
+fgDzCV/O9DfJj6UaiCUayVE7UujXoke7AlKQEJcqvnD/CoTv2Y8jV1A6mPf6CTEI
+Sl1BMeFSmeFyvZll+xJ8Up1KfQZxKhtpP1s/rp6ZNlqSs1LM5+vcDHHZ6COTbq7t
+2vvcmGDTqeCLsqicBg1kJyMPRtqa0bNPj2bcVtcK0Ndfn6eL2hi+EoBy2nIXi6aG
+PpXf85b9bCLd5pZI80nHzFlhdvV+SxqrfwIDAQABo4IBBTCCAQEwCQYDVR0TBAIw
+ADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4QgENBCYWJE9wZW5TU0wgR2Vu
+ZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUoYjECaDz/ZELru/r
+jfTB1ShlVrAwaAYDVR0jBGEwX4AU5bMt3t4EnBI1vNGo2wPsxAMIeD+hQ6RBMD8x
+CzAJBgNVBAYTAnVzMQ4wDAYDVQQIDAVkdW1teTEOMAwGA1UECgwFZHVtbXkxEDAO
+BgNVBAMMB3Jvb3QgY2GCAhAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr
+BgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEAiiR2knMMym4O+3fD1KlYSnc2UR3v
+0FlRVAsr8wvTlVjJhx7DbRusBNJHWX66mUgK9x5OLnhyvyqlFVhR9AwlnxgfLWz9
+nnACeXzcjQZnKWFQWu8bJSC6Ene6rd1g2acK6SOjxavVbj7JVFnmlHF/naZUzvMl
+mJivYta4k7ob8UcX0I5TlJpzglU3UHyyJd5d9zhbF8wqbBq63zR2ovWci4pYCg+F
+jYcTGYVZJti3SHO+9/EqTC9x2KDNs3o0+rreJ3GuoonkInKZMQQZJQ6qILvkxlhT
+jyU5xlcaJ+0tSaiFK3eF0nXIpFYdZbIHYPCdLjh9AZ2dkFcAgSa/L8+tsVt60k8D
+HTO0Hz6dW5D2ckeebZvz5LACMN89gVzrc/rVkeg7QmpSbjkTSLC2KJS53hJzWcEI
+3KB73B9iY+ZYytcYBTYLizsAxd5g7j9z8UXrmVQ4mWbh2+xKiG+9aVOzCZ09AYi6
+WVK2aRcMQshgkkqPOloN9OeQNCE8Exf7N/zHsBhygorJXoD/PFgnV1VZm8xkOdiJ
+zTb3bpGdmL5+bzzS6wP8Q7pGZGYdlnB7JNO8oMYPPtzX8OOx92BTkPnqJnnRWTpR
+SjMEEdQe8K7iXxejQkjaAq5BlwaAOjCjPTqYomECcYjC0WaXsmrPcnZwSqpnHZZ2
+OiINYJub5cvBLNo=
+-----END CERTIFICATE-----
diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/client.key.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/client.key.pem
new file mode 100644
index 0000000000..a4c5fd4a56
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/client.key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAyxZFTLqvGd9SpFAykyRyLQgHcR5hgD55mz+9fl1OfnMoAc7y
+TdPVLksDLmeFUlxcvCtLHysJklIBX62c6LzbsVcfLg/DPJlQxFnkhJCRKen4fp7x
+9h62qqJkDFVXsiEFza9L1lsN4OwqU8i4RRgZ/xggM/s/wVBtynioeW9QADNmKZ1n
+6HVKkYwdOynbFSggYfFrL3HL54bC9roZUETin0G5wZ9QU+srgivT0a/KC3ourBYH
+XAI40iHuuOBf3syDVJ6xId/r3UO3qkiQ5q7pwglg+8Nx7Q3CFtGZY3ewxSSSDo6B
+OyweGYMsBaxMO3EyTqecyfXn3n4XPqwmDalWYQIDAQABAoIBAFhIOR3OtVlw3BLz
+jdiq6jsrF1kUFNxTzDcxsSUiWIHde1G17Vzpre0uzJY6iBkyb1mZFFHbOpDxtwkp
+hmEh3/qqXbJ/RaatGxAP56e81G28+LnKTHJqDYwFhapa2wFjG4u7HSN0d4cEAq5j
+Pb9DZ+GdUjpmiON3HBL8+ne3bLZ42uI+DSVe8d3irbqg2rqsiANf0gdimMW4nuI4
+rVxf8HrY43PdQn/Vby+7qLRE3tmIlpbTqJGRtWRjdeBBI91APCrRljjXrKqT6Zpa
+E6Daz3YIQvXkIT0q+WkeN1VmQbtRnk7kRsPNp15kSwpHfmv6o/vkO9OUb1n71P2F
+wnB0WDECgYEA8iltnKxXnjqwZ/vzIWzcd94j+mdZg/K2/JCOqjwMvpSGCvx2zUmq
+Y2nxO2K85AVeOm/Yt87SMODB6AQ9CsrVGEUAzzacvCJDb8oUhaOL5gypnyvZiGCy
+snzXfgB+v/xuGekIjs2y7E8h3GG40j0aNQnUY1Fuc6iaeJG4BtjkuQUCgYEA1rE4
+DrTSsUh3hLYQusIHZR8Lecrrd4QUZSMKLkWjobiSTw3m4mglx1s2G4eZ3WuzOyFq
+Dp3/b3yfT8prdPBGA6shHNFf+1TO1q1/pIt15dc3sFwxMkuunai8N4QZJRqZLbYq
+FkNFkZ20hFHcH/NHDsAsRL/0tJdEmJ2ruP+Qdq0CgYBsdPGKwgVb8J0hdU4nIkJ7
+zRoABFmrJwGdjIDY7Zwnnw2JzhjHSL7vV3ubRVWkKmNReNZvPEoXahJuf7d3JfDa
+tczvAV6hRBc/8hnO4Li/h9xQVatP0T83gYJiBIbAJaaKJDyY+Lex7p8TvRCx2Hvs
+VUKyWL5HPrQwW9M3/dwyoQKBgQCNQoPA4Wcz8Jt7PZQaXaoh9eBGHab6t3P366s6
+MOXudZQG4f3FgINC/ZfHW1x43PFL+btfrMOyJkxoYqZ7hdB7f3DFFlpR80Y46GVw
+7bYAKbBhoPdZwYQ+BhT5bjhhOnQJKK/egBrZKevpmDb+6sIZSYaXIbovzMv8otmn
+WrhB7QKBgAdl+KYBQULCUBp8qCQH5sAQoWErpyuD2FNN6LGknpPqn4DdujvwEP0Z
+OSvbauLkI0Qc9/MezKPTeYXlFqdbpItwyySJsUkiI3HhVYlBgDkZ7xb6uHIH5E6I
+bKgIW5JEf5I7Eu1iurORkXxCCGMkiQmEs4X5kSXXRYgXfNgAD0FX
+-----END RSA PRIVATE KEY-----
diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/localhost-1.key.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/localhost-1.key.pem
new file mode 100644
index 0000000000..8cba174841
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/localhost-1.key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAycY/7H1xk3/XHZRopULV7YsOzPIrMG25zoACbpDZxjS0I+2r
+1c7VwnvE8TszAkloLi+Skku5CYC7IvVEEEuKuIuV+8M48FJEwlCPge8LPiy18C+n
+pCEdfgDzCV/O9DfJj6UaiCUayVE7UujXoke7AlKQEJcqvnD/CoTv2Y8jV1A6mPf6
+CTEISl1BMeFSmeFyvZll+xJ8Up1KfQZxKhtpP1s/rp6ZNlqSs1LM5+vcDHHZ6COT
+bq7t2vvcmGDTqeCLsqicBg1kJyMPRtqa0bNPj2bcVtcK0Ndfn6eL2hi+EoBy2nIX
+i6aGPpXf85b9bCLd5pZI80nHzFlhdvV+SxqrfwIDAQABAoIBAQC022161aoTEtjH
+m7n8v56vUCCRFVQfEYsljFohrtZ0sdLyDVwjxkSWEYiizXRYTWIDXALd/N+7o9aZ
+bAx5Kq0J45wpUYBc8PDO15T6W0DRlxPxWVXDaSddRQ6TTXxcLREPH2dbtx5+asBo
+/Woi/Haki0q0hDr8/p2sWSH/+SwtWpOezGVlrWrkMeIhlBwHZfdHVoZvSx65Uv7x
+WU07vsjrbXNDwf+2fmklAQrzhedCeh8loGyjtN3cfrTjrE1zqpEsHnlZcJxe6sRB
+1nOqpoUnpZXklDDIYC8EmeubmDJ0jnXOQCDDep3MzVcnZGyF5E/+szaa1NL70Ayj
+rbKk1Y3ZAoGBAPy/1ym7Cjl4OGHN2fdkR6iL68ebJozpr+eTSxDNLuBSi5IJxJyG
+1+B4+v1u0RwZ3DjrSQsO5DCbZ+DHU6O/DAJK2CxUED+M+G2kRyffailRQmNzjpRG
+75dIhSkSRYH8vdvEOnGpeQBZwBcCRH/2YUMlZeSfx9fHJhk1nyUxJeHjAoGBAMxe
+k+cBb0zYok+Ww1xTwOdq0PwKj0oDsEg8hOdWc8pH0SlOAB4BI5kmfd1JDMHfRc49
+7tpNqjsPrnlb9xd8l0281Lj2NoVSE5KX1JtsOsKecQsvHH5zRk4eJ3h/mNixpjfe
+79Zc/O40T4rWpQRqhat+WHveJC0/ON4AH4uT0BK1AoGBAPcTioCu6YXYsjVaCJPB
+IhPwBGOylfL2lxDoel9IVWTRDMOMbPkfEHXNjn6lECJKXW//Af6fZg7mPJwN/wN5
+xYGQLNbYrrGRW2HDUBP4YU1WtHGIC3+EAL+BEztdMzmpGuh1YTSvmSvwkMltXA1D
+iz0amArw72lOsz29n3+6FfBFAoGAIpRqMC8k9vq80/yth6TAQifnvo3G2v4uyLo8
+vqv5IaPvNy70hB8rN9G0gEnI99Dgjdoa3SNBB4dKvUwbTgUN0OB/meBHL13I5Af+
+uGGiu6V1eS/6gUbeAX/Gq/PjF99PQareKAZJ4cBGKTbSayHfBjp1nFflBSbqZ13b
++JEFJvUCgYBOs2J2XXamPbI7gu7B2TE9j/62v0SJyoHq2LHMmYUDRuPdPk3eKCt3
+283w+E8XUIFbctaxsbo8msNjjvV22D/Nci3d87aPe8bn1SVto3GnTuwnOpRq3E+3
+wAarqrhiZbGZSCcAkEOk7FlxAwYnCM6paqMxDEMCJ4qChMM42E9ZyQ==
+-----END RSA PRIVATE KEY-----
diff --git a/src/python/grpcio_tests/tests/unit/resources.py b/src/python/grpcio_tests/tests/unit/resources.py
index 823d2307d3..11ef9e8565 100644
--- a/src/python/grpcio_tests/tests/unit/resources.py
+++ b/src/python/grpcio_tests/tests/unit/resources.py
@@ -11,7 +11,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.
-"""Constants and functions for data used in interoperability testing."""
+"""Constants and functions for data used in testing."""
import os
@@ -34,3 +34,81 @@ def private_key():
def certificate_chain():
return pkg_resources.resource_string(__name__,
_CERTIFICATE_CHAIN_RESOURCE_PATH)
+
+
+def cert_hier_1_root_ca_cert():
+ return pkg_resources.resource_string(
+ __name__, 'credentials/certificate_hierarchy_1/certs/ca.cert.pem')
+
+
+def cert_hier_1_intermediate_ca_cert():
+ return pkg_resources.resource_string(
+ __name__,
+ 'credentials/certificate_hierarchy_1/intermediate/certs/intermediate.cert.pem'
+ )
+
+
+def cert_hier_1_client_1_key():
+ return pkg_resources.resource_string(
+ __name__,
+ 'credentials/certificate_hierarchy_1/intermediate/private/client.key.pem'
+ )
+
+
+def cert_hier_1_client_1_cert():
+ return pkg_resources.resource_string(
+ __name__,
+ 'credentials/certificate_hierarchy_1/intermediate/certs/client.cert.pem')
+
+
+def cert_hier_1_server_1_key():
+ return pkg_resources.resource_string(
+ __name__,
+ 'credentials/certificate_hierarchy_1/intermediate/private/localhost-1.key.pem'
+ )
+
+
+def cert_hier_1_server_1_cert():
+ return pkg_resources.resource_string(
+ __name__,
+ 'credentials/certificate_hierarchy_1/intermediate/certs/localhost-1.cert.pem'
+ )
+
+
+def cert_hier_2_root_ca_cert():
+ return pkg_resources.resource_string(
+ __name__, 'credentials/certificate_hierarchy_2/certs/ca.cert.pem')
+
+
+def cert_hier_2_intermediate_ca_cert():
+ return pkg_resources.resource_string(
+ __name__,
+ 'credentials/certificate_hierarchy_2/intermediate/certs/intermediate.cert.pem'
+ )
+
+
+def cert_hier_2_client_1_key():
+ return pkg_resources.resource_string(
+ __name__,
+ 'credentials/certificate_hierarchy_2/intermediate/private/client.key.pem'
+ )
+
+
+def cert_hier_2_client_1_cert():
+ return pkg_resources.resource_string(
+ __name__,
+ 'credentials/certificate_hierarchy_2/intermediate/certs/client.cert.pem')
+
+
+def cert_hier_2_server_1_key():
+ return pkg_resources.resource_string(
+ __name__,
+ 'credentials/certificate_hierarchy_2/intermediate/private/localhost-1.key.pem'
+ )
+
+
+def cert_hier_2_server_1_cert():
+ return pkg_resources.resource_string(
+ __name__,
+ 'credentials/certificate_hierarchy_2/intermediate/certs/localhost-1.cert.pem'
+ )
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 0588787910..3eb838857a 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -215,7 +215,7 @@
ifeq ($(SYSTEM),Darwin)
CXXFLAGS += -stdlib=libc++
endif
- % for arg in ['CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'LDFLAGS', 'DEFINES']:
+ % for arg in ['CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'COREFLAGS', 'LDFLAGS', 'DEFINES']:
% if defaults.get('global', []).get(arg, None) is not None:
${arg} += ${defaults.get('global').get(arg)}
% endif
@@ -1268,6 +1268,16 @@
$(Q) mkdir -p `dirname $@`
$(Q) $(HOST_CXX) $(HOST_CXXFLAGS) $(HOST_CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+ $(OBJDIR)/$(CONFIG)/src/core/%.o : src/core/%.cc
+ $(E) "[CXX] Compiling $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COREFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+
+ $(OBJDIR)/$(CONFIG)/test/core/%.o : test/core/%.cc
+ $(E) "[CXX] Compiling $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COREFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
+
$(OBJDIR)/$(CONFIG)/%.o : %.cc
$(E) "[CXX] Compiling $<"
$(Q) mkdir -p `dirname $@`
diff --git a/templates/test/core/surface/public_headers_must_be_c89.c.template b/templates/test/core/surface/public_headers_must_be_c89.c.template
index e2d3b1810a..6e4a83666e 100644
--- a/templates/test/core/surface/public_headers_must_be_c89.c.template
+++ b/templates/test/core/surface/public_headers_must_be_c89.c.template
@@ -48,10 +48,8 @@
#include <stdio.h>
int main(int argc, char **argv) {
- if(argc == 12345678) {
- % for fn in fns:
- printf("%lx", (unsigned long) ${fn});
- % endfor
- }
+ % for fn in fns:
+ printf("%lx", (unsigned long) ${fn});
+ % endfor
return 0;
}
diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc
index 5ac783611d..c49a866a6c 100644
--- a/test/core/end2end/fixtures/http_proxy_fixture.cc
+++ b/test/core/end2end/fixtures/http_proxy_fixture.cc
@@ -88,9 +88,11 @@ typedef struct proxy_connection {
grpc_slice_buffer client_read_buffer;
grpc_slice_buffer client_deferred_write_buffer;
+ bool client_is_writing;
grpc_slice_buffer client_write_buffer;
grpc_slice_buffer server_read_buffer;
grpc_slice_buffer server_deferred_write_buffer;
+ bool server_is_writing;
grpc_slice_buffer server_write_buffer;
grpc_http_parser http_parser;
@@ -141,6 +143,7 @@ static void proxy_connection_failed(proxy_connection* conn, bool is_client,
// Callback for writing proxy data to the client.
static void on_client_write_done(void* arg, grpc_error* error) {
proxy_connection* conn = (proxy_connection*)arg;
+ conn->client_is_writing = false;
if (error != GRPC_ERROR_NONE) {
proxy_connection_failed(conn, true /* is_client */,
"HTTP proxy client write", error);
@@ -153,6 +156,7 @@ static void on_client_write_done(void* arg, grpc_error* error) {
if (conn->client_deferred_write_buffer.length > 0) {
grpc_slice_buffer_move_into(&conn->client_deferred_write_buffer,
&conn->client_write_buffer);
+ conn->client_is_writing = true;
grpc_endpoint_write(conn->client_endpoint, &conn->client_write_buffer,
&conn->on_client_write_done);
} else {
@@ -164,6 +168,7 @@ static void on_client_write_done(void* arg, grpc_error* error) {
// Callback for writing proxy data to the backend server.
static void on_server_write_done(void* arg, grpc_error* error) {
proxy_connection* conn = (proxy_connection*)arg;
+ conn->server_is_writing = false;
if (error != GRPC_ERROR_NONE) {
proxy_connection_failed(conn, false /* is_client */,
"HTTP proxy server write", error);
@@ -176,6 +181,7 @@ static void on_server_write_done(void* arg, grpc_error* error) {
if (conn->server_deferred_write_buffer.length > 0) {
grpc_slice_buffer_move_into(&conn->server_deferred_write_buffer,
&conn->server_write_buffer);
+ conn->server_is_writing = true;
grpc_endpoint_write(conn->server_endpoint, &conn->server_write_buffer,
&conn->on_server_write_done);
} else {
@@ -199,13 +205,14 @@ static void on_client_read_done(void* arg, grpc_error* error) {
// the current write is finished.
//
// Otherwise, move the read data into the write buffer and write it.
- if (conn->server_write_buffer.length > 0) {
+ if (conn->server_is_writing) {
grpc_slice_buffer_move_into(&conn->client_read_buffer,
&conn->server_deferred_write_buffer);
} else {
grpc_slice_buffer_move_into(&conn->client_read_buffer,
&conn->server_write_buffer);
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);
}
@@ -229,13 +236,14 @@ static void on_server_read_done(void* arg, grpc_error* error) {
// the current write is finished.
//
// Otherwise, move the read data into the write buffer and write it.
- if (conn->client_write_buffer.length > 0) {
+ if (conn->client_is_writing) {
grpc_slice_buffer_move_into(&conn->server_read_buffer,
&conn->client_deferred_write_buffer);
} else {
grpc_slice_buffer_move_into(&conn->server_read_buffer,
&conn->client_write_buffer);
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);
}
@@ -247,6 +255,7 @@ static void on_server_read_done(void* arg, grpc_error* error) {
// Callback to write the HTTP response for the CONNECT request.
static void on_write_response_done(void* arg, grpc_error* error) {
proxy_connection* conn = (proxy_connection*)arg;
+ conn->client_is_writing = false;
if (error != GRPC_ERROR_NONE) {
proxy_connection_failed(conn, true /* is_client */,
"HTTP proxy write response", error);
@@ -286,6 +295,7 @@ static void on_server_connect_done(void* arg, grpc_error* error) {
grpc_slice slice =
grpc_slice_from_copied_string("HTTP/1.0 200 connected\r\n\r\n");
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);
}
@@ -429,9 +439,11 @@ static void on_accept(void* arg, grpc_endpoint* endpoint,
grpc_combiner_scheduler(conn->proxy->combiner));
grpc_slice_buffer_init(&conn->client_read_buffer);
grpc_slice_buffer_init(&conn->client_deferred_write_buffer);
+ conn->client_is_writing = false;
grpc_slice_buffer_init(&conn->client_write_buffer);
grpc_slice_buffer_init(&conn->server_read_buffer);
grpc_slice_buffer_init(&conn->server_deferred_write_buffer);
+ conn->server_is_writing = false;
grpc_slice_buffer_init(&conn->server_write_buffer);
grpc_http_parser_init(&conn->http_parser, GRPC_HTTP_REQUEST,
&conn->http_request);
diff --git a/test/core/iomgr/timer_list_test.cc b/test/core/iomgr/timer_list_test.cc
index 3041674bd7..a4a53a0e46 100644
--- a/test/core/iomgr/timer_list_test.cc
+++ b/test/core/iomgr/timer_list_test.cc
@@ -28,11 +28,12 @@
#include <grpc/support/log.h>
#include "src/core/lib/debug/trace.h"
#include "test/core/util/test_config.h"
+#include "test/core/util/tracer_util.h"
#define MAX_CB 30
-extern "C" grpc_tracer_flag grpc_timer_trace;
-extern "C" grpc_tracer_flag grpc_timer_check_trace;
+extern grpc_core::TraceFlag grpc_timer_trace;
+extern grpc_core::TraceFlag grpc_timer_check_trace;
static int cb_called[MAX_CB][2];
@@ -48,8 +49,8 @@ static void add_test(void) {
gpr_log(GPR_INFO, "add_test");
grpc_timer_list_init();
- grpc_timer_trace.value = 1;
- grpc_timer_check_trace.value = 1;
+ 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_millis start = grpc_core::ExecCtx::Get()->Now();
@@ -113,8 +114,8 @@ void destruction_test(void) {
grpc_core::ExecCtx::Get()->TestOnlySetNow(0);
grpc_timer_list_init();
- grpc_timer_trace.value = 1;
- grpc_timer_check_trace.value = 1;
+ 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(
diff --git a/test/core/support/BUILD b/test/core/support/BUILD
index 9d042fdc9f..69512cd9a9 100644
--- a/test/core/support/BUILD
+++ b/test/core/support/BUILD
@@ -139,6 +139,16 @@ grpc_cc_test(
)
grpc_cc_test(
+ name = "manual_constructor_test",
+ srcs = ["manual_constructor_test.cc"],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//test/core/util:gpr_test_util",
+ ],
+)
+
+grpc_cc_test(
name = "spinlock_test",
srcs = ["spinlock_test.cc"],
language = "C++",
diff --git a/test/core/support/manual_constructor_test.cc b/test/core/support/manual_constructor_test.cc
new file mode 100644
index 0000000000..714f8b21a0
--- /dev/null
+++ b/test/core/support/manual_constructor_test.cc
@@ -0,0 +1,99 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/* Test of gpr synchronization support. */
+
+#include "src/core/lib/support/manual_constructor.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <cstring>
+#include "src/core/lib/support/abstract.h"
+#include "test/core/util/test_config.h"
+
+class A {
+ public:
+ A() {}
+ virtual ~A() {}
+ virtual const char* foo() { return "A_foo"; }
+ virtual const char* bar() { return "A_bar"; }
+ GRPC_ABSTRACT_BASE_CLASS
+};
+
+class B : public A {
+ public:
+ B() {}
+ ~B() {}
+ const char* foo() override { return "B_foo"; }
+ char get_junk() { return junk[0]; }
+
+ private:
+ char junk[1000];
+};
+
+class C : public B {
+ public:
+ C() {}
+ ~C() {}
+ virtual const char* bar() { return "C_bar"; }
+ char get_more_junk() { return more_junk[0]; }
+
+ private:
+ char more_junk[1000];
+};
+
+class D : public A {
+ public:
+ virtual const char* bar() { return "D_bar"; }
+};
+
+static void basic_test() {
+ grpc_core::PolymorphicManualConstructor<A, B> poly;
+ poly.Init<B>();
+ GPR_ASSERT(!strcmp(poly->foo(), "B_foo"));
+ GPR_ASSERT(!strcmp(poly->bar(), "A_bar"));
+}
+
+static void complex_test() {
+ grpc_core::PolymorphicManualConstructor<A, B, C, D> polyB;
+ polyB.Init<B>();
+ GPR_ASSERT(!strcmp(polyB->foo(), "B_foo"));
+ GPR_ASSERT(!strcmp(polyB->bar(), "A_bar"));
+
+ grpc_core::PolymorphicManualConstructor<A, B, C, D> polyC;
+ polyC.Init<C>();
+ GPR_ASSERT(!strcmp(polyC->foo(), "B_foo"));
+ GPR_ASSERT(!strcmp(polyC->bar(), "C_bar"));
+
+ grpc_core::PolymorphicManualConstructor<A, B, C, D> polyD;
+ polyD.Init<D>();
+ GPR_ASSERT(!strcmp(polyD->foo(), "A_foo"));
+ GPR_ASSERT(!strcmp(polyD->bar(), "D_bar"));
+}
+
+/* ------------------------------------------------- */
+
+int main(int argc, char* argv[]) {
+ grpc_test_init(argc, argv);
+ basic_test();
+ complex_test();
+ 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 db9f902dbf..b5a83c8eed 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -66,288 +66,286 @@
#include <stdio.h>
int main(int argc, char **argv) {
- if(argc == 12345678) {
- printf("%lx", (unsigned long) grpc_compression_algorithm_parse);
- printf("%lx", (unsigned long) grpc_compression_algorithm_name);
- printf("%lx", (unsigned long) grpc_stream_compression_algorithm_name);
- printf("%lx", (unsigned long) grpc_compression_algorithm_for_level);
- printf("%lx", (unsigned long) grpc_stream_compression_algorithm_for_level);
- printf("%lx", (unsigned long) grpc_compression_options_init);
- printf("%lx", (unsigned long) grpc_compression_options_enable_algorithm);
- printf("%lx", (unsigned long) grpc_compression_options_disable_algorithm);
- printf("%lx", (unsigned long) grpc_compression_options_is_algorithm_enabled);
- printf("%lx", (unsigned long) grpc_compression_options_is_stream_compression_algorithm_enabled);
- printf("%lx", (unsigned long) grpc_metadata_array_init);
- printf("%lx", (unsigned long) grpc_metadata_array_destroy);
- printf("%lx", (unsigned long) grpc_call_details_init);
- printf("%lx", (unsigned long) grpc_call_details_destroy);
- printf("%lx", (unsigned long) grpc_register_plugin);
- printf("%lx", (unsigned long) grpc_init);
- printf("%lx", (unsigned long) grpc_shutdown);
- printf("%lx", (unsigned long) grpc_version_string);
- printf("%lx", (unsigned long) grpc_g_stands_for);
- 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);
- printf("%lx", (unsigned long) grpc_completion_queue_next);
- printf("%lx", (unsigned long) grpc_completion_queue_pluck);
- printf("%lx", (unsigned long) grpc_completion_queue_shutdown);
- printf("%lx", (unsigned long) grpc_completion_queue_destroy);
- printf("%lx", (unsigned long) grpc_completion_queue_thread_local_cache_init);
- printf("%lx", (unsigned long) grpc_completion_queue_thread_local_cache_flush);
- printf("%lx", (unsigned long) grpc_alarm_create);
- printf("%lx", (unsigned long) grpc_alarm_set);
- printf("%lx", (unsigned long) grpc_alarm_cancel);
- printf("%lx", (unsigned long) grpc_alarm_destroy);
- printf("%lx", (unsigned long) grpc_channel_check_connectivity_state);
- printf("%lx", (unsigned long) grpc_channel_num_external_connectivity_watchers);
- printf("%lx", (unsigned long) grpc_channel_watch_connectivity_state);
- printf("%lx", (unsigned long) grpc_channel_support_connectivity_watcher);
- printf("%lx", (unsigned long) grpc_channel_create_call);
- printf("%lx", (unsigned long) grpc_channel_ping);
- printf("%lx", (unsigned long) grpc_channel_register_call);
- printf("%lx", (unsigned long) grpc_channel_create_registered_call);
- printf("%lx", (unsigned long) grpc_call_arena_alloc);
- printf("%lx", (unsigned long) grpc_call_start_batch);
- printf("%lx", (unsigned long) grpc_call_get_peer);
- printf("%lx", (unsigned long) grpc_census_call_set_context);
- printf("%lx", (unsigned long) grpc_census_call_get_context);
- printf("%lx", (unsigned long) grpc_channel_get_target);
- printf("%lx", (unsigned long) grpc_channel_get_info);
- printf("%lx", (unsigned long) grpc_insecure_channel_create);
- printf("%lx", (unsigned long) grpc_lame_client_channel_create);
- printf("%lx", (unsigned long) grpc_channel_destroy);
- printf("%lx", (unsigned long) grpc_call_cancel);
- printf("%lx", (unsigned long) grpc_call_cancel_with_status);
- printf("%lx", (unsigned long) grpc_call_ref);
- printf("%lx", (unsigned long) grpc_call_unref);
- printf("%lx", (unsigned long) grpc_server_request_call);
- printf("%lx", (unsigned long) grpc_server_register_method);
- printf("%lx", (unsigned long) grpc_server_request_registered_call);
- printf("%lx", (unsigned long) grpc_server_create);
- printf("%lx", (unsigned long) grpc_server_register_completion_queue);
- printf("%lx", (unsigned long) grpc_server_add_insecure_http2_port);
- printf("%lx", (unsigned long) grpc_server_start);
- printf("%lx", (unsigned long) grpc_server_shutdown_and_notify);
- printf("%lx", (unsigned long) grpc_server_cancel_all_calls);
- printf("%lx", (unsigned long) grpc_server_destroy);
- printf("%lx", (unsigned long) grpc_tracer_set_enabled);
- printf("%lx", (unsigned long) grpc_header_key_is_legal);
- printf("%lx", (unsigned long) grpc_header_nonbin_value_is_legal);
- printf("%lx", (unsigned long) grpc_is_binary_header);
- printf("%lx", (unsigned long) grpc_call_error_to_string);
- printf("%lx", (unsigned long) grpc_resource_quota_create);
- 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_arg_vtable);
- printf("%lx", (unsigned long) grpc_auth_property_iterator_next);
- printf("%lx", (unsigned long) grpc_auth_context_property_iterator);
- printf("%lx", (unsigned long) grpc_auth_context_peer_identity);
- printf("%lx", (unsigned long) grpc_auth_context_find_properties_by_name);
- printf("%lx", (unsigned long) grpc_auth_context_peer_identity_property_name);
- printf("%lx", (unsigned long) grpc_auth_context_peer_is_authenticated);
- printf("%lx", (unsigned long) grpc_call_auth_context);
- printf("%lx", (unsigned long) grpc_auth_context_release);
- printf("%lx", (unsigned long) grpc_auth_context_add_property);
- printf("%lx", (unsigned long) grpc_auth_context_add_cstring_property);
- printf("%lx", (unsigned long) grpc_auth_context_set_peer_identity_property_name);
- printf("%lx", (unsigned long) grpc_channel_credentials_release);
- printf("%lx", (unsigned long) grpc_google_default_credentials_create);
- printf("%lx", (unsigned long) grpc_set_ssl_roots_override_callback);
- printf("%lx", (unsigned long) grpc_ssl_credentials_create);
- printf("%lx", (unsigned long) grpc_call_credentials_release);
- printf("%lx", (unsigned long) grpc_composite_channel_credentials_create);
- printf("%lx", (unsigned long) grpc_composite_call_credentials_create);
- printf("%lx", (unsigned long) grpc_google_compute_engine_credentials_create);
- printf("%lx", (unsigned long) grpc_max_auth_token_lifetime);
- printf("%lx", (unsigned long) grpc_service_account_jwt_access_credentials_create);
- printf("%lx", (unsigned long) grpc_google_refresh_token_credentials_create);
- printf("%lx", (unsigned long) grpc_access_token_credentials_create);
- printf("%lx", (unsigned long) grpc_google_iam_credentials_create);
- printf("%lx", (unsigned long) grpc_metadata_credentials_create_from_plugin);
- printf("%lx", (unsigned long) grpc_secure_channel_create);
- printf("%lx", (unsigned long) grpc_server_credentials_release);
- printf("%lx", (unsigned long) grpc_ssl_server_certificate_config_create);
- printf("%lx", (unsigned long) grpc_ssl_server_certificate_config_destroy);
- printf("%lx", (unsigned long) grpc_ssl_server_credentials_create);
- printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_ex);
- printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_options_using_config);
- printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_options_using_config_fetcher);
- printf("%lx", (unsigned long) grpc_ssl_server_credentials_options_destroy);
- printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_with_options);
- printf("%lx", (unsigned long) grpc_server_add_secure_http2_port);
- printf("%lx", (unsigned long) grpc_call_set_credentials);
- printf("%lx", (unsigned long) grpc_server_credentials_set_auth_metadata_processor);
- printf("%lx", (unsigned long) grpc_raw_byte_buffer_create);
- printf("%lx", (unsigned long) grpc_raw_compressed_byte_buffer_create);
- printf("%lx", (unsigned long) grpc_byte_buffer_copy);
- printf("%lx", (unsigned long) grpc_byte_buffer_length);
- printf("%lx", (unsigned long) grpc_byte_buffer_destroy);
- printf("%lx", (unsigned long) grpc_byte_buffer_reader_init);
- printf("%lx", (unsigned long) grpc_byte_buffer_reader_destroy);
- printf("%lx", (unsigned long) grpc_byte_buffer_reader_next);
- printf("%lx", (unsigned long) grpc_byte_buffer_reader_readall);
- printf("%lx", (unsigned long) grpc_raw_byte_buffer_from_reader);
- printf("%lx", (unsigned long) grpc_slice_ref);
- printf("%lx", (unsigned long) grpc_slice_unref);
- printf("%lx", (unsigned long) grpc_slice_copy);
- printf("%lx", (unsigned long) grpc_slice_new);
- printf("%lx", (unsigned long) grpc_slice_new_with_user_data);
- printf("%lx", (unsigned long) grpc_slice_new_with_len);
- printf("%lx", (unsigned long) grpc_slice_malloc);
- printf("%lx", (unsigned long) grpc_slice_malloc_large);
- printf("%lx", (unsigned long) grpc_slice_intern);
- printf("%lx", (unsigned long) grpc_slice_from_copied_string);
- printf("%lx", (unsigned long) grpc_slice_from_copied_buffer);
- printf("%lx", (unsigned long) grpc_slice_from_static_string);
- printf("%lx", (unsigned long) grpc_slice_from_static_buffer);
- printf("%lx", (unsigned long) grpc_slice_sub);
- printf("%lx", (unsigned long) grpc_slice_sub_no_ref);
- printf("%lx", (unsigned long) grpc_slice_split_tail);
- printf("%lx", (unsigned long) grpc_slice_split_tail_maybe_ref);
- printf("%lx", (unsigned long) grpc_slice_split_head);
- printf("%lx", (unsigned long) grpc_empty_slice);
- printf("%lx", (unsigned long) grpc_slice_default_hash_impl);
- printf("%lx", (unsigned long) grpc_slice_default_eq_impl);
- printf("%lx", (unsigned long) grpc_slice_eq);
- printf("%lx", (unsigned long) grpc_slice_cmp);
- printf("%lx", (unsigned long) grpc_slice_str_cmp);
- printf("%lx", (unsigned long) grpc_slice_buf_start_eq);
- printf("%lx", (unsigned long) grpc_slice_rchr);
- printf("%lx", (unsigned long) grpc_slice_chr);
- printf("%lx", (unsigned long) grpc_slice_slice);
- printf("%lx", (unsigned long) grpc_slice_hash);
- printf("%lx", (unsigned long) grpc_slice_is_equivalent);
- printf("%lx", (unsigned long) grpc_slice_dup);
- printf("%lx", (unsigned long) grpc_slice_to_c_string);
- printf("%lx", (unsigned long) grpc_slice_buffer_init);
- printf("%lx", (unsigned long) grpc_slice_buffer_destroy);
- printf("%lx", (unsigned long) grpc_slice_buffer_add);
- printf("%lx", (unsigned long) grpc_slice_buffer_add_indexed);
- printf("%lx", (unsigned long) grpc_slice_buffer_addn);
- printf("%lx", (unsigned long) grpc_slice_buffer_tiny_add);
- printf("%lx", (unsigned long) grpc_slice_buffer_pop);
- printf("%lx", (unsigned long) grpc_slice_buffer_reset_and_unref);
- printf("%lx", (unsigned long) grpc_slice_buffer_swap);
- printf("%lx", (unsigned long) grpc_slice_buffer_move_into);
- printf("%lx", (unsigned long) grpc_slice_buffer_trim_end);
- printf("%lx", (unsigned long) grpc_slice_buffer_move_first);
- printf("%lx", (unsigned long) grpc_slice_buffer_move_first_no_ref);
- printf("%lx", (unsigned long) grpc_slice_buffer_move_first_into_buffer);
- printf("%lx", (unsigned long) grpc_slice_buffer_take_first);
- printf("%lx", (unsigned long) grpc_slice_buffer_undo_take_first);
- printf("%lx", (unsigned long) gpr_malloc);
- printf("%lx", (unsigned long) gpr_zalloc);
- printf("%lx", (unsigned long) gpr_free);
- printf("%lx", (unsigned long) gpr_realloc);
- printf("%lx", (unsigned long) gpr_malloc_aligned);
- printf("%lx", (unsigned long) gpr_free_aligned);
- printf("%lx", (unsigned long) gpr_set_allocation_functions);
- printf("%lx", (unsigned long) gpr_get_allocation_functions);
- printf("%lx", (unsigned long) gpr_avl_create);
- printf("%lx", (unsigned long) gpr_avl_ref);
- printf("%lx", (unsigned long) gpr_avl_unref);
- printf("%lx", (unsigned long) gpr_avl_add);
- printf("%lx", (unsigned long) gpr_avl_remove);
- printf("%lx", (unsigned long) gpr_avl_get);
- printf("%lx", (unsigned long) gpr_avl_maybe_get);
- printf("%lx", (unsigned long) gpr_avl_is_empty);
- printf("%lx", (unsigned long) gpr_cmdline_create);
- printf("%lx", (unsigned long) gpr_cmdline_add_int);
- printf("%lx", (unsigned long) gpr_cmdline_add_flag);
- printf("%lx", (unsigned long) gpr_cmdline_add_string);
- printf("%lx", (unsigned long) gpr_cmdline_on_extra_arg);
- printf("%lx", (unsigned long) gpr_cmdline_set_survive_failure);
- printf("%lx", (unsigned long) gpr_cmdline_parse);
- printf("%lx", (unsigned long) gpr_cmdline_destroy);
- printf("%lx", (unsigned long) gpr_cmdline_usage_string);
- printf("%lx", (unsigned long) gpr_cpu_num_cores);
- printf("%lx", (unsigned long) gpr_cpu_current_cpu);
- printf("%lx", (unsigned long) gpr_histogram_create);
- printf("%lx", (unsigned long) gpr_histogram_destroy);
- printf("%lx", (unsigned long) gpr_histogram_add);
- printf("%lx", (unsigned long) gpr_histogram_merge);
- printf("%lx", (unsigned long) gpr_histogram_percentile);
- printf("%lx", (unsigned long) gpr_histogram_mean);
- printf("%lx", (unsigned long) gpr_histogram_stddev);
- printf("%lx", (unsigned long) gpr_histogram_variance);
- printf("%lx", (unsigned long) gpr_histogram_maximum);
- printf("%lx", (unsigned long) gpr_histogram_minimum);
- printf("%lx", (unsigned long) gpr_histogram_count);
- printf("%lx", (unsigned long) gpr_histogram_sum);
- printf("%lx", (unsigned long) gpr_histogram_sum_of_squares);
- printf("%lx", (unsigned long) gpr_histogram_get_contents);
- printf("%lx", (unsigned long) gpr_histogram_merge_contents);
- printf("%lx", (unsigned long) gpr_join_host_port);
- printf("%lx", (unsigned long) gpr_split_host_port);
- printf("%lx", (unsigned long) gpr_log_severity_string);
- printf("%lx", (unsigned long) gpr_log);
- printf("%lx", (unsigned long) gpr_log_message);
- printf("%lx", (unsigned long) gpr_set_log_verbosity);
- printf("%lx", (unsigned long) gpr_log_verbosity_init);
- printf("%lx", (unsigned long) gpr_set_log_function);
- printf("%lx", (unsigned long) gpr_strdup);
- printf("%lx", (unsigned long) gpr_asprintf);
- printf("%lx", (unsigned long) gpr_subprocess_binary_extension);
- printf("%lx", (unsigned long) gpr_subprocess_create);
- printf("%lx", (unsigned long) gpr_subprocess_destroy);
- printf("%lx", (unsigned long) gpr_subprocess_join);
- printf("%lx", (unsigned long) gpr_subprocess_interrupt);
- printf("%lx", (unsigned long) gpr_mu_init);
- printf("%lx", (unsigned long) gpr_mu_destroy);
- printf("%lx", (unsigned long) gpr_mu_lock);
- printf("%lx", (unsigned long) gpr_mu_unlock);
- printf("%lx", (unsigned long) gpr_mu_trylock);
- printf("%lx", (unsigned long) gpr_cv_init);
- printf("%lx", (unsigned long) gpr_cv_destroy);
- printf("%lx", (unsigned long) gpr_cv_wait);
- printf("%lx", (unsigned long) gpr_cv_signal);
- printf("%lx", (unsigned long) gpr_cv_broadcast);
- printf("%lx", (unsigned long) gpr_once_init);
- printf("%lx", (unsigned long) gpr_event_init);
- printf("%lx", (unsigned long) gpr_event_set);
- printf("%lx", (unsigned long) gpr_event_get);
- printf("%lx", (unsigned long) gpr_event_wait);
- printf("%lx", (unsigned long) gpr_ref_init);
- printf("%lx", (unsigned long) gpr_ref);
- printf("%lx", (unsigned long) gpr_ref_non_zero);
- printf("%lx", (unsigned long) gpr_refn);
- printf("%lx", (unsigned long) gpr_unref);
- printf("%lx", (unsigned long) gpr_ref_is_unique);
- printf("%lx", (unsigned long) gpr_stats_init);
- printf("%lx", (unsigned long) gpr_stats_inc);
- printf("%lx", (unsigned long) gpr_stats_read);
- printf("%lx", (unsigned long) gpr_thd_new);
- printf("%lx", (unsigned long) gpr_thd_options_default);
- printf("%lx", (unsigned long) gpr_thd_options_set_detached);
- printf("%lx", (unsigned long) gpr_thd_options_set_joinable);
- printf("%lx", (unsigned long) gpr_thd_options_is_detached);
- printf("%lx", (unsigned long) gpr_thd_options_is_joinable);
- printf("%lx", (unsigned long) gpr_thd_currentid);
- printf("%lx", (unsigned long) gpr_thd_join);
- printf("%lx", (unsigned long) gpr_time_0);
- printf("%lx", (unsigned long) gpr_inf_future);
- printf("%lx", (unsigned long) gpr_inf_past);
- printf("%lx", (unsigned long) gpr_time_init);
- printf("%lx", (unsigned long) gpr_now);
- printf("%lx", (unsigned long) gpr_convert_clock_type);
- printf("%lx", (unsigned long) gpr_time_cmp);
- printf("%lx", (unsigned long) gpr_time_max);
- printf("%lx", (unsigned long) gpr_time_min);
- printf("%lx", (unsigned long) gpr_time_add);
- printf("%lx", (unsigned long) gpr_time_sub);
- printf("%lx", (unsigned long) gpr_time_from_micros);
- printf("%lx", (unsigned long) gpr_time_from_nanos);
- printf("%lx", (unsigned long) gpr_time_from_millis);
- printf("%lx", (unsigned long) gpr_time_from_seconds);
- printf("%lx", (unsigned long) gpr_time_from_minutes);
- printf("%lx", (unsigned long) gpr_time_from_hours);
- printf("%lx", (unsigned long) gpr_time_to_millis);
- printf("%lx", (unsigned long) gpr_time_similar);
- printf("%lx", (unsigned long) gpr_sleep_until);
- printf("%lx", (unsigned long) gpr_timespec_to_micros);
- }
+ printf("%lx", (unsigned long) grpc_compression_algorithm_parse);
+ printf("%lx", (unsigned long) grpc_compression_algorithm_name);
+ printf("%lx", (unsigned long) grpc_stream_compression_algorithm_name);
+ printf("%lx", (unsigned long) grpc_compression_algorithm_for_level);
+ printf("%lx", (unsigned long) grpc_stream_compression_algorithm_for_level);
+ printf("%lx", (unsigned long) grpc_compression_options_init);
+ printf("%lx", (unsigned long) grpc_compression_options_enable_algorithm);
+ printf("%lx", (unsigned long) grpc_compression_options_disable_algorithm);
+ printf("%lx", (unsigned long) grpc_compression_options_is_algorithm_enabled);
+ printf("%lx", (unsigned long) grpc_compression_options_is_stream_compression_algorithm_enabled);
+ printf("%lx", (unsigned long) grpc_metadata_array_init);
+ printf("%lx", (unsigned long) grpc_metadata_array_destroy);
+ printf("%lx", (unsigned long) grpc_call_details_init);
+ printf("%lx", (unsigned long) grpc_call_details_destroy);
+ printf("%lx", (unsigned long) grpc_register_plugin);
+ printf("%lx", (unsigned long) grpc_init);
+ printf("%lx", (unsigned long) grpc_shutdown);
+ printf("%lx", (unsigned long) grpc_version_string);
+ printf("%lx", (unsigned long) grpc_g_stands_for);
+ 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);
+ printf("%lx", (unsigned long) grpc_completion_queue_next);
+ printf("%lx", (unsigned long) grpc_completion_queue_pluck);
+ printf("%lx", (unsigned long) grpc_completion_queue_shutdown);
+ printf("%lx", (unsigned long) grpc_completion_queue_destroy);
+ printf("%lx", (unsigned long) grpc_completion_queue_thread_local_cache_init);
+ printf("%lx", (unsigned long) grpc_completion_queue_thread_local_cache_flush);
+ printf("%lx", (unsigned long) grpc_alarm_create);
+ printf("%lx", (unsigned long) grpc_alarm_set);
+ printf("%lx", (unsigned long) grpc_alarm_cancel);
+ printf("%lx", (unsigned long) grpc_alarm_destroy);
+ printf("%lx", (unsigned long) grpc_channel_check_connectivity_state);
+ printf("%lx", (unsigned long) grpc_channel_num_external_connectivity_watchers);
+ printf("%lx", (unsigned long) grpc_channel_watch_connectivity_state);
+ printf("%lx", (unsigned long) grpc_channel_support_connectivity_watcher);
+ printf("%lx", (unsigned long) grpc_channel_create_call);
+ printf("%lx", (unsigned long) grpc_channel_ping);
+ printf("%lx", (unsigned long) grpc_channel_register_call);
+ printf("%lx", (unsigned long) grpc_channel_create_registered_call);
+ printf("%lx", (unsigned long) grpc_call_arena_alloc);
+ printf("%lx", (unsigned long) grpc_call_start_batch);
+ printf("%lx", (unsigned long) grpc_call_get_peer);
+ printf("%lx", (unsigned long) grpc_census_call_set_context);
+ printf("%lx", (unsigned long) grpc_census_call_get_context);
+ printf("%lx", (unsigned long) grpc_channel_get_target);
+ printf("%lx", (unsigned long) grpc_channel_get_info);
+ printf("%lx", (unsigned long) grpc_insecure_channel_create);
+ printf("%lx", (unsigned long) grpc_lame_client_channel_create);
+ printf("%lx", (unsigned long) grpc_channel_destroy);
+ printf("%lx", (unsigned long) grpc_call_cancel);
+ printf("%lx", (unsigned long) grpc_call_cancel_with_status);
+ printf("%lx", (unsigned long) grpc_call_ref);
+ printf("%lx", (unsigned long) grpc_call_unref);
+ printf("%lx", (unsigned long) grpc_server_request_call);
+ printf("%lx", (unsigned long) grpc_server_register_method);
+ printf("%lx", (unsigned long) grpc_server_request_registered_call);
+ printf("%lx", (unsigned long) grpc_server_create);
+ printf("%lx", (unsigned long) grpc_server_register_completion_queue);
+ printf("%lx", (unsigned long) grpc_server_add_insecure_http2_port);
+ printf("%lx", (unsigned long) grpc_server_start);
+ printf("%lx", (unsigned long) grpc_server_shutdown_and_notify);
+ printf("%lx", (unsigned long) grpc_server_cancel_all_calls);
+ printf("%lx", (unsigned long) grpc_server_destroy);
+ printf("%lx", (unsigned long) grpc_tracer_set_enabled);
+ printf("%lx", (unsigned long) grpc_header_key_is_legal);
+ printf("%lx", (unsigned long) grpc_header_nonbin_value_is_legal);
+ printf("%lx", (unsigned long) grpc_is_binary_header);
+ printf("%lx", (unsigned long) grpc_call_error_to_string);
+ printf("%lx", (unsigned long) grpc_resource_quota_create);
+ 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_arg_vtable);
+ printf("%lx", (unsigned long) grpc_auth_property_iterator_next);
+ printf("%lx", (unsigned long) grpc_auth_context_property_iterator);
+ printf("%lx", (unsigned long) grpc_auth_context_peer_identity);
+ printf("%lx", (unsigned long) grpc_auth_context_find_properties_by_name);
+ printf("%lx", (unsigned long) grpc_auth_context_peer_identity_property_name);
+ printf("%lx", (unsigned long) grpc_auth_context_peer_is_authenticated);
+ printf("%lx", (unsigned long) grpc_call_auth_context);
+ printf("%lx", (unsigned long) grpc_auth_context_release);
+ printf("%lx", (unsigned long) grpc_auth_context_add_property);
+ printf("%lx", (unsigned long) grpc_auth_context_add_cstring_property);
+ printf("%lx", (unsigned long) grpc_auth_context_set_peer_identity_property_name);
+ printf("%lx", (unsigned long) grpc_channel_credentials_release);
+ printf("%lx", (unsigned long) grpc_google_default_credentials_create);
+ printf("%lx", (unsigned long) grpc_set_ssl_roots_override_callback);
+ printf("%lx", (unsigned long) grpc_ssl_credentials_create);
+ printf("%lx", (unsigned long) grpc_call_credentials_release);
+ printf("%lx", (unsigned long) grpc_composite_channel_credentials_create);
+ printf("%lx", (unsigned long) grpc_composite_call_credentials_create);
+ printf("%lx", (unsigned long) grpc_google_compute_engine_credentials_create);
+ printf("%lx", (unsigned long) grpc_max_auth_token_lifetime);
+ printf("%lx", (unsigned long) grpc_service_account_jwt_access_credentials_create);
+ printf("%lx", (unsigned long) grpc_google_refresh_token_credentials_create);
+ printf("%lx", (unsigned long) grpc_access_token_credentials_create);
+ printf("%lx", (unsigned long) grpc_google_iam_credentials_create);
+ printf("%lx", (unsigned long) grpc_metadata_credentials_create_from_plugin);
+ printf("%lx", (unsigned long) grpc_secure_channel_create);
+ printf("%lx", (unsigned long) grpc_server_credentials_release);
+ printf("%lx", (unsigned long) grpc_ssl_server_certificate_config_create);
+ printf("%lx", (unsigned long) grpc_ssl_server_certificate_config_destroy);
+ printf("%lx", (unsigned long) grpc_ssl_server_credentials_create);
+ printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_ex);
+ printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_options_using_config);
+ printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_options_using_config_fetcher);
+ printf("%lx", (unsigned long) grpc_ssl_server_credentials_options_destroy);
+ printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_with_options);
+ printf("%lx", (unsigned long) grpc_server_add_secure_http2_port);
+ printf("%lx", (unsigned long) grpc_call_set_credentials);
+ printf("%lx", (unsigned long) grpc_server_credentials_set_auth_metadata_processor);
+ printf("%lx", (unsigned long) grpc_raw_byte_buffer_create);
+ printf("%lx", (unsigned long) grpc_raw_compressed_byte_buffer_create);
+ printf("%lx", (unsigned long) grpc_byte_buffer_copy);
+ printf("%lx", (unsigned long) grpc_byte_buffer_length);
+ printf("%lx", (unsigned long) grpc_byte_buffer_destroy);
+ printf("%lx", (unsigned long) grpc_byte_buffer_reader_init);
+ printf("%lx", (unsigned long) grpc_byte_buffer_reader_destroy);
+ printf("%lx", (unsigned long) grpc_byte_buffer_reader_next);
+ printf("%lx", (unsigned long) grpc_byte_buffer_reader_readall);
+ printf("%lx", (unsigned long) grpc_raw_byte_buffer_from_reader);
+ printf("%lx", (unsigned long) grpc_slice_ref);
+ printf("%lx", (unsigned long) grpc_slice_unref);
+ printf("%lx", (unsigned long) grpc_slice_copy);
+ printf("%lx", (unsigned long) grpc_slice_new);
+ printf("%lx", (unsigned long) grpc_slice_new_with_user_data);
+ printf("%lx", (unsigned long) grpc_slice_new_with_len);
+ printf("%lx", (unsigned long) grpc_slice_malloc);
+ printf("%lx", (unsigned long) grpc_slice_malloc_large);
+ printf("%lx", (unsigned long) grpc_slice_intern);
+ printf("%lx", (unsigned long) grpc_slice_from_copied_string);
+ printf("%lx", (unsigned long) grpc_slice_from_copied_buffer);
+ printf("%lx", (unsigned long) grpc_slice_from_static_string);
+ printf("%lx", (unsigned long) grpc_slice_from_static_buffer);
+ printf("%lx", (unsigned long) grpc_slice_sub);
+ printf("%lx", (unsigned long) grpc_slice_sub_no_ref);
+ printf("%lx", (unsigned long) grpc_slice_split_tail);
+ printf("%lx", (unsigned long) grpc_slice_split_tail_maybe_ref);
+ printf("%lx", (unsigned long) grpc_slice_split_head);
+ printf("%lx", (unsigned long) grpc_empty_slice);
+ printf("%lx", (unsigned long) grpc_slice_default_hash_impl);
+ printf("%lx", (unsigned long) grpc_slice_default_eq_impl);
+ printf("%lx", (unsigned long) grpc_slice_eq);
+ printf("%lx", (unsigned long) grpc_slice_cmp);
+ printf("%lx", (unsigned long) grpc_slice_str_cmp);
+ printf("%lx", (unsigned long) grpc_slice_buf_start_eq);
+ printf("%lx", (unsigned long) grpc_slice_rchr);
+ printf("%lx", (unsigned long) grpc_slice_chr);
+ printf("%lx", (unsigned long) grpc_slice_slice);
+ printf("%lx", (unsigned long) grpc_slice_hash);
+ printf("%lx", (unsigned long) grpc_slice_is_equivalent);
+ printf("%lx", (unsigned long) grpc_slice_dup);
+ printf("%lx", (unsigned long) grpc_slice_to_c_string);
+ printf("%lx", (unsigned long) grpc_slice_buffer_init);
+ printf("%lx", (unsigned long) grpc_slice_buffer_destroy);
+ printf("%lx", (unsigned long) grpc_slice_buffer_add);
+ printf("%lx", (unsigned long) grpc_slice_buffer_add_indexed);
+ printf("%lx", (unsigned long) grpc_slice_buffer_addn);
+ printf("%lx", (unsigned long) grpc_slice_buffer_tiny_add);
+ printf("%lx", (unsigned long) grpc_slice_buffer_pop);
+ printf("%lx", (unsigned long) grpc_slice_buffer_reset_and_unref);
+ printf("%lx", (unsigned long) grpc_slice_buffer_swap);
+ printf("%lx", (unsigned long) grpc_slice_buffer_move_into);
+ printf("%lx", (unsigned long) grpc_slice_buffer_trim_end);
+ printf("%lx", (unsigned long) grpc_slice_buffer_move_first);
+ printf("%lx", (unsigned long) grpc_slice_buffer_move_first_no_ref);
+ printf("%lx", (unsigned long) grpc_slice_buffer_move_first_into_buffer);
+ printf("%lx", (unsigned long) grpc_slice_buffer_take_first);
+ printf("%lx", (unsigned long) grpc_slice_buffer_undo_take_first);
+ printf("%lx", (unsigned long) gpr_malloc);
+ printf("%lx", (unsigned long) gpr_zalloc);
+ printf("%lx", (unsigned long) gpr_free);
+ printf("%lx", (unsigned long) gpr_realloc);
+ printf("%lx", (unsigned long) gpr_malloc_aligned);
+ printf("%lx", (unsigned long) gpr_free_aligned);
+ printf("%lx", (unsigned long) gpr_set_allocation_functions);
+ printf("%lx", (unsigned long) gpr_get_allocation_functions);
+ printf("%lx", (unsigned long) gpr_avl_create);
+ printf("%lx", (unsigned long) gpr_avl_ref);
+ printf("%lx", (unsigned long) gpr_avl_unref);
+ printf("%lx", (unsigned long) gpr_avl_add);
+ printf("%lx", (unsigned long) gpr_avl_remove);
+ printf("%lx", (unsigned long) gpr_avl_get);
+ printf("%lx", (unsigned long) gpr_avl_maybe_get);
+ printf("%lx", (unsigned long) gpr_avl_is_empty);
+ printf("%lx", (unsigned long) gpr_cmdline_create);
+ printf("%lx", (unsigned long) gpr_cmdline_add_int);
+ printf("%lx", (unsigned long) gpr_cmdline_add_flag);
+ printf("%lx", (unsigned long) gpr_cmdline_add_string);
+ printf("%lx", (unsigned long) gpr_cmdline_on_extra_arg);
+ printf("%lx", (unsigned long) gpr_cmdline_set_survive_failure);
+ printf("%lx", (unsigned long) gpr_cmdline_parse);
+ printf("%lx", (unsigned long) gpr_cmdline_destroy);
+ printf("%lx", (unsigned long) gpr_cmdline_usage_string);
+ printf("%lx", (unsigned long) gpr_cpu_num_cores);
+ printf("%lx", (unsigned long) gpr_cpu_current_cpu);
+ printf("%lx", (unsigned long) gpr_histogram_create);
+ printf("%lx", (unsigned long) gpr_histogram_destroy);
+ printf("%lx", (unsigned long) gpr_histogram_add);
+ printf("%lx", (unsigned long) gpr_histogram_merge);
+ printf("%lx", (unsigned long) gpr_histogram_percentile);
+ printf("%lx", (unsigned long) gpr_histogram_mean);
+ printf("%lx", (unsigned long) gpr_histogram_stddev);
+ printf("%lx", (unsigned long) gpr_histogram_variance);
+ printf("%lx", (unsigned long) gpr_histogram_maximum);
+ printf("%lx", (unsigned long) gpr_histogram_minimum);
+ printf("%lx", (unsigned long) gpr_histogram_count);
+ printf("%lx", (unsigned long) gpr_histogram_sum);
+ printf("%lx", (unsigned long) gpr_histogram_sum_of_squares);
+ printf("%lx", (unsigned long) gpr_histogram_get_contents);
+ printf("%lx", (unsigned long) gpr_histogram_merge_contents);
+ printf("%lx", (unsigned long) gpr_join_host_port);
+ printf("%lx", (unsigned long) gpr_split_host_port);
+ printf("%lx", (unsigned long) gpr_log_severity_string);
+ printf("%lx", (unsigned long) gpr_log);
+ printf("%lx", (unsigned long) gpr_log_message);
+ printf("%lx", (unsigned long) gpr_set_log_verbosity);
+ printf("%lx", (unsigned long) gpr_log_verbosity_init);
+ printf("%lx", (unsigned long) gpr_set_log_function);
+ printf("%lx", (unsigned long) gpr_strdup);
+ printf("%lx", (unsigned long) gpr_asprintf);
+ printf("%lx", (unsigned long) gpr_subprocess_binary_extension);
+ printf("%lx", (unsigned long) gpr_subprocess_create);
+ printf("%lx", (unsigned long) gpr_subprocess_destroy);
+ printf("%lx", (unsigned long) gpr_subprocess_join);
+ printf("%lx", (unsigned long) gpr_subprocess_interrupt);
+ printf("%lx", (unsigned long) gpr_mu_init);
+ printf("%lx", (unsigned long) gpr_mu_destroy);
+ printf("%lx", (unsigned long) gpr_mu_lock);
+ printf("%lx", (unsigned long) gpr_mu_unlock);
+ printf("%lx", (unsigned long) gpr_mu_trylock);
+ printf("%lx", (unsigned long) gpr_cv_init);
+ printf("%lx", (unsigned long) gpr_cv_destroy);
+ printf("%lx", (unsigned long) gpr_cv_wait);
+ printf("%lx", (unsigned long) gpr_cv_signal);
+ printf("%lx", (unsigned long) gpr_cv_broadcast);
+ printf("%lx", (unsigned long) gpr_once_init);
+ printf("%lx", (unsigned long) gpr_event_init);
+ printf("%lx", (unsigned long) gpr_event_set);
+ printf("%lx", (unsigned long) gpr_event_get);
+ printf("%lx", (unsigned long) gpr_event_wait);
+ printf("%lx", (unsigned long) gpr_ref_init);
+ printf("%lx", (unsigned long) gpr_ref);
+ printf("%lx", (unsigned long) gpr_ref_non_zero);
+ printf("%lx", (unsigned long) gpr_refn);
+ printf("%lx", (unsigned long) gpr_unref);
+ printf("%lx", (unsigned long) gpr_ref_is_unique);
+ printf("%lx", (unsigned long) gpr_stats_init);
+ printf("%lx", (unsigned long) gpr_stats_inc);
+ printf("%lx", (unsigned long) gpr_stats_read);
+ printf("%lx", (unsigned long) gpr_thd_new);
+ printf("%lx", (unsigned long) gpr_thd_options_default);
+ printf("%lx", (unsigned long) gpr_thd_options_set_detached);
+ printf("%lx", (unsigned long) gpr_thd_options_set_joinable);
+ printf("%lx", (unsigned long) gpr_thd_options_is_detached);
+ printf("%lx", (unsigned long) gpr_thd_options_is_joinable);
+ printf("%lx", (unsigned long) gpr_thd_currentid);
+ printf("%lx", (unsigned long) gpr_thd_join);
+ printf("%lx", (unsigned long) gpr_time_0);
+ printf("%lx", (unsigned long) gpr_inf_future);
+ printf("%lx", (unsigned long) gpr_inf_past);
+ printf("%lx", (unsigned long) gpr_time_init);
+ printf("%lx", (unsigned long) gpr_now);
+ printf("%lx", (unsigned long) gpr_convert_clock_type);
+ printf("%lx", (unsigned long) gpr_time_cmp);
+ printf("%lx", (unsigned long) gpr_time_max);
+ printf("%lx", (unsigned long) gpr_time_min);
+ printf("%lx", (unsigned long) gpr_time_add);
+ printf("%lx", (unsigned long) gpr_time_sub);
+ printf("%lx", (unsigned long) gpr_time_from_micros);
+ printf("%lx", (unsigned long) gpr_time_from_nanos);
+ printf("%lx", (unsigned long) gpr_time_from_millis);
+ printf("%lx", (unsigned long) gpr_time_from_seconds);
+ printf("%lx", (unsigned long) gpr_time_from_minutes);
+ printf("%lx", (unsigned long) gpr_time_from_hours);
+ printf("%lx", (unsigned long) gpr_time_to_millis);
+ printf("%lx", (unsigned long) gpr_time_similar);
+ printf("%lx", (unsigned long) gpr_sleep_until);
+ printf("%lx", (unsigned long) gpr_timespec_to_micros);
return 0;
}
diff --git a/test/core/transport/connectivity_state_test.cc b/test/core/transport/connectivity_state_test.cc
index 06bb093d32..feb603cd23 100644
--- a/test/core/transport/connectivity_state_test.cc
+++ b/test/core/transport/connectivity_state_test.cc
@@ -23,6 +23,7 @@
#include <grpc/support/log.h>
#include "test/core/util/test_config.h"
+#include "test/core/util/tracer_util.h"
#define THE_ARG ((void*)(size_t)0xcafebabe)
@@ -132,7 +133,7 @@ static void test_subscribe_with_failure_then_destroy(void) {
int main(int argc, char** argv) {
grpc_test_init(argc, argv);
- grpc_connectivity_state_trace.value = 1;
+ grpc_core::testing::grpc_tracer_enable_flag(&grpc_connectivity_state_trace);
test_connectivity_state_name();
test_check();
test_subscribe_then_unsubscribe();
diff --git a/test/core/util/BUILD b/test/core/util/BUILD
index 2437923435..6443553466 100644
--- a/test/core/util/BUILD
+++ b/test/core/util/BUILD
@@ -57,6 +57,7 @@ grpc_cc_library(
"reconnect_server.cc",
"slice_splitter.cc",
"test_tcp_server.cc",
+ "tracer_util.cc",
"trickle_endpoint.cc",
],
hdrs = [
@@ -69,6 +70,7 @@ grpc_cc_library(
"reconnect_server.h",
"slice_splitter.h",
"test_tcp_server.h",
+ "tracer_util.h",
"trickle_endpoint.h",
],
language = "C++",
diff --git a/test/core/util/tracer_util.cc b/test/core/util/tracer_util.cc
new file mode 100644
index 0000000000..34a132daa7
--- /dev/null
+++ b/test/core/util/tracer_util.cc
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/util/test_config.h"
+
+#include "src/core/lib/debug/trace.h"
+
+namespace grpc_core {
+namespace testing {
+
+void grpc_tracer_enable_flag(grpc_core::TraceFlag* flag) {
+ flag->set_enabled(1);
+}
+
+} // namespace testing
+} // namespace grpc_core
diff --git a/test/core/util/tracer_util.h b/test/core/util/tracer_util.h
new file mode 100644
index 0000000000..0b432ffa46
--- /dev/null
+++ b/test/core/util/tracer_util.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_TEST_CORE_UTIL_TRACER_UTIL_H
+#define GRPC_TEST_CORE_UTIL_TRACER_UTIL_H
+
+namespace grpc_core {
+class TraceFlag;
+
+namespace testing {
+// enables the TraceFlag passed to it. Used for testing purposes.
+void grpc_tracer_enable_flag(grpc_core::TraceFlag* flag);
+
+} // namespace testing
+} // namespace grpc_core
+
+#endif /* GRPC_TEST_CORE_UTIL_TRACER_UTIL_H */
diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc
index 0ee491a271..fd888a5a40 100644
--- a/test/cpp/microbenchmarks/bm_error.cc
+++ b/test/cpp/microbenchmarks/bm_error.cc
@@ -251,7 +251,7 @@ static void BM_ErrorGetStatus(benchmark::State& state) {
grpc_status_code status;
grpc_slice slice;
grpc_error_get_status(fixture.error(), fixture.deadline(), &status, &slice,
- nullptr);
+ nullptr, nullptr);
}
track_counters.Finish(state);
@@ -265,7 +265,7 @@ static void BM_ErrorGetStatusCode(benchmark::State& state) {
while (state.KeepRunning()) {
grpc_status_code status;
grpc_error_get_status(fixture.error(), fixture.deadline(), &status, nullptr,
- nullptr);
+ nullptr, nullptr);
}
track_counters.Finish(state);
@@ -279,7 +279,7 @@ static void BM_ErrorHttpError(benchmark::State& state) {
while (state.KeepRunning()) {
grpc_http2_error_code error;
grpc_error_get_status(fixture.error(), fixture.deadline(), nullptr, nullptr,
- &error);
+ &error, nullptr);
}
track_counters.Finish(state);
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index f7cdfc2bd7..07888214e7 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -236,6 +236,22 @@ class AsyncClient : public ClientImpl<StubType, RequestType> {
this->EndThreads(); // this needed for resolution
}
+ ClientRpcContext* ProcessTag(size_t thread_idx, void* tag) {
+ ClientRpcContext* ctx = ClientRpcContext::detag(tag);
+ if (shutdown_state_[thread_idx]->shutdown) {
+ ctx->TryCancel();
+ delete ctx;
+ bool ok;
+ while (cli_cqs_[cq_[thread_idx]]->Next(&tag, &ok)) {
+ ctx = ClientRpcContext::detag(tag);
+ ctx->TryCancel();
+ delete ctx;
+ }
+ return nullptr;
+ }
+ return ctx;
+ }
+
void ThreadFunc(size_t thread_idx, Client::Thread* t) override final {
void* got_tag;
bool ok;
@@ -245,9 +261,13 @@ class AsyncClient : public ClientImpl<StubType, RequestType> {
if (!cli_cqs_[cq_[thread_idx]]->Next(&got_tag, &ok)) {
return;
}
- ClientRpcContext* ctx = ClientRpcContext::detag(got_tag);
std::mutex* shutdown_mu = &shutdown_state_[thread_idx]->mutex;
shutdown_mu->lock();
+ ClientRpcContext* ctx = ProcessTag(thread_idx, got_tag);
+ if (ctx == nullptr) {
+ shutdown_mu->unlock();
+ return;
+ }
while (cli_cqs_[cq_[thread_idx]]->DoThenAsyncNext(
[&, ctx, ok, entry_ptr, shutdown_mu]() {
if (!ctx->RunNextState(ok, entry_ptr)) {
@@ -260,19 +280,9 @@ class AsyncClient : public ClientImpl<StubType, RequestType> {
},
&got_tag, &ok, gpr_inf_future(GPR_CLOCK_REALTIME))) {
t->UpdateHistogram(entry_ptr);
- // Got a regular event, so process it
- ctx = ClientRpcContext::detag(got_tag);
- // Proceed while holding a lock to make sure that
- // this thread isn't supposed to shut down
shutdown_mu->lock();
- if (shutdown_state_[thread_idx]->shutdown) {
- ctx->TryCancel();
- delete ctx;
- while (cli_cqs_[cq_[thread_idx]]->Next(&got_tag, &ok)) {
- ctx = ClientRpcContext::detag(got_tag);
- ctx->TryCancel();
- delete ctx;
- }
+ ctx = ProcessTag(thread_idx, got_tag);
+ if (ctx == nullptr) {
shutdown_mu->unlock();
return;
}
diff --git a/third_party/cares/cares.BUILD b/third_party/cares/cares.BUILD
index 8cc01b64c4..85ca506ab0 100644
--- a/third_party/cares/cares.BUILD
+++ b/third_party/cares/cares.BUILD
@@ -8,7 +8,7 @@ config_setting(
config_setting(
name = "android",
values = {
- "crosstool_top": "//external:android/crosstool",
+ "crosstool_top": "//external:android/crosstool",
},
)
@@ -18,120 +18,128 @@ config_setting(
name = "ios_x86_64",
values = {"cpu": "ios_x86_64"},
)
+
config_setting(
name = "ios_armv7",
values = {"cpu": "ios_armv7"},
)
+
config_setting(
name = "ios_armv7s",
values = {"cpu": "ios_armv7s"},
)
+
config_setting(
name = "ios_arm64",
values = {"cpu": "ios_arm64"},
)
+genrule(
+ name = "ares_build",
+ srcs = ["@cares_local_files//:ares_build_h"],
+ outs = ["ares_build.h"],
+ cmd = "cat $(location @cares_local_files//:ares_build_h) > $@",
+)
+
+# cc_library(
+# name = "ares_build_h",
+# hdrs = ["ares_build.h"],
+# data = [":ares_build"],
+# includes = ["."],
+# )
+
+genrule(
+ name = "ares_config",
+ srcs = ["@cares_local_files//:ares_config_h"],
+ outs = ["ares_config.h"],
+ cmd = "cat $(location @cares_local_files//:ares_config_h) > $@",
+)
+
+# cc_library(
+# name = "ares_config_h",
+# hdrs = ["ares_config.h"],
+# data = [":ares_config"],
+# includes = ["."],
+# )
+
cc_library(
name = "ares",
srcs = [
- "cares/ares__close_sockets.c",
- "cares/ares__get_hostent.c",
- "cares/ares__read_line.c",
- "cares/ares__timeval.c",
- "cares/ares_cancel.c",
- "cares/ares_create_query.c",
- "cares/ares_data.c",
- "cares/ares_destroy.c",
- "cares/ares_expand_name.c",
- "cares/ares_expand_string.c",
- "cares/ares_fds.c",
- "cares/ares_free_hostent.c",
- "cares/ares_free_string.c",
- "cares/ares_getenv.c",
- "cares/ares_gethostbyaddr.c",
- "cares/ares_gethostbyname.c",
- "cares/ares_getnameinfo.c",
- "cares/ares_getopt.c",
- "cares/ares_getsock.c",
- "cares/ares_init.c",
- "cares/ares_library_init.c",
- "cares/ares_llist.c",
- "cares/ares_mkquery.c",
- "cares/ares_nowarn.c",
- "cares/ares_options.c",
- "cares/ares_parse_a_reply.c",
- "cares/ares_parse_aaaa_reply.c",
- "cares/ares_parse_mx_reply.c",
- "cares/ares_parse_naptr_reply.c",
- "cares/ares_parse_ns_reply.c",
- "cares/ares_parse_ptr_reply.c",
- "cares/ares_parse_soa_reply.c",
- "cares/ares_parse_srv_reply.c",
- "cares/ares_parse_txt_reply.c",
- "cares/ares_platform.c",
- "cares/ares_process.c",
- "cares/ares_query.c",
- "cares/ares_search.c",
- "cares/ares_send.c",
- "cares/ares_strcasecmp.c",
- "cares/ares_strdup.c",
- "cares/ares_strerror.c",
- "cares/ares_timeout.c",
- "cares/ares_version.c",
- "cares/ares_writev.c",
- "cares/bitncmp.c",
- "cares/inet_net_pton.c",
- "cares/inet_ntop.c",
- "cares/windows_port.c",
+ "ares__close_sockets.c",
+ "ares__get_hostent.c",
+ "ares__read_line.c",
+ "ares__timeval.c",
+ "ares_cancel.c",
+ "ares_create_query.c",
+ "ares_data.c",
+ "ares_destroy.c",
+ "ares_expand_name.c",
+ "ares_expand_string.c",
+ "ares_fds.c",
+ "ares_free_hostent.c",
+ "ares_free_string.c",
+ "ares_getenv.c",
+ "ares_gethostbyaddr.c",
+ "ares_gethostbyname.c",
+ "ares_getnameinfo.c",
+ "ares_getopt.c",
+ "ares_getsock.c",
+ "ares_init.c",
+ "ares_library_init.c",
+ "ares_llist.c",
+ "ares_mkquery.c",
+ "ares_nowarn.c",
+ "ares_options.c",
+ "ares_parse_a_reply.c",
+ "ares_parse_aaaa_reply.c",
+ "ares_parse_mx_reply.c",
+ "ares_parse_naptr_reply.c",
+ "ares_parse_ns_reply.c",
+ "ares_parse_ptr_reply.c",
+ "ares_parse_soa_reply.c",
+ "ares_parse_srv_reply.c",
+ "ares_parse_txt_reply.c",
+ "ares_platform.c",
+ "ares_process.c",
+ "ares_query.c",
+ "ares_search.c",
+ "ares_send.c",
+ "ares_strcasecmp.c",
+ "ares_strdup.c",
+ "ares_strerror.c",
+ "ares_timeout.c",
+ "ares_version.c",
+ "ares_writev.c",
+ "bitncmp.c",
+ "inet_net_pton.c",
+ "inet_ntop.c",
+ "windows_port.c",
],
hdrs = [
+ "ares.h",
"ares_build.h",
- "cares/ares.h",
- "cares/ares_data.h",
- "cares/ares_dns.h",
- "cares/ares_getenv.h",
- "cares/ares_getopt.h",
- "cares/ares_inet_net_pton.h",
- "cares/ares_iphlpapi.h",
- "cares/ares_ipv6.h",
- "cares/ares_library_init.h",
- "cares/ares_llist.h",
- "cares/ares_nowarn.h",
- "cares/ares_platform.h",
- "cares/ares_private.h",
- "cares/ares_rules.h",
- "cares/ares_setup.h",
- "cares/ares_strcasecmp.h",
- "cares/ares_strdup.h",
- "cares/ares_version.h",
- "cares/bitncmp.h",
- "cares/config-win32.h",
- "cares/nameser.h",
- "cares/setup_once.h",
- ] + select({
- ":ios_x86_64": ["config_darwin/ares_config.h"],
- ":ios_armv7": ["config_darwin/ares_config.h"],
- ":ios_armv7s": ["config_darwin/ares_config.h"],
- ":ios_arm64": ["config_darwin/ares_config.h"],
- ":darwin": ["config_darwin/ares_config.h"],
- ":android": ["config_android/ares_config.h"],
- "//conditions:default": ["config_linux/ares_config.h"],
- }),
- includes = [
- ".",
- "cares"
- ] + select({
- ":ios_x86_64": ["config_darwin"],
- ":ios_armv7": ["config_darwin"],
- ":ios_armv7s": ["config_darwin"],
- ":ios_arm64": ["config_darwin"],
- ":darwin": ["config_darwin"],
- ":android": ["config_android"],
- "//conditions:default": ["config_linux"],
- }),
- linkstatic = 1,
- visibility = [
- "//visibility:public",
+ "ares_config.h",
+ "ares_data.h",
+ "ares_dns.h",
+ "ares_getenv.h",
+ "ares_getopt.h",
+ "ares_inet_net_pton.h",
+ "ares_iphlpapi.h",
+ "ares_ipv6.h",
+ "ares_library_init.h",
+ "ares_llist.h",
+ "ares_nowarn.h",
+ "ares_platform.h",
+ "ares_private.h",
+ "ares_rules.h",
+ "ares_setup.h",
+ "ares_strcasecmp.h",
+ "ares_strdup.h",
+ "ares_version.h",
+ "bitncmp.h",
+ "config-win32.h",
+ "nameser.h",
+ "setup_once.h",
],
copts = [
"-D_GNU_SOURCE",
@@ -139,4 +147,13 @@ cc_library(
"-DNOMINMAX",
"-DHAVE_CONFIG_H",
],
+ data = [
+ ":ares_build",
+ ":ares_config",
+ ],
+ includes = ["."],
+ linkstatic = 1,
+ visibility = [
+ "//visibility:public",
+ ],
)
diff --git a/third_party/cares/cares_local_files.BUILD b/third_party/cares/cares_local_files.BUILD
new file mode 100644
index 0000000000..fe59447beb
--- /dev/null
+++ b/third_party/cares/cares_local_files.BUILD
@@ -0,0 +1,57 @@
+package(
+ default_visibility = ["//visibility:public"],
+)
+
+config_setting(
+ name = "darwin",
+ values = {"cpu": "darwin"},
+)
+
+# Android is not officially supported through C++.
+# This just helps with the build for now.
+config_setting(
+ name = "android",
+ values = {
+ "crosstool_top": "//external:android/crosstool",
+ },
+)
+
+# iOS is not officially supported through C++.
+# This just helps with the build for now.
+config_setting(
+ name = "ios_x86_64",
+ values = {"cpu": "ios_x86_64"},
+)
+
+config_setting(
+ name = "ios_armv7",
+ values = {"cpu": "ios_armv7"},
+)
+
+config_setting(
+ name = "ios_armv7s",
+ values = {"cpu": "ios_armv7s"},
+)
+
+config_setting(
+ name = "ios_arm64",
+ values = {"cpu": "ios_arm64"},
+)
+
+filegroup(
+ name = "ares_build_h",
+ srcs = ["ares_build.h"],
+)
+
+filegroup(
+ name = "ares_config_h",
+ srcs = select({
+ ":ios_x86_64": ["config_darwin/ares_config.h"],
+ ":ios_armv7": ["config_darwin/ares_config.h"],
+ ":ios_armv7s": ["config_darwin/ares_config.h"],
+ ":ios_arm64": ["config_darwin/ares_config.h"],
+ ":darwin": ["config_darwin/ares_config.h"],
+ ":android": ["config_android/ares_config.h"],
+ "//conditions:default": ["config_linux/ares_config.h"],
+ }),
+)
diff --git a/tools/distrib/python/check_grpcio_tools.py b/tools/distrib/python/check_grpcio_tools.py
index c5afa713e6..b56ccaea7a 100755
--- a/tools/distrib/python/check_grpcio_tools.py
+++ b/tools/distrib/python/check_grpcio_tools.py
@@ -14,17 +14,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import cStringIO
-
-import make_grpcio_tools as make
+import make_grpcio_tools as _make
OUT_OF_DATE_MESSAGE = """file {} is out of date
Have you called tools/distrib/python/make_grpcio_tools.py since upgrading protobuf?"""
-check_protoc_lib_deps_content = make.get_deps()
+submodule_commit_hash = _make.protobuf_submodule_commit_hash()
+
+with open(_make.GRPC_PYTHON_PROTOC_LIB_DEPS, 'r') as _protoc_lib_deps_file:
+ content = _protoc_lib_deps_file.read().splitlines()
+
+testString = (_make.COMMIT_HASH_PREFIX +
+ submodule_commit_hash +
+ _make.COMMIT_HASH_SUFFIX)
-with open(make.GRPC_PYTHON_PROTOC_LIB_DEPS, 'r') as protoc_lib_deps_file:
- if protoc_lib_deps_file.read() != check_protoc_lib_deps_content:
- print(OUT_OF_DATE_MESSAGE.format(make.GRPC_PYTHON_PROTOC_LIB_DEPS))
- raise SystemExit(1)
+if testString not in content:
+ print(OUT_OF_DATE_MESSAGE.format(_make.GRPC_PYTHON_PROTOC_LIB_DEPS))
+ raise SystemExit(1)
diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
index 18470d59d5..2a42a518fc 100644
--- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
+++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
@@ -1,5 +1,5 @@
-# Copyright 2016 gRPC authors.
+# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -19,3 +19,5 @@ PROTO_FILES=['google/protobuf/wrappers.proto', 'google/protobuf/type.proto', 'go
CC_INCLUDE='third_party/protobuf/src'
PROTO_INCLUDE='third_party/protobuf/src'
+
+PROTOBUF_SUBMODULE_VERSION="80a37e0782d2d702d52234b62dd4b9ec74fd2c95"
diff --git a/tools/distrib/python/make_grpcio_tools.py b/tools/distrib/python/make_grpcio_tools.py
index 5bc07ff360..c865f0bcc0 100755
--- a/tools/distrib/python/make_grpcio_tools.py
+++ b/tools/distrib/python/make_grpcio_tools.py
@@ -28,7 +28,7 @@ import traceback
import uuid
DEPS_FILE_CONTENT="""
-# Copyright 2016 gRPC authors.
+# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -48,8 +48,13 @@ PROTO_FILES={proto_files}
CC_INCLUDE={cc_include}
PROTO_INCLUDE={proto_include}
+
+{commit_hash}
"""
+COMMIT_HASH_PREFIX = 'PROTOBUF_SUBMODULE_VERSION="'
+COMMIT_HASH_SUFFIX = '"'
+
# Bazel query result prefix for expected source files in protobuf.
PROTOBUF_CC_PREFIX = '//:src/'
PROTOBUF_PROTO_PREFIX = '//:src/'
@@ -63,6 +68,7 @@ GRPC_PYTHON_ROOT = os.path.join(GRPC_ROOT, 'tools', 'distrib',
GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT = os.path.join('third_party', 'protobuf', 'src')
GRPC_PROTOBUF = os.path.join(GRPC_ROOT, GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT)
+GRPC_PROTOBUF_SUBMODULE_ROOT = os.path.join(GRPC_ROOT, 'third_party', 'protobuf')
GRPC_PROTOC_PLUGINS = os.path.join(GRPC_ROOT, 'src', 'compiler')
GRPC_PYTHON_PROTOBUF = os.path.join(GRPC_PYTHON_ROOT, 'third_party', 'protobuf',
'src')
@@ -78,6 +84,14 @@ BAZEL_DEPS = os.path.join(GRPC_ROOT, 'tools', 'distrib', 'python', 'bazel_deps.s
BAZEL_DEPS_PROTOC_LIB_QUERY = '//:protoc_lib'
BAZEL_DEPS_COMMON_PROTOS_QUERY = '//:well_known_protos'
+def protobuf_submodule_commit_hash():
+ """Gets the commit hash for the HEAD of the protobuf submodule currently
+ checked out."""
+ cwd = os.getcwd()
+ os.chdir(GRPC_PROTOBUF_SUBMODULE_ROOT)
+ output = subprocess.check_output(['git', 'rev-parse', 'HEAD'])
+ os.chdir(cwd)
+ return output.splitlines()[0].strip()
def bazel_query(query):
output = subprocess.check_output([BAZEL_DEPS, query])
@@ -94,11 +108,13 @@ def get_deps():
proto_files = [
name[len(PROTOBUF_PROTO_PREFIX):] for name in proto_files_output
if name.endswith('.proto') and name.startswith(PROTOBUF_PROTO_PREFIX)]
+ commit_hash = protobuf_submodule_commit_hash()
deps_file_content = DEPS_FILE_CONTENT.format(
cc_files=cc_files,
proto_files=proto_files,
cc_include=repr(GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT),
- proto_include=repr(GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT))
+ proto_include=repr(GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT),
+ commit_hash=COMMIT_HASH_PREFIX + commit_hash + COMMIT_HASH_SUFFIX)
return deps_file_content
def long_path(path):
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index c9c64399f7..3c564e203a 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -1026,6 +1026,7 @@ src/core/lib/slice/percent_encoding.h \
src/core/lib/slice/slice_hash_table.h \
src/core/lib/slice/slice_internal.h \
src/core/lib/slice/slice_string_helpers.h \
+src/core/lib/support/abstract.h \
src/core/lib/support/arena.h \
src/core/lib/support/atomic.h \
src/core/lib/support/atomic_with_atm.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index b9844f8b89..5674124f44 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1073,7 +1073,6 @@ src/core/lib/iomgr/README.md \
src/core/lib/iomgr/block_annotate.h \
src/core/lib/iomgr/call_combiner.cc \
src/core/lib/iomgr/call_combiner.h \
-src/core/lib/iomgr/closure.cc \
src/core/lib/iomgr/closure.h \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/combiner.h \
@@ -1268,6 +1267,7 @@ src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_internal.h \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/slice/slice_string_helpers.h \
+src/core/lib/support/abstract.h \
src/core/lib/support/alloc.cc \
src/core/lib/support/arena.cc \
src/core/lib/support/arena.h \
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index e97178180e..5a3429c81f 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -756,6 +756,21 @@
"headers": [],
"is_filegroup": false,
"language": "c",
+ "name": "gpr_manual_constructor_test",
+ "src": [
+ "test/core/support/manual_constructor_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c",
"name": "gpr_mpscq_test",
"src": [
"test/core/support/mpscq_test.cc"
@@ -7814,6 +7829,7 @@
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
"src/core/lib/profiling/timers.h",
+ "src/core/lib/support/abstract.h",
"src/core/lib/support/arena.h",
"src/core/lib/support/atomic.h",
"src/core/lib/support/atomic_with_atm.h",
@@ -7862,6 +7878,7 @@
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
"src/core/lib/profiling/timers.h",
+ "src/core/lib/support/abstract.h",
"src/core/lib/support/arena.h",
"src/core/lib/support/atomic.h",
"src/core/lib/support/atomic_with_atm.h",
@@ -7978,7 +7995,6 @@
"src/core/lib/http/httpcli.cc",
"src/core/lib/http/parser.cc",
"src/core/lib/iomgr/call_combiner.cc",
- "src/core/lib/iomgr/closure.cc",
"src/core/lib/iomgr/combiner.cc",
"src/core/lib/iomgr/endpoint.cc",
"src/core/lib/iomgr/endpoint_pair_posix.cc",
@@ -8903,6 +8919,7 @@
"test/core/util/port.h",
"test/core/util/port_server_client.h",
"test/core/util/slice_splitter.h",
+ "test/core/util/tracer_util.h",
"test/core/util/trickle_endpoint.h"
],
"is_filegroup": true,
@@ -8937,6 +8954,8 @@
"test/core/util/port_server_client.h",
"test/core/util/slice_splitter.cc",
"test/core/util/slice_splitter.h",
+ "test/core/util/tracer_util.cc",
+ "test/core/util/tracer_util.h",
"test/core/util/trickle_endpoint.cc",
"test/core/util/trickle_endpoint.h"
],
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 4a5817cad1..dfd7bfafe6 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -920,6 +920,30 @@
"posix",
"windows"
],
+ "cpu_cost": 3,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": false,
+ "language": "c",
+ "name": "gpr_manual_constructor_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
"cpu_cost": 30,
"exclude_configs": [],
"exclude_iomgrs": [],
diff --git a/tools/run_tests/sanity/check_bazel_workspace.py b/tools/run_tests/sanity/check_bazel_workspace.py
new file mode 100755
index 0000000000..776c78b03f
--- /dev/null
+++ b/tools/run_tests/sanity/check_bazel_workspace.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+# Copyright 2016 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import print_function
+
+import ast
+import os
+import re
+import subprocess
+import sys
+
+os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
+
+git_hash_pattern = re.compile('[0-9a-f]{40}')
+
+# Parse git hashes from submodules
+git_submodules = subprocess.check_output('git submodule', shell=True).strip().split('\n')
+git_submodule_hashes = {re.search(git_hash_pattern, s).group() for s in git_submodules}
+
+# Parse git hashes from Bazel WORKSPACE {new_}http_archive rules
+with open('WORKSPACE', 'r') as f:
+ workspace_rules = [expr.value for expr in ast.parse(f.read()).body]
+
+http_archive_rules = [rule for rule in workspace_rules if rule.func.id.endswith('http_archive')]
+archive_urls = [kw.value.s for rule in http_archive_rules for kw in rule.keywords if kw.arg == 'url']
+workspace_git_hashes = {re.search(git_hash_pattern, url).group() for url in archive_urls}
+
+# Validate the equivalence of the git submodules and Bazel git dependencies. The
+# condition we impose is that there is a git submodule for every dependency in
+# the workspace, but not necessarily conversely. E.g. Bloaty is a dependency
+# not used by any of the targets built by Bazel.
+if len(workspace_git_hashes - git_submodule_hashes) > 0:
+ print("Found discrepancies between git submodules and Bazel WORKSPACE dependencies")
+ sys.exit(1)
+
+sys.exit(0)
diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
index 3ca5c1b6c0..81eec4d149 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_bazel_workspace.py
- script: tools/run_tests/sanity/check_cache_mk.sh
- script: tools/run_tests/sanity/check_owners.sh
- script: tools/run_tests/sanity/check_sources_and_headers.py