aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Muxi Yan <mxyan@google.com>2018-01-24 16:16:23 -0800
committerGravatar Muxi Yan <mxyan@google.com>2018-01-24 16:16:23 -0800
commitfd900e09fbafad16159617af86ca5b56f4819182 (patch)
tree8cc6e609fcec3e38e6966143f53cb2bd1d2417df
parent401f903151825dc06a90ab145791828276278521 (diff)
parent7e05426477dbb0235b806ddaa87b6ea95031efdd (diff)
Merge remote-tracking branch 'upstream/master' into fix-stream-compression-config-interface
-rw-r--r--.gitignore4
-rw-r--r--BUILD34
-rw-r--r--CMakeLists.txt53
-rw-r--r--Makefile76
-rw-r--r--build.yaml51
-rw-r--r--doc/g_stands_for.md1
-rw-r--r--examples/cpp/helloworld/cocoapods/HelloWorldCpp.xcodeproj/project.pbxproj409
-rw-r--r--examples/cpp/helloworld/cocoapods/HelloWorldCpp/AppDelegate.h23
-rw-r--r--examples/cpp/helloworld/cocoapods/HelloWorldCpp/AppDelegate.mm22
-rw-r--r--examples/cpp/helloworld/cocoapods/HelloWorldCpp/Assets.xcassets/AppIcon.appiconset/Contents.json93
-rw-r--r--examples/cpp/helloworld/cocoapods/HelloWorldCpp/Base.lproj/LaunchScreen.storyboard25
-rw-r--r--examples/cpp/helloworld/cocoapods/HelloWorldCpp/Base.lproj/Main.storyboard24
-rw-r--r--examples/cpp/helloworld/cocoapods/HelloWorldCpp/Info.plist45
-rw-r--r--examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.h23
-rw-r--r--examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.mm101
-rw-r--r--examples/cpp/helloworld/cocoapods/HelloWorldCpp/main.m26
-rw-r--r--examples/cpp/helloworld/cocoapods/Podfile8
-rw-r--r--gRPC-C++.podspec683
-rw-r--r--gRPC-Core.podspec50
-rw-r--r--gRPC-ProtoRPC.podspec2
-rw-r--r--gRPC-RxLibrary.podspec2
-rw-r--r--gRPC.podspec2
-rw-r--r--grpc.gemspec22
-rw-r--r--include/grpc/support/alloc.h5
-rw-r--r--package.xml35
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc64
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc867
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/subchannel_list.h2
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc2
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc2
-rw-r--r--src/core/ext/filters/client_channel/subchannel.cc4
-rw-r--r--src/core/ext/filters/client_channel/subchannel.h4
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/flow_control.h4
-rw-r--r--src/core/ext/transport/chttp2/transport/internal.h2
-rw-r--r--src/core/lib/gpr/alloc.cc4
-rw-r--r--src/core/lib/gpr/arena.cc31
-rw-r--r--src/core/lib/gpr/fork.cc16
-rw-r--r--src/core/lib/gprpp/README.md (renamed from src/core/lib/gpr++/README.md)0
-rw-r--r--src/core/lib/gprpp/abstract.h (renamed from src/core/lib/gpr++/abstract.h)6
-rw-r--r--src/core/lib/gprpp/atomic.h (renamed from src/core/lib/gpr++/atomic.h)10
-rw-r--r--src/core/lib/gprpp/atomic_with_atm.h (renamed from src/core/lib/gpr++/atomic_with_atm.h)6
-rw-r--r--src/core/lib/gprpp/atomic_with_std.h (renamed from src/core/lib/gpr++/atomic_with_std.h)6
-rw-r--r--src/core/lib/gprpp/debug_location.h (renamed from src/core/lib/gpr++/debug_location.h)6
-rw-r--r--src/core/lib/gprpp/inlined_vector.h (renamed from src/core/lib/gpr++/inlined_vector.h)8
-rw-r--r--src/core/lib/gprpp/manual_constructor.h (renamed from src/core/lib/gpr++/manual_constructor.h)4
-rw-r--r--src/core/lib/gprpp/memory.h (renamed from src/core/lib/gpr++/memory.h)6
-rw-r--r--src/core/lib/gprpp/orphanable.h (renamed from src/core/lib/gpr++/orphanable.h)12
-rw-r--r--src/core/lib/gprpp/ref_counted.h (renamed from src/core/lib/gpr++/ref_counted.h)12
-rw-r--r--src/core/lib/gprpp/ref_counted_ptr.h (renamed from src/core/lib/gpr++/ref_counted_ptr.h)8
-rw-r--r--src/core/lib/iomgr/ev_epoll1_linux.cc2
-rw-r--r--src/core/lib/iomgr/ev_epollex_linux.cc2
-rw-r--r--src/core/lib/iomgr/ev_epollsig_linux.cc2
-rw-r--r--src/core/lib/surface/lame_client.cc2
-rw-r--r--src/core/lib/surface/version.cc2
-rw-r--r--src/core/tsi/ssl_transport_security.cc62
-rw-r--r--src/cpp/common/version_cc.cc2
-rw-r--r--src/csharp/Grpc.Core.Tests/Internal/DefaultObjectPoolTest.cs18
-rw-r--r--src/csharp/Grpc.Core/GrpcEnvironment.cs4
-rw-r--r--src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs22
-rw-r--r--src/csharp/Grpc.Core/Internal/DefaultObjectPool.cs11
-rw-r--r--src/csharp/Grpc.Core/Internal/IPooledObject.cs34
-rw-r--r--src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs23
-rwxr-xr-xsrc/csharp/Grpc.Core/Version.csproj.include2
-rw-r--r--src/csharp/Grpc.Core/VersionInfo.cs4
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.bat2
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.sh4
-rw-r--r--src/objective-c/!ProtoCompiler-gRPCPlugin.podspec2
-rw-r--r--src/objective-c/GRPCClient/private/version.h2
-rw-r--r--src/objective-c/tests/version.h2
-rw-r--r--src/php/composer.json2
-rw-r--r--src/php/ext/grpc/call.c25
-rw-r--r--src/php/ext/grpc/call.h3
-rw-r--r--src/php/ext/grpc/call_credentials.c11
-rw-r--r--src/php/ext/grpc/channel.c135
-rwxr-xr-xsrc/php/ext/grpc/channel.h5
-rw-r--r--src/php/ext/grpc/channel_credentials.c14
-rw-r--r--src/php/ext/grpc/php7_wrapper.h2
-rw-r--r--src/php/ext/grpc/php_grpc.c3
-rw-r--r--src/php/ext/grpc/version.h2
-rw-r--r--src/proto/grpc/testing/control.proto3
-rw-r--r--src/python/grpcio/grpc/_grpcio_metadata.py2
-rw-r--r--src/python/grpcio/grpc/_interceptor.py91
-rw-r--r--src/python/grpcio/grpc_version.py2
-rw-r--r--src/python/grpcio_health_checking/grpc_version.py2
-rw-r--r--src/python/grpcio_reflection/grpc_version.py2
-rw-r--r--src/python/grpcio_testing/grpc_version.py2
-rw-r--r--src/python/grpcio_tests/grpc_version.py2
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.h2
-rw-r--r--src/ruby/lib/grpc/version.rb2
-rw-r--r--src/ruby/tools/version.rb2
-rw-r--r--summerofcode/ideas.md39
-rw-r--r--templates/gRPC-C++.podspec.template193
-rw-r--r--templates/package.xml.template13
-rw-r--r--test/core/end2end/goaway_server_test.cc4
-rw-r--r--test/core/gpr/alloc_test.cc14
-rw-r--r--test/core/gpr/arena_test.cc2
-rw-r--r--test/core/gprpp/BUILD (renamed from test/core/gpr++/BUILD)7
-rw-r--r--test/core/gprpp/inlined_vector_test.cc (renamed from test/core/gpr++/inlined_vector_test.cc)4
-rw-r--r--test/core/gprpp/manual_constructor_test.cc (renamed from test/core/gpr++/manual_constructor_test.cc)4
-rw-r--r--test/core/gprpp/memory_test.cc (renamed from test/core/gpr++/memory_test.cc)2
-rw-r--r--test/core/gprpp/orphanable_test.cc (renamed from test/core/gpr++/orphanable_test.cc)4
-rw-r--r--test/core/gprpp/ref_counted_ptr_test.cc (renamed from test/core/gpr++/ref_counted_ptr_test.cc)6
-rw-r--r--test/core/gprpp/ref_counted_test.cc (renamed from test/core/gpr++/ref_counted_test.cc)4
-rw-r--r--test/cpp/cocoapods/GRPCCppTests.xcodeproj/project.pbxproj533
-rw-r--r--test/cpp/cocoapods/Podfile71
-rw-r--r--test/cpp/cocoapods/generic/Info.plist22
-rw-r--r--test/cpp/cocoapods/generic/generic.mm244
-rw-r--r--test/cpp/cocoapods/test/Info.plist22
-rw-r--r--test/cpp/cocoapods/test/server_context_test_spouse_test.mm100
-rw-r--r--test/cpp/end2end/BUILD18
-rw-r--r--test/cpp/end2end/end2end_test.cc25
-rw-r--r--test/cpp/end2end/grpclb_end2end_test.cc47
-rw-r--r--test/cpp/end2end/server_early_return_test.cc233
-rw-r--r--test/cpp/end2end/test_service_impl.cc13
-rw-r--r--test/cpp/end2end/test_service_impl.h1
-rw-r--r--test/cpp/qps/client_async.cc38
-rw-r--r--test/cpp/qps/client_sync.cc1
-rw-r--r--test/cpp/qps/driver.cc1
-rwxr-xr-xtools/buildgen/plugins/expand_version.py7
-rw-r--r--tools/distrib/python/grpcio_tools/grpc_version.py2
-rwxr-xr-xtools/distrib/run_clang_tidy.py2
-rwxr-xr-xtools/dockerfile/grpc_clang_tidy/clang_tidy_all_the_things.sh2
-rw-r--r--tools/doxygen/Doxyfile.c++2
-rw-r--r--tools/doxygen/Doxyfile.c++.internal24
-rw-r--r--tools/doxygen/Doxyfile.core.internal24
-rw-r--r--tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh2
-rw-r--r--tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh2
-rw-r--r--tools/internal_ci/linux/grpc_tsan_on_foundry.sh58
-rw-r--r--tools/interop_matrix/client_matrix.py2
-rw-r--r--tools/run_tests/generated/sources_and_headers.json75
-rw-r--r--tools/run_tests/generated/tests.json24
-rwxr-xr-xtools/run_tests/run_tests_matrix.py13
135 files changed, 4393 insertions, 940 deletions
diff --git a/.gitignore b/.gitignore
index 882828ef79..0f3cd78947 100644
--- a/.gitignore
+++ b/.gitignore
@@ -94,9 +94,9 @@ DerivedData
*.pbrpc.*
# Cocoapods artifacts
-# Podfile.lock and the workspace file are tracked, to ease deleting them. That's
-# needed to trigger "pod install" to rerun the preinstall commands.
Pods/
+Podfile.lock
+*.xcworkspace
# Artifacts directory
/artifacts/
diff --git a/BUILD b/BUILD
index 8412151ac8..e512ee1156 100644
--- a/BUILD
+++ b/BUILD
@@ -54,11 +54,11 @@ config_setting(
)
# This should be updated along with build.yaml
-g_stands_for = "glossy"
+g_stands_for = "glamorous"
core_version = "5.0.0-dev"
-version = "1.9.0-dev"
+version = "1.10.0-dev"
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",
@@ -549,9 +549,9 @@ grpc_cc_library(
name = "gpr++_base",
language = "c++",
public_hdrs = [
- "src/core/lib/gpr++/abstract.h",
- "src/core/lib/gpr++/manual_constructor.h",
- "src/core/lib/gpr++/memory.h",
+ "src/core/lib/gprpp/abstract.h",
+ "src/core/lib/gprpp/manual_constructor.h",
+ "src/core/lib/gprpp/memory.h",
],
)
@@ -559,11 +559,11 @@ grpc_cc_library(
name = "atomic",
language = "c++",
public_hdrs = [
- "src/core/lib/gpr++/atomic.h",
+ "src/core/lib/gprpp/atomic.h",
],
hdrs = [
- "src/core/lib/gpr++/atomic_with_atm.h",
- "src/core/lib/gpr++/atomic_with_std.h",
+ "src/core/lib/gprpp/atomic_with_atm.h",
+ "src/core/lib/gprpp/atomic_with_std.h",
],
deps = [
"gpr",
@@ -574,22 +574,26 @@ grpc_cc_library(
name = "inlined_vector",
language = "c++",
public_hdrs = [
- "src/core/lib/gpr++/inlined_vector.h",
+ "src/core/lib/gprpp/inlined_vector.h",
+ ],
+ deps = [
+ "gpr++_base",
],
)
grpc_cc_library(
name = "debug_location",
language = "c++",
- public_hdrs = ["src/core/lib/gpr++/debug_location.h"],
+ public_hdrs = ["src/core/lib/gprpp/debug_location.h"],
)
grpc_cc_library(
name = "orphanable",
language = "c++",
- public_hdrs = ["src/core/lib/gpr++/orphanable.h"],
+ public_hdrs = ["src/core/lib/gprpp/orphanable.h"],
deps = [
"debug_location",
+ "gpr++_base",
"grpc_trace",
],
)
@@ -597,9 +601,10 @@ grpc_cc_library(
grpc_cc_library(
name = "ref_counted",
language = "c++",
- public_hdrs = ["src/core/lib/gpr++/ref_counted.h"],
+ public_hdrs = ["src/core/lib/gprpp/ref_counted.h"],
deps = [
"debug_location",
+ "gpr++_base",
"grpc_trace",
],
)
@@ -607,7 +612,10 @@ grpc_cc_library(
grpc_cc_library(
name = "ref_counted_ptr",
language = "c++",
- public_hdrs = ["src/core/lib/gpr++/ref_counted_ptr.h"],
+ public_hdrs = ["src/core/lib/gprpp/ref_counted_ptr.h"],
+ deps = [
+ "gpr++_base",
+ ],
)
grpc_cc_library(
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 77519c96fa..c557e9469a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,7 @@
cmake_minimum_required(VERSION 2.8)
set(PACKAGE_NAME "grpc")
-set(PACKAGE_VERSION "1.9.0-dev")
+set(PACKAGE_VERSION "1.10.0-dev")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@@ -590,6 +590,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx server_crash_test)
endif()
add_dependencies(buildtests_cxx server_crash_test_client)
+add_dependencies(buildtests_cxx server_early_return_test)
add_dependencies(buildtests_cxx server_request_call_test)
add_dependencies(buildtests_cxx shutdown_test)
add_dependencies(buildtests_cxx stats_test)
@@ -5802,7 +5803,7 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(gpr_manual_constructor_test
- test/core/gpr++/manual_constructor_test.cc
+ test/core/gprpp/manual_constructor_test.cc
)
@@ -10573,7 +10574,7 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(inlined_vector_test
- test/core/gpr++/inlined_vector_test.cc
+ test/core/gprpp/inlined_vector_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
@@ -10818,7 +10819,7 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(memory_test
- test/core/gpr++/memory_test.cc
+ test/core/gprpp/memory_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
@@ -10969,7 +10970,7 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(orphanable_test
- test/core/gpr++/orphanable_test.cc
+ test/core/gprpp/orphanable_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
@@ -11369,7 +11370,7 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(ref_counted_ptr_test
- test/core/gpr++/ref_counted_ptr_test.cc
+ test/core/gprpp/ref_counted_ptr_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
@@ -11406,7 +11407,7 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(ref_counted_test
- test/core/gpr++/ref_counted_test.cc
+ test/core/gprpp/ref_counted_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
@@ -11728,6 +11729,44 @@ target_link_libraries(server_crash_test_client
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(server_early_return_test
+ test/cpp/end2end/server_early_return_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(server_early_return_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+ PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+ PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+ PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+ PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(server_early_return_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc++_test_util
+ grpc_test_util
+ grpc++
+ grpc
+ gpr_test_util
+ gpr
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(server_request_call_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/echo_messages.grpc.pb.cc
diff --git a/Makefile b/Makefile
index 1880e2a20a..39a94d8c55 100644
--- a/Makefile
+++ b/Makefile
@@ -419,8 +419,8 @@ Q = @
endif
CORE_VERSION = 5.0.0-dev
-CPP_VERSION = 1.9.0-dev
-CSHARP_VERSION = 1.9.0-dev
+CPP_VERSION = 1.10.0-dev
+CSHARP_VERSION = 1.10.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -1179,6 +1179,7 @@ server_builder_test: $(BINDIR)/$(CONFIG)/server_builder_test
server_context_test_spouse_test: $(BINDIR)/$(CONFIG)/server_context_test_spouse_test
server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test
server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client
+server_early_return_test: $(BINDIR)/$(CONFIG)/server_early_return_test
server_request_call_test: $(BINDIR)/$(CONFIG)/server_request_call_test
shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test
stats_test: $(BINDIR)/$(CONFIG)/stats_test
@@ -1622,6 +1623,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
$(BINDIR)/$(CONFIG)/server_crash_test \
$(BINDIR)/$(CONFIG)/server_crash_test_client \
+ $(BINDIR)/$(CONFIG)/server_early_return_test \
$(BINDIR)/$(CONFIG)/server_request_call_test \
$(BINDIR)/$(CONFIG)/shutdown_test \
$(BINDIR)/$(CONFIG)/stats_test \
@@ -1754,6 +1756,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/server_context_test_spouse_test \
$(BINDIR)/$(CONFIG)/server_crash_test \
$(BINDIR)/$(CONFIG)/server_crash_test_client \
+ $(BINDIR)/$(CONFIG)/server_early_return_test \
$(BINDIR)/$(CONFIG)/server_request_call_test \
$(BINDIR)/$(CONFIG)/shutdown_test \
$(BINDIR)/$(CONFIG)/stats_test \
@@ -2171,6 +2174,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/server_context_test_spouse_test || ( echo test server_context_test_spouse_test failed ; exit 1 )
$(E) "[RUN] Testing server_crash_test"
$(Q) $(BINDIR)/$(CONFIG)/server_crash_test || ( echo test server_crash_test failed ; exit 1 )
+ $(E) "[RUN] Testing server_early_return_test"
+ $(Q) $(BINDIR)/$(CONFIG)/server_early_return_test || ( echo test server_early_return_test failed ; exit 1 )
$(E) "[RUN] Testing server_request_call_test"
$(Q) $(BINDIR)/$(CONFIG)/server_request_call_test || ( echo test server_request_call_test failed ; exit 1 )
$(E) "[RUN] Testing shutdown_test"
@@ -10066,7 +10071,7 @@ endif
GPR_MANUAL_CONSTRUCTOR_TEST_SRC = \
- test/core/gpr++/manual_constructor_test.cc \
+ test/core/gprpp/manual_constructor_test.cc \
GPR_MANUAL_CONSTRUCTOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_MANUAL_CONSTRUCTOR_TEST_SRC))))
ifeq ($(NO_SECURE),true)
@@ -10086,7 +10091,7 @@ $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_O
endif
-$(OBJDIR)/$(CONFIG)/test/core/gpr++/manual_constructor_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gprpp/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)
@@ -15796,7 +15801,7 @@ endif
INLINED_VECTOR_TEST_SRC = \
- test/core/gpr++/inlined_vector_test.cc \
+ test/core/gprpp/inlined_vector_test.cc \
INLINED_VECTOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INLINED_VECTOR_TEST_SRC))))
ifeq ($(NO_SECURE),true)
@@ -15827,7 +15832,7 @@ endif
endif
-$(OBJDIR)/$(CONFIG)/test/core/gpr++/inlined_vector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gprpp/inlined_vector_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_inlined_vector_test: $(INLINED_VECTOR_TEST_OBJS:.o=.dep)
@@ -16030,7 +16035,7 @@ endif
MEMORY_TEST_SRC = \
- test/core/gpr++/memory_test.cc \
+ test/core/gprpp/memory_test.cc \
MEMORY_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MEMORY_TEST_SRC))))
ifeq ($(NO_SECURE),true)
@@ -16061,7 +16066,7 @@ endif
endif
-$(OBJDIR)/$(CONFIG)/test/core/gpr++/memory_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gprpp/memory_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_memory_test: $(MEMORY_TEST_OBJS:.o=.dep)
@@ -16207,7 +16212,7 @@ endif
ORPHANABLE_TEST_SRC = \
- test/core/gpr++/orphanable_test.cc \
+ test/core/gprpp/orphanable_test.cc \
ORPHANABLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(ORPHANABLE_TEST_SRC))))
ifeq ($(NO_SECURE),true)
@@ -16238,7 +16243,7 @@ endif
endif
-$(OBJDIR)/$(CONFIG)/test/core/gpr++/orphanable_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gprpp/orphanable_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_orphanable_test: $(ORPHANABLE_TEST_OBJS:.o=.dep)
@@ -16614,7 +16619,7 @@ $(OBJDIR)/$(CONFIG)/test/cpp/interop/reconnect_interop_server.o: $(GENDIR)/src/p
REF_COUNTED_PTR_TEST_SRC = \
- test/core/gpr++/ref_counted_ptr_test.cc \
+ test/core/gprpp/ref_counted_ptr_test.cc \
REF_COUNTED_PTR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(REF_COUNTED_PTR_TEST_SRC))))
ifeq ($(NO_SECURE),true)
@@ -16645,7 +16650,7 @@ endif
endif
-$(OBJDIR)/$(CONFIG)/test/core/gpr++/ref_counted_ptr_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_ptr_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_ref_counted_ptr_test: $(REF_COUNTED_PTR_TEST_OBJS:.o=.dep)
@@ -16657,7 +16662,7 @@ endif
REF_COUNTED_TEST_SRC = \
- test/core/gpr++/ref_counted_test.cc \
+ test/core/gprpp/ref_counted_test.cc \
REF_COUNTED_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(REF_COUNTED_TEST_SRC))))
ifeq ($(NO_SECURE),true)
@@ -16688,7 +16693,7 @@ endif
endif
-$(OBJDIR)/$(CONFIG)/test/core/gpr++/ref_counted_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/gprpp/ref_counted_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_ref_counted_test: $(REF_COUNTED_TEST_OBJS:.o=.dep)
@@ -17007,6 +17012,49 @@ endif
endif
+SERVER_EARLY_RETURN_TEST_SRC = \
+ test/cpp/end2end/server_early_return_test.cc \
+
+SERVER_EARLY_RETURN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_EARLY_RETURN_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/server_early_return_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/server_early_return_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/server_early_return_test: $(PROTOBUF_DEP) $(SERVER_EARLY_RETURN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(SERVER_EARLY_RETURN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_early_return_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_early_return_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_server_early_return_test: $(SERVER_EARLY_RETURN_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(SERVER_EARLY_RETURN_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
SERVER_REQUEST_CALL_TEST_SRC = \
$(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
diff --git a/build.yaml b/build.yaml
index db97c4b46f..d4d5af1371 100644
--- a/build.yaml
+++ b/build.yaml
@@ -13,8 +13,8 @@ settings:
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 5.0.0-dev
- g_stands_for: glossy
- version: 1.9.0-dev
+ g_stands_for: glamorous
+ version: 1.10.0-dev
filegroups:
- name: census
public_headers:
@@ -101,12 +101,6 @@ filegroups:
- include/grpc/support/tls_pthread.h
- include/grpc/support/useful.h
headers:
- - src/core/lib/gpr++/abstract.h
- - src/core/lib/gpr++/atomic.h
- - src/core/lib/gpr++/atomic_with_atm.h
- - src/core/lib/gpr++/atomic_with_std.h
- - src/core/lib/gpr++/manual_constructor.h
- - src/core/lib/gpr++/memory.h
- src/core/lib/gpr/arena.h
- src/core/lib/gpr/env.h
- src/core/lib/gpr/fork.h
@@ -118,6 +112,12 @@ filegroups:
- src/core/lib/gpr/thd_internal.h
- src/core/lib/gpr/time_precise.h
- src/core/lib/gpr/tmpfile.h
+ - src/core/lib/gprpp/abstract.h
+ - src/core/lib/gprpp/atomic.h
+ - src/core/lib/gprpp/atomic_with_atm.h
+ - src/core/lib/gprpp/atomic_with_std.h
+ - src/core/lib/gprpp/manual_constructor.h
+ - src/core/lib/gprpp/memory.h
- src/core/lib/profiling/timers.h
uses:
- gpr_codegen
@@ -325,11 +325,11 @@ filegroups:
- src/core/lib/compression/stream_compression_identity.h
- src/core/lib/debug/stats.h
- src/core/lib/debug/stats_data.h
- - src/core/lib/gpr++/debug_location.h
- - src/core/lib/gpr++/inlined_vector.h
- - src/core/lib/gpr++/orphanable.h
- - src/core/lib/gpr++/ref_counted.h
- - src/core/lib/gpr++/ref_counted_ptr.h
+ - src/core/lib/gprpp/debug_location.h
+ - src/core/lib/gprpp/inlined_vector.h
+ - src/core/lib/gprpp/orphanable.h
+ - src/core/lib/gprpp/ref_counted.h
+ - src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/http/format_request.h
- src/core/lib/http/httpcli.h
- src/core/lib/http/parser.h
@@ -2192,7 +2192,7 @@ targets:
build: test
language: c
src:
- - test/core/gpr++/manual_constructor_test.cc
+ - test/core/gprpp/manual_constructor_test.cc
deps:
- gpr_test_util
- gpr
@@ -4269,7 +4269,7 @@ targets:
build: test
language: c++
src:
- - test/core/gpr++/inlined_vector_test.cc
+ - test/core/gprpp/inlined_vector_test.cc
deps:
- grpc_test_util
- grpc++
@@ -4375,7 +4375,7 @@ targets:
build: test
language: c++
src:
- - test/core/gpr++/memory_test.cc
+ - test/core/gprpp/memory_test.cc
deps:
- grpc_test_util
- grpc++
@@ -4427,7 +4427,7 @@ targets:
build: test
language: c++
src:
- - test/core/gpr++/orphanable_test.cc
+ - test/core/gprpp/orphanable_test.cc
deps:
- grpc_test_util
- grpc++
@@ -4580,7 +4580,7 @@ targets:
build: test
language: c++
src:
- - test/core/gpr++/ref_counted_ptr_test.cc
+ - test/core/gprpp/ref_counted_ptr_test.cc
deps:
- grpc_test_util
- grpc++
@@ -4594,7 +4594,7 @@ targets:
build: test
language: c++
src:
- - test/core/gpr++/ref_counted_test.cc
+ - test/core/gprpp/ref_counted_test.cc
deps:
- grpc_test_util
- grpc++
@@ -4708,6 +4708,19 @@ targets:
- grpc
- gpr_test_util
- gpr
+- name: server_early_return_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - test/cpp/end2end/server_early_return_test.cc
+ deps:
+ - grpc++_test_util
+ - grpc_test_util
+ - grpc++
+ - grpc
+ - gpr_test_util
+ - gpr
- name: server_request_call_test
gtest: true
build: test
diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md
index edc6dc1e79..19875c36a0 100644
--- a/doc/g_stands_for.md
+++ b/doc/g_stands_for.md
@@ -13,3 +13,4 @@ future), and the corresponding version numbers that used them:
- 1.7 'g' stands for 'gambit'
- 1.8 'g' stands for 'generous'
- 1.9 'g' stands for 'glossy'
+- 1.10 'g' stands for 'glamorous'
diff --git a/examples/cpp/helloworld/cocoapods/HelloWorldCpp.xcodeproj/project.pbxproj b/examples/cpp/helloworld/cocoapods/HelloWorldCpp.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..b722b80400
--- /dev/null
+++ b/examples/cpp/helloworld/cocoapods/HelloWorldCpp.xcodeproj/project.pbxproj
@@ -0,0 +1,409 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 48;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 3DC71E95B8670DC619CF8693 /* libPods-HelloWorldCpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E3077D82811A6434769B437 /* libPods-HelloWorldCpp.a */; };
+ 5E9D65611FFD689B00C955D4 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E9D65601FFD689B00C955D4 /* AppDelegate.mm */; };
+ 5E9D65641FFD689B00C955D4 /* ViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E9D65631FFD689B00C955D4 /* ViewController.mm */; };
+ 5E9D65671FFD689B00C955D4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E9D65651FFD689B00C955D4 /* Main.storyboard */; };
+ 5E9D65691FFD689B00C955D4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5E9D65681FFD689B00C955D4 /* Assets.xcassets */; };
+ 5E9D656C1FFD689B00C955D4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5E9D656A1FFD689B00C955D4 /* LaunchScreen.storyboard */; };
+ 5E9D656F1FFD689C00C955D4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E9D656E1FFD689C00C955D4 /* main.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 0A6137606FDBA874FCF64753 /* Pods-HelloWorldCpp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorldCpp.release.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorldCpp/Pods-HelloWorldCpp.release.xcconfig"; sourceTree = "<group>"; };
+ 5E9D655C1FFD689B00C955D4 /* HelloWorldCpp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorldCpp.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5E9D655F1FFD689B00C955D4 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ 5E9D65601FFD689B00C955D4 /* AppDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AppDelegate.mm; sourceTree = "<group>"; };
+ 5E9D65621FFD689B00C955D4 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
+ 5E9D65631FFD689B00C955D4 /* ViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ViewController.mm; sourceTree = "<group>"; };
+ 5E9D65661FFD689B00C955D4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+ 5E9D65681FFD689B00C955D4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+ 5E9D656B1FFD689B00C955D4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+ 5E9D656D1FFD689C00C955D4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 5E9D656E1FFD689C00C955D4 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 8E3077D82811A6434769B437 /* libPods-HelloWorldCpp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorldCpp.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ AF0FF6EB66DA2C30CFC575EA /* Pods-HelloWorldCpp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorldCpp.debug.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorldCpp/Pods-HelloWorldCpp.debug.xcconfig"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 5E9D65591FFD689B00C955D4 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3DC71E95B8670DC619CF8693 /* libPods-HelloWorldCpp.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 08FBFA5AB49E037A86EA64D7 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 8E3077D82811A6434769B437 /* libPods-HelloWorldCpp.a */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 5E9D65531FFD689B00C955D4 = {
+ isa = PBXGroup;
+ children = (
+ 5E9D655E1FFD689B00C955D4 /* HelloWorldCpp */,
+ 5E9D655D1FFD689B00C955D4 /* Products */,
+ E40B264856595518D408CF3E /* Pods */,
+ 08FBFA5AB49E037A86EA64D7 /* Frameworks */,
+ );
+ sourceTree = "<group>";
+ };
+ 5E9D655D1FFD689B00C955D4 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 5E9D655C1FFD689B00C955D4 /* HelloWorldCpp.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 5E9D655E1FFD689B00C955D4 /* HelloWorldCpp */ = {
+ isa = PBXGroup;
+ children = (
+ 5E9D655F1FFD689B00C955D4 /* AppDelegate.h */,
+ 5E9D65601FFD689B00C955D4 /* AppDelegate.mm */,
+ 5E9D65621FFD689B00C955D4 /* ViewController.h */,
+ 5E9D65631FFD689B00C955D4 /* ViewController.mm */,
+ 5E9D65651FFD689B00C955D4 /* Main.storyboard */,
+ 5E9D65681FFD689B00C955D4 /* Assets.xcassets */,
+ 5E9D656A1FFD689B00C955D4 /* LaunchScreen.storyboard */,
+ 5E9D656D1FFD689C00C955D4 /* Info.plist */,
+ 5E9D656E1FFD689C00C955D4 /* main.m */,
+ );
+ path = HelloWorldCpp;
+ sourceTree = "<group>";
+ };
+ E40B264856595518D408CF3E /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ AF0FF6EB66DA2C30CFC575EA /* Pods-HelloWorldCpp.debug.xcconfig */,
+ 0A6137606FDBA874FCF64753 /* Pods-HelloWorldCpp.release.xcconfig */,
+ );
+ name = Pods;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 5E9D655B1FFD689B00C955D4 /* HelloWorldCpp */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 5E9D65721FFD689C00C955D4 /* Build configuration list for PBXNativeTarget "HelloWorldCpp" */;
+ buildPhases = (
+ 4D66D60BD88AA4D5813859A9 /* [CP] Check Pods Manifest.lock */,
+ 5E9D65581FFD689B00C955D4 /* Sources */,
+ 5E9D65591FFD689B00C955D4 /* Frameworks */,
+ 5E9D655A1FFD689B00C955D4 /* Resources */,
+ CA89B315EACC5A6F8816FD26 /* [CP] Embed Pods Frameworks */,
+ 6C4D930C765719D03893663B /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = HelloWorldCpp;
+ productName = HelloWorldCpp;
+ productReference = 5E9D655C1FFD689B00C955D4 /* HelloWorldCpp.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 5E9D65541FFD689B00C955D4 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0920;
+ ORGANIZATIONNAME = gRPC;
+ TargetAttributes = {
+ 5E9D655B1FFD689B00C955D4 = {
+ CreatedOnToolsVersion = 9.2;
+ ProvisioningStyle = Automatic;
+ };
+ };
+ };
+ buildConfigurationList = 5E9D65571FFD689B00C955D4 /* Build configuration list for PBXProject "HelloWorldCpp" */;
+ compatibilityVersion = "Xcode 8.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 5E9D65531FFD689B00C955D4;
+ productRefGroup = 5E9D655D1FFD689B00C955D4 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 5E9D655B1FFD689B00C955D4 /* HelloWorldCpp */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 5E9D655A1FFD689B00C955D4 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5E9D656C1FFD689B00C955D4 /* LaunchScreen.storyboard in Resources */,
+ 5E9D65691FFD689B00C955D4 /* Assets.xcassets in Resources */,
+ 5E9D65671FFD689B00C955D4 /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 4D66D60BD88AA4D5813859A9 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-HelloWorldCpp-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 6C4D930C765719D03893663B /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-HelloWorldCpp/Pods-HelloWorldCpp-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ CA89B315EACC5A6F8816FD26 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-HelloWorldCpp/Pods-HelloWorldCpp-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 5E9D65581FFD689B00C955D4 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5E9D65641FFD689B00C955D4 /* ViewController.mm in Sources */,
+ 5E9D656F1FFD689C00C955D4 /* main.m in Sources */,
+ 5E9D65611FFD689B00C955D4 /* AppDelegate.mm in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 5E9D65651FFD689B00C955D4 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 5E9D65661FFD689B00C955D4 /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "<group>";
+ };
+ 5E9D656A1FFD689B00C955D4 /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 5E9D656B1FFD689B00C955D4 /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 5E9D65701FFD689C00C955D4 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 5E9D65711FFD689C00C955D4 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 5E9D65731FFD689C00C955D4 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = AF0FF6EB66DA2C30CFC575EA /* Pods-HelloWorldCpp.debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = EQHXZ8M8AV;
+ INFOPLIST_FILE = HelloWorldCpp/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.HelloWorldCpp;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 5E9D65741FFD689C00C955D4 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 0A6137606FDBA874FCF64753 /* Pods-HelloWorldCpp.release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = EQHXZ8M8AV;
+ INFOPLIST_FILE = HelloWorldCpp/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.HelloWorldCpp;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 5E9D65571FFD689B00C955D4 /* Build configuration list for PBXProject "HelloWorldCpp" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5E9D65701FFD689C00C955D4 /* Debug */,
+ 5E9D65711FFD689C00C955D4 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 5E9D65721FFD689C00C955D4 /* Build configuration list for PBXNativeTarget "HelloWorldCpp" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5E9D65731FFD689C00C955D4 /* Debug */,
+ 5E9D65741FFD689C00C955D4 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 5E9D65541FFD689B00C955D4 /* Project object */;
+}
diff --git a/examples/cpp/helloworld/cocoapods/HelloWorldCpp/AppDelegate.h b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/AppDelegate.h
new file mode 100644
index 0000000000..91ba988c4a
--- /dev/null
+++ b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/AppDelegate.h
@@ -0,0 +1,23 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+@property (strong, nonatomic) UIWindow *window;
+@end
diff --git a/examples/cpp/helloworld/cocoapods/HelloWorldCpp/AppDelegate.mm b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/AppDelegate.mm
new file mode 100644
index 0000000000..5c60aec65b
--- /dev/null
+++ b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/AppDelegate.mm
@@ -0,0 +1,22 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import "AppDelegate.h"
+
+@implementation AppDelegate
+@end
diff --git a/examples/cpp/helloworld/cocoapods/HelloWorldCpp/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..1d060ed288
--- /dev/null
+++ b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,93 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "20x20",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "20x20",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "20x20",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "20x20",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/examples/cpp/helloworld/cocoapods/HelloWorldCpp/Base.lproj/LaunchScreen.storyboard b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000000..f83f6fd581
--- /dev/null
+++ b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A277" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="EHf-IW-A2E">
+ <objects>
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="53" y="375"/>
+ </scene>
+ </scenes>
+</document>
diff --git a/examples/cpp/helloworld/cocoapods/HelloWorldCpp/Base.lproj/Main.storyboard b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/Base.lproj/Main.storyboard
new file mode 100644
index 0000000000..d7c78a1255
--- /dev/null
+++ b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/Base.lproj/Main.storyboard
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A277" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="tne-QT-ifu">
+ <objects>
+ <viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
+ <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+ <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+ </objects>
+ </scene>
+ </scenes>
+</document>
diff --git a/examples/cpp/helloworld/cocoapods/HelloWorldCpp/Info.plist b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/Info.plist
new file mode 100644
index 0000000000..16be3b6811
--- /dev/null
+++ b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/Info.plist
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UILaunchStoryboardName</key>
+ <string>LaunchScreen</string>
+ <key>UIMainStoryboardFile</key>
+ <string>Main</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.h b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.h
new file mode 100644
index 0000000000..28d4ca0961
--- /dev/null
+++ b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.h
@@ -0,0 +1,23 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface ViewController : UIViewController
+@end
+
diff --git a/examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.mm b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.mm
new file mode 100644
index 0000000000..6ff1ca593d
--- /dev/null
+++ b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.mm
@@ -0,0 +1,101 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import "ViewController.h"
+#import <grpc++/grpc++.h>
+#include <grpc++/generic/generic_stub.h>
+#include <grpc++/generic/async_generic_service.h>
+
+static void* tag(int i) { return (void*)(intptr_t)i; }
+
+// Serialized Proto bytes of Hello World example
+const uint8_t kMessage[] =
+ {0x0A, 0x0B, 0x4F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2D, 0x43};
+
+@interface ViewController ()
+
+@end
+
+@implementation ViewController {
+ grpc::CompletionQueue cq_;
+ std::unique_ptr<grpc::GenericStub> generic_stub_;
+}
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ // Setup call stub
+ std::shared_ptr<grpc::Channel> channel =
+ CreateChannel("localhost:50051", grpc::InsecureChannelCredentials());
+ generic_stub_.reset(new grpc::GenericStub(channel));
+
+ const grpc::string kMethodName("/helloworld.Greeter/SayHello");
+ void* got_tag;
+ bool ok;
+
+ grpc::ClientContext cli_ctx;
+ std::unique_ptr<grpc::GenericClientAsyncReaderWriter> call =
+ generic_stub_->Call(&cli_ctx, kMethodName, &cq_, tag(1));
+ cq_.Next(&got_tag, &ok);
+ if (!ok || got_tag != tag(1)) {
+ NSLog(@"Failed to create call.");
+ abort();
+ }
+ grpc::Slice send_slice = grpc::Slice(kMessage, sizeof(kMessage) / sizeof(kMessage[0]));
+ std::unique_ptr<grpc::ByteBuffer> send_buffer(new grpc::ByteBuffer(&send_slice, 1));
+ call->Write(*send_buffer, tag(2));
+ cq_.Next(&got_tag, &ok);
+ if (!ok || got_tag != tag(2)) {
+ NSLog(@"Failed to send message.");
+ abort();
+ }
+ grpc::ByteBuffer recv_buffer;
+ call->Read(&recv_buffer, tag(3));
+ cq_.Next(&got_tag, &ok);
+ if (!ok || got_tag != tag(3)) {
+ NSLog(@"Failed to receive message.");
+ abort();
+ }
+
+ grpc::Status status;
+ call->Finish(&status, tag(4));
+ cq_.Next(&got_tag, &ok);
+ if (!ok || got_tag != tag(4)) {
+ NSLog(@"Failed to finish call.");
+ abort();
+ }
+ if (!status.ok()) {
+ NSLog(@"Received unsuccessful status code: %d", status.error_code());
+ abort();
+ }
+ std::vector<grpc::Slice> slices;
+ recv_buffer.Dump(&slices);
+ NSString *recvBytes = [[NSString alloc] init];
+ for (auto slice : slices) {
+ auto p = slice.begin();
+ while (p != slice.end()) {
+ recvBytes =
+ [recvBytes stringByAppendingString:[NSString stringWithFormat:@"%02x ", *p]];
+ p++;
+ }
+ }
+ NSLog(@"Hello World succeeded.\nReceived bytes: %@\n"
+ "Expected bytes: 0a 11 48 65 6c 6c 6f 20 4f 62 6a 65 63 74 69 76 65 2d 43", recvBytes);
+}
+
+@end
diff --git a/examples/cpp/helloworld/cocoapods/HelloWorldCpp/main.m b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/main.m
new file mode 100644
index 0000000000..a3a2225806
--- /dev/null
+++ b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/main.m
@@ -0,0 +1,26 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
diff --git a/examples/cpp/helloworld/cocoapods/Podfile b/examples/cpp/helloworld/cocoapods/Podfile
new file mode 100644
index 0000000000..5467f97080
--- /dev/null
+++ b/examples/cpp/helloworld/cocoapods/Podfile
@@ -0,0 +1,8 @@
+source 'https://github.com/CocoaPods/Specs.git'
+platform :ios, '8.0'
+
+install! 'cocoapods', :deterministic_uuids => false
+
+target 'HelloWorldCpp' do
+ pod 'gRPC-C++'
+end
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
new file mode 100644
index 0000000000..abbb69c88f
--- /dev/null
+++ b/gRPC-C++.podspec
@@ -0,0 +1,683 @@
+# This file has been automatically generated from a template file.
+# Please make modifications to `templates/gRPC-C++.podspec.template`
+# instead. This file can be regenerated from the template by running
+# `tools/buildgen/generate_projects.sh`.
+
+# gRPC C++ CocoaPods podspec
+#
+# 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.
+
+
+Pod::Spec.new do |s|
+ s.name = 'gRPC-C++'
+ # TODO (mxyan): use version that match gRPC version when pod is stabilized
+ # version = '1.10.0-dev'
+ version = '0.0.1'
+ s.version = version
+ s.summary = 'gRPC C++ library'
+ s.homepage = 'https://grpc.io'
+ s.license = 'Apache License, Version 2.0'
+ s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' }
+
+ grpc_version = '1.10.0-dev'
+
+ s.source = {
+ :git => 'https://github.com/grpc/grpc.git',
+ :tag => "v#{grpc_version}",
+ }
+
+ s.ios.deployment_target = '7.0'
+ s.osx.deployment_target = '10.9'
+ s.requires_arc = false
+
+ # Add include prefix `grpc++` (i.e. `#include <grpc++/xxx.h>`).
+ s.header_dir = 'grpc++'
+
+ s.pod_target_xcconfig = {
+ 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(PODS_TARGET_SRCROOT)/include"',
+ 'USER_HEADER_SEARCH_PATHS' => '"$(PODS_TARGET_SRCROOT)"',
+ 'GCC_PREPROCESSOR_DEFINITIONS' => '"$(inherited)" "COCOAPODS=1" "PB_NO_PACKED_STRUCTS=1"',
+ 'CLANG_WARN_STRICT_PROTOTYPES' => 'NO',
+ 'CLANG_WARN_DOCUMENTATION_COMMENTS' => 'NO',
+
+ # If we don't set these two settings, `include/grpc/support/time.h` and
+ # `src/core/lib/support/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
+ # build.
+ 'USE_HEADERMAP' => 'NO',
+ 'ALWAYS_SEARCH_USER_PATHS' => 'NO',
+ }
+
+ s.libraries = 'c++'
+
+ s.default_subspecs = 'Interface', 'Implementation'
+
+ s.subspec 'Interface' do |ss|
+ ss.header_mappings_dir = 'include/grpc++'
+
+ ss.source_files = 'include/grpc++/alarm.h',
+ 'include/grpc++/channel.h',
+ 'include/grpc++/client_context.h',
+ 'include/grpc++/completion_queue.h',
+ 'include/grpc++/create_channel.h',
+ 'include/grpc++/create_channel_posix.h',
+ 'include/grpc++/ext/health_check_service_server_builder_option.h',
+ 'include/grpc++/generic/async_generic_service.h',
+ 'include/grpc++/generic/generic_stub.h',
+ 'include/grpc++/grpc++.h',
+ 'include/grpc++/health_check_service_interface.h',
+ 'include/grpc++/impl/call.h',
+ 'include/grpc++/impl/channel_argument_option.h',
+ 'include/grpc++/impl/client_unary_call.h',
+ 'include/grpc++/impl/codegen/core_codegen.h',
+ 'include/grpc++/impl/grpc_library.h',
+ 'include/grpc++/impl/method_handler_impl.h',
+ 'include/grpc++/impl/rpc_method.h',
+ 'include/grpc++/impl/rpc_service_method.h',
+ 'include/grpc++/impl/serialization_traits.h',
+ 'include/grpc++/impl/server_builder_option.h',
+ 'include/grpc++/impl/server_builder_plugin.h',
+ 'include/grpc++/impl/server_initializer.h',
+ 'include/grpc++/impl/service_type.h',
+ 'include/grpc++/resource_quota.h',
+ 'include/grpc++/security/auth_context.h',
+ 'include/grpc++/security/auth_metadata_processor.h',
+ 'include/grpc++/security/credentials.h',
+ 'include/grpc++/security/server_credentials.h',
+ 'include/grpc++/server.h',
+ 'include/grpc++/server_builder.h',
+ 'include/grpc++/server_context.h',
+ 'include/grpc++/server_posix.h',
+ 'include/grpc++/support/async_stream.h',
+ 'include/grpc++/support/async_unary_call.h',
+ 'include/grpc++/support/byte_buffer.h',
+ 'include/grpc++/support/channel_arguments.h',
+ 'include/grpc++/support/config.h',
+ 'include/grpc++/support/slice.h',
+ 'include/grpc++/support/status.h',
+ 'include/grpc++/support/status_code_enum.h',
+ 'include/grpc++/support/string_ref.h',
+ 'include/grpc++/support/stub_options.h',
+ 'include/grpc++/support/sync_stream.h',
+ 'include/grpc++/support/time.h',
+ 'include/grpc++/impl/codegen/async_stream.h',
+ 'include/grpc++/impl/codegen/async_unary_call.h',
+ 'include/grpc++/impl/codegen/byte_buffer.h',
+ 'include/grpc++/impl/codegen/call.h',
+ 'include/grpc++/impl/codegen/call_hook.h',
+ 'include/grpc++/impl/codegen/channel_interface.h',
+ 'include/grpc++/impl/codegen/client_context.h',
+ 'include/grpc++/impl/codegen/client_unary_call.h',
+ 'include/grpc++/impl/codegen/completion_queue.h',
+ 'include/grpc++/impl/codegen/completion_queue_tag.h',
+ 'include/grpc++/impl/codegen/config.h',
+ 'include/grpc++/impl/codegen/core_codegen_interface.h',
+ 'include/grpc++/impl/codegen/create_auth_context.h',
+ 'include/grpc++/impl/codegen/grpc_library.h',
+ 'include/grpc++/impl/codegen/metadata_map.h',
+ 'include/grpc++/impl/codegen/method_handler_impl.h',
+ 'include/grpc++/impl/codegen/rpc_method.h',
+ 'include/grpc++/impl/codegen/rpc_service_method.h',
+ 'include/grpc++/impl/codegen/security/auth_context.h',
+ 'include/grpc++/impl/codegen/serialization_traits.h',
+ 'include/grpc++/impl/codegen/server_context.h',
+ 'include/grpc++/impl/codegen/server_interface.h',
+ 'include/grpc++/impl/codegen/service_type.h',
+ 'include/grpc++/impl/codegen/slice.h',
+ 'include/grpc++/impl/codegen/status.h',
+ 'include/grpc++/impl/codegen/status_code_enum.h',
+ 'include/grpc++/impl/codegen/string_ref.h',
+ 'include/grpc++/impl/codegen/stub_options.h',
+ 'include/grpc++/impl/codegen/sync_stream.h',
+ 'include/grpc++/impl/codegen/time.h'
+ end
+
+ s.subspec 'Implementation' do |ss|
+ ss.header_mappings_dir = '.'
+ ss.dependency "#{s.name}/Interface", version
+ ss.dependency 'gRPC-Core', grpc_version
+ ss.dependency 'nanopb', '~> 0.3'
+
+ ss.source_files = 'include/grpc++/impl/codegen/core_codegen.h',
+ 'src/cpp/client/secure_credentials.h',
+ 'src/cpp/common/secure_auth_context.h',
+ 'src/cpp/server/secure_server_credentials.h',
+ 'src/cpp/client/create_channel_internal.h',
+ 'src/cpp/common/channel_filter.h',
+ 'src/cpp/server/dynamic_thread_pool.h',
+ 'src/cpp/server/health/default_health_check_service.h',
+ 'src/cpp/server/health/health.pb.h',
+ 'src/cpp/server/thread_pool_interface.h',
+ 'src/cpp/thread_manager/thread_manager.h',
+ 'src/cpp/client/insecure_credentials.cc',
+ 'src/cpp/client/secure_credentials.cc',
+ 'src/cpp/common/auth_property_iterator.cc',
+ 'src/cpp/common/secure_auth_context.cc',
+ 'src/cpp/common/secure_channel_arguments.cc',
+ 'src/cpp/common/secure_create_auth_context.cc',
+ 'src/cpp/server/insecure_server_credentials.cc',
+ 'src/cpp/server/secure_server_credentials.cc',
+ 'src/cpp/client/channel_cc.cc',
+ 'src/cpp/client/client_context.cc',
+ 'src/cpp/client/create_channel.cc',
+ 'src/cpp/client/create_channel_internal.cc',
+ 'src/cpp/client/create_channel_posix.cc',
+ 'src/cpp/client/credentials_cc.cc',
+ 'src/cpp/client/generic_stub.cc',
+ 'src/cpp/common/channel_arguments.cc',
+ 'src/cpp/common/channel_filter.cc',
+ 'src/cpp/common/completion_queue_cc.cc',
+ 'src/cpp/common/core_codegen.cc',
+ 'src/cpp/common/resource_quota_cc.cc',
+ 'src/cpp/common/rpc_method.cc',
+ 'src/cpp/common/version_cc.cc',
+ 'src/cpp/server/async_generic_service.cc',
+ 'src/cpp/server/channel_argument_option.cc',
+ 'src/cpp/server/create_default_thread_pool.cc',
+ 'src/cpp/server/dynamic_thread_pool.cc',
+ 'src/cpp/server/health/default_health_check_service.cc',
+ 'src/cpp/server/health/health.pb.c',
+ 'src/cpp/server/health/health_check_service.cc',
+ 'src/cpp/server/health/health_check_service_server_builder_option.cc',
+ 'src/cpp/server/server_builder.cc',
+ 'src/cpp/server/server_cc.cc',
+ 'src/cpp/server/server_context.cc',
+ 'src/cpp/server/server_credentials.cc',
+ 'src/cpp/server/server_posix.cc',
+ 'src/cpp/thread_manager/thread_manager.cc',
+ 'src/cpp/util/byte_buffer_cc.cc',
+ 'src/cpp/util/slice_cc.cc',
+ 'src/cpp/util/status.cc',
+ 'src/cpp/util/string_ref.cc',
+ 'src/cpp/util/time_cc.cc',
+ 'src/cpp/codegen/codegen_init.cc',
+ 'src/core/lib/gpr/arena.h',
+ 'src/core/lib/gpr/env.h',
+ 'src/core/lib/gpr/fork.h',
+ 'src/core/lib/gpr/mpscq.h',
+ 'src/core/lib/gpr/murmur_hash.h',
+ 'src/core/lib/gpr/spinlock.h',
+ 'src/core/lib/gpr/string.h',
+ 'src/core/lib/gpr/string_windows.h',
+ 'src/core/lib/gpr/thd_internal.h',
+ 'src/core/lib/gpr/time_precise.h',
+ 'src/core/lib/gpr/tmpfile.h',
+ 'src/core/lib/gprpp/abstract.h',
+ 'src/core/lib/gprpp/atomic.h',
+ 'src/core/lib/gprpp/atomic_with_atm.h',
+ 'src/core/lib/gprpp/atomic_with_std.h',
+ 'src/core/lib/gprpp/manual_constructor.h',
+ 'src/core/lib/gprpp/memory.h',
+ 'src/core/lib/profiling/timers.h',
+ 'src/core/ext/transport/chttp2/transport/bin_decoder.h',
+ 'src/core/ext/transport/chttp2/transport/bin_encoder.h',
+ 'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
+ 'src/core/ext/transport/chttp2/transport/flow_control.h',
+ 'src/core/ext/transport/chttp2/transport/frame.h',
+ 'src/core/ext/transport/chttp2/transport/frame_data.h',
+ 'src/core/ext/transport/chttp2/transport/frame_goaway.h',
+ 'src/core/ext/transport/chttp2/transport/frame_ping.h',
+ 'src/core/ext/transport/chttp2/transport/frame_rst_stream.h',
+ 'src/core/ext/transport/chttp2/transport/frame_settings.h',
+ 'src/core/ext/transport/chttp2/transport/frame_window_update.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_parser.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_table.h',
+ 'src/core/ext/transport/chttp2/transport/http2_settings.h',
+ 'src/core/ext/transport/chttp2/transport/huffsyms.h',
+ 'src/core/ext/transport/chttp2/transport/incoming_metadata.h',
+ 'src/core/ext/transport/chttp2/transport/internal.h',
+ 'src/core/ext/transport/chttp2/transport/stream_map.h',
+ 'src/core/ext/transport/chttp2/transport/varint.h',
+ 'src/core/ext/transport/chttp2/alpn/alpn.h',
+ 'src/core/ext/filters/http/client/http_client_filter.h',
+ 'src/core/ext/filters/http/message_compress/message_compress_filter.h',
+ 'src/core/ext/filters/http/server/http_server_filter.h',
+ 'src/core/lib/security/context/security_context.h',
+ 'src/core/lib/security/credentials/composite/composite_credentials.h',
+ 'src/core/lib/security/credentials/credentials.h',
+ 'src/core/lib/security/credentials/fake/fake_credentials.h',
+ 'src/core/lib/security/credentials/google_default/google_default_credentials.h',
+ 'src/core/lib/security/credentials/iam/iam_credentials.h',
+ 'src/core/lib/security/credentials/jwt/json_token.h',
+ 'src/core/lib/security/credentials/jwt/jwt_credentials.h',
+ 'src/core/lib/security/credentials/jwt/jwt_verifier.h',
+ 'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
+ 'src/core/lib/security/credentials/plugin/plugin_credentials.h',
+ 'src/core/lib/security/credentials/ssl/ssl_credentials.h',
+ 'src/core/lib/security/transport/auth_filters.h',
+ 'src/core/lib/security/transport/lb_targets_info.h',
+ 'src/core/lib/security/transport/secure_endpoint.h',
+ 'src/core/lib/security/transport/security_connector.h',
+ 'src/core/lib/security/transport/security_handshaker.h',
+ 'src/core/lib/security/transport/tsi_error.h',
+ 'src/core/lib/security/util/json_util.h',
+ 'src/core/tsi/fake_transport_security.h',
+ 'src/core/tsi/gts_transport_security.h',
+ 'src/core/tsi/ssl_transport_security.h',
+ 'src/core/tsi/ssl_types.h',
+ 'src/core/tsi/transport_security_grpc.h',
+ 'src/core/tsi/transport_security.h',
+ 'src/core/tsi/transport_security_adapter.h',
+ 'src/core/tsi/transport_security_interface.h',
+ 'src/core/ext/transport/chttp2/server/chttp2_server.h',
+ 'src/core/ext/filters/client_channel/backup_poller.h',
+ 'src/core/ext/filters/client_channel/client_channel.h',
+ 'src/core/ext/filters/client_channel/client_channel_factory.h',
+ 'src/core/ext/filters/client_channel/connector.h',
+ 'src/core/ext/filters/client_channel/http_connect_handshaker.h',
+ 'src/core/ext/filters/client_channel/http_proxy.h',
+ 'src/core/ext/filters/client_channel/lb_policy.h',
+ 'src/core/ext/filters/client_channel/lb_policy_factory.h',
+ 'src/core/ext/filters/client_channel/lb_policy_registry.h',
+ 'src/core/ext/filters/client_channel/parse_address.h',
+ 'src/core/ext/filters/client_channel/proxy_mapper.h',
+ 'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
+ 'src/core/ext/filters/client_channel/resolver.h',
+ 'src/core/ext/filters/client_channel/resolver_factory.h',
+ 'src/core/ext/filters/client_channel/resolver_registry.h',
+ 'src/core/ext/filters/client_channel/retry_throttle.h',
+ 'src/core/ext/filters/client_channel/subchannel.h',
+ 'src/core/ext/filters/client_channel/subchannel_index.h',
+ 'src/core/ext/filters/client_channel/uri_parser.h',
+ 'src/core/ext/filters/deadline/deadline_filter.h',
+ 'src/core/ext/transport/chttp2/client/chttp2_connector.h',
+ 'src/core/ext/transport/inproc/inproc_transport.h',
+ 'src/core/lib/backoff/backoff.h',
+ 'src/core/lib/channel/channel_args.h',
+ 'src/core/lib/channel/channel_stack.h',
+ 'src/core/lib/channel/channel_stack_builder.h',
+ 'src/core/lib/channel/connected_channel.h',
+ 'src/core/lib/channel/context.h',
+ 'src/core/lib/channel/handshaker.h',
+ 'src/core/lib/channel/handshaker_factory.h',
+ 'src/core/lib/channel/handshaker_registry.h',
+ 'src/core/lib/compression/algorithm_metadata.h',
+ 'src/core/lib/compression/message_compress.h',
+ 'src/core/lib/compression/stream_compression.h',
+ 'src/core/lib/compression/stream_compression_gzip.h',
+ 'src/core/lib/compression/stream_compression_identity.h',
+ 'src/core/lib/debug/stats.h',
+ 'src/core/lib/debug/stats_data.h',
+ 'src/core/lib/gprpp/debug_location.h',
+ 'src/core/lib/gprpp/inlined_vector.h',
+ 'src/core/lib/gprpp/orphanable.h',
+ 'src/core/lib/gprpp/ref_counted.h',
+ 'src/core/lib/gprpp/ref_counted_ptr.h',
+ 'src/core/lib/http/format_request.h',
+ 'src/core/lib/http/httpcli.h',
+ 'src/core/lib/http/parser.h',
+ 'src/core/lib/iomgr/block_annotate.h',
+ 'src/core/lib/iomgr/call_combiner.h',
+ 'src/core/lib/iomgr/closure.h',
+ 'src/core/lib/iomgr/combiner.h',
+ 'src/core/lib/iomgr/endpoint.h',
+ 'src/core/lib/iomgr/endpoint_pair.h',
+ 'src/core/lib/iomgr/error.h',
+ 'src/core/lib/iomgr/error_internal.h',
+ 'src/core/lib/iomgr/ev_epoll1_linux.h',
+ 'src/core/lib/iomgr/ev_epollex_linux.h',
+ 'src/core/lib/iomgr/ev_epollsig_linux.h',
+ 'src/core/lib/iomgr/ev_poll_posix.h',
+ 'src/core/lib/iomgr/ev_posix.h',
+ 'src/core/lib/iomgr/exec_ctx.h',
+ 'src/core/lib/iomgr/executor.h',
+ 'src/core/lib/iomgr/gethostname.h',
+ 'src/core/lib/iomgr/iocp_windows.h',
+ 'src/core/lib/iomgr/iomgr.h',
+ 'src/core/lib/iomgr/iomgr_internal.h',
+ 'src/core/lib/iomgr/iomgr_posix.h',
+ 'src/core/lib/iomgr/iomgr_uv.h',
+ 'src/core/lib/iomgr/is_epollexclusive_available.h',
+ 'src/core/lib/iomgr/load_file.h',
+ 'src/core/lib/iomgr/lockfree_event.h',
+ 'src/core/lib/iomgr/nameser.h',
+ 'src/core/lib/iomgr/network_status_tracker.h',
+ 'src/core/lib/iomgr/polling_entity.h',
+ 'src/core/lib/iomgr/pollset.h',
+ 'src/core/lib/iomgr/pollset_set.h',
+ 'src/core/lib/iomgr/pollset_set_windows.h',
+ 'src/core/lib/iomgr/pollset_uv.h',
+ 'src/core/lib/iomgr/pollset_windows.h',
+ 'src/core/lib/iomgr/port.h',
+ 'src/core/lib/iomgr/resolve_address.h',
+ 'src/core/lib/iomgr/resource_quota.h',
+ 'src/core/lib/iomgr/sockaddr.h',
+ 'src/core/lib/iomgr/sockaddr_posix.h',
+ 'src/core/lib/iomgr/sockaddr_utils.h',
+ 'src/core/lib/iomgr/sockaddr_windows.h',
+ 'src/core/lib/iomgr/socket_factory_posix.h',
+ 'src/core/lib/iomgr/socket_mutator.h',
+ 'src/core/lib/iomgr/socket_utils.h',
+ 'src/core/lib/iomgr/socket_utils_posix.h',
+ 'src/core/lib/iomgr/socket_windows.h',
+ 'src/core/lib/iomgr/sys_epoll_wrapper.h',
+ 'src/core/lib/iomgr/tcp_client.h',
+ 'src/core/lib/iomgr/tcp_client_posix.h',
+ 'src/core/lib/iomgr/tcp_posix.h',
+ 'src/core/lib/iomgr/tcp_server.h',
+ 'src/core/lib/iomgr/tcp_server_utils_posix.h',
+ 'src/core/lib/iomgr/tcp_uv.h',
+ 'src/core/lib/iomgr/tcp_windows.h',
+ 'src/core/lib/iomgr/time_averaged_stats.h',
+ 'src/core/lib/iomgr/timer.h',
+ 'src/core/lib/iomgr/timer_generic.h',
+ 'src/core/lib/iomgr/timer_heap.h',
+ 'src/core/lib/iomgr/timer_manager.h',
+ 'src/core/lib/iomgr/timer_uv.h',
+ 'src/core/lib/iomgr/udp_server.h',
+ 'src/core/lib/iomgr/unix_sockets_posix.h',
+ 'src/core/lib/iomgr/wakeup_fd_cv.h',
+ 'src/core/lib/iomgr/wakeup_fd_pipe.h',
+ 'src/core/lib/iomgr/wakeup_fd_posix.h',
+ 'src/core/lib/json/json.h',
+ 'src/core/lib/json/json_common.h',
+ 'src/core/lib/json/json_reader.h',
+ 'src/core/lib/json/json_writer.h',
+ 'src/core/lib/slice/b64.h',
+ '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/surface/alarm_internal.h',
+ 'src/core/lib/surface/api_trace.h',
+ 'src/core/lib/surface/call.h',
+ 'src/core/lib/surface/call_test_only.h',
+ 'src/core/lib/surface/channel.h',
+ 'src/core/lib/surface/channel_init.h',
+ 'src/core/lib/surface/channel_stack_type.h',
+ 'src/core/lib/surface/completion_queue.h',
+ 'src/core/lib/surface/completion_queue_factory.h',
+ 'src/core/lib/surface/event_string.h',
+ 'src/core/lib/surface/init.h',
+ 'src/core/lib/surface/lame_client.h',
+ 'src/core/lib/surface/server.h',
+ 'src/core/lib/surface/validate_metadata.h',
+ 'src/core/lib/transport/bdp_estimator.h',
+ 'src/core/lib/transport/byte_stream.h',
+ 'src/core/lib/transport/connectivity_state.h',
+ 'src/core/lib/transport/error_utils.h',
+ 'src/core/lib/transport/http2_errors.h',
+ 'src/core/lib/transport/metadata.h',
+ 'src/core/lib/transport/metadata_batch.h',
+ 'src/core/lib/transport/pid_controller.h',
+ 'src/core/lib/transport/service_config.h',
+ 'src/core/lib/transport/static_metadata.h',
+ 'src/core/lib/transport/status_conversion.h',
+ 'src/core/lib/transport/timeout_encoding.h',
+ 'src/core/lib/transport/transport.h',
+ 'src/core/lib/transport/transport_impl.h',
+ 'src/core/lib/debug/trace.h',
+ 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h',
+ 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h',
+ 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
+ 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
+ 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
+ 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
+ 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
+ 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h',
+ 'src/core/ext/filters/load_reporting/server_load_reporting_filter.h',
+ 'src/core/ext/filters/load_reporting/server_load_reporting_plugin.h',
+ 'src/core/ext/filters/max_age/max_age_filter.h',
+ 'src/core/ext/filters/message_size/message_size_filter.h',
+ 'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h',
+ 'src/core/ext/filters/workarounds/workaround_utils.h'
+
+ ss.private_header_files = 'include/grpc++/impl/codegen/core_codegen.h',
+ 'src/cpp/client/secure_credentials.h',
+ 'src/cpp/common/secure_auth_context.h',
+ 'src/cpp/server/secure_server_credentials.h',
+ 'src/cpp/client/create_channel_internal.h',
+ 'src/cpp/common/channel_filter.h',
+ 'src/cpp/server/dynamic_thread_pool.h',
+ 'src/cpp/server/health/default_health_check_service.h',
+ 'src/cpp/server/health/health.pb.h',
+ 'src/cpp/server/thread_pool_interface.h',
+ 'src/cpp/thread_manager/thread_manager.h',
+ 'src/core/lib/gpr/arena.h',
+ 'src/core/lib/gpr/env.h',
+ 'src/core/lib/gpr/fork.h',
+ 'src/core/lib/gpr/mpscq.h',
+ 'src/core/lib/gpr/murmur_hash.h',
+ 'src/core/lib/gpr/spinlock.h',
+ 'src/core/lib/gpr/string.h',
+ 'src/core/lib/gpr/string_windows.h',
+ 'src/core/lib/gpr/thd_internal.h',
+ 'src/core/lib/gpr/time_precise.h',
+ 'src/core/lib/gpr/tmpfile.h',
+ 'src/core/lib/gprpp/abstract.h',
+ 'src/core/lib/gprpp/atomic.h',
+ 'src/core/lib/gprpp/atomic_with_atm.h',
+ 'src/core/lib/gprpp/atomic_with_std.h',
+ 'src/core/lib/gprpp/manual_constructor.h',
+ 'src/core/lib/gprpp/memory.h',
+ 'src/core/lib/profiling/timers.h',
+ 'src/core/lib/backoff/backoff.h',
+ 'src/core/lib/channel/channel_args.h',
+ 'src/core/lib/channel/channel_stack.h',
+ 'src/core/lib/channel/channel_stack_builder.h',
+ 'src/core/lib/channel/connected_channel.h',
+ 'src/core/lib/channel/context.h',
+ 'src/core/lib/channel/handshaker.h',
+ 'src/core/lib/channel/handshaker_factory.h',
+ 'src/core/lib/channel/handshaker_registry.h',
+ 'src/core/lib/compression/algorithm_metadata.h',
+ 'src/core/lib/compression/message_compress.h',
+ 'src/core/lib/compression/stream_compression.h',
+ 'src/core/lib/compression/stream_compression_gzip.h',
+ 'src/core/lib/compression/stream_compression_identity.h',
+ 'src/core/lib/debug/stats.h',
+ 'src/core/lib/debug/stats_data.h',
+ 'src/core/lib/gprpp/debug_location.h',
+ 'src/core/lib/gprpp/inlined_vector.h',
+ 'src/core/lib/gprpp/orphanable.h',
+ 'src/core/lib/gprpp/ref_counted.h',
+ 'src/core/lib/gprpp/ref_counted_ptr.h',
+ 'src/core/lib/http/format_request.h',
+ 'src/core/lib/http/httpcli.h',
+ 'src/core/lib/http/parser.h',
+ 'src/core/lib/iomgr/block_annotate.h',
+ 'src/core/lib/iomgr/call_combiner.h',
+ 'src/core/lib/iomgr/closure.h',
+ 'src/core/lib/iomgr/combiner.h',
+ 'src/core/lib/iomgr/endpoint.h',
+ 'src/core/lib/iomgr/endpoint_pair.h',
+ 'src/core/lib/iomgr/error.h',
+ 'src/core/lib/iomgr/error_internal.h',
+ 'src/core/lib/iomgr/ev_epoll1_linux.h',
+ 'src/core/lib/iomgr/ev_epollex_linux.h',
+ 'src/core/lib/iomgr/ev_epollsig_linux.h',
+ 'src/core/lib/iomgr/ev_poll_posix.h',
+ 'src/core/lib/iomgr/ev_posix.h',
+ 'src/core/lib/iomgr/exec_ctx.h',
+ 'src/core/lib/iomgr/executor.h',
+ 'src/core/lib/iomgr/gethostname.h',
+ 'src/core/lib/iomgr/iocp_windows.h',
+ 'src/core/lib/iomgr/iomgr.h',
+ 'src/core/lib/iomgr/iomgr_internal.h',
+ 'src/core/lib/iomgr/iomgr_posix.h',
+ 'src/core/lib/iomgr/iomgr_uv.h',
+ 'src/core/lib/iomgr/is_epollexclusive_available.h',
+ 'src/core/lib/iomgr/load_file.h',
+ 'src/core/lib/iomgr/lockfree_event.h',
+ 'src/core/lib/iomgr/nameser.h',
+ 'src/core/lib/iomgr/network_status_tracker.h',
+ 'src/core/lib/iomgr/polling_entity.h',
+ 'src/core/lib/iomgr/pollset.h',
+ 'src/core/lib/iomgr/pollset_set.h',
+ 'src/core/lib/iomgr/pollset_set_windows.h',
+ 'src/core/lib/iomgr/pollset_uv.h',
+ 'src/core/lib/iomgr/pollset_windows.h',
+ 'src/core/lib/iomgr/port.h',
+ 'src/core/lib/iomgr/resolve_address.h',
+ 'src/core/lib/iomgr/resource_quota.h',
+ 'src/core/lib/iomgr/sockaddr.h',
+ 'src/core/lib/iomgr/sockaddr_posix.h',
+ 'src/core/lib/iomgr/sockaddr_utils.h',
+ 'src/core/lib/iomgr/sockaddr_windows.h',
+ 'src/core/lib/iomgr/socket_factory_posix.h',
+ 'src/core/lib/iomgr/socket_mutator.h',
+ 'src/core/lib/iomgr/socket_utils.h',
+ 'src/core/lib/iomgr/socket_utils_posix.h',
+ 'src/core/lib/iomgr/socket_windows.h',
+ 'src/core/lib/iomgr/sys_epoll_wrapper.h',
+ 'src/core/lib/iomgr/tcp_client.h',
+ 'src/core/lib/iomgr/tcp_client_posix.h',
+ 'src/core/lib/iomgr/tcp_posix.h',
+ 'src/core/lib/iomgr/tcp_server.h',
+ 'src/core/lib/iomgr/tcp_server_utils_posix.h',
+ 'src/core/lib/iomgr/tcp_uv.h',
+ 'src/core/lib/iomgr/tcp_windows.h',
+ 'src/core/lib/iomgr/time_averaged_stats.h',
+ 'src/core/lib/iomgr/timer.h',
+ 'src/core/lib/iomgr/timer_generic.h',
+ 'src/core/lib/iomgr/timer_heap.h',
+ 'src/core/lib/iomgr/timer_manager.h',
+ 'src/core/lib/iomgr/timer_uv.h',
+ 'src/core/lib/iomgr/udp_server.h',
+ 'src/core/lib/iomgr/unix_sockets_posix.h',
+ 'src/core/lib/iomgr/wakeup_fd_cv.h',
+ 'src/core/lib/iomgr/wakeup_fd_pipe.h',
+ 'src/core/lib/iomgr/wakeup_fd_posix.h',
+ 'src/core/lib/json/json.h',
+ 'src/core/lib/json/json_common.h',
+ 'src/core/lib/json/json_reader.h',
+ 'src/core/lib/json/json_writer.h',
+ 'src/core/lib/slice/b64.h',
+ '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/surface/alarm_internal.h',
+ 'src/core/lib/surface/api_trace.h',
+ 'src/core/lib/surface/call.h',
+ 'src/core/lib/surface/call_test_only.h',
+ 'src/core/lib/surface/channel.h',
+ 'src/core/lib/surface/channel_init.h',
+ 'src/core/lib/surface/channel_stack_type.h',
+ 'src/core/lib/surface/completion_queue.h',
+ 'src/core/lib/surface/completion_queue_factory.h',
+ 'src/core/lib/surface/event_string.h',
+ 'src/core/lib/surface/init.h',
+ 'src/core/lib/surface/lame_client.h',
+ 'src/core/lib/surface/server.h',
+ 'src/core/lib/surface/validate_metadata.h',
+ 'src/core/lib/transport/bdp_estimator.h',
+ 'src/core/lib/transport/byte_stream.h',
+ 'src/core/lib/transport/connectivity_state.h',
+ 'src/core/lib/transport/error_utils.h',
+ 'src/core/lib/transport/http2_errors.h',
+ 'src/core/lib/transport/metadata.h',
+ 'src/core/lib/transport/metadata_batch.h',
+ 'src/core/lib/transport/pid_controller.h',
+ 'src/core/lib/transport/service_config.h',
+ 'src/core/lib/transport/static_metadata.h',
+ 'src/core/lib/transport/status_conversion.h',
+ 'src/core/lib/transport/timeout_encoding.h',
+ 'src/core/lib/transport/transport.h',
+ 'src/core/lib/transport/transport_impl.h',
+ 'src/core/lib/debug/trace.h',
+ 'src/core/ext/transport/inproc/inproc_transport.h'
+ end
+
+ s.subspec 'Tests' do |ss|
+ ss.header_mappings_dir = '.'
+
+ ss.dependency "#{s.name}/Interface", version
+ ss.dependency "#{s.name}/Implementation", version
+ ss.dependency "gRPC-Core/Tests", grpc_version
+
+ ss.source_files = 'test/cpp/util/create_test_channel.cc',
+ 'test/cpp/util/string_ref_helper.cc',
+ 'test/cpp/util/subprocess.cc',
+ 'test/cpp/util/test_credentials_provider.cc',
+ 'test/cpp/util/create_test_channel.h',
+ 'test/cpp/util/string_ref_helper.h',
+ 'test/cpp/util/subprocess.h',
+ 'test/cpp/util/test_credentials_provider.h',
+ 'test/core/util/test_config.h',
+ 'test/core/end2end/data/ssl_test_data.h',
+ 'test/core/security/oauth2_utils.h',
+ 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
+ 'test/core/end2end/cq_verifier.h',
+ 'test/core/end2end/fixtures/http_proxy_fixture.h',
+ 'test/core/end2end/fixtures/proxy.h',
+ 'test/core/iomgr/endpoint_tests.h',
+ 'test/core/util/debugger_macros.h',
+ 'test/core/util/grpc_profiler.h',
+ 'test/core/util/histogram.h',
+ 'test/core/util/memory_counters.h',
+ 'test/core/util/mock_endpoint.h',
+ 'test/core/util/parse_hexstring.h',
+ 'test/core/util/passthru_endpoint.h',
+ 'test/core/util/port.h',
+ 'test/core/util/port_server_client.h',
+ 'test/core/util/slice_splitter.h',
+ 'test/core/util/tracer_util.h',
+ 'test/core/util/trickle_endpoint.h',
+ 'src/core/ext/filters/client_channel/backup_poller.h',
+ 'src/core/ext/filters/client_channel/client_channel.h',
+ 'src/core/ext/filters/client_channel/client_channel_factory.h',
+ 'src/core/ext/filters/client_channel/connector.h',
+ 'src/core/ext/filters/client_channel/http_connect_handshaker.h',
+ 'src/core/ext/filters/client_channel/http_proxy.h',
+ 'src/core/ext/filters/client_channel/lb_policy.h',
+ 'src/core/ext/filters/client_channel/lb_policy_factory.h',
+ 'src/core/ext/filters/client_channel/lb_policy_registry.h',
+ 'src/core/ext/filters/client_channel/parse_address.h',
+ 'src/core/ext/filters/client_channel/proxy_mapper.h',
+ 'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
+ 'src/core/ext/filters/client_channel/resolver.h',
+ 'src/core/ext/filters/client_channel/resolver_factory.h',
+ 'src/core/ext/filters/client_channel/resolver_registry.h',
+ 'src/core/ext/filters/client_channel/retry_throttle.h',
+ 'src/core/ext/filters/client_channel/subchannel.h',
+ 'src/core/ext/filters/client_channel/subchannel_index.h',
+ 'src/core/ext/filters/client_channel/uri_parser.h',
+ 'src/core/ext/filters/deadline/deadline_filter.h',
+ 'src/core/ext/transport/chttp2/transport/bin_decoder.h',
+ 'src/core/ext/transport/chttp2/transport/bin_encoder.h',
+ 'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
+ 'src/core/ext/transport/chttp2/transport/flow_control.h',
+ 'src/core/ext/transport/chttp2/transport/frame.h',
+ 'src/core/ext/transport/chttp2/transport/frame_data.h',
+ 'src/core/ext/transport/chttp2/transport/frame_goaway.h',
+ 'src/core/ext/transport/chttp2/transport/frame_ping.h',
+ 'src/core/ext/transport/chttp2/transport/frame_rst_stream.h',
+ 'src/core/ext/transport/chttp2/transport/frame_settings.h',
+ 'src/core/ext/transport/chttp2/transport/frame_window_update.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_parser.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_table.h',
+ 'src/core/ext/transport/chttp2/transport/http2_settings.h',
+ 'src/core/ext/transport/chttp2/transport/huffsyms.h',
+ 'src/core/ext/transport/chttp2/transport/incoming_metadata.h',
+ 'src/core/ext/transport/chttp2/transport/internal.h',
+ 'src/core/ext/transport/chttp2/transport/stream_map.h',
+ 'src/core/ext/transport/chttp2/transport/varint.h',
+ 'src/core/ext/transport/chttp2/alpn/alpn.h',
+ 'src/core/ext/filters/http/client/http_client_filter.h',
+ 'src/core/ext/filters/http/message_compress/message_compress_filter.h',
+ 'src/core/ext/filters/http/server/http_server_filter.h'
+ end
+
+ s.prepare_command = <<-END_OF_COMMAND
+ find src/cpp/ -type f -exec sed -E -i'.back' 's;#include "third_party/nanopb/(.*)";#include <nanopb/\\1>;g' {} \\\;
+ find src/cpp/ -name "*.back" -type f -delete
+ find src/core/ -regex ".*\.h" -type f -exec sed -E -i'.back' 's;#include "third_party/nanopb/(.*)";#include <nanopb/\\1>;g' {} \\\;
+ find src/core/ -name "*.back" -type f -delete
+ END_OF_COMMAND
+end
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 27410ed0b3..7ee7bb52d2 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
- version = '1.9.0-dev'
+ version = '1.10.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'
@@ -193,13 +193,7 @@ Pod::Spec.new do |s|
ss.dependency 'nanopb', '~> 0.3'
# To save you from scrolling, this is the last part of the podspec.
- ss.source_files = 'src/core/lib/gpr++/abstract.h',
- 'src/core/lib/gpr++/atomic.h',
- 'src/core/lib/gpr++/atomic_with_atm.h',
- 'src/core/lib/gpr++/atomic_with_std.h',
- 'src/core/lib/gpr++/manual_constructor.h',
- 'src/core/lib/gpr++/memory.h',
- 'src/core/lib/gpr/arena.h',
+ ss.source_files = 'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/fork.h',
'src/core/lib/gpr/mpscq.h',
@@ -210,6 +204,12 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/thd_internal.h',
'src/core/lib/gpr/time_precise.h',
'src/core/lib/gpr/tmpfile.h',
+ 'src/core/lib/gprpp/abstract.h',
+ 'src/core/lib/gprpp/atomic.h',
+ 'src/core/lib/gprpp/atomic_with_atm.h',
+ 'src/core/lib/gprpp/atomic_with_std.h',
+ 'src/core/lib/gprpp/manual_constructor.h',
+ 'src/core/lib/gprpp/memory.h',
'src/core/lib/profiling/timers.h',
'src/core/lib/gpr/alloc.cc',
'src/core/lib/gpr/arena.cc',
@@ -346,11 +346,11 @@ Pod::Spec.new do |s|
'src/core/lib/compression/stream_compression_identity.h',
'src/core/lib/debug/stats.h',
'src/core/lib/debug/stats_data.h',
- 'src/core/lib/gpr++/debug_location.h',
- 'src/core/lib/gpr++/inlined_vector.h',
- 'src/core/lib/gpr++/orphanable.h',
- 'src/core/lib/gpr++/ref_counted.h',
- 'src/core/lib/gpr++/ref_counted_ptr.h',
+ 'src/core/lib/gprpp/debug_location.h',
+ 'src/core/lib/gprpp/inlined_vector.h',
+ 'src/core/lib/gprpp/orphanable.h',
+ 'src/core/lib/gprpp/ref_counted.h',
+ 'src/core/lib/gprpp/ref_counted_ptr.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
@@ -722,13 +722,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/workarounds/workaround_utils.cc',
'src/core/plugin_registry/grpc_plugin_registry.cc'
- ss.private_header_files = 'src/core/lib/gpr++/abstract.h',
- 'src/core/lib/gpr++/atomic.h',
- 'src/core/lib/gpr++/atomic_with_atm.h',
- 'src/core/lib/gpr++/atomic_with_std.h',
- 'src/core/lib/gpr++/manual_constructor.h',
- 'src/core/lib/gpr++/memory.h',
- 'src/core/lib/gpr/arena.h',
+ ss.private_header_files = 'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/fork.h',
'src/core/lib/gpr/mpscq.h',
@@ -739,6 +733,12 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/thd_internal.h',
'src/core/lib/gpr/time_precise.h',
'src/core/lib/gpr/tmpfile.h',
+ 'src/core/lib/gprpp/abstract.h',
+ 'src/core/lib/gprpp/atomic.h',
+ 'src/core/lib/gprpp/atomic_with_atm.h',
+ 'src/core/lib/gprpp/atomic_with_std.h',
+ 'src/core/lib/gprpp/manual_constructor.h',
+ 'src/core/lib/gprpp/memory.h',
'src/core/lib/profiling/timers.h',
'src/core/ext/transport/chttp2/transport/bin_decoder.h',
'src/core/ext/transport/chttp2/transport/bin_encoder.h',
@@ -831,11 +831,11 @@ Pod::Spec.new do |s|
'src/core/lib/compression/stream_compression_identity.h',
'src/core/lib/debug/stats.h',
'src/core/lib/debug/stats_data.h',
- 'src/core/lib/gpr++/debug_location.h',
- 'src/core/lib/gpr++/inlined_vector.h',
- 'src/core/lib/gpr++/orphanable.h',
- 'src/core/lib/gpr++/ref_counted.h',
- 'src/core/lib/gpr++/ref_counted_ptr.h',
+ 'src/core/lib/gprpp/debug_location.h',
+ 'src/core/lib/gprpp/inlined_vector.h',
+ 'src/core/lib/gprpp/orphanable.h',
+ 'src/core/lib/gprpp/ref_counted.h',
+ 'src/core/lib/gprpp/ref_counted_ptr.h',
'src/core/lib/http/format_request.h',
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec
index cb1c5480da..a0375bd0b8 100644
--- a/gRPC-ProtoRPC.podspec
+++ b/gRPC-ProtoRPC.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
- version = '1.9.0-dev'
+ version = '1.10.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'
diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec
index 0f9abb6f4b..280aafefb6 100644
--- a/gRPC-RxLibrary.podspec
+++ b/gRPC-RxLibrary.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
- version = '1.9.0-dev'
+ version = '1.10.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'https://grpc.io'
diff --git a/gRPC.podspec b/gRPC.podspec
index 1f3a0a9950..930d991a6c 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
- version = '1.9.0-dev'
+ version = '1.10.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'
diff --git a/grpc.gemspec b/grpc.gemspec
index b763649d8b..41e56d0bf1 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -83,12 +83,6 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/impl/codegen/sync_generic.h )
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/gpr++/abstract.h )
- s.files += %w( src/core/lib/gpr++/atomic.h )
- s.files += %w( src/core/lib/gpr++/atomic_with_atm.h )
- s.files += %w( src/core/lib/gpr++/atomic_with_std.h )
- s.files += %w( src/core/lib/gpr++/manual_constructor.h )
- s.files += %w( src/core/lib/gpr++/memory.h )
s.files += %w( src/core/lib/gpr/arena.h )
s.files += %w( src/core/lib/gpr/env.h )
s.files += %w( src/core/lib/gpr/fork.h )
@@ -100,6 +94,12 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/thd_internal.h )
s.files += %w( src/core/lib/gpr/time_precise.h )
s.files += %w( src/core/lib/gpr/tmpfile.h )
+ s.files += %w( src/core/lib/gprpp/abstract.h )
+ s.files += %w( src/core/lib/gprpp/atomic.h )
+ s.files += %w( src/core/lib/gprpp/atomic_with_atm.h )
+ s.files += %w( src/core/lib/gprpp/atomic_with_std.h )
+ s.files += %w( src/core/lib/gprpp/manual_constructor.h )
+ s.files += %w( src/core/lib/gprpp/memory.h )
s.files += %w( src/core/lib/profiling/timers.h )
s.files += %w( src/core/lib/gpr/alloc.cc )
s.files += %w( src/core/lib/gpr/arena.cc )
@@ -272,11 +272,11 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/compression/stream_compression_identity.h )
s.files += %w( src/core/lib/debug/stats.h )
s.files += %w( src/core/lib/debug/stats_data.h )
- s.files += %w( src/core/lib/gpr++/debug_location.h )
- s.files += %w( src/core/lib/gpr++/inlined_vector.h )
- s.files += %w( src/core/lib/gpr++/orphanable.h )
- s.files += %w( src/core/lib/gpr++/ref_counted.h )
- s.files += %w( src/core/lib/gpr++/ref_counted_ptr.h )
+ s.files += %w( src/core/lib/gprpp/debug_location.h )
+ s.files += %w( src/core/lib/gprpp/inlined_vector.h )
+ s.files += %w( src/core/lib/gprpp/orphanable.h )
+ s.files += %w( src/core/lib/gprpp/ref_counted.h )
+ s.files += %w( src/core/lib/gprpp/ref_counted_ptr.h )
s.files += %w( src/core/lib/http/format_request.h )
s.files += %w( src/core/lib/http/httpcli.h )
s.files += %w( src/core/lib/http/parser.h )
diff --git a/include/grpc/support/alloc.h b/include/grpc/support/alloc.h
index c559198237..577d4f0069 100644
--- a/include/grpc/support/alloc.h
+++ b/include/grpc/support/alloc.h
@@ -46,8 +46,9 @@ GPRAPI void* gpr_zalloc(size_t size);
GPRAPI void gpr_free(void* ptr);
/** realloc, never returns NULL */
GPRAPI void* gpr_realloc(void* p, size_t size);
-/** aligned malloc, never returns NULL, will align to 1 << alignment_log */
-GPRAPI void* gpr_malloc_aligned(size_t size, size_t alignment_log);
+/** aligned malloc, never returns NULL, will align to alignment, which
+ * must be a power of 2. */
+GPRAPI void* gpr_malloc_aligned(size_t size, size_t alignment);
/** free memory allocated by gpr_malloc_aligned */
GPRAPI void gpr_free_aligned(void* ptr);
diff --git a/package.xml b/package.xml
index e605567eb1..3f529a2096 100644
--- a/package.xml
+++ b/package.xml
@@ -10,11 +10,11 @@
<email>grpc-packages@google.com</email>
<active>yes</active>
</lead>
- <date>2017-08-24</date>
+ <date>2018-01-19</date>
<time>16:06:07</time>
<version>
- <release>1.9.0dev</release>
- <api>1.9.0dev</api>
+ <release>1.10.0dev</release>
+ <api>1.10.0dev</api>
</version>
<stability>
<release>beta</release>
@@ -22,12 +22,7 @@
</stability>
<license>Apache 2.0</license>
<notes>
-- Channel are now by default persistent #11878
-- Some bug fixes from 1.4 branch #12109, #12123
-- Fixed hang bug when fork() was used #11814
-- License changed to Apache 2.0
-- Added support for php_namespace option in codegen plugin #11886
-- Updated gRPC C Core library version 1.6
+- TBD
</notes>
<contents>
<dir baseinstalldir="/" name="/">
@@ -95,12 +90,6 @@
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_generic.h" role="src" />
<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/gpr++/abstract.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr++/atomic.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr++/atomic_with_atm.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr++/atomic_with_std.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr++/manual_constructor.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr++/memory.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/arena.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/env.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/fork.h" role="src" />
@@ -112,6 +101,12 @@
<file baseinstalldir="/" name="src/core/lib/gpr/thd_internal.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/time_precise.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/tmpfile.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/abstract.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/atomic.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/atomic_with_atm.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/atomic_with_std.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/manual_constructor.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/memory.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/alloc.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/arena.cc" role="src" />
@@ -284,11 +279,11 @@
<file baseinstalldir="/" name="src/core/lib/compression/stream_compression_identity.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/debug/stats.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/debug/stats_data.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr++/debug_location.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr++/inlined_vector.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr++/orphanable.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr++/ref_counted.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr++/ref_counted_ptr.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/debug_location.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/inlined_vector.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/orphanable.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/ref_counted.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/ref_counted_ptr.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/format_request.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/httpcli.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/parser.h" role="src" />
diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h
index e19726efb3..30660cb83d 100644
--- a/src/core/ext/filters/client_channel/lb_policy.h
+++ b/src/core/ext/filters/client_channel/lb_policy.h
@@ -20,7 +20,7 @@
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H
#include "src/core/ext/filters/client_channel/subchannel.h"
-#include "src/core/lib/gpr++/ref_counted_ptr.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/transport/connectivity_state.h"
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
index 1708d81e61..4596f90745 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
@@ -69,11 +69,13 @@ static grpc_error* init_call_elem(grpc_call_element* elem,
call_data* calld = (call_data*)elem->call_data;
// Get stats object from context and take a ref.
GPR_ASSERT(args->context != nullptr);
- GPR_ASSERT(args->context[GRPC_GRPCLB_CLIENT_STATS].value != nullptr);
- calld->client_stats = grpc_grpclb_client_stats_ref(
- (grpc_grpclb_client_stats*)args->context[GRPC_GRPCLB_CLIENT_STATS].value);
- // Record call started.
- grpc_grpclb_client_stats_add_call_started(calld->client_stats);
+ if (args->context[GRPC_GRPCLB_CLIENT_STATS].value != nullptr) {
+ calld->client_stats = grpc_grpclb_client_stats_ref(
+ (grpc_grpclb_client_stats*)args->context[GRPC_GRPCLB_CLIENT_STATS]
+ .value);
+ // Record call started.
+ grpc_grpclb_client_stats_add_call_started(calld->client_stats);
+ }
return GRPC_ERROR_NONE;
}
@@ -81,36 +83,40 @@ static void destroy_call_elem(grpc_call_element* elem,
const grpc_call_final_info* final_info,
grpc_closure* ignored) {
call_data* calld = (call_data*)elem->call_data;
- // Record call finished, optionally setting client_failed_to_send and
- // received.
- grpc_grpclb_client_stats_add_call_finished(
- !calld->send_initial_metadata_succeeded /* client_failed_to_send */,
- calld->recv_initial_metadata_succeeded /* known_received */,
- calld->client_stats);
- // All done, so unref the stats object.
- grpc_grpclb_client_stats_unref(calld->client_stats);
+ if (calld->client_stats != nullptr) {
+ // Record call finished, optionally setting client_failed_to_send and
+ // received.
+ grpc_grpclb_client_stats_add_call_finished(
+ !calld->send_initial_metadata_succeeded /* client_failed_to_send */,
+ calld->recv_initial_metadata_succeeded /* known_received */,
+ calld->client_stats);
+ // All done, so unref the stats object.
+ grpc_grpclb_client_stats_unref(calld->client_stats);
+ }
}
static void start_transport_stream_op_batch(
grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
call_data* calld = (call_data*)elem->call_data;
GPR_TIMER_BEGIN("clr_start_transport_stream_op_batch", 0);
- // Intercept send_initial_metadata.
- if (batch->send_initial_metadata) {
- calld->original_on_complete_for_send = batch->on_complete;
- GRPC_CLOSURE_INIT(&calld->on_complete_for_send, on_complete_for_send, calld,
- grpc_schedule_on_exec_ctx);
- batch->on_complete = &calld->on_complete_for_send;
- }
- // Intercept recv_initial_metadata.
- if (batch->recv_initial_metadata) {
- calld->original_recv_initial_metadata_ready =
- batch->payload->recv_initial_metadata.recv_initial_metadata_ready;
- GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready,
- recv_initial_metadata_ready, calld,
- grpc_schedule_on_exec_ctx);
- batch->payload->recv_initial_metadata.recv_initial_metadata_ready =
- &calld->recv_initial_metadata_ready;
+ if (calld->client_stats != nullptr) {
+ // Intercept send_initial_metadata.
+ if (batch->send_initial_metadata) {
+ calld->original_on_complete_for_send = batch->on_complete;
+ GRPC_CLOSURE_INIT(&calld->on_complete_for_send, on_complete_for_send,
+ calld, grpc_schedule_on_exec_ctx);
+ batch->on_complete = &calld->on_complete_for_send;
+ }
+ // Intercept recv_initial_metadata.
+ if (batch->recv_initial_metadata) {
+ calld->original_recv_initial_metadata_ready =
+ batch->payload->recv_initial_metadata.recv_initial_metadata_ready;
+ GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready,
+ recv_initial_metadata_ready, calld,
+ grpc_schedule_on_exec_ctx);
+ batch->payload->recv_initial_metadata.recv_initial_metadata_ready =
+ &calld->recv_initial_metadata_ready;
+ }
}
// Chain to next filter.
grpc_call_next_op(elem, batch);
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 6c29cd8218..1709e5622e 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
@@ -106,8 +106,8 @@
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/gpr++/manual_constructor.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -169,25 +169,78 @@ struct pending_ping {
} // namespace
-struct glb_lb_policy {
- /** base policy: must be first */
+typedef struct glb_lb_call_data {
+ struct glb_lb_policy* glb_policy;
+ // TODO(juanlishen): c++ize this struct.
+ gpr_refcount refs;
+
+ /** The streaming call to the LB server. Always non-NULL. */
+ grpc_call* lb_call;
+
+ /** The initial metadata received from the LB server. */
+ grpc_metadata_array lb_initial_metadata_recv;
+
+ /** The message sent to the LB server. It's used to query for backends (the
+ * value may vary if the LB server indicates a redirect) or send client load
+ * report. */
+ grpc_byte_buffer* send_message_payload;
+ /** The callback after the initial request is sent. */
+ grpc_closure lb_on_sent_initial_request;
+
+ /** The response received from the LB server, if any. */
+ grpc_byte_buffer* recv_message_payload;
+ /** The callback to process the response received from the LB server. */
+ grpc_closure lb_on_response_received;
+ bool seen_initial_response;
+
+ /** The callback to process the status received from the LB server, which
+ * signals the end of the LB call. */
+ grpc_closure lb_on_server_status_received;
+ /** The trailing metadata from the LB server. */
+ grpc_metadata_array lb_trailing_metadata_recv;
+ /** The call status code and details. */
+ grpc_status_code lb_call_status;
+ grpc_slice lb_call_status_details;
+
+ /** The stats for client-side load reporting associated with this LB call.
+ * Created after the first serverlist is received. */
+ grpc_grpclb_client_stats* client_stats;
+ /** The interval and timer for next client load report. */
+ grpc_millis client_stats_report_interval;
+ grpc_timer client_load_report_timer;
+ bool client_load_report_timer_callback_pending;
+ bool last_client_load_report_counters_were_zero;
+ bool client_load_report_is_due;
+ /** The closure used for either the load report timer or the callback for
+ * completion of sending the load report. */
+ grpc_closure client_load_report_closure;
+} glb_lb_call_data;
+
+typedef struct glb_lb_policy {
+ /** Base policy: must be first. */
grpc_lb_policy base;
- /** who the client is trying to communicate with */
+ /** Who the client is trying to communicate with. */
const char* server_name;
+
+ /** Channel related data that will be propagated to the internal RR policy. */
grpc_client_channel_factory* cc_factory;
grpc_channel_args* args;
- /** timeout in milliseconds for the LB call. 0 means no deadline. */
- int lb_call_timeout_ms;
-
- /** timeout in milliseconds for before using fallback backend addresses.
+ /** Timeout in milliseconds for before using fallback backend addresses.
* 0 means not using fallback. */
int lb_fallback_timeout_ms;
- /** for communicating with the LB server */
+ /** The channel for communicating with the LB server. */
grpc_channel* lb_channel;
+ /** The data associated with the current LB call. It holds a ref to this LB
+ * policy. It's initialized every time we query for backends. It's reset to
+ * NULL whenever the current LB call is no longer needed (e.g., the LB policy
+ * is shutting down, or the LB call has ended). A non-NULL lb_calld always
+ * contains a non-NULL lb_call. */
+ glb_lb_call_data* lb_calld;
+
/** response generator to inject address updates into \a lb_channel */
grpc_fake_resolver_response_generator* response_generator;
@@ -225,9 +278,6 @@ struct glb_lb_policy {
bool shutting_down;
- /** are we currently updating lb_call? */
- bool updating_lb_call;
-
/** are we already watching the LB channel's connectivity? */
bool watching_lb_channel;
@@ -243,65 +293,70 @@ struct glb_lb_policy {
/************************************************************/
/* client data associated with the LB server communication */
/************************************************************/
- /* Finished sending initial request. */
- grpc_closure lb_on_sent_initial_request;
-
- /* Status from the LB server has been received. This signals the end of the LB
- * call. */
- grpc_closure lb_on_server_status_received;
-
- /* A response from the LB server has been received. Process it */
- grpc_closure lb_on_response_received;
-
- /* LB call retry timer callback. */
- grpc_closure lb_on_call_retry;
-
- /* LB fallback timer callback. */
- grpc_closure lb_on_fallback;
-
- grpc_call* lb_call; /* streaming call to the LB server, */
-
- grpc_metadata_array lb_initial_metadata_recv; /* initial MD from LB server */
- grpc_metadata_array
- lb_trailing_metadata_recv; /* trailing MD from LB server */
-
- /* what's being sent to the LB server. Note that its value may vary if the LB
- * server indicates a redirect. */
- grpc_byte_buffer* lb_request_payload;
-
- /* response the LB server, if any. Processed in lb_on_response_received() */
- grpc_byte_buffer* lb_response_payload;
-
- /* call status code and details, set in lb_on_server_status_received() */
- grpc_status_code lb_call_status;
- grpc_slice lb_call_status_details;
/** LB call retry backoff state */
grpc_core::ManualConstructor<grpc_core::BackOff> lb_call_backoff;
+ /** timeout in milliseconds for the LB call. 0 means no deadline. */
+ int lb_call_timeout_ms;
+
/** LB call retry timer */
grpc_timer lb_call_retry_timer;
+ /** LB call retry timer callback */
+ grpc_closure lb_on_call_retry;
/** LB fallback timer */
grpc_timer lb_fallback_timer;
+ /** LB fallback timer callback */
+ grpc_closure lb_on_fallback;
+} glb_lb_policy;
- bool initial_request_sent;
- bool seen_initial_response;
+static void glb_lb_call_data_ref(glb_lb_call_data* lb_calld,
+ const char* reason) {
+ gpr_ref_non_zero(&lb_calld->refs);
+ if (grpc_lb_glb_trace.enabled()) {
+ const gpr_atm count = gpr_atm_acq_load(&lb_calld->refs.count);
+ gpr_log(GPR_DEBUG, "[%s %p] lb_calld %p REF %lu->%lu (%s)",
+ grpc_lb_glb_trace.name(), lb_calld->glb_policy, lb_calld,
+ (unsigned long)(count - 1), (unsigned long)count, reason);
+ }
+}
- /* Stats for client-side load reporting. Should be unreffed and
- * recreated whenever lb_call is replaced. */
- grpc_grpclb_client_stats* client_stats;
- /* Interval and timer for next client load report. */
- grpc_millis client_stats_report_interval;
- grpc_timer client_load_report_timer;
- bool client_load_report_timer_callback_pending;
- bool last_client_load_report_counters_were_zero;
- /* Closure used for either the load report timer or the callback for
- * completion of sending the load report. */
- grpc_closure client_load_report_closure;
- /* Client load report message payload. */
- grpc_byte_buffer* client_load_report_payload;
-};
+static void glb_lb_call_data_unref(glb_lb_call_data* lb_calld,
+ const char* reason) {
+ const bool done = gpr_unref(&lb_calld->refs);
+ if (grpc_lb_glb_trace.enabled()) {
+ const gpr_atm count = gpr_atm_acq_load(&lb_calld->refs.count);
+ gpr_log(GPR_DEBUG, "[%s %p] lb_calld %p UNREF %lu->%lu (%s)",
+ grpc_lb_glb_trace.name(), lb_calld->glb_policy, lb_calld,
+ (unsigned long)(count + 1), (unsigned long)count, reason);
+ }
+ if (done) {
+ GPR_ASSERT(lb_calld->lb_call != nullptr);
+ grpc_call_unref(lb_calld->lb_call);
+ grpc_metadata_array_destroy(&lb_calld->lb_initial_metadata_recv);
+ grpc_metadata_array_destroy(&lb_calld->lb_trailing_metadata_recv);
+ grpc_byte_buffer_destroy(lb_calld->send_message_payload);
+ grpc_byte_buffer_destroy(lb_calld->recv_message_payload);
+ grpc_slice_unref_internal(lb_calld->lb_call_status_details);
+ if (lb_calld->client_stats != nullptr) {
+ grpc_grpclb_client_stats_unref(lb_calld->client_stats);
+ }
+ GRPC_LB_POLICY_UNREF(&lb_calld->glb_policy->base, "lb_calld");
+ gpr_free(lb_calld);
+ }
+}
+
+static void lb_call_data_shutdown(glb_lb_policy* glb_policy) {
+ GPR_ASSERT(glb_policy->lb_calld != nullptr);
+ GPR_ASSERT(glb_policy->lb_calld->lb_call != nullptr);
+ // lb_on_server_status_received will complete the cancellation and clean up.
+ grpc_call_cancel(glb_policy->lb_calld->lb_call, nullptr);
+ if (glb_policy->lb_calld->client_load_report_timer_callback_pending) {
+ grpc_timer_cancel(&glb_policy->lb_calld->client_load_report_timer);
+ }
+ glb_policy->lb_calld = nullptr;
+}
/* add lb_token of selected subchannel (address) to the call's initial
* metadata */
@@ -334,11 +389,12 @@ static void pending_pick_set_metadata_and_context(pending_pick* pp) {
abort();
}
// Pass on client stats via context. Passes ownership of the reference.
- GPR_ASSERT(pp->client_stats != nullptr);
- pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value =
- pp->client_stats;
- pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy =
- destroy_client_stats;
+ if (pp->client_stats != nullptr) {
+ pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value =
+ pp->client_stats;
+ pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy =
+ destroy_client_stats;
+ }
} else {
if (pp->client_stats != nullptr) {
grpc_grpclb_client_stats_unref(pp->client_stats);
@@ -605,9 +661,11 @@ static bool pick_from_internal_rr_locked(glb_lb_policy* glb_policy,
// the client_load_reporting filter, because we do not create a
// subchannel call (and therefore no client_load_reporting filter)
// for dropped calls.
- GPR_ASSERT(glb_policy->client_stats != nullptr);
- grpc_grpclb_client_stats_add_call_dropped_locked(
- server->load_balance_token, glb_policy->client_stats);
+ if (glb_policy->lb_calld != nullptr &&
+ glb_policy->lb_calld->client_stats != nullptr) {
+ grpc_grpclb_client_stats_add_call_dropped_locked(
+ server->load_balance_token, glb_policy->lb_calld->client_stats);
+ }
if (force_async) {
GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_NONE);
gpr_free(pp);
@@ -618,7 +676,11 @@ static bool pick_from_internal_rr_locked(glb_lb_policy* glb_policy,
}
}
// Set client_stats and user_data.
- pp->client_stats = grpc_grpclb_client_stats_ref(glb_policy->client_stats);
+ if (glb_policy->lb_calld != nullptr &&
+ glb_policy->lb_calld->client_stats != nullptr) {
+ pp->client_stats =
+ grpc_grpclb_client_stats_ref(glb_policy->lb_calld->client_stats);
+ }
GPR_ASSERT(pp->pick->user_data == nullptr);
pp->pick->user_data = (void**)&pp->lb_token;
// Pick via the RR policy.
@@ -872,9 +934,6 @@ static void glb_destroy(grpc_lb_policy* pol) {
GPR_ASSERT(glb_policy->pending_pings == nullptr);
gpr_free((void*)glb_policy->server_name);
grpc_channel_args_destroy(glb_policy->args);
- if (glb_policy->client_stats != nullptr) {
- grpc_grpclb_client_stats_unref(glb_policy->client_stats);
- }
grpc_connectivity_state_destroy(&glb_policy->state_tracker);
if (glb_policy->serverlist != nullptr) {
grpc_grpclb_destroy_serverlist(glb_policy->serverlist);
@@ -892,13 +951,8 @@ static void glb_shutdown_locked(grpc_lb_policy* pol,
glb_lb_policy* glb_policy = (glb_lb_policy*)pol;
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
glb_policy->shutting_down = true;
- /* glb_policy->lb_call and this local lb_call must be consistent at this point
- * because glb_policy->lb_call is only assigned in lb_call_init_locked as part
- * of query_for_backends_locked, which can only be invoked while
- * glb_policy->shutting_down is false. */
- if (glb_policy->lb_call != nullptr) {
- grpc_call_cancel(glb_policy->lb_call, nullptr);
- /* lb_on_server_status_received will pick up the cancel and clean up */
+ if (glb_policy->lb_calld != nullptr) {
+ lb_call_data_shutdown(glb_policy);
}
if (glb_policy->retry_timer_callback_pending) {
grpc_timer_cancel(&glb_policy->lb_call_retry_timer);
@@ -1048,7 +1102,6 @@ static void start_picking_locked(glb_lb_policy* glb_policy) {
grpc_timer_init(&glb_policy->lb_fallback_timer, deadline,
&glb_policy->lb_on_fallback);
}
-
glb_policy->started_picking = true;
glb_policy->lb_call_backoff->Reset();
query_for_backends_locked(glb_policy);
@@ -1089,7 +1142,6 @@ static int glb_pick_locked(grpc_lb_policy* pol,
gpr_log(GPR_INFO, "[grpclb %p] about to PICK from RR %p", glb_policy,
glb_policy->rr_policy);
}
- GPR_ASSERT(glb_policy->client_stats != nullptr);
pick_done =
pick_from_internal_rr_locked(glb_policy, false /* force_async */, pp);
}
@@ -1139,8 +1191,8 @@ static void glb_notify_on_state_change_locked(grpc_lb_policy* pol,
static void lb_call_on_retry_timer_locked(void* arg, grpc_error* error) {
glb_lb_policy* glb_policy = (glb_lb_policy*)arg;
glb_policy->retry_timer_callback_pending = false;
- if (!glb_policy->shutting_down && glb_policy->lb_call == nullptr &&
- error == GRPC_ERROR_NONE) {
+ if (!glb_policy->shutting_down && error == GRPC_ERROR_NONE &&
+ glb_policy->lb_calld == nullptr) {
if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO, "[grpclb %p] Restarting call to LB server", glb_policy);
}
@@ -1149,84 +1201,55 @@ static void lb_call_on_retry_timer_locked(void* arg, grpc_error* error) {
GRPC_LB_POLICY_UNREF(&glb_policy->base, "grpclb_retry_timer");
}
-static void maybe_restart_lb_call(glb_lb_policy* glb_policy) {
- if (glb_policy->started_picking && glb_policy->updating_lb_call) {
- if (glb_policy->retry_timer_callback_pending) {
- grpc_timer_cancel(&glb_policy->lb_call_retry_timer);
- }
- if (!glb_policy->shutting_down) start_picking_locked(glb_policy);
- glb_policy->updating_lb_call = false;
- } else if (!glb_policy->shutting_down) {
- /* if we aren't shutting down, restart the LB client call after some time */
- grpc_millis next_try = glb_policy->lb_call_backoff->NextAttemptTime();
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[grpclb %p] Connection to LB server lost...",
+static void start_lb_call_retry_timer_locked(glb_lb_policy* glb_policy) {
+ grpc_millis next_try = glb_policy->lb_call_backoff->NextAttemptTime();
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "[grpclb %p] Connection to LB server lost...",
+ glb_policy);
+ grpc_millis timeout = next_try - grpc_core::ExecCtx::Get()->Now();
+ if (timeout > 0) {
+ gpr_log(GPR_DEBUG,
+ "[grpclb %p] ... retry_timer_active in %" PRIuPTR "ms.",
+ glb_policy, timeout);
+ } else {
+ gpr_log(GPR_DEBUG, "[grpclb %p] ... retry_timer_active immediately.",
glb_policy);
- grpc_millis timeout = next_try - grpc_core::ExecCtx::Get()->Now();
- if (timeout > 0) {
- gpr_log(GPR_DEBUG,
- "[grpclb %p] ... retry LB call after %" PRIuPTR "ms.",
- glb_policy, timeout);
- } else {
- gpr_log(GPR_DEBUG, "[grpclb %p] ... retry LB call immediately.",
- glb_policy);
- }
}
- GRPC_LB_POLICY_REF(&glb_policy->base, "grpclb_retry_timer");
- GRPC_CLOSURE_INIT(&glb_policy->lb_on_call_retry,
- lb_call_on_retry_timer_locked, glb_policy,
- grpc_combiner_scheduler(glb_policy->base.combiner));
- glb_policy->retry_timer_callback_pending = true;
- grpc_timer_init(&glb_policy->lb_call_retry_timer, next_try,
- &glb_policy->lb_on_call_retry);
}
- GRPC_LB_POLICY_UNREF(&glb_policy->base,
- "lb_on_server_status_received_locked");
+ GRPC_LB_POLICY_REF(&glb_policy->base, "grpclb_retry_timer");
+ GRPC_CLOSURE_INIT(&glb_policy->lb_on_call_retry,
+ lb_call_on_retry_timer_locked, glb_policy,
+ grpc_combiner_scheduler(glb_policy->base.combiner));
+ glb_policy->retry_timer_callback_pending = true;
+ grpc_timer_init(&glb_policy->lb_call_retry_timer, next_try,
+ &glb_policy->lb_on_call_retry);
}
-static void send_client_load_report_locked(void* arg, grpc_error* error);
+static void maybe_send_client_load_report_locked(void* arg, grpc_error* error);
-static void schedule_next_client_load_report(glb_lb_policy* glb_policy) {
+static void schedule_next_client_load_report(glb_lb_call_data* lb_calld) {
const grpc_millis next_client_load_report_time =
- grpc_core::ExecCtx::Get()->Now() +
- glb_policy->client_stats_report_interval;
- GRPC_CLOSURE_INIT(&glb_policy->client_load_report_closure,
- send_client_load_report_locked, glb_policy,
- grpc_combiner_scheduler(glb_policy->base.combiner));
- grpc_timer_init(&glb_policy->client_load_report_timer,
+ grpc_core::ExecCtx::Get()->Now() + lb_calld->client_stats_report_interval;
+ GRPC_CLOSURE_INIT(
+ &lb_calld->client_load_report_closure,
+ maybe_send_client_load_report_locked, lb_calld,
+ grpc_combiner_scheduler(lb_calld->glb_policy->base.combiner));
+ grpc_timer_init(&lb_calld->client_load_report_timer,
next_client_load_report_time,
- &glb_policy->client_load_report_closure);
+ &lb_calld->client_load_report_closure);
+ lb_calld->client_load_report_timer_callback_pending = true;
}
static void client_load_report_done_locked(void* arg, grpc_error* error) {
- glb_lb_policy* glb_policy = (glb_lb_policy*)arg;
- grpc_byte_buffer_destroy(glb_policy->client_load_report_payload);
- glb_policy->client_load_report_payload = nullptr;
- if (error != GRPC_ERROR_NONE || glb_policy->lb_call == nullptr) {
- glb_policy->client_load_report_timer_callback_pending = false;
- GRPC_LB_POLICY_UNREF(&glb_policy->base, "client_load_report");
- if (glb_policy->lb_call == nullptr) {
- maybe_restart_lb_call(glb_policy);
- }
+ glb_lb_call_data* lb_calld = (glb_lb_call_data*)arg;
+ glb_lb_policy* glb_policy = lb_calld->glb_policy;
+ grpc_byte_buffer_destroy(lb_calld->send_message_payload);
+ lb_calld->send_message_payload = nullptr;
+ if (error != GRPC_ERROR_NONE || lb_calld != glb_policy->lb_calld) {
+ glb_lb_call_data_unref(lb_calld, "client_load_report");
return;
}
- schedule_next_client_load_report(glb_policy);
-}
-
-static void do_send_client_load_report_locked(glb_lb_policy* glb_policy) {
- grpc_op op;
- memset(&op, 0, sizeof(op));
- op.op = GRPC_OP_SEND_MESSAGE;
- op.data.send_message.send_message = glb_policy->client_load_report_payload;
- GRPC_CLOSURE_INIT(&glb_policy->client_load_report_closure,
- client_load_report_done_locked, glb_policy,
- grpc_combiner_scheduler(glb_policy->base.combiner));
- grpc_call_error call_error = grpc_call_start_batch_and_execute(
- glb_policy->lb_call, &op, 1, &glb_policy->client_load_report_closure);
- if (call_error != GRPC_CALL_OK) {
- gpr_log(GPR_ERROR, "[grpclb %p] call_error=%d", glb_policy, call_error);
- GPR_ASSERT(GRPC_CALL_OK == call_error);
- }
+ schedule_next_client_load_report(lb_calld);
}
static bool load_report_counters_are_zero(grpc_grpclb_request* request) {
@@ -1241,341 +1264,377 @@ static bool load_report_counters_are_zero(grpc_grpclb_request* request) {
(drop_entries == nullptr || drop_entries->num_entries == 0);
}
-static void send_client_load_report_locked(void* arg, grpc_error* error) {
- glb_lb_policy* glb_policy = (glb_lb_policy*)arg;
- if (error == GRPC_ERROR_CANCELLED || glb_policy->lb_call == nullptr) {
- glb_policy->client_load_report_timer_callback_pending = false;
- GRPC_LB_POLICY_UNREF(&glb_policy->base, "client_load_report");
- if (glb_policy->lb_call == nullptr) {
- maybe_restart_lb_call(glb_policy);
- }
- return;
- }
+static void send_client_load_report_locked(glb_lb_call_data* lb_calld) {
+ glb_lb_policy* glb_policy = lb_calld->glb_policy;
// Construct message payload.
- GPR_ASSERT(glb_policy->client_load_report_payload == nullptr);
+ GPR_ASSERT(lb_calld->send_message_payload == nullptr);
grpc_grpclb_request* request =
- grpc_grpclb_load_report_request_create_locked(glb_policy->client_stats);
+ grpc_grpclb_load_report_request_create_locked(lb_calld->client_stats);
// Skip client load report if the counters were all zero in the last
// report and they are still zero in this one.
if (load_report_counters_are_zero(request)) {
- if (glb_policy->last_client_load_report_counters_were_zero) {
+ if (lb_calld->last_client_load_report_counters_were_zero) {
grpc_grpclb_request_destroy(request);
- schedule_next_client_load_report(glb_policy);
+ schedule_next_client_load_report(lb_calld);
return;
}
- glb_policy->last_client_load_report_counters_were_zero = true;
+ lb_calld->last_client_load_report_counters_were_zero = true;
} else {
- glb_policy->last_client_load_report_counters_were_zero = false;
+ lb_calld->last_client_load_report_counters_were_zero = false;
}
grpc_slice request_payload_slice = grpc_grpclb_request_encode(request);
- glb_policy->client_load_report_payload =
+ lb_calld->send_message_payload =
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_slice_unref_internal(request_payload_slice);
grpc_grpclb_request_destroy(request);
+ // Send the report.
+ grpc_op op;
+ memset(&op, 0, sizeof(op));
+ op.op = GRPC_OP_SEND_MESSAGE;
+ op.data.send_message.send_message = lb_calld->send_message_payload;
+ GRPC_CLOSURE_INIT(&lb_calld->client_load_report_closure,
+ client_load_report_done_locked, lb_calld,
+ grpc_combiner_scheduler(glb_policy->base.combiner));
+ grpc_call_error call_error = grpc_call_start_batch_and_execute(
+ lb_calld->lb_call, &op, 1, &lb_calld->client_load_report_closure);
+ if (call_error != GRPC_CALL_OK) {
+ gpr_log(GPR_ERROR, "[grpclb %p] call_error=%d", glb_policy, call_error);
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
+ }
+}
+
+static void maybe_send_client_load_report_locked(void* arg, grpc_error* error) {
+ glb_lb_call_data* lb_calld = (glb_lb_call_data*)arg;
+ glb_lb_policy* glb_policy = lb_calld->glb_policy;
+ lb_calld->client_load_report_timer_callback_pending = false;
+ if (error != GRPC_ERROR_NONE || lb_calld != glb_policy->lb_calld) {
+ glb_lb_call_data_unref(lb_calld, "client_load_report");
+ return;
+ }
// If we've already sent the initial request, then we can go ahead and send
// the load report. Otherwise, we need to wait until the initial request has
- // been sent to send this (see lb_on_sent_initial_request_locked() below).
- if (glb_policy->initial_request_sent) {
- do_send_client_load_report_locked(glb_policy);
+ // been sent to send this (see lb_on_sent_initial_request_locked()).
+ if (lb_calld->send_message_payload == nullptr) {
+ send_client_load_report_locked(lb_calld);
+ } else {
+ lb_calld->client_load_report_is_due = true;
}
}
static void lb_on_sent_initial_request_locked(void* arg, grpc_error* error);
static void lb_on_server_status_received_locked(void* arg, grpc_error* error);
static void lb_on_response_received_locked(void* arg, grpc_error* error);
-static void lb_call_init_locked(glb_lb_policy* glb_policy) {
+static glb_lb_call_data* lb_call_data_create_locked(glb_lb_policy* glb_policy) {
+ GPR_ASSERT(!glb_policy->shutting_down);
+ // Init the LB call. Note that the LB call will progress every time there's
+ // activity in glb_policy->base.interested_parties, which is comprised of the
+ // polling entities from client_channel.
GPR_ASSERT(glb_policy->server_name != nullptr);
GPR_ASSERT(glb_policy->server_name[0] != '\0');
- GPR_ASSERT(glb_policy->lb_call == nullptr);
- GPR_ASSERT(!glb_policy->shutting_down);
-
- /* Note the following LB call progresses every time there's activity in \a
- * glb_policy->base.interested_parties, which is comprised of the polling
- * entities from \a client_channel. */
grpc_slice host = grpc_slice_from_copied_string(glb_policy->server_name);
grpc_millis deadline =
glb_policy->lb_call_timeout_ms == 0
? GRPC_MILLIS_INF_FUTURE
: grpc_core::ExecCtx::Get()->Now() + glb_policy->lb_call_timeout_ms;
- glb_policy->lb_call = grpc_channel_create_pollset_set_call(
+ glb_lb_call_data* lb_calld = (glb_lb_call_data*)gpr_zalloc(sizeof(*lb_calld));
+ lb_calld->lb_call = grpc_channel_create_pollset_set_call(
glb_policy->lb_channel, nullptr, GRPC_PROPAGATE_DEFAULTS,
glb_policy->base.interested_parties,
GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD,
&host, deadline, nullptr);
grpc_slice_unref_internal(host);
-
- if (glb_policy->client_stats != nullptr) {
- grpc_grpclb_client_stats_unref(glb_policy->client_stats);
- }
- glb_policy->client_stats = grpc_grpclb_client_stats_create();
-
- grpc_metadata_array_init(&glb_policy->lb_initial_metadata_recv);
- grpc_metadata_array_init(&glb_policy->lb_trailing_metadata_recv);
-
+ // Init the LB call request payload.
grpc_grpclb_request* request =
grpc_grpclb_request_create(glb_policy->server_name);
grpc_slice request_payload_slice = grpc_grpclb_request_encode(request);
- glb_policy->lb_request_payload =
+ lb_calld->send_message_payload =
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_slice_unref_internal(request_payload_slice);
grpc_grpclb_request_destroy(request);
-
- GRPC_CLOSURE_INIT(&glb_policy->lb_on_sent_initial_request,
- lb_on_sent_initial_request_locked, glb_policy,
+ // Init other data associated with the LB call.
+ lb_calld->glb_policy = glb_policy;
+ gpr_ref_init(&lb_calld->refs, 1);
+ grpc_metadata_array_init(&lb_calld->lb_initial_metadata_recv);
+ grpc_metadata_array_init(&lb_calld->lb_trailing_metadata_recv);
+ GRPC_CLOSURE_INIT(&lb_calld->lb_on_sent_initial_request,
+ lb_on_sent_initial_request_locked, lb_calld,
grpc_combiner_scheduler(glb_policy->base.combiner));
- GRPC_CLOSURE_INIT(&glb_policy->lb_on_server_status_received,
- lb_on_server_status_received_locked, glb_policy,
+ GRPC_CLOSURE_INIT(&lb_calld->lb_on_response_received,
+ lb_on_response_received_locked, lb_calld,
grpc_combiner_scheduler(glb_policy->base.combiner));
- GRPC_CLOSURE_INIT(&glb_policy->lb_on_response_received,
- lb_on_response_received_locked, glb_policy,
+ GRPC_CLOSURE_INIT(&lb_calld->lb_on_server_status_received,
+ lb_on_server_status_received_locked, lb_calld,
grpc_combiner_scheduler(glb_policy->base.combiner));
-
- grpc_core::BackOff::Options backoff_options;
- backoff_options
- .set_initial_backoff(GRPC_GRPCLB_INITIAL_CONNECT_BACKOFF_SECONDS * 1000)
- .set_multiplier(GRPC_GRPCLB_RECONNECT_BACKOFF_MULTIPLIER)
- .set_jitter(GRPC_GRPCLB_RECONNECT_JITTER)
- .set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
-
- glb_policy->lb_call_backoff.Init(backoff_options);
-
- glb_policy->initial_request_sent = false;
- glb_policy->seen_initial_response = false;
- glb_policy->last_client_load_report_counters_were_zero = false;
-}
-
-static void lb_call_destroy_locked(glb_lb_policy* glb_policy) {
- GPR_ASSERT(glb_policy->lb_call != nullptr);
- grpc_call_unref(glb_policy->lb_call);
- glb_policy->lb_call = nullptr;
-
- grpc_metadata_array_destroy(&glb_policy->lb_initial_metadata_recv);
- grpc_metadata_array_destroy(&glb_policy->lb_trailing_metadata_recv);
-
- grpc_byte_buffer_destroy(glb_policy->lb_request_payload);
- grpc_slice_unref_internal(glb_policy->lb_call_status_details);
-
- if (glb_policy->client_load_report_timer_callback_pending) {
- grpc_timer_cancel(&glb_policy->client_load_report_timer);
- }
+ // Hold a ref to the glb_policy.
+ GRPC_LB_POLICY_REF(&glb_policy->base, "lb_calld");
+ return lb_calld;
}
/*
* Auxiliary functions and LB client callbacks.
*/
+
static void query_for_backends_locked(glb_lb_policy* glb_policy) {
GPR_ASSERT(glb_policy->lb_channel != nullptr);
if (glb_policy->shutting_down) return;
-
- lb_call_init_locked(glb_policy);
-
+ // Init the LB call data.
+ GPR_ASSERT(glb_policy->lb_calld == nullptr);
+ glb_policy->lb_calld = lb_call_data_create_locked(glb_policy);
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);
+ "[grpclb %p] Query for backends (lb_channel: %p, lb_calld: %p, "
+ "lb_call: %p)",
+ glb_policy, glb_policy->lb_channel, glb_policy->lb_calld,
+ glb_policy->lb_calld->lb_call);
}
- GPR_ASSERT(glb_policy->lb_call != nullptr);
-
+ GPR_ASSERT(glb_policy->lb_calld->lb_call != nullptr);
+ // Create the ops.
grpc_call_error call_error;
grpc_op ops[3];
memset(ops, 0, sizeof(ops));
-
+ // Op: send initial metadata.
grpc_op* op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op->flags = 0;
op->reserved = nullptr;
op++;
+ // Op: send request message.
+ GPR_ASSERT(glb_policy->lb_calld->send_message_payload != nullptr);
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message =
+ glb_policy->lb_calld->send_message_payload;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ glb_lb_call_data_ref(glb_policy->lb_calld,
+ "lb_on_sent_initial_request_locked");
+ call_error = grpc_call_start_batch_and_execute(
+ glb_policy->lb_calld->lb_call, ops, (size_t)(op - ops),
+ &glb_policy->lb_calld->lb_on_sent_initial_request);
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
+ // Op: recv initial metadata.
+ op = ops;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata.recv_initial_metadata =
- &glb_policy->lb_initial_metadata_recv;
+ &glb_policy->lb_calld->lb_initial_metadata_recv;
op->flags = 0;
op->reserved = nullptr;
op++;
- GPR_ASSERT(glb_policy->lb_request_payload != nullptr);
- op->op = GRPC_OP_SEND_MESSAGE;
- op->data.send_message.send_message = glb_policy->lb_request_payload;
+ // Op: recv response.
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message =
+ &glb_policy->lb_calld->recv_message_payload;
op->flags = 0;
op->reserved = nullptr;
op++;
- /* take a ref to be released in lb_on_sent_initial_request_locked() */
- GRPC_LB_POLICY_REF(&glb_policy->base, "lb_on_sent_initial_request_locked");
+ glb_lb_call_data_ref(glb_policy->lb_calld, "lb_on_response_received_locked");
call_error = grpc_call_start_batch_and_execute(
- glb_policy->lb_call, ops, (size_t)(op - ops),
- &glb_policy->lb_on_sent_initial_request);
+ glb_policy->lb_calld->lb_call, ops, (size_t)(op - ops),
+ &glb_policy->lb_calld->lb_on_response_received);
GPR_ASSERT(GRPC_CALL_OK == call_error);
-
+ // Op: recv server status.
op = ops;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata =
- &glb_policy->lb_trailing_metadata_recv;
- op->data.recv_status_on_client.status = &glb_policy->lb_call_status;
+ &glb_policy->lb_calld->lb_trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &glb_policy->lb_calld->lb_call_status;
op->data.recv_status_on_client.status_details =
- &glb_policy->lb_call_status_details;
+ &glb_policy->lb_calld->lb_call_status_details;
op->flags = 0;
op->reserved = nullptr;
op++;
- /* take a ref to be released in lb_on_server_status_received_locked() */
- GRPC_LB_POLICY_REF(&glb_policy->base, "lb_on_server_status_received_locked");
+ // This callback signals the end of the LB call, so it relies on the initial
+ // ref instead of a new ref. When it's invoked, it's the initial ref that is
+ // unreffed.
call_error = grpc_call_start_batch_and_execute(
- glb_policy->lb_call, ops, (size_t)(op - ops),
- &glb_policy->lb_on_server_status_received);
- GPR_ASSERT(GRPC_CALL_OK == call_error);
-
- op = ops;
- op->op = GRPC_OP_RECV_MESSAGE;
- op->data.recv_message.recv_message = &glb_policy->lb_response_payload;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- /* take a ref to be unref'd/reused in lb_on_response_received_locked() */
- GRPC_LB_POLICY_REF(&glb_policy->base, "lb_on_response_received_locked");
- call_error = grpc_call_start_batch_and_execute(
- glb_policy->lb_call, ops, (size_t)(op - ops),
- &glb_policy->lb_on_response_received);
+ glb_policy->lb_calld->lb_call, ops, (size_t)(op - ops),
+ &glb_policy->lb_calld->lb_on_server_status_received);
GPR_ASSERT(GRPC_CALL_OK == call_error);
}
static void lb_on_sent_initial_request_locked(void* arg, grpc_error* error) {
- glb_lb_policy* glb_policy = (glb_lb_policy*)arg;
- glb_policy->initial_request_sent = true;
+ glb_lb_call_data* lb_calld = (glb_lb_call_data*)arg;
+ grpc_byte_buffer_destroy(lb_calld->send_message_payload);
+ lb_calld->send_message_payload = nullptr;
// If we attempted to send a client load report before the initial request was
- // sent, send the load report now.
- if (glb_policy->client_load_report_payload != nullptr) {
- do_send_client_load_report_locked(glb_policy);
+ // sent (and this lb_calld is still in use), send the load report now.
+ if (lb_calld->client_load_report_is_due &&
+ lb_calld == lb_calld->glb_policy->lb_calld) {
+ send_client_load_report_locked(lb_calld);
+ lb_calld->client_load_report_is_due = false;
}
- GRPC_LB_POLICY_UNREF(&glb_policy->base, "lb_on_sent_initial_request_locked");
+ glb_lb_call_data_unref(lb_calld, "lb_on_sent_initial_request_locked");
}
static void lb_on_response_received_locked(void* arg, grpc_error* error) {
- glb_lb_policy* glb_policy = (glb_lb_policy*)arg;
+ glb_lb_call_data* lb_calld = (glb_lb_call_data*)arg;
+ glb_lb_policy* glb_policy = lb_calld->glb_policy;
+ // Empty payload means the LB call was cancelled.
+ if (lb_calld != glb_policy->lb_calld ||
+ lb_calld->recv_message_payload == nullptr) {
+ glb_lb_call_data_unref(lb_calld, "lb_on_response_received_locked");
+ return;
+ }
grpc_op ops[2];
memset(ops, 0, sizeof(ops));
grpc_op* op = ops;
- if (glb_policy->lb_response_payload != nullptr) {
- glb_policy->lb_call_backoff->Reset();
- /* Received data from the LB server. Look inside
- * glb_policy->lb_response_payload, for a serverlist. */
- grpc_byte_buffer_reader bbr;
- grpc_byte_buffer_reader_init(&bbr, glb_policy->lb_response_payload);
- grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
- grpc_byte_buffer_reader_destroy(&bbr);
- grpc_byte_buffer_destroy(glb_policy->lb_response_payload);
-
- grpc_grpclb_initial_response* response = nullptr;
- if (!glb_policy->seen_initial_response &&
- (response = grpc_grpclb_initial_response_parse(response_slice)) !=
- nullptr) {
- if (response->has_client_stats_report_interval) {
- glb_policy->client_stats_report_interval = GPR_MAX(
- GPR_MS_PER_SEC, grpc_grpclb_duration_to_millis(
- &response->client_stats_report_interval));
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO,
- "[grpclb %p] Received initial LB response message; "
- "client load reporting interval = %" PRIdPTR " milliseconds",
- glb_policy, glb_policy->client_stats_report_interval);
- }
- /* take a ref to be unref'd in send_client_load_report_locked() */
- glb_policy->client_load_report_timer_callback_pending = true;
- GRPC_LB_POLICY_REF(&glb_policy->base, "client_load_report");
- schedule_next_client_load_report(glb_policy);
- } else if (grpc_lb_glb_trace.enabled()) {
+ glb_policy->lb_call_backoff->Reset();
+ grpc_byte_buffer_reader bbr;
+ grpc_byte_buffer_reader_init(&bbr, lb_calld->recv_message_payload);
+ grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
+ grpc_byte_buffer_reader_destroy(&bbr);
+ grpc_byte_buffer_destroy(lb_calld->recv_message_payload);
+ lb_calld->recv_message_payload = nullptr;
+ grpc_grpclb_initial_response* initial_response;
+ grpc_grpclb_serverlist* serverlist;
+ if (!lb_calld->seen_initial_response &&
+ (initial_response = grpc_grpclb_initial_response_parse(response_slice)) !=
+ nullptr) {
+ // Have NOT seen initial response, look for initial response.
+ if (initial_response->has_client_stats_report_interval) {
+ lb_calld->client_stats_report_interval = GPR_MAX(
+ GPR_MS_PER_SEC, grpc_grpclb_duration_to_millis(
+ &initial_response->client_stats_report_interval));
+ if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
- "[grpclb %p] Received initial LB response message; client load "
- "reporting NOT enabled",
- glb_policy);
+ "[grpclb %p] Received initial LB response message; "
+ "client load reporting interval = %" PRIdPTR " milliseconds",
+ glb_policy, lb_calld->client_stats_report_interval);
}
- grpc_grpclb_initial_response_destroy(response);
- glb_policy->seen_initial_response = true;
- } else {
- grpc_grpclb_serverlist* serverlist =
- grpc_grpclb_response_parse_serverlist(response_slice);
- if (serverlist != nullptr) {
- GPR_ASSERT(glb_policy->lb_call != nullptr);
+ } else if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[grpclb %p] Received initial LB response message; client load "
+ "reporting NOT enabled",
+ glb_policy);
+ }
+ grpc_grpclb_initial_response_destroy(initial_response);
+ lb_calld->seen_initial_response = true;
+ } else if ((serverlist = grpc_grpclb_response_parse_serverlist(
+ response_slice)) != nullptr) {
+ // Have seen initial response, look for serverlist.
+ GPR_ASSERT(lb_calld->lb_call != nullptr);
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[grpclb %p] Serverlist with %" PRIuPTR " servers received",
+ glb_policy, serverlist->num_servers);
+ for (size_t i = 0; i < serverlist->num_servers; ++i) {
+ grpc_resolved_address addr;
+ parse_server(serverlist->servers[i], &addr);
+ char* ipport;
+ grpc_sockaddr_to_string(&ipport, &addr, false);
+ gpr_log(GPR_INFO, "[grpclb %p] Serverlist[%" PRIuPTR "]: %s",
+ glb_policy, i, ipport);
+ gpr_free(ipport);
+ }
+ }
+ /* update serverlist */
+ if (serverlist->num_servers > 0) {
+ // Start sending client load report only after we start using the
+ // serverlist returned from the current LB call.
+ if (lb_calld->client_stats_report_interval > 0 &&
+ lb_calld->client_stats == nullptr) {
+ lb_calld->client_stats = grpc_grpclb_client_stats_create();
+ glb_lb_call_data_ref(lb_calld, "client_load_report");
+ schedule_next_client_load_report(lb_calld);
+ }
+ if (grpc_grpclb_serverlist_equals(glb_policy->serverlist, serverlist)) {
if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
- "[grpclb %p] Serverlist with %" PRIuPTR " servers received",
- glb_policy, serverlist->num_servers);
- for (size_t i = 0; i < serverlist->num_servers; ++i) {
- grpc_resolved_address addr;
- parse_server(serverlist->servers[i], &addr);
- char* ipport;
- grpc_sockaddr_to_string(&ipport, &addr, false);
- gpr_log(GPR_INFO, "[grpclb %p] Serverlist[%" PRIuPTR "]: %s",
- glb_policy, i, ipport);
- gpr_free(ipport);
- }
+ "[grpclb %p] Incoming server list identical to current, "
+ "ignoring.",
+ glb_policy);
}
- /* update serverlist */
- if (serverlist->num_servers > 0) {
- if (grpc_grpclb_serverlist_equals(glb_policy->serverlist,
- serverlist)) {
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO,
- "[grpclb %p] Incoming server list identical to current, "
- "ignoring.",
- glb_policy);
- }
- grpc_grpclb_destroy_serverlist(serverlist);
- } else { /* new serverlist */
- if (glb_policy->serverlist != nullptr) {
- /* dispose of the old serverlist */
- grpc_grpclb_destroy_serverlist(glb_policy->serverlist);
- } else {
- /* or dispose of the fallback */
- grpc_lb_addresses_destroy(glb_policy->fallback_backend_addresses);
- glb_policy->fallback_backend_addresses = nullptr;
- if (glb_policy->fallback_timer_callback_pending) {
- grpc_timer_cancel(&glb_policy->lb_fallback_timer);
- }
- }
- /* and update the copy in the glb_lb_policy instance. This
- * serverlist instance will be destroyed either upon the next
- * update or in glb_destroy() */
- glb_policy->serverlist = serverlist;
- glb_policy->serverlist_index = 0;
- rr_handover_locked(glb_policy);
- }
+ grpc_grpclb_destroy_serverlist(serverlist);
+ } else { /* new serverlist */
+ if (glb_policy->serverlist != nullptr) {
+ /* dispose of the old serverlist */
+ grpc_grpclb_destroy_serverlist(glb_policy->serverlist);
} else {
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO,
- "[grpclb %p] Received empty server list, ignoring.",
- glb_policy);
+ /* or dispose of the fallback */
+ grpc_lb_addresses_destroy(glb_policy->fallback_backend_addresses);
+ glb_policy->fallback_backend_addresses = nullptr;
+ if (glb_policy->fallback_timer_callback_pending) {
+ grpc_timer_cancel(&glb_policy->lb_fallback_timer);
+ glb_policy->fallback_timer_callback_pending = false;
}
- grpc_grpclb_destroy_serverlist(serverlist);
}
- } else { /* serverlist == nullptr */
- gpr_log(GPR_ERROR,
- "[grpclb %p] Invalid LB response received: '%s'. Ignoring.",
- glb_policy,
- grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX));
+ /* and update the copy in the glb_lb_policy instance. This
+ * serverlist instance will be destroyed either upon the next
+ * update or in glb_destroy() */
+ glb_policy->serverlist = serverlist;
+ glb_policy->serverlist_index = 0;
+ rr_handover_locked(glb_policy);
+ }
+ } else {
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_INFO, "[grpclb %p] Received empty server list, ignoring.",
+ glb_policy);
}
+ grpc_grpclb_destroy_serverlist(serverlist);
}
- grpc_slice_unref_internal(response_slice);
- if (!glb_policy->shutting_down) {
- /* keep listening for serverlist updates */
- op->op = GRPC_OP_RECV_MESSAGE;
- op->data.recv_message.recv_message = &glb_policy->lb_response_payload;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- /* reuse the "lb_on_response_received_locked" ref taken in
- * query_for_backends_locked() */
- const grpc_call_error call_error = grpc_call_start_batch_and_execute(
- glb_policy->lb_call, ops, (size_t)(op - ops),
- &glb_policy->lb_on_response_received); /* loop */
- GPR_ASSERT(GRPC_CALL_OK == call_error);
+ } else {
+ // No valid initial response or serverlist found.
+ gpr_log(GPR_ERROR,
+ "[grpclb %p] Invalid LB response received: '%s'. Ignoring.",
+ glb_policy,
+ grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX));
+ }
+ grpc_slice_unref_internal(response_slice);
+ if (!glb_policy->shutting_down) {
+ // Keep listening for serverlist updates.
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &lb_calld->recv_message_payload;
+ op->flags = 0;
+ op->reserved = nullptr;
+ op++;
+ // Reuse the "lb_on_response_received_locked" ref taken in
+ // query_for_backends_locked().
+ const grpc_call_error call_error = grpc_call_start_batch_and_execute(
+ lb_calld->lb_call, ops, (size_t)(op - ops),
+ &lb_calld->lb_on_response_received);
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
+ } else {
+ glb_lb_call_data_unref(lb_calld,
+ "lb_on_response_received_locked+glb_shutdown");
+ }
+}
+
+static void lb_on_server_status_received_locked(void* arg, grpc_error* error) {
+ glb_lb_call_data* lb_calld = (glb_lb_call_data*)arg;
+ glb_lb_policy* glb_policy = lb_calld->glb_policy;
+ GPR_ASSERT(lb_calld->lb_call != nullptr);
+ if (grpc_lb_glb_trace.enabled()) {
+ char* status_details =
+ grpc_slice_to_c_string(lb_calld->lb_call_status_details);
+ gpr_log(GPR_INFO,
+ "[grpclb %p] Status from LB server received. Status = %d, details "
+ "= '%s', (lb_calld: %p, lb_call: %p), error '%s'",
+ lb_calld->glb_policy, lb_calld->lb_call_status, status_details,
+ lb_calld, lb_calld->lb_call, grpc_error_string(error));
+ gpr_free(status_details);
+ }
+ // If this lb_calld is still in use, this call ended because of a failure so
+ // we want to retry connecting. Otherwise, we have deliberately ended this
+ // call and no further action is required.
+ if (lb_calld == glb_policy->lb_calld) {
+ glb_policy->lb_calld = nullptr;
+ if (lb_calld->client_load_report_timer_callback_pending) {
+ grpc_timer_cancel(&lb_calld->client_load_report_timer);
+ }
+ GPR_ASSERT(!glb_policy->shutting_down);
+ if (lb_calld->seen_initial_response) {
+ // If we lose connection to the LB server, reset the backoff and restart
+ // the LB call immediately.
+ glb_policy->lb_call_backoff->Reset();
+ query_for_backends_locked(glb_policy);
} else {
- GRPC_LB_POLICY_UNREF(&glb_policy->base,
- "lb_on_response_received_locked_shutdown");
+ // If this LB call fails establishing any connection to the LB server,
+ // retry later.
+ start_lb_call_retry_timer_locked(glb_policy);
}
- } else { /* empty payload: call cancelled. */
- /* dispose of the "lb_on_response_received_locked" ref taken in
- * query_for_backends_locked() and reused in every reception loop */
- GRPC_LB_POLICY_UNREF(&glb_policy->base,
- "lb_on_response_received_locked_empty_payload");
}
+ glb_lb_call_data_unref(lb_calld, "lb_call_ended");
}
static void lb_on_fallback_timer_locked(void* arg, grpc_error* error) {
@@ -1597,29 +1656,6 @@ static void lb_on_fallback_timer_locked(void* arg, grpc_error* error) {
GRPC_LB_POLICY_UNREF(&glb_policy->base, "grpclb_fallback_timer");
}
-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_lb_glb_trace.enabled()) {
- char* status_details =
- grpc_slice_to_c_string(glb_policy->lb_call_status_details);
- gpr_log(GPR_INFO,
- "[grpclb %p] Status from LB server received. Status = %d, Details "
- "= '%s', (call: %p), error '%s'",
- glb_policy, glb_policy->lb_call_status, status_details,
- glb_policy->lb_call, grpc_error_string(error));
- gpr_free(status_details);
- }
- /* We need to perform cleanups no matter what. */
- lb_call_destroy_locked(glb_policy);
- // If the load report timer is still pending, we wait for it to be
- // called before restarting the call. Otherwise, we restart the call
- // here.
- if (!glb_policy->client_load_report_timer_callback_pending) {
- maybe_restart_lb_call(glb_policy);
- }
-}
-
static void fallback_update_locked(glb_lb_policy* glb_policy,
const grpc_lb_addresses* addresses) {
GPR_ASSERT(glb_policy->fallback_backend_addresses != nullptr);
@@ -1701,7 +1737,7 @@ static void glb_lb_channel_on_connectivity_changed_cb(void* arg,
switch (glb_policy->lb_channel_connectivity) {
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_TRANSIENT_FAILURE: {
- /* resub. */
+ // Keep watching the LB channel.
grpc_channel_element* client_channel_elem =
grpc_channel_stack_last_element(
grpc_channel_get_channel_stack(glb_policy->lb_channel));
@@ -1714,29 +1750,26 @@ static void glb_lb_channel_on_connectivity_changed_cb(void* arg,
&glb_policy->lb_channel_on_connectivity_changed, nullptr);
break;
}
+ // The LB channel may be IDLE because it's shut down before the update.
+ // Restart the LB call to kick the LB channel into gear.
case GRPC_CHANNEL_IDLE:
- // lb channel inactive (probably shutdown prior to update). Restart lb
- // call to kick the lb channel into gear.
- /* fallthrough */
case GRPC_CHANNEL_READY:
- if (glb_policy->lb_call != nullptr) {
- glb_policy->updating_lb_call = true;
- grpc_call_cancel(glb_policy->lb_call, nullptr);
- // lb_on_server_status_received() will pick up the cancel and reinit
- // lb_call.
- } else if (glb_policy->started_picking) {
+ if (glb_policy->lb_calld != nullptr) {
+ lb_call_data_shutdown(glb_policy);
+ }
+ if (glb_policy->started_picking) {
if (glb_policy->retry_timer_callback_pending) {
grpc_timer_cancel(&glb_policy->lb_call_retry_timer);
}
- start_picking_locked(glb_policy);
+ glb_policy->lb_call_backoff->Reset();
+ query_for_backends_locked(glb_policy);
}
- /* fallthrough */
+ // Fall through.
case GRPC_CHANNEL_SHUTDOWN:
done:
glb_policy->watching_lb_channel = false;
GRPC_LB_POLICY_UNREF(&glb_policy->base,
"watch_lb_channel_connectivity_cb_shutdown");
- break;
}
}
@@ -1851,6 +1884,14 @@ static grpc_lb_policy* glb_create(grpc_lb_policy_factory* factory,
grpc_lb_policy_init(&glb_policy->base, &glb_lb_policy_vtable, args->combiner);
grpc_connectivity_state_init(&glb_policy->state_tracker, GRPC_CHANNEL_IDLE,
"grpclb");
+ // Init LB call backoff option.
+ grpc_core::BackOff::Options backoff_options;
+ backoff_options
+ .set_initial_backoff(GRPC_GRPCLB_INITIAL_CONNECT_BACKOFF_SECONDS * 1000)
+ .set_multiplier(GRPC_GRPCLB_RECONNECT_BACKOFF_MULTIPLIER)
+ .set_jitter(GRPC_GRPCLB_RECONNECT_JITTER)
+ .set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
+ glb_policy->lb_call_backoff.Init(backoff_options);
return &glb_policy->base;
}
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 e217a0b0c0..24c381a46d 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
@@ -34,7 +34,7 @@
#include "src/core/ext/filters/client_channel/subchannel_index.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/debug/trace.h"
-#include "src/core/lib/gpr++/ref_counted_ptr.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/transport/connectivity_state.h"
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
index f4e345def6..3377605263 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
@@ -22,7 +22,7 @@
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/lib/debug/trace.h"
-#include "src/core/lib/gpr++/ref_counted_ptr.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/transport/connectivity_state.h"
// TODO(roth): This code is intended to be shared between pick_first and
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
index 1efdc26d56..6ba5f932f0 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
@@ -34,9 +34,9 @@
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/gpr++/manual_constructor.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/gethostname.h"
#include "src/core/lib/iomgr/resolve_address.h"
diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
index 66a03c5a85..62f03d52c0 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
@@ -29,9 +29,9 @@
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/gpr++/manual_constructor.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/timer.h"
diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc
index bb43651d0c..cad8578511 100644
--- a/src/core/ext/filters/client_channel/subchannel.cc
+++ b/src/core/ext/filters/client_channel/subchannel.cc
@@ -37,8 +37,8 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/debug/stats.h"
-#include "src/core/lib/gpr++/debug_location.h"
-#include "src/core/lib/gpr++/manual_constructor.h"
+#include "src/core/lib/gprpp/debug_location.h"
+#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/profiling/timers.h"
diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h
index f2a5c1e273..b7593ec911 100644
--- a/src/core/ext/filters/client_channel/subchannel.h
+++ b/src/core/ext/filters/client_channel/subchannel.h
@@ -21,9 +21,9 @@
#include "src/core/ext/filters/client_channel/connector.h"
#include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/gpr++/ref_counted.h"
-#include "src/core/lib/gpr++/ref_counted_ptr.h"
#include "src/core/lib/gpr/arena.h"
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/metadata.h"
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index e067b696a1..530ab17bc7 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -1886,7 +1886,7 @@ void grpc_chttp2_maybe_complete_recv_trailing_metadata(grpc_chttp2_transport* t,
grpc_chttp2_maybe_complete_recv_message(t, s);
if (s->recv_trailing_metadata_finished != nullptr && s->read_closed &&
s->write_closed) {
- if (s->seen_error) {
+ if (s->seen_error || !t->is_client) {
grpc_slice_buffer_reset_and_unref_internal(&s->frame_storage);
if (!s->pending_byte_stream) {
grpc_slice_buffer_reset_and_unref_internal(
diff --git a/src/core/ext/transport/chttp2/transport/flow_control.h b/src/core/ext/transport/chttp2/transport/flow_control.h
index 7e83ea05cd..2ee1345260 100644
--- a/src/core/ext/transport/chttp2/transport/flow_control.h
+++ b/src/core/ext/transport/chttp2/transport/flow_control.h
@@ -24,8 +24,8 @@
#include <grpc/support/useful.h>
#include "src/core/ext/transport/chttp2/transport/http2_settings.h"
-#include "src/core/lib/gpr++/abstract.h"
-#include "src/core/lib/gpr++/manual_constructor.h"
+#include "src/core/lib/gprpp/abstract.h"
+#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/transport/bdp_estimator.h"
#include "src/core/lib/transport/pid_controller.h"
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index de901f0ce8..6b6c0b28e2 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -35,7 +35,7 @@
#include "src/core/ext/transport/chttp2/transport/incoming_metadata.h"
#include "src/core/ext/transport/chttp2/transport/stream_map.h"
#include "src/core/lib/compression/stream_compression.h"
-#include "src/core/lib/gpr++/manual_constructor.h"
+#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/timer.h"
diff --git a/src/core/lib/gpr/alloc.cc b/src/core/lib/gpr/alloc.cc
index 518bdb99f7..000b7dcb25 100644
--- a/src/core/lib/gpr/alloc.cc
+++ b/src/core/lib/gpr/alloc.cc
@@ -90,8 +90,8 @@ void* gpr_realloc(void* p, size_t size) {
return p;
}
-void* gpr_malloc_aligned(size_t size, size_t alignment_log) {
- size_t alignment = ((size_t)1) << alignment_log;
+void* gpr_malloc_aligned(size_t size, size_t alignment) {
+ GPR_ASSERT(((alignment - 1) & alignment) == 0); // Must be power of 2.
size_t extra = alignment - 1 + sizeof(void*);
void* p = gpr_malloc(size + extra);
void** ret = (void**)(((uintptr_t)p + extra) & ~(alignment - 1));
diff --git a/src/core/lib/gpr/arena.cc b/src/core/lib/gpr/arena.cc
index 177c176732..687592a140 100644
--- a/src/core/lib/gpr/arena.cc
+++ b/src/core/lib/gpr/arena.cc
@@ -17,11 +17,19 @@
*/
#include "src/core/lib/gpr/arena.h"
+
+#include <string.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
+// TODO(roth): We currently assume that all callers need alignment of 16
+// bytes, which may be wrong in some cases. As part of converting the
+// arena API to C++, we should consider replacing gpr_arena_alloc() with a
+// template that takes the type of the value being allocated, which
+// would allow us to use the alignment actually needed by the caller.
#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
(((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u))
@@ -36,9 +44,16 @@ struct gpr_arena {
zone initial_zone;
};
+static void* zalloc_aligned(size_t size) {
+ void* ptr = gpr_malloc_aligned(size, GPR_MAX_ALIGNMENT);
+ memset(ptr, 0, size);
+ return ptr;
+}
+
gpr_arena* gpr_arena_create(size_t initial_size) {
initial_size = ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
- gpr_arena* a = (gpr_arena*)gpr_zalloc(sizeof(gpr_arena) + initial_size);
+ gpr_arena* a = (gpr_arena*)zalloc_aligned(
+ ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size);
a->initial_zone.size_end = initial_size;
return a;
}
@@ -46,10 +61,10 @@ gpr_arena* gpr_arena_create(size_t initial_size) {
size_t gpr_arena_destroy(gpr_arena* arena) {
gpr_atm size = gpr_atm_no_barrier_load(&arena->size_so_far);
zone* z = (zone*)gpr_atm_no_barrier_load(&arena->initial_zone.next_atm);
- gpr_free(arena);
+ gpr_free_aligned(arena);
while (z) {
zone* next_z = (zone*)gpr_atm_no_barrier_load(&z->next_atm);
- gpr_free(z);
+ gpr_free_aligned(z);
z = next_z;
}
return (size_t)size;
@@ -64,11 +79,12 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
zone* next_z = (zone*)gpr_atm_acq_load(&z->next_atm);
if (next_z == nullptr) {
size_t next_z_size = (size_t)gpr_atm_no_barrier_load(&arena->size_so_far);
- next_z = (zone*)gpr_zalloc(sizeof(zone) + next_z_size);
+ next_z = (zone*)zalloc_aligned(ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) +
+ next_z_size);
next_z->size_begin = z->size_end;
next_z->size_end = z->size_end + next_z_size;
if (!gpr_atm_rel_cas(&z->next_atm, (gpr_atm)NULL, (gpr_atm)next_z)) {
- gpr_free(next_z);
+ gpr_free_aligned(next_z);
next_z = (zone*)gpr_atm_acq_load(&z->next_atm);
}
}
@@ -79,5 +95,8 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
}
GPR_ASSERT(start >= z->size_begin);
GPR_ASSERT(start + size <= z->size_end);
- return ((char*)(z + 1)) + start - z->size_begin;
+ char* ptr = (z == &arena->initial_zone)
+ ? (char*)arena + ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena))
+ : (char*)z + ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
+ return ptr + start - z->size_begin;
}
diff --git a/src/core/lib/gpr/fork.cc b/src/core/lib/gpr/fork.cc
index c47e686378..92023f4350 100644
--- a/src/core/lib/gpr/fork.cc
+++ b/src/core/lib/gpr/fork.cc
@@ -38,18 +38,32 @@ void grpc_fork_support_init() {
fork_support_enabled = 1;
#else
fork_support_enabled = 0;
+#endif
+ bool env_var_set = false;
char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT");
if (env != nullptr) {
static const char* truthy[] = {"yes", "Yes", "YES", "true",
"True", "TRUE", "1"};
+ static const char* falsey[] = {"no", "No", "NO", "false",
+ "False", "FALSE", "0"};
for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) {
if (0 == strcmp(env, truthy[i])) {
fork_support_enabled = 1;
+ env_var_set = true;
+ break;
+ }
+ }
+ if (!env_var_set) {
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(falsey); i++) {
+ if (0 == strcmp(env, falsey[i])) {
+ fork_support_enabled = 0;
+ env_var_set = true;
+ break;
+ }
}
}
gpr_free(env);
}
-#endif
if (override_fork_support_enabled != -1) {
fork_support_enabled = override_fork_support_enabled;
}
diff --git a/src/core/lib/gpr++/README.md b/src/core/lib/gprpp/README.md
index eab018bb31..eab018bb31 100644
--- a/src/core/lib/gpr++/README.md
+++ b/src/core/lib/gprpp/README.md
diff --git a/src/core/lib/gpr++/abstract.h b/src/core/lib/gprpp/abstract.h
index 51d7572302..cc96edc49b 100644
--- a/src/core/lib/gpr++/abstract.h
+++ b/src/core/lib/gprpp/abstract.h
@@ -16,8 +16,8 @@
*
*/
-#ifndef GRPC_CORE_LIB_GPRXX_ABSTRACT_H
-#define GRPC_CORE_LIB_GPRXX_ABSTRACT_H
+#ifndef GRPC_CORE_LIB_GPRPP_ABSTRACT_H
+#define GRPC_CORE_LIB_GPRPP_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
@@ -31,4 +31,4 @@
#define GRPC_ABSTRACT \
{ GPR_ASSERT(false); }
-#endif /* GRPC_CORE_LIB_GPRXX_ABSTRACT_H */
+#endif /* GRPC_CORE_LIB_GPRPP_ABSTRACT_H */
diff --git a/src/core/lib/gpr++/atomic.h b/src/core/lib/gprpp/atomic.h
index d68ccea864..8b08fc4e9c 100644
--- a/src/core/lib/gpr++/atomic.h
+++ b/src/core/lib/gprpp/atomic.h
@@ -16,15 +16,15 @@
*
*/
-#ifndef GRPC_CORE_LIB_GPRXX_ATOMIC_H
-#define GRPC_CORE_LIB_GPRXX_ATOMIC_H
+#ifndef GRPC_CORE_LIB_GPRPP_ATOMIC_H
+#define GRPC_CORE_LIB_GPRPP_ATOMIC_H
#include <grpc/support/port_platform.h>
#ifdef GPR_HAS_CXX11_ATOMIC
-#include "src/core/lib/gpr++/atomic_with_std.h"
+#include "src/core/lib/gprpp/atomic_with_std.h"
#else
-#include "src/core/lib/gpr++/atomic_with_atm.h"
+#include "src/core/lib/gprpp/atomic_with_atm.h"
#endif
-#endif /* GRPC_CORE_LIB_GPRXX_ATOMIC_H */
+#endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_H */
diff --git a/src/core/lib/gpr++/atomic_with_atm.h b/src/core/lib/gprpp/atomic_with_atm.h
index 09490e8148..6abf0bc38d 100644
--- a/src/core/lib/gpr++/atomic_with_atm.h
+++ b/src/core/lib/gprpp/atomic_with_atm.h
@@ -16,8 +16,8 @@
*
*/
-#ifndef GRPC_CORE_LIB_GPRXX_ATOMIC_WITH_ATM_H
-#define GRPC_CORE_LIB_GPRXX_ATOMIC_WITH_ATM_H
+#ifndef GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H
+#define GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H
#include <grpc/support/atm.h>
@@ -52,4 +52,4 @@ class atomic<bool> {
} // namespace grpc_core
-#endif /* GRPC_CORE_LIB_GPRXX_ATOMIC_WITH_ATM_H */
+#endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H */
diff --git a/src/core/lib/gpr++/atomic_with_std.h b/src/core/lib/gprpp/atomic_with_std.h
index b6ff90655e..83322b81c1 100644
--- a/src/core/lib/gpr++/atomic_with_std.h
+++ b/src/core/lib/gprpp/atomic_with_std.h
@@ -16,8 +16,8 @@
*
*/
-#ifndef GRPC_CORE_LIB_GPRXX_ATOMIC_WITH_STD_H
-#define GRPC_CORE_LIB_GPRXX_ATOMIC_WITH_STD_H
+#ifndef GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H
+#define GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H
#include <atomic>
@@ -30,4 +30,4 @@ typedef std::memory_order memory_order;
} // namespace grpc_core
-#endif /* GRPC_CORE_LIB_GPRXX_ATOMIC_WITH_STD_H */
+#endif /* GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H */
diff --git a/src/core/lib/gpr++/debug_location.h b/src/core/lib/gprpp/debug_location.h
index 5a8665ce19..287761beaf 100644
--- a/src/core/lib/gpr++/debug_location.h
+++ b/src/core/lib/gprpp/debug_location.h
@@ -16,8 +16,8 @@
*
*/
-#ifndef GRPC_CORE_LIB_GPRXX_DEBUG_LOCATION_H
-#define GRPC_CORE_LIB_GPRXX_DEBUG_LOCATION_H
+#ifndef GRPC_CORE_LIB_GPRPP_DEBUG_LOCATION_H
+#define GRPC_CORE_LIB_GPRPP_DEBUG_LOCATION_H
namespace grpc_core {
@@ -49,4 +49,4 @@ class DebugLocation {
} // namespace grpc_core
-#endif /* GRPC_CORE_LIB_GPRXX_DEBUG_LOCATION_H */
+#endif /* GRPC_CORE_LIB_GPRPP_DEBUG_LOCATION_H */
diff --git a/src/core/lib/gpr++/inlined_vector.h b/src/core/lib/gprpp/inlined_vector.h
index 17ee9e16bb..b78f85b893 100644
--- a/src/core/lib/gpr++/inlined_vector.h
+++ b/src/core/lib/gprpp/inlined_vector.h
@@ -16,12 +16,12 @@
*
*/
-#ifndef GRPC_CORE_LIB_GPRXX_INLINED_VECTOR_H
-#define GRPC_CORE_LIB_GPRXX_INLINED_VECTOR_H
+#ifndef GRPC_CORE_LIB_GPRPP_INLINED_VECTOR_H
+#define GRPC_CORE_LIB_GPRPP_INLINED_VECTOR_H
#include <cassert>
-#include "src/core/lib/gpr++/memory.h"
+#include "src/core/lib/gprpp/memory.h"
namespace grpc_core {
@@ -109,4 +109,4 @@ class InlinedVector {
} // namespace grpc_core
-#endif /* GRPC_CORE_LIB_GPRXX_INLINED_VECTOR_H */
+#endif /* GRPC_CORE_LIB_GPRPP_INLINED_VECTOR_H */
diff --git a/src/core/lib/gpr++/manual_constructor.h b/src/core/lib/gprpp/manual_constructor.h
index a3f006da34..cee38abc1b 100644
--- a/src/core/lib/gpr++/manual_constructor.h
+++ b/src/core/lib/gprpp/manual_constructor.h
@@ -16,8 +16,8 @@
*
*/
-#ifndef GRPC_CORE_LIB_GPRXX_MANUAL_CONSTRUCTOR_H
-#define GRPC_CORE_LIB_GPRXX_MANUAL_CONSTRUCTOR_H
+#ifndef GRPC_CORE_LIB_GPRPP_MANUAL_CONSTRUCTOR_H
+#define GRPC_CORE_LIB_GPRPP_MANUAL_CONSTRUCTOR_H
// manually construct a region of memory with some type
diff --git a/src/core/lib/gpr++/memory.h b/src/core/lib/gprpp/memory.h
index 75ed3d6cea..17f42f5983 100644
--- a/src/core/lib/gpr++/memory.h
+++ b/src/core/lib/gprpp/memory.h
@@ -16,8 +16,8 @@
*
*/
-#ifndef GRPC_CORE_LIB_GPRXX_MEMORY_H
-#define GRPC_CORE_LIB_GPRXX_MEMORY_H
+#ifndef GRPC_CORE_LIB_GPRPP_MEMORY_H
+#define GRPC_CORE_LIB_GPRPP_MEMORY_H
#include <grpc/support/alloc.h>
@@ -97,4 +97,4 @@ class Allocator {
} // namespace grpc_core
-#endif /* GRPC_CORE_LIB_GPRXX_MEMORY_H */
+#endif /* GRPC_CORE_LIB_GPRPP_MEMORY_H */
diff --git a/src/core/lib/gpr++/orphanable.h b/src/core/lib/gprpp/orphanable.h
index f106e74dde..50199730c9 100644
--- a/src/core/lib/gpr++/orphanable.h
+++ b/src/core/lib/gprpp/orphanable.h
@@ -16,8 +16,8 @@
*
*/
-#ifndef GRPC_CORE_LIB_GPRXX_ORPHANABLE_H
-#define GRPC_CORE_LIB_GPRXX_ORPHANABLE_H
+#ifndef GRPC_CORE_LIB_GPRPP_ORPHANABLE_H
+#define GRPC_CORE_LIB_GPRPP_ORPHANABLE_H
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
@@ -25,9 +25,9 @@
#include <memory>
#include "src/core/lib/debug/trace.h"
-#include "src/core/lib/gpr++/abstract.h"
-#include "src/core/lib/gpr++/debug_location.h"
-#include "src/core/lib/gpr++/memory.h"
+#include "src/core/lib/gprpp/abstract.h"
+#include "src/core/lib/gprpp/debug_location.h"
+#include "src/core/lib/gprpp/memory.h"
namespace grpc_core {
@@ -168,4 +168,4 @@ class InternallyRefCountedWithTracing : public Orphanable {
} // namespace grpc_core
-#endif /* GRPC_CORE_LIB_GPRXX_ORPHANABLE_H */
+#endif /* GRPC_CORE_LIB_GPRPP_ORPHANABLE_H */
diff --git a/src/core/lib/gpr++/ref_counted.h b/src/core/lib/gprpp/ref_counted.h
index c2ae76c0ae..c68118a71a 100644
--- a/src/core/lib/gpr++/ref_counted.h
+++ b/src/core/lib/gprpp/ref_counted.h
@@ -16,16 +16,16 @@
*
*/
-#ifndef GRPC_CORE_LIB_GPRXX_REF_COUNTED_H
-#define GRPC_CORE_LIB_GPRXX_REF_COUNTED_H
+#ifndef GRPC_CORE_LIB_GPRPP_REF_COUNTED_H
+#define GRPC_CORE_LIB_GPRPP_REF_COUNTED_H
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include "src/core/lib/debug/trace.h"
-#include "src/core/lib/gpr++/abstract.h"
-#include "src/core/lib/gpr++/debug_location.h"
-#include "src/core/lib/gpr++/memory.h"
+#include "src/core/lib/gprpp/abstract.h"
+#include "src/core/lib/gprpp/debug_location.h"
+#include "src/core/lib/gprpp/memory.h"
namespace grpc_core {
@@ -130,4 +130,4 @@ class RefCountedWithTracing {
} // namespace grpc_core
-#endif /* GRPC_CORE_LIB_GPRXX_REF_COUNTED_H */
+#endif /* GRPC_CORE_LIB_GPRPP_REF_COUNTED_H */
diff --git a/src/core/lib/gpr++/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h
index 862294d1aa..dda0f00d79 100644
--- a/src/core/lib/gpr++/ref_counted_ptr.h
+++ b/src/core/lib/gprpp/ref_counted_ptr.h
@@ -16,12 +16,12 @@
*
*/
-#ifndef GRPC_CORE_LIB_GPRXX_REF_COUNTED_PTR_H
-#define GRPC_CORE_LIB_GPRXX_REF_COUNTED_PTR_H
+#ifndef GRPC_CORE_LIB_GPRPP_REF_COUNTED_PTR_H
+#define GRPC_CORE_LIB_GPRPP_REF_COUNTED_PTR_H
#include <utility>
-#include "src/core/lib/gpr++/memory.h"
+#include "src/core/lib/gprpp/memory.h"
namespace grpc_core {
@@ -96,4 +96,4 @@ inline RefCountedPtr<T> MakeRefCounted(Args&&... args) {
} // namespace grpc_core
-#endif /* GRPC_CORE_LIB_GPRXX_REF_COUNTED_PTR_H */
+#endif /* GRPC_CORE_LIB_GPRPP_REF_COUNTED_PTR_H */
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc
index 1cb0150f45..42d7cdd348 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.cc
+++ b/src/core/lib/iomgr/ev_epoll1_linux.cc
@@ -43,8 +43,8 @@
#include <grpc/support/useful.h>
#include "src/core/lib/debug/stats.h"
-#include "src/core/lib/gpr++/manual_constructor.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/block_annotate.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index b81c00ca7a..416e8384b4 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -41,8 +41,8 @@
#include <grpc/support/useful.h>
#include "src/core/lib/debug/stats.h"
-#include "src/core/lib/gpr++/manual_constructor.h"
#include "src/core/lib/gpr/spinlock.h"
+#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/block_annotate.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/is_epollexclusive_available.h"
diff --git a/src/core/lib/iomgr/ev_epollsig_linux.cc b/src/core/lib/iomgr/ev_epollsig_linux.cc
index 11c64d080c..1518348992 100644
--- a/src/core/lib/iomgr/ev_epollsig_linux.cc
+++ b/src/core/lib/iomgr/ev_epollsig_linux.cc
@@ -43,7 +43,7 @@
#include <grpc/support/useful.h>
#include "src/core/lib/debug/stats.h"
-#include "src/core/lib/gpr++/manual_constructor.h"
+#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/block_annotate.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
diff --git a/src/core/lib/surface/lame_client.cc b/src/core/lib/surface/lame_client.cc
index 27a2a4eeb6..a1f1cf1107 100644
--- a/src/core/lib/surface/lame_client.cc
+++ b/src/core/lib/surface/lame_client.cc
@@ -23,7 +23,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include "src/core/lib/gpr++/atomic.h"
+#include "src/core/lib/gprpp/atomic.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/string.h"
diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc
index 7d36c6c9e1..19498a6df7 100644
--- a/src/core/lib/surface/version.cc
+++ b/src/core/lib/surface/version.cc
@@ -23,4 +23,4 @@
const char* grpc_version_string(void) { return "5.0.0-dev"; }
-const char* grpc_g_stands_for(void) { return "glossy"; }
+const char* grpc_g_stands_for(void) { return "glamorous"; }
diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc
index 229f7efd37..b396a621bd 100644
--- a/src/core/tsi/ssl_transport_security.cc
+++ b/src/core/tsi/ssl_transport_security.cc
@@ -96,8 +96,7 @@ struct tsi_ssl_server_handshaker_factory {
typedef struct {
tsi_handshaker base;
SSL* ssl;
- BIO* into_ssl;
- BIO* from_ssl;
+ BIO* network_io;
tsi_result result;
tsi_ssl_handshaker_factory* factory_ref;
} tsi_ssl_handshaker;
@@ -105,8 +104,7 @@ typedef struct {
typedef struct {
tsi_frame_protector base;
SSL* ssl;
- BIO* into_ssl;
- BIO* from_ssl;
+ BIO* network_io;
unsigned char* buffer;
size_t buffer_size;
size_t buffer_offset;
@@ -730,11 +728,11 @@ static tsi_result ssl_protector_protect(tsi_frame_protector* self,
tsi_result result = TSI_OK;
/* First see if we have some pending data in the SSL BIO. */
- int pending_in_ssl = (int)BIO_pending(impl->from_ssl);
+ int pending_in_ssl = (int)BIO_pending(impl->network_io);
if (pending_in_ssl > 0) {
*unprotected_bytes_size = 0;
GPR_ASSERT(*protected_output_frames_size <= INT_MAX);
- read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
+ read_from_ssl = BIO_read(impl->network_io, protected_output_frames,
(int)*protected_output_frames_size);
if (read_from_ssl < 0) {
gpr_log(GPR_ERROR,
@@ -762,7 +760,7 @@ static tsi_result ssl_protector_protect(tsi_frame_protector* self,
if (result != TSI_OK) return result;
GPR_ASSERT(*protected_output_frames_size <= INT_MAX);
- read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
+ read_from_ssl = BIO_read(impl->network_io, protected_output_frames,
(int)*protected_output_frames_size);
if (read_from_ssl < 0) {
gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write.");
@@ -788,20 +786,20 @@ static tsi_result ssl_protector_protect_flush(
impl->buffer_offset = 0;
}
- pending = (int)BIO_pending(impl->from_ssl);
+ pending = (int)BIO_pending(impl->network_io);
GPR_ASSERT(pending >= 0);
*still_pending_size = (size_t)pending;
if (*still_pending_size == 0) return TSI_OK;
GPR_ASSERT(*protected_output_frames_size <= INT_MAX);
- read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
+ read_from_ssl = BIO_read(impl->network_io, protected_output_frames,
(int)*protected_output_frames_size);
if (read_from_ssl <= 0) {
gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write.");
return TSI_INTERNAL_ERROR;
}
*protected_output_frames_size = (size_t)read_from_ssl;
- pending = (int)BIO_pending(impl->from_ssl);
+ pending = (int)BIO_pending(impl->network_io);
GPR_ASSERT(pending >= 0);
*still_pending_size = (size_t)pending;
return TSI_OK;
@@ -831,7 +829,7 @@ static tsi_result ssl_protector_unprotect(
/* Then, try to write some data to ssl. */
GPR_ASSERT(*protected_frames_bytes_size <= INT_MAX);
- written_into_ssl = BIO_write(impl->into_ssl, protected_frames_bytes,
+ written_into_ssl = BIO_write(impl->network_io, protected_frames_bytes,
(int)*protected_frames_bytes_size);
if (written_into_ssl < 0) {
gpr_log(GPR_ERROR, "Sending protected frame to ssl failed with %d",
@@ -853,6 +851,7 @@ static void ssl_protector_destroy(tsi_frame_protector* self) {
tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self;
if (impl->buffer != nullptr) gpr_free(impl->buffer);
if (impl->ssl != nullptr) SSL_free(impl->ssl);
+ if (impl->network_io != nullptr) BIO_free(impl->network_io);
gpr_free(self);
}
@@ -916,10 +915,10 @@ static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker* self,
return TSI_INVALID_ARGUMENT;
}
GPR_ASSERT(*bytes_size <= INT_MAX);
- bytes_read_from_ssl = BIO_read(impl->from_ssl, bytes, (int)*bytes_size);
+ bytes_read_from_ssl = BIO_read(impl->network_io, bytes, (int)*bytes_size);
if (bytes_read_from_ssl < 0) {
*bytes_size = 0;
- if (!BIO_should_retry(impl->from_ssl)) {
+ if (!BIO_should_retry(impl->network_io)) {
impl->result = TSI_INTERNAL_ERROR;
return impl->result;
} else {
@@ -927,7 +926,7 @@ static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker* self,
}
}
*bytes_size = (size_t)bytes_read_from_ssl;
- return BIO_pending(impl->from_ssl) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA;
+ return BIO_pending(impl->network_io) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA;
}
static tsi_result ssl_handshaker_get_result(tsi_handshaker* self) {
@@ -948,7 +947,7 @@ static tsi_result ssl_handshaker_process_bytes_from_peer(
}
GPR_ASSERT(*bytes_size <= INT_MAX);
bytes_written_into_ssl_size =
- BIO_write(impl->into_ssl, bytes, (int)*bytes_size);
+ BIO_write(impl->network_io, bytes, (int)*bytes_size);
if (bytes_written_into_ssl_size < 0) {
gpr_log(GPR_ERROR, "Could not write to memory BIO.");
impl->result = TSI_INTERNAL_ERROR;
@@ -965,7 +964,7 @@ static tsi_result ssl_handshaker_process_bytes_from_peer(
ssl_result = SSL_get_error(impl->ssl, ssl_result);
switch (ssl_result) {
case SSL_ERROR_WANT_READ:
- if (BIO_pending(impl->from_ssl) == 0) {
+ if (BIO_pending(impl->network_io) == 0) {
/* We need more data. */
return TSI_INCOMPLETE_DATA;
} else {
@@ -1058,12 +1057,13 @@ static tsi_result ssl_handshaker_create_frame_protector(
return TSI_INTERNAL_ERROR;
}
- /* Transfer ownership of ssl to the frame protector. It is OK as the caller
- * cannot call anything else but destroy on the handshaker after this call. */
+ /* Transfer ownership of ssl and network_io to the frame protector. It is OK
+ * as the caller cannot call anything else but destroy on the handshaker
+ * after this call. */
protector_impl->ssl = impl->ssl;
impl->ssl = nullptr;
- protector_impl->into_ssl = impl->into_ssl;
- protector_impl->from_ssl = impl->from_ssl;
+ protector_impl->network_io = impl->network_io;
+ impl->network_io = nullptr;
protector_impl->base.vtable = &frame_protector_vtable;
*protector = &protector_impl->base;
@@ -1072,7 +1072,8 @@ static tsi_result ssl_handshaker_create_frame_protector(
static void ssl_handshaker_destroy(tsi_handshaker* self) {
tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self;
- SSL_free(impl->ssl); /* The BIO objects are owned by ssl */
+ SSL_free(impl->ssl);
+ BIO_free(impl->network_io);
tsi_ssl_handshaker_factory_unref(impl->factory_ref);
gpr_free(impl);
}
@@ -1094,8 +1095,8 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client,
tsi_ssl_handshaker_factory* factory,
tsi_handshaker** handshaker) {
SSL* ssl = SSL_new(ctx);
- BIO* into_ssl = nullptr;
- BIO* from_ssl = nullptr;
+ BIO* network_io = nullptr;
+ BIO* ssl_io = nullptr;
tsi_ssl_handshaker* impl = nullptr;
*handshaker = nullptr;
if (ctx == nullptr) {
@@ -1107,16 +1108,12 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client,
}
SSL_set_info_callback(ssl, ssl_info_callback);
- into_ssl = BIO_new(BIO_s_mem());
- from_ssl = BIO_new(BIO_s_mem());
- if (into_ssl == nullptr || from_ssl == nullptr) {
- gpr_log(GPR_ERROR, "BIO_new failed.");
+ if (!BIO_new_bio_pair(&network_io, 0, &ssl_io, 0)) {
+ gpr_log(GPR_ERROR, "BIO_new_bio_pair failed.");
SSL_free(ssl);
- if (into_ssl != nullptr) BIO_free(into_ssl);
- if (from_ssl != nullptr) BIO_free(into_ssl);
return TSI_OUT_OF_RESOURCES;
}
- SSL_set_bio(ssl, into_ssl, from_ssl);
+ SSL_set_bio(ssl, ssl_io, ssl_io);
if (is_client) {
int ssl_result;
SSL_set_connect_state(ssl);
@@ -1125,6 +1122,7 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client,
gpr_log(GPR_ERROR, "Invalid server name indication %s.",
server_name_indication);
SSL_free(ssl);
+ BIO_free(network_io);
return TSI_INTERNAL_ERROR;
}
}
@@ -1135,6 +1133,7 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client,
"Unexpected error received from first SSL_do_handshake call: %s",
ssl_error_string(ssl_result));
SSL_free(ssl);
+ BIO_free(network_io);
return TSI_INTERNAL_ERROR;
}
} else {
@@ -1143,8 +1142,7 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client,
impl = (tsi_ssl_handshaker*)gpr_zalloc(sizeof(*impl));
impl->ssl = ssl;
- impl->into_ssl = into_ssl;
- impl->from_ssl = from_ssl;
+ impl->network_io = network_io;
impl->result = TSI_HANDSHAKE_IN_PROGRESS;
impl->base.vtable = &handshaker_vtable;
impl->factory_ref = tsi_ssl_handshaker_factory_ref(factory);
diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc
index 7f01a66dcf..8bc926048f 100644
--- a/src/cpp/common/version_cc.cc
+++ b/src/cpp/common/version_cc.cc
@@ -22,5 +22,5 @@
#include <grpc++/grpc++.h>
namespace grpc {
-grpc::string Version() { return "1.9.0-dev"; }
+grpc::string Version() { return "1.10.0-dev"; }
} // namespace grpc
diff --git a/src/csharp/Grpc.Core.Tests/Internal/DefaultObjectPoolTest.cs b/src/csharp/Grpc.Core.Tests/Internal/DefaultObjectPoolTest.cs
index b6bb0a9eae..9c6f8a2117 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/DefaultObjectPoolTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/DefaultObjectPoolTest.cs
@@ -60,6 +60,16 @@ namespace Grpc.Core.Internal.Tests
}
[Test]
+ public void LeaseSetsReturnAction()
+ {
+ var pool = new DefaultObjectPool<TestPooledObject>(() => new TestPooledObject(), 10, 0);
+ var origLeased = pool.Lease();
+ origLeased.ReturnAction(origLeased);
+ pool.Dispose();
+ Assert.AreNotSame(origLeased, pool.Lease());
+ }
+
+ [Test]
public void Constructor()
{
Assert.Throws<ArgumentNullException>(() => new DefaultObjectPool<TestPooledObject>(null, 10, 2));
@@ -67,8 +77,14 @@ namespace Grpc.Core.Internal.Tests
Assert.Throws<ArgumentException>(() => new DefaultObjectPool<TestPooledObject>(() => new TestPooledObject(), 10, -1));
}
- class TestPooledObject : IDisposable
+ class TestPooledObject : IPooledObject<TestPooledObject>
{
+ public Action<TestPooledObject> ReturnAction;
+
+ public void SetReturnToPoolAction(Action<TestPooledObject> returnAction)
+ {
+ this.ReturnAction = returnAction;
+ }
public void Dispose()
{
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index 6296f1863b..6bb2f6c3e5 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -299,8 +299,8 @@ namespace Grpc.Core
private GrpcEnvironment()
{
GrpcNativeInit();
- batchContextPool = new DefaultObjectPool<BatchContextSafeHandle>(() => BatchContextSafeHandle.Create(this.batchContextPool), batchContextPoolSharedCapacity, batchContextPoolThreadLocalCapacity);
- requestCallContextPool = new DefaultObjectPool<RequestCallContextSafeHandle>(() => RequestCallContextSafeHandle.Create(this.requestCallContextPool), requestCallContextPoolSharedCapacity, requestCallContextPoolThreadLocalCapacity);
+ batchContextPool = new DefaultObjectPool<BatchContextSafeHandle>(() => BatchContextSafeHandle.Create(), batchContextPoolSharedCapacity, batchContextPoolThreadLocalCapacity);
+ requestCallContextPool = new DefaultObjectPool<RequestCallContextSafeHandle>(() => RequestCallContextSafeHandle.Create(), requestCallContextPoolSharedCapacity, requestCallContextPoolThreadLocalCapacity);
threadPool = new GrpcThreadPool(this, GetThreadPoolSizeOrDefault(), GetCompletionQueueCountOrDefault(), inlineHandlers);
threadPool.Start();
}
diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
index 83385ad7d3..53a859d18f 100644
--- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
@@ -33,22 +33,21 @@ namespace Grpc.Core.Internal
/// <summary>
/// grpcsharp_batch_context
/// </summary>
- internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback
+ internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback, IPooledObject<BatchContextSafeHandle>
{
static readonly NativeMethods Native = NativeMethods.Get();
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<BatchContextSafeHandle>();
- IObjectPool<BatchContextSafeHandle> ownedByPool;
+ Action<BatchContextSafeHandle> returnToPoolAction;
CompletionCallbackData completionCallbackData;
private BatchContextSafeHandle()
{
}
- public static BatchContextSafeHandle Create(IObjectPool<BatchContextSafeHandle> ownedByPool = null)
+ public static BatchContextSafeHandle Create()
{
var ctx = Native.grpcsharp_batch_context_create();
- ctx.ownedByPool = ownedByPool;
return ctx;
}
@@ -60,6 +59,12 @@ namespace Grpc.Core.Internal
}
}
+ public void SetReturnToPoolAction(Action<BatchContextSafeHandle> returnAction)
+ {
+ GrpcPreconditions.CheckState(returnToPoolAction == null);
+ returnToPoolAction = returnAction;
+ }
+
public void SetCompletionCallback(BatchCompletionDelegate callback, object state)
{
GrpcPreconditions.CheckState(completionCallbackData.Callback == null);
@@ -109,10 +114,15 @@ namespace Grpc.Core.Internal
public void Recycle()
{
- if (ownedByPool != null)
+ if (returnToPoolAction != null)
{
Native.grpcsharp_batch_context_reset(this);
- ownedByPool.Return(this);
+
+ var origReturnAction = returnToPoolAction;
+ // Not clearing all the references to the pool could prevent garbage collection of the pool object
+ // and thus cause memory leaks.
+ returnToPoolAction = null;
+ origReturnAction(this);
}
else
{
diff --git a/src/csharp/Grpc.Core/Internal/DefaultObjectPool.cs b/src/csharp/Grpc.Core/Internal/DefaultObjectPool.cs
index 2f030f3e02..0e1dc4d158 100644
--- a/src/csharp/Grpc.Core/Internal/DefaultObjectPool.cs
+++ b/src/csharp/Grpc.Core/Internal/DefaultObjectPool.cs
@@ -27,9 +27,10 @@ namespace Grpc.Core.Internal
/// Pool of objects that combines a shared pool and a thread local pool.
/// </summary>
internal class DefaultObjectPool<T> : IObjectPool<T>
- where T : class, IDisposable
+ where T : class, IPooledObject<T>
{
readonly object myLock = new object();
+ readonly Action<T> returnAction;
readonly Func<T> itemFactory;
// Queue shared between threads, access needs to be synchronized.
@@ -54,6 +55,7 @@ namespace Grpc.Core.Internal
{
GrpcPreconditions.CheckArgument(sharedCapacity >= 0);
GrpcPreconditions.CheckArgument(threadLocalCapacity >= 0);
+ this.returnAction = Return;
this.itemFactory = GrpcPreconditions.CheckNotNull(itemFactory, nameof(itemFactory));
this.sharedQueue = new Queue<T>(sharedCapacity);
this.sharedCapacity = sharedCapacity;
@@ -74,6 +76,13 @@ namespace Grpc.Core.Internal
/// </summary>
public T Lease()
{
+ var item = LeaseInternal();
+ item.SetReturnToPoolAction(returnAction);
+ return item;
+ }
+
+ private T LeaseInternal()
+ {
var localData = threadLocalData.Value;
if (localData.Queue.Count > 0)
{
diff --git a/src/csharp/Grpc.Core/Internal/IPooledObject.cs b/src/csharp/Grpc.Core/Internal/IPooledObject.cs
new file mode 100644
index 0000000000..e20bd51dce
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/IPooledObject.cs
@@ -0,0 +1,34 @@
+#region Copyright notice and license
+
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// An object that can be pooled in <c>IObjectPool</c>.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ internal interface IPooledObject<T> : IDisposable
+ {
+ /// <summary>
+ /// Set the action that will be invoked to return a leased object to the pool.
+ /// </summary>
+ void SetReturnToPoolAction(Action<T> returnAction);
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs
index 59e9d9b1ab..ebc2d6d8d6 100644
--- a/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs
@@ -20,26 +20,26 @@ using System;
using System.Runtime.InteropServices;
using Grpc.Core;
using Grpc.Core.Logging;
+using Grpc.Core.Utils;
namespace Grpc.Core.Internal
{
/// <summary>
/// grpcsharp_request_call_context
/// </summary>
- internal class RequestCallContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback
+ internal class RequestCallContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback, IPooledObject<RequestCallContextSafeHandle>
{
static readonly NativeMethods Native = NativeMethods.Get();
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<RequestCallContextSafeHandle>();
- IObjectPool<RequestCallContextSafeHandle> ownedByPool;
+ Action<RequestCallContextSafeHandle> returnToPoolAction;
private RequestCallContextSafeHandle()
{
}
- public static RequestCallContextSafeHandle Create(IObjectPool<RequestCallContextSafeHandle> ownedByPool = null)
+ public static RequestCallContextSafeHandle Create()
{
var ctx = Native.grpcsharp_request_call_context_create();
- ctx.ownedByPool = ownedByPool;
return ctx;
}
@@ -51,6 +51,12 @@ namespace Grpc.Core.Internal
}
}
+ public void SetReturnToPoolAction(Action<RequestCallContextSafeHandle> returnAction)
+ {
+ GrpcPreconditions.CheckState(returnToPoolAction == null);
+ returnToPoolAction = returnAction;
+ }
+
public RequestCallCompletionDelegate CompletionCallback { get; set; }
// Gets data of server_rpc_new completion.
@@ -76,10 +82,15 @@ namespace Grpc.Core.Internal
public void Recycle()
{
- if (ownedByPool != null)
+ if (returnToPoolAction != null)
{
Native.grpcsharp_request_call_context_reset(this);
- ownedByPool.Return(this);
+
+ var origReturnAction = returnToPoolAction;
+ // Not clearing all the references to the pool could prevent garbage collection of the pool object
+ // and thus cause memory leaks.
+ returnToPoolAction = null;
+ origReturnAction(this);
}
else
{
diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include
index 2d9e4ba16a..539d3a9f80 100755
--- a/src/csharp/Grpc.Core/Version.csproj.include
+++ b/src/csharp/Grpc.Core/Version.csproj.include
@@ -1,7 +1,7 @@
<!-- This file is generated -->
<Project>
<PropertyGroup>
- <GrpcCsharpVersion>1.9.0-dev</GrpcCsharpVersion>
+ <GrpcCsharpVersion>1.10.0-dev</GrpcCsharpVersion>
<GoogleProtobufVersion>3.3.0</GoogleProtobufVersion>
</PropertyGroup>
</Project>
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index 9b5da1c947..f1aef46c6c 100644
--- a/src/csharp/Grpc.Core/VersionInfo.cs
+++ b/src/csharp/Grpc.Core/VersionInfo.cs
@@ -33,11 +33,11 @@ namespace Grpc.Core
/// <summary>
/// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
/// </summary>
- public const string CurrentAssemblyFileVersion = "1.9.0.0";
+ public const string CurrentAssemblyFileVersion = "1.10.0.0";
/// <summary>
/// Current version of gRPC C#
/// </summary>
- public const string CurrentVersion = "1.9.0-dev";
+ public const string CurrentVersion = "1.10.0-dev";
}
}
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index 8f89e2846a..4087d8b67a 100755
--- a/src/csharp/build_packages_dotnetcli.bat
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -13,7 +13,7 @@
@rem limitations under the License.
@rem Current package versions
-set VERSION=1.9.0-dev
+set VERSION=1.10.0-dev
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe
diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh
index 6a6cafe2bd..8ccc537a60 100755
--- a/src/csharp/build_packages_dotnetcli.sh
+++ b/src/csharp/build_packages_dotnetcli.sh
@@ -39,7 +39,7 @@ dotnet pack --configuration Release Grpc.Auth --output ../../../artifacts
dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts
dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts
-nuget pack Grpc.nuspec -Version "1.9.0-dev" -OutputDirectory ../../artifacts
-nuget pack Grpc.Tools.nuspec -Version "1.9.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.nuspec -Version "1.10.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.Tools.nuspec -Version "1.10.0-dev" -OutputDirectory ../../artifacts
(cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)
diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
index 22501765f9..037ad4d9b0 100644
--- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
+++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
@@ -42,7 +42,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler-gRPCPlugin'
- v = '1.9.0-dev'
+ v = '1.10.0-dev'
s.version = v
s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
s.description = <<-DESC
diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h
index 69dd6266fd..5c134e3642 100644
--- a/src/objective-c/GRPCClient/private/version.h
+++ b/src/objective-c/GRPCClient/private/version.h
@@ -23,4 +23,4 @@
// `tools/buildgen/generate_projects.sh`.
-#define GRPC_OBJC_VERSION_STRING @"1.9.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.10.0-dev"
diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h
index 6e3a073020..d8581b9779 100644
--- a/src/objective-c/tests/version.h
+++ b/src/objective-c/tests/version.h
@@ -23,5 +23,5 @@
// `tools/buildgen/generate_projects.sh`.
-#define GRPC_OBJC_VERSION_STRING @"1.9.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.10.0-dev"
#define GRPC_C_VERSION_STRING @"5.0.0-dev"
diff --git a/src/php/composer.json b/src/php/composer.json
index 43833980f9..ea21417956 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -2,7 +2,7 @@
"name": "grpc/grpc-dev",
"description": "gRPC library for PHP - for Developement use only",
"license": "Apache-2.0",
- "version": "1.9.0",
+ "version": "1.10.0",
"require": {
"php": ">=5.5.0",
"google/protobuf": "^v3.3.0"
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index c4997f720d..ff55c3cbfa 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -99,6 +99,7 @@ zval *grpc_parse_metadata_array(grpc_metadata_array
1 TSRMLS_CC);
efree(str_key);
efree(str_val);
+ PHP_GRPC_FREE_STD_ZVAL(array);
return NULL;
}
php_grpc_add_next_index_stringl(data, str_val,
@@ -127,10 +128,12 @@ bool create_metadata_array(zval *array, grpc_metadata_array *metadata) {
HashTable *inner_array_hash;
zval *value;
zval *inner_array;
+ grpc_metadata_array_init(metadata);
+ metadata->count = 0;
+ metadata->metadata = NULL;
if (Z_TYPE_P(array) != IS_ARRAY) {
return false;
}
- grpc_metadata_array_init(metadata);
array_hash = Z_ARRVAL_P(array);
char *key;
@@ -174,6 +177,18 @@ bool create_metadata_array(zval *array, grpc_metadata_array *metadata) {
return true;
}
+void grpc_php_metadata_array_destroy_including_entries(
+ grpc_metadata_array* array) {
+ size_t i;
+ if (array->metadata) {
+ for (i = 0; i < array->count; i++) {
+ grpc_slice_unref(array->metadata[i].key);
+ grpc_slice_unref(array->metadata[i].value);
+ }
+ }
+ grpc_metadata_array_destroy(array);
+}
+
/* Wraps a grpc_call struct in a PHP object. Owned indicates whether the
struct should be destroyed at the end of the object's lifecycle */
zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC) {
@@ -502,8 +517,8 @@ PHP_METHOD(Call, startBatch) {
}
cleanup:
- grpc_metadata_array_destroy(&metadata);
- grpc_metadata_array_destroy(&trailing_metadata);
+ grpc_php_metadata_array_destroy_including_entries(&metadata);
+ grpc_php_metadata_array_destroy_including_entries(&trailing_metadata);
grpc_metadata_array_destroy(&recv_metadata);
grpc_metadata_array_destroy(&recv_trailing_metadata);
grpc_slice_unref(recv_status_details);
@@ -526,7 +541,9 @@ cleanup:
*/
PHP_METHOD(Call, getPeer) {
wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis());
- PHP_GRPC_RETURN_STRING(grpc_call_get_peer(call->wrapped), 1);
+ char *peer = grpc_call_get_peer(call->wrapped);
+ PHP_GRPC_RETVAL_STRING(peer, 1);
+ gpr_free(peer);
}
/**
diff --git a/src/php/ext/grpc/call.h b/src/php/ext/grpc/call.h
index 5bde5d5390..104ac301c1 100644
--- a/src/php/ext/grpc/call.h
+++ b/src/php/ext/grpc/call.h
@@ -69,5 +69,6 @@ void grpc_init_call(TSRMLS_D);
/* Populates a grpc_metadata_array with the data in a PHP array object.
Returns true on success and false on failure */
bool create_metadata_array(zval *array, grpc_metadata_array *metadata);
-
+void grpc_php_metadata_array_destroy_including_entries(
+ grpc_metadata_array* array);
#endif /* NET_GRPC_PHP_GRPC_CHANNEL_H_ */
diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c
index a395d53614..41c488a79c 100644
--- a/src/php/ext/grpc/call_credentials.c
+++ b/src/php/ext/grpc/call_credentials.c
@@ -120,6 +120,8 @@ PHP_METHOD(CallCredentials, createFromPlugin) {
fci->params, fci->param_count) == FAILURE) {
zend_throw_exception(spl_ce_InvalidArgumentException,
"createFromPlugin expects 1 callback", 1 TSRMLS_CC);
+ free(fci);
+ free(fci_cache);
return;
}
@@ -183,15 +185,17 @@ int plugin_get_metadata(
*status = GRPC_STATUS_OK;
*error_details = NULL;
+ bool should_return = false;
grpc_metadata_array metadata;
if (retval == NULL || Z_TYPE_P(retval) != IS_ARRAY) {
*status = GRPC_STATUS_INVALID_ARGUMENT;
- return true; // Synchronous return.
+ should_return = true; // Synchronous return.
}
if (!create_metadata_array(retval, &metadata)) {
*status = GRPC_STATUS_INVALID_ARGUMENT;
- return true; // Synchronous return.
+ should_return = true; // Synchronous return.
+ grpc_php_metadata_array_destroy_including_entries(&metadata);
}
if (retval != NULL) {
@@ -204,6 +208,9 @@ int plugin_get_metadata(
PHP_GRPC_FREE_STD_ZVAL(retval);
#endif
}
+ if (should_return) {
+ return true;
+ }
if (metadata.count > GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX) {
*status = GRPC_STATUS_INTERNAL;
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index db59869c7f..4054723b43 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -41,6 +41,7 @@
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
#include "completion_queue.h"
#include "channel_credentials.h"
@@ -56,22 +57,63 @@ int le_plink;
/* Frees and destroys an instance of wrapped_grpc_channel */
PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_channel)
+ bool is_last_wrapper = false;
+ // In_persistent_list is used when the user don't close the channel.
+ // In this case, le in the list won't be freed.
+ bool in_persistent_list = true;
if (p->wrapper != NULL) {
gpr_mu_lock(&p->wrapper->mu);
if (p->wrapper->wrapped != NULL) {
- php_grpc_zend_resource *rsrc;
- php_grpc_int key_len = strlen(p->wrapper->key);
- // only destroy the channel here if not found in the persistent list
- gpr_mu_lock(&global_persistent_list_mu);
- if (!(PHP_GRPC_PERSISTENT_LIST_FIND(&EG(persistent_list), p->wrapper->key,
- key_len, rsrc))) {
- grpc_channel_destroy(p->wrapper->wrapped);
- free(p->wrapper->target);
- free(p->wrapper->args_hashstr);
+ if (p->wrapper->is_valid) {
+ php_grpc_zend_resource *rsrc;
+ php_grpc_int key_len = strlen(p->wrapper->key);
+ // only destroy the channel here if not found in the persistent list
+ gpr_mu_lock(&global_persistent_list_mu);
+ if (!(PHP_GRPC_PERSISTENT_LIST_FIND(&EG(persistent_list), p->wrapper->key,
+ key_len, rsrc))) {
+ in_persistent_list = false;
+ grpc_channel_destroy(p->wrapper->wrapped);
+ free(p->wrapper->target);
+ free(p->wrapper->args_hashstr);
+ if(p->wrapper->creds_hashstr != NULL){
+ free(p->wrapper->creds_hashstr);
+ p->wrapper->creds_hashstr = NULL;
+ }
+ }
+ gpr_mu_unlock(&global_persistent_list_mu);
}
- gpr_mu_unlock(&global_persistent_list_mu);
+ }
+ p->wrapper->ref_count -= 1;
+ if (p->wrapper->ref_count == 0) {
+ is_last_wrapper = true;
}
gpr_mu_unlock(&p->wrapper->mu);
+ if (is_last_wrapper) {
+ if (in_persistent_list) {
+ // If ref_count==0 and the key still in the list, it means the user
+ // don't call channel->close().persistent list should free the
+ // allocation in such case, as well as related wrapped channel.
+ if (p->wrapper->wrapped != NULL) {
+ gpr_mu_lock(&p->wrapper->mu);
+ grpc_channel_destroy(p->wrapper->wrapped);
+ free(p->wrapper->target);
+ free(p->wrapper->args_hashstr);
+ if(p->wrapper->creds_hashstr != NULL){
+ free(p->wrapper->creds_hashstr);
+ p->wrapper->creds_hashstr = NULL;
+ }
+ p->wrapper->wrapped = NULL;
+ php_grpc_delete_persistent_list_entry(p->wrapper->key,
+ strlen(p->wrapper->key)
+ TSRMLS_CC);
+ gpr_mu_unlock(&p->wrapper->mu);
+ }
+ }
+ gpr_mu_destroy(&p->wrapper->mu);
+ free(p->wrapper->key);
+ free(p->wrapper);
+ }
+ p->wrapper = NULL;
}
PHP_GRPC_FREE_WRAPPED_FUNC_END()
@@ -276,9 +318,16 @@ PHP_METHOD(Channel, __construct) {
channel->wrapper->key = key;
channel->wrapper->target = strdup(target);
channel->wrapper->args_hashstr = strdup(sha1str);
+ channel->wrapper->creds_hashstr = NULL;
+ channel->wrapper->ref_count = 1;
+ channel->wrapper->is_valid = true;
if (creds != NULL && creds->hashstr != NULL) {
- channel->wrapper->creds_hashstr = creds->hashstr;
+ php_grpc_int creds_hashstr_len = strlen(creds->hashstr);
+ char *channel_creds_hashstr = malloc(creds_hashstr_len + 1);
+ strcpy(channel_creds_hashstr, creds->hashstr);
+ channel->wrapper->creds_hashstr = channel_creds_hashstr;
}
+
gpr_mu_init(&channel->wrapper->mu);
smart_str_free(&buf);
@@ -303,7 +352,17 @@ PHP_METHOD(Channel, __construct) {
channel, target, args, creds, key, key_len TSRMLS_CC);
} else {
efree(args.args);
+ if (channel->wrapper->creds_hashstr != NULL){
+ free(channel->wrapper->creds_hashstr);
+ channel->wrapper->creds_hashstr = NULL;
+ }
+ free(channel->wrapper->creds_hashstr);
+ free(channel->wrapper->key);
+ free(channel->wrapper->target);
+ free(channel->wrapper->args_hashstr);
+ free(channel->wrapper);
channel->wrapper = le->channel;
+ channel->wrapper->ref_count += 1;
}
}
}
@@ -323,7 +382,8 @@ PHP_METHOD(Channel, getTarget) {
}
char *target = grpc_channel_get_target(channel->wrapper->wrapped);
gpr_mu_unlock(&channel->wrapper->mu);
- PHP_GRPC_RETURN_STRING(target, 1);
+ PHP_GRPC_RETVAL_STRING(target, 1);
+ gpr_free(target);
}
/**
@@ -411,18 +471,46 @@ PHP_METHOD(Channel, watchConnectivityState) {
*/
PHP_METHOD(Channel, close) {
wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis());
- gpr_mu_lock(&channel->wrapper->mu);
- if (channel->wrapper->wrapped != NULL) {
- grpc_channel_destroy(channel->wrapper->wrapped);
- free(channel->wrapper->target);
- free(channel->wrapper->args_hashstr);
- channel->wrapper->wrapped = NULL;
-
- php_grpc_delete_persistent_list_entry(channel->wrapper->key,
- strlen(channel->wrapper->key)
- TSRMLS_CC);
+ bool is_last_wrapper = false;
+ if (channel->wrapper != NULL) {
+ // Channel_wrapper hasn't call close before.
+ gpr_mu_lock(&channel->wrapper->mu);
+ if (channel->wrapper->wrapped != NULL) {
+ if (channel->wrapper->is_valid) {
+ // Wrapped channel hasn't been destoryed by other wrapper.
+ grpc_channel_destroy(channel->wrapper->wrapped);
+ free(channel->wrapper->target);
+ free(channel->wrapper->args_hashstr);
+ if(channel->wrapper->creds_hashstr != NULL){
+ free(channel->wrapper->creds_hashstr);
+ channel->wrapper->creds_hashstr = NULL;
+ }
+ channel->wrapper->wrapped = NULL;
+ channel->wrapper->is_valid = false;
+
+ php_grpc_delete_persistent_list_entry(channel->wrapper->key,
+ strlen(channel->wrapper->key)
+ TSRMLS_CC);
+ }
+ }
+ channel->wrapper->ref_count -= 1;
+ if(channel->wrapper->ref_count == 0){
+ // Mark that the wrapper can be freed because mu should be
+ // destroyed outside the lock.
+ is_last_wrapper = true;
+ }
+ gpr_mu_unlock(&channel->wrapper->mu);
}
- gpr_mu_unlock(&channel->wrapper->mu);
+ gpr_mu_lock(&global_persistent_list_mu);
+ if (is_last_wrapper) {
+ gpr_mu_destroy(&channel->wrapper->mu);
+ free(channel->wrapper->key);
+ free(channel->wrapper);
+ }
+ // Set channel->wrapper to NULL to avoid call close twice for the same
+ // channel.
+ channel->wrapper = NULL;
+ gpr_mu_unlock(&global_persistent_list_mu);
}
// Delete an entry from the persistent list
@@ -437,6 +525,7 @@ void php_grpc_delete_persistent_list_entry(char *key, php_grpc_int key_len
le = (channel_persistent_le_t *)rsrc->ptr;
le->channel = NULL;
php_grpc_zend_hash_del(&EG(persistent_list), key, key_len+1);
+ free(le);
}
gpr_mu_unlock(&global_persistent_list_mu);
}
diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h
index 69adc4782c..86bfdea51a 100755
--- a/src/php/ext/grpc/channel.h
+++ b/src/php/ext/grpc/channel.h
@@ -40,6 +40,11 @@ typedef struct _grpc_channel_wrapper {
char *args_hashstr;
char *creds_hashstr;
gpr_mu mu;
+ // is_valid is used to check the wrapped channel has been freed
+ // before to avoid double free.
+ bool is_valid;
+ // ref_count is used to let the last wrapper free related channel and key.
+ size_t ref_count;
} grpc_channel_wrapper;
/* Wrapper struct for grpc_channel that can be associated with a PHP object */
diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c
index d120d6e90f..624d7cc75c 100644
--- a/src/php/ext/grpc/channel_credentials.c
+++ b/src/php/ext/grpc/channel_credentials.c
@@ -57,8 +57,13 @@ static grpc_ssl_roots_override_result get_ssl_roots_override(
/* Frees and destroys an instance of wrapped_grpc_channel_credentials */
PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_channel_credentials)
+ if (p->hashstr != NULL) {
+ free(p->hashstr);
+ p->hashstr = NULL;
+ }
if (p->wrapped != NULL) {
grpc_channel_credentials_release(p->wrapped);
+ p->wrapped = NULL;
}
PHP_GRPC_FREE_WRAPPED_FUNC_END()
@@ -152,7 +157,7 @@ PHP_METHOD(ChannelCredentials, createSsl) {
}
php_grpc_int hashkey_len = root_certs_length + cert_chain_length;
- char *hashkey = emalloc(hashkey_len);
+ char *hashkey = emalloc(hashkey_len + 1);
if (root_certs_length > 0) {
strcpy(hashkey, pem_root_certs);
}
@@ -199,8 +204,13 @@ PHP_METHOD(ChannelCredentials, createComposite) {
grpc_channel_credentials *creds =
grpc_composite_channel_credentials_create(cred1->wrapped, cred2->wrapped,
NULL);
+ // wrapped_grpc_channel_credentials object should keeps it's own
+ // allocation. Otherwise it conflicts free hashstr with call.c.
+ php_grpc_int cred1_len = strlen(cred1->hashstr);
+ char *cred1_hashstr = malloc(cred1_len+1);
+ strcpy(cred1_hashstr, cred1->hashstr);
zval *creds_object =
- grpc_php_wrap_channel_credentials(creds, cred1->hashstr, true
+ grpc_php_wrap_channel_credentials(creds, cred1_hashstr, true
TSRMLS_CC);
RETURN_DESTROY_ZVAL(creds_object);
}
diff --git a/src/php/ext/grpc/php7_wrapper.h b/src/php/ext/grpc/php7_wrapper.h
index 96091f9dad..2f4a53611c 100644
--- a/src/php/ext/grpc/php7_wrapper.h
+++ b/src/php/ext/grpc/php7_wrapper.h
@@ -33,6 +33,7 @@
#define php_grpc_add_next_index_stringl(data, str, len, b) \
add_next_index_stringl(data, str, len, b)
+#define PHP_GRPC_RETVAL_STRING(val, dup) RETVAL_STRING(val, dup)
#define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val, dup)
#define PHP_GRPC_MAKE_STD_ZVAL(pzv) MAKE_STD_ZVAL(pzv)
#define PHP_GRPC_FREE_STD_ZVAL(pzv)
@@ -145,6 +146,7 @@ static inline int php_grpc_zend_hash_find(HashTable *ht, char *key, int len,
#define php_grpc_add_next_index_stringl(data, str, len, b) \
add_next_index_stringl(data, str, len)
+#define PHP_GRPC_RETVAL_STRING(val, dup) RETVAL_STRING(val)
#define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val)
#define PHP_GRPC_MAKE_STD_ZVAL(pzv) \
pzv = (zval *)emalloc(sizeof(zval));
diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c
index 0f2c5b8114..5971babc00 100644
--- a/src/php/ext/grpc/php_grpc.c
+++ b/src/php/ext/grpc/php_grpc.c
@@ -253,7 +253,8 @@ PHP_MSHUTDOWN_FUNCTION(grpc) {
*/
PHP_MINFO_FUNCTION(grpc) {
php_info_print_table_start();
- php_info_print_table_header(2, "grpc support", "enabled");
+ php_info_print_table_row(2, "grpc support", "enabled");
+ php_info_print_table_row(2, "grpc module version", PHP_GRPC_VERSION);
php_info_print_table_end();
/* Remove comments if you have entries in php.ini
diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h
index 48131d72d1..408f2a4765 100644
--- a/src/php/ext/grpc/version.h
+++ b/src/php/ext/grpc/version.h
@@ -20,6 +20,6 @@
#ifndef VERSION_H
#define VERSION_H
-#define PHP_GRPC_VERSION "1.9.0dev"
+#define PHP_GRPC_VERSION "1.10.0dev"
#endif /* VERSION_H */
diff --git a/src/proto/grpc/testing/control.proto b/src/proto/grpc/testing/control.proto
index 2ff2e4e8a2..57592662c4 100644
--- a/src/proto/grpc/testing/control.proto
+++ b/src/proto/grpc/testing/control.proto
@@ -108,6 +108,9 @@ message ClientConfig {
// Number of messages on a stream before it gets finished/restarted
int32 messages_per_stream = 18;
+
+ // Use coalescing API when possible.
+ bool use_coalesce_api = 19;
}
message ClientStatus { ClientStats stats = 1; }
diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py
index 993c49d4af..6032828c77 100644
--- a/src/python/grpcio/grpc/_grpcio_metadata.py
+++ b/src/python/grpcio/grpc/_grpcio_metadata.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
-__version__ = """1.9.0.dev0"""
+__version__ = """1.10.0.dev0"""
diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py
index 56a280624f..d029472c68 100644
--- a/src/python/grpcio/grpc/_interceptor.py
+++ b/src/python/grpcio/grpc/_interceptor.py
@@ -51,6 +51,30 @@ class _ClientCallDetails(
pass
+def _unwrap_client_call_details(call_details, default_details):
+ try:
+ method = call_details.method
+ except AttributeError:
+ method = default_details.method
+
+ try:
+ timeout = call_details.timeout
+ except AttributeError:
+ timeout = default_details.timeout
+
+ try:
+ metadata = call_details.metadata
+ except AttributeError:
+ metadata = default_details.metadata
+
+ try:
+ credentials = call_details.credentials
+ except AttributeError:
+ credentials = default_details.credentials
+
+ return method, timeout, metadata, credentials
+
+
class _LocalFailure(grpc.RpcError, grpc.Future, grpc.Call):
def __init__(self, exception, traceback):
@@ -126,15 +150,18 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
def future(self, request, timeout=None, metadata=None, credentials=None):
- def continuation(client_call_details, request):
- return self._thunk(client_call_details.method).future(
- request,
- timeout=client_call_details.timeout,
- metadata=client_call_details.metadata,
- credentials=client_call_details.credentials)
-
client_call_details = _ClientCallDetails(self._method, timeout,
metadata, credentials)
+
+ def continuation(new_details, request):
+ new_method, new_timeout, new_metadata, new_credentials = (
+ _unwrap_client_call_details(new_details, client_call_details))
+ return self._thunk(new_method).future(
+ request,
+ timeout=new_timeout,
+ metadata=new_metadata,
+ credentials=new_credentials)
+
try:
return self._interceptor.intercept_unary_unary(
continuation, client_call_details, request)
@@ -150,16 +177,18 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
self._interceptor = interceptor
def __call__(self, request, timeout=None, metadata=None, credentials=None):
+ client_call_details = _ClientCallDetails(self._method, timeout,
+ metadata, credentials)
- def continuation(client_call_details, request):
- return self._thunk(client_call_details.method)(
+ def continuation(new_details, request):
+ new_method, new_timeout, new_metadata, new_credentials = (
+ _unwrap_client_call_details(new_details, client_call_details))
+ return self._thunk(new_method)(
request,
- timeout=client_call_details.timeout,
- metadata=client_call_details.metadata,
- credentials=client_call_details.credentials)
+ timeout=new_timeout,
+ metadata=new_metadata,
+ credentials=new_credentials)
- client_call_details = _ClientCallDetails(self._method, timeout,
- metadata, credentials)
try:
return self._interceptor.intercept_unary_stream(
continuation, client_call_details, request)
@@ -203,17 +232,18 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
timeout=None,
metadata=None,
credentials=None):
-
- def continuation(client_call_details, request_iterator):
- return self._thunk(client_call_details.method).future(
- request_iterator,
- timeout=client_call_details.timeout,
- metadata=client_call_details.metadata,
- credentials=client_call_details.credentials)
-
client_call_details = _ClientCallDetails(self._method, timeout,
metadata, credentials)
+ def continuation(new_details, request_iterator):
+ new_method, new_timeout, new_metadata, new_credentials = (
+ _unwrap_client_call_details(new_details, client_call_details))
+ return self._thunk(new_method).future(
+ request_iterator,
+ timeout=new_timeout,
+ metadata=new_metadata,
+ credentials=new_credentials)
+
try:
return self._interceptor.intercept_stream_unary(
continuation, client_call_details, request_iterator)
@@ -233,17 +263,18 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
timeout=None,
metadata=None,
credentials=None):
-
- def continuation(client_call_details, request_iterator):
- return self._thunk(client_call_details.method)(
- request_iterator,
- timeout=client_call_details.timeout,
- metadata=client_call_details.metadata,
- credentials=client_call_details.credentials)
-
client_call_details = _ClientCallDetails(self._method, timeout,
metadata, credentials)
+ def continuation(new_details, request_iterator):
+ new_method, new_timeout, new_metadata, new_credentials = (
+ _unwrap_client_call_details(new_details, client_call_details))
+ return self._thunk(new_method)(
+ request_iterator,
+ timeout=new_timeout,
+ metadata=new_metadata,
+ credentials=new_credentials)
+
try:
return self._interceptor.intercept_stream_stream(
continuation, client_call_details, request_iterator)
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index 1fac57b03a..a654eb026a 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
-VERSION = '1.9.0.dev0'
+VERSION = '1.10.0.dev0'
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index 5b7e5859bc..d3185c6972 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
-VERSION = '1.9.0.dev0'
+VERSION = '1.10.0.dev0'
diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py
index 0ad9621154..7203d0d321 100644
--- a/src/python/grpcio_reflection/grpc_version.py
+++ b/src/python/grpcio_reflection/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
-VERSION = '1.9.0.dev0'
+VERSION = '1.10.0.dev0'
diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py
index 0eb5fbf94d..bf9e55e10e 100644
--- a/src/python/grpcio_testing/grpc_version.py
+++ b/src/python/grpcio_testing/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!!
-VERSION = '1.9.0.dev0'
+VERSION = '1.10.0.dev0'
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index b1b4d7e0c2..2583e42016 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
-VERSION = '1.9.0.dev0'
+VERSION = '1.10.0.dev0'
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index 555168c3bb..d701d2f571 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -583,7 +583,7 @@ extern gpr_free_type gpr_free_import;
typedef void*(*gpr_realloc_type)(void* p, size_t size);
extern gpr_realloc_type gpr_realloc_import;
#define gpr_realloc gpr_realloc_import
-typedef void*(*gpr_malloc_aligned_type)(size_t size, size_t alignment_log);
+typedef void*(*gpr_malloc_aligned_type)(size_t size, size_t alignment);
extern gpr_malloc_aligned_type gpr_malloc_aligned_import;
#define gpr_malloc_aligned gpr_malloc_aligned_import
typedef void(*gpr_free_aligned_type)(void* ptr);
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index be1412511a..9d9f2f4968 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -14,5 +14,5 @@
# GRPC contains the General RPC module.
module GRPC
- VERSION = '1.9.0.dev'
+ VERSION = '1.10.0.dev'
end
diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb
index 48aad39e08..2682294bd2 100644
--- a/src/ruby/tools/version.rb
+++ b/src/ruby/tools/version.rb
@@ -14,6 +14,6 @@
module GRPC
module Tools
- VERSION = '1.9.0.dev'
+ VERSION = '1.10.0.dev'
end
end
diff --git a/summerofcode/ideas.md b/summerofcode/ideas.md
index 49991f0c75..d89bc372cc 100644
--- a/summerofcode/ideas.md
+++ b/summerofcode/ideas.md
@@ -11,37 +11,26 @@ to know the gRPC code and team!
**Required skills for all projects:** git version control, collaborative
software development on github.com, and software development in at least one
-of gRPC's ten languages on at least one of Linux, Mac OS X, and Windows.
+of gRPC's ten languages on at least one of Linux, macOS, and Windows.
-------------------------------------
-gRPC C Core:
+gRPC Core:
-1. Port gRPC to one of the major BSD platforms ([FreeBSD](https://freebsd.org), [NetBSD](https://netbsd.org), and [OpenBSD](https://openbsd.org)) and create packages for them. Add [kqueue](https://www.freebsd.org/cgi/man.cgi?query=kqueue) support in the process.
- * **Required skills:** C programming language, BSD operating system.
- * **Likely mentors:** [Nicolas Noble](https://github.com/nicolasnoble),
- [Vijay Pai](https://github.com/vjpai).
+1. Implement ["early OK" semantics](https://github.com/grpc/grpc/issues/7032). The gRPC wire protocol allows servers to complete an RPC with OK status without having processed all requests ever sent to the client; it's the gRPC Core that currently restricts applications from so behaving. This behavioral gap in the gRPC Core should be filled in.
+ * **Required skills:** C programming language, C++ programming language.
+ * **Likely mentors:** [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Nicolas Noble](https://github.com/nicolasnoble).
+1. [Make channel-connectivity-watching cancellable](https://github.com/grpc/grpc/issues/3064). Anything worth waiting for is worth cancelling. The fact that channel connectivity is currently poll-based means that clean shutdown of gRPC channels can take as long as the poll interval. No one should have to wait two hundred milliseconds to garbage-collect an object.
+ * **Required skills:** C programming language, C++ programming language, Python programming language.
+ * **Likely mentors:** [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Vijay Pai](https://github.com/vjpai).
gRPC Python:
-1. Port gRPC Python to [PyPy](http://pypy.org). Investigate the state of [Cython support](http://docs.cython.org/src/userguide/pypy.html) to do this or potentially explore [cffi](https://cffi.readthedocs.org/en/latest/).
- * **Required skills:** Python programming language, PyPy Python interpreter.
- * **Likely mentors:** [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Masood Malekghassemi](https://github.com/soltanmm).
-1. Develop and test Python 3.5 Support for gRPC. Make necessary changes to port gRPC and package it for supported platforms.
- * **Required skills:** Python programming language, Python 3.5 interpreter.
- * **Likely mentors:** [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Masood Malekghassemi](https://github.com/soltanmm).
+1. Support static type-checking of both gRPC Python itself and of code that uses gRPC Python. No one likes dynamic typing and Python is finally outgrowing it! There are probably errors in the implementation of gRPC Python that [pytype](https://github.com/google/pytype) or [mypy](http://mypy-lang.org/) could detect. There are certainly errors in other code that uses gRPC Python that they could detect.
+ * **Required skills:** Python programming language, open source development across multiple repositories and projects.
+ * **Likely mentors:** [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Kailash Sethuraman](https://github.com/hsaliak), [Ken Payson](https://github.com/kpayson64), [Mehrdad Afshari](https://github.com/mehrdada).
-gRPC Ruby/Java:
-
-1. [jRuby](http://jruby.org) support for gRPC. Develop a jRuby wrapper for gRPC based on grpc-java and ensure that it is API compatible with the existing Ruby implementation and passes all tests.
- * **Required skills:** Java programming language, Ruby programming language.
- * **Likely mentors:** [Michael Lumish](https://github.com/murgatroid99), [Eric Anderson](https://github.com/ejona86).
-
-
-gRPC Wire Protocol:
-
-1. Develop a [Wireshark](https://wireshark.org) plugin for the gRPC protocol. Provide documentation and tutorials for this plugin.
- * **Bonus:** consider set-up and use with mobile clients.
- * **Required skills:** Wireshark software.
- * **Likely mentors:** [Nicolas Noble](https://github.com/nicolasnoble).
+1. [Enable building of gRPC Python with Bazel](https://github.com/grpc/grpc/issues/8079). Bazel is the designated replacement for our constellation of crufty build scripts, but it's still under active development itself. Up for a challenge? gRPC Python could easily be the most complex codebase to be built with Bazel.
+ * **Required skills:** Python programming language, Bazel toolchain, Cython, open source development across multiple repositories and projects.
+ * **Likely mentors:** [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Ken Payson](https://github.com/kpayson64), [Mehrdad Afshari](https://github.com/mehrdada).
diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template
new file mode 100644
index 0000000000..78adb27915
--- /dev/null
+++ b/templates/gRPC-C++.podspec.template
@@ -0,0 +1,193 @@
+%YAML 1.2
+--- |
+ # This file has been automatically generated from a template file.
+ # Please make modifications to `templates/gRPC-C++.podspec.template`
+ # instead. This file can be regenerated from the template by running
+ # `tools/buildgen/generate_projects.sh`.
+
+ # gRPC C++ CocoaPods podspec
+ #
+ # 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.
+
+ <%!
+ def grpc_lib_files(libs, expect_libs, groups):
+ out = []
+ for lib in libs:
+ if lib.name in expect_libs:
+ for group in groups:
+ out += lib.get(group, [])
+ return out
+
+ def grpc_private_files(libs):
+ out = grpc_lib_files(libs, ("grpc", "gpr"), ("headers", "src"))
+ return out
+
+ def grpc_private_headers(libs):
+ out = grpc_lib_files(libs, ("grpc", "gpr"), ("headers",))
+ return out
+
+ def grpc_public_headers(libs):
+ out = grpc_lib_files(libs, ("grpc", "gpr"), ("public_headers",))
+ return out
+
+ def grpcpp_proto_files(filegroups):
+ out = grpc_lib_files(filegroups, ("grpc++_codegen_proto", "grpc++_config_proto"), ("headers", "src", "public_headers"))
+ excl_files = grpc_lib_files(filegroups, ("grpc++_codegen_base",), ("headers", "src", "public_headers"))
+ out = [file for file in out if file not in excl_files]
+ return out
+
+ def grpcpp_private_files(libs, filegroups):
+ out = grpc_lib_files(libs, ("grpc++",), ("headers", "src"))
+ excl_files = grpc_private_files(libs)
+
+ # We exclude proto related files in this particular podspec so that we can provide a protobuf-independent lib
+ excl_files += grpcpp_proto_files(filegroups)
+ out = [file for file in out if file not in excl_files]
+
+ # Since some C++ source files directly included private headers in C core, we include all the
+ # C core headers in C++ Implementation subspec as well.
+ out += [file for file in grpc_private_headers(libs) if not file.startswith("third_party/nanopb/")]
+ return out
+
+ def grpcpp_private_headers(libs, filegroups):
+ out = grpc_lib_files(libs, ("grpc++",), ("headers",))
+
+ # We exclude proto related files in this particular podspec so that we can provide a protobuf-independent lib
+ excl_files = grpcpp_proto_files(filegroups)
+ out = [file for file in out if file not in excl_files]
+
+ # Since some C++ source files directly included private headers in C core, we intentionally
+ # keep the C core headers in \a out. But we should exclude nanopb headers.
+ out = [file for file in out if not file.startswith("third_party/nanopb/")]
+ return out
+
+ def grpcpp_public_headers(libs, filegroups):
+ out = grpc_lib_files(libs, ("grpc++",), ("public_headers",))
+ excl_files = grpc_public_headers(libs)
+
+ # We exclude proto related files in this particular podspec so that we can provide a protobuf-independent lib
+ excl_files += grpcpp_proto_files(filegroups)
+
+ out = [file for file in out if file not in excl_files]
+ return out
+
+ def grpc_test_util_files(libs):
+ out = grpc_lib_files(libs, ("grpc_test_util", "gpr_test_util"), ("src", "headers"))
+ return out
+
+ def grpc_test_util_headers(libs):
+ out = grpc_lib_files(libs, ("grpc_test_util", "gpr_test_util"), ("headers",))
+ return out
+
+ def grpcpp_test_util_files(libs, filegroups):
+ out = grpc_lib_files(libs, ("grpc++_test_util",), ("src", "headers"))
+ excl_files = grpc_test_util_files(libs) + grpcpp_private_files(libs, filegroups)
+
+ # We exclude proto related files in this particular podspec so that we can provide a protobuf-independent lib
+ excl_files += grpc_lib_files(filegroups, ("grpc++_codegen_proto", "grpc++_config_proto"), ("headers", "src"))
+ excl_files += ["test/cpp/util/byte_buffer_proto_helper.cc",
+ "test/cpp/util/byte_buffer_proto_helper.h",
+ "test/cpp/end2end/test_service_impl.cc",
+ "test/cpp/end2end/test_service_impl.h"]
+ excl_files += [file for file in out if file.endswith(".proto")]
+
+ out = [file for file in out if not file in excl_files]
+
+ # Since some C++ test files directly included private headers in C core, we intentionally add these header
+ # files to this subspec
+ out += grpc_test_util_headers(libs)
+
+ return out
+
+ def ruby_multiline_list(files, indent):
+ return (',\n' + indent*' ').join('\'%s\'' % f for f in files)
+ %>
+ Pod::Spec.new do |s|
+ s.name = 'gRPC-C++'
+ # TODO (mxyan): use version that match gRPC version when pod is stabilized
+ # version = '${settings.version}'
+ version = '0.0.1'
+ s.version = version
+ s.summary = 'gRPC C++ library'
+ s.homepage = 'https://grpc.io'
+ s.license = 'Apache License, Version 2.0'
+ s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' }
+
+ grpc_version = '${settings.version}'
+
+ s.source = {
+ :git => 'https://github.com/grpc/grpc.git',
+ :tag => "v#{grpc_version}",
+ }
+
+ s.ios.deployment_target = '7.0'
+ s.osx.deployment_target = '10.9'
+ s.requires_arc = false
+
+ # Add include prefix `grpc++` (i.e. `#include <grpc++/xxx.h>`).
+ s.header_dir = 'grpc++'
+
+ s.pod_target_xcconfig = {
+ 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(PODS_TARGET_SRCROOT)/include"',
+ 'USER_HEADER_SEARCH_PATHS' => '"$(PODS_TARGET_SRCROOT)"',
+ 'GCC_PREPROCESSOR_DEFINITIONS' => '"$(inherited)" "COCOAPODS=1" "PB_NO_PACKED_STRUCTS=1"',
+ 'CLANG_WARN_STRICT_PROTOTYPES' => 'NO',
+ 'CLANG_WARN_DOCUMENTATION_COMMENTS' => 'NO',
+
+ # If we don't set these two settings, `include/grpc/support/time.h` and
+ # `src/core/lib/support/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
+ # build.
+ 'USE_HEADERMAP' => 'NO',
+ 'ALWAYS_SEARCH_USER_PATHS' => 'NO',
+ }
+
+ s.libraries = 'c++'
+
+ s.default_subspecs = 'Interface', 'Implementation'
+
+ s.subspec 'Interface' do |ss|
+ ss.header_mappings_dir = 'include/grpc++'
+
+ ss.source_files = ${ruby_multiline_list(grpcpp_public_headers(libs, filegroups), 22)}
+ end
+
+ s.subspec 'Implementation' do |ss|
+ ss.header_mappings_dir = '.'
+ ss.dependency "#{s.name}/Interface", version
+ ss.dependency 'gRPC-Core', grpc_version
+ ss.dependency 'nanopb', '~> 0.3'
+
+ ss.source_files = ${ruby_multiline_list(grpcpp_private_files(libs, filegroups), 22)}
+
+ ss.private_header_files = ${ruby_multiline_list(grpcpp_private_headers(libs, filegroups), 30)}
+ end
+
+ s.subspec 'Tests' do |ss|
+ ss.header_mappings_dir = '.'
+
+ ss.dependency "#{s.name}/Interface", version
+ ss.dependency "#{s.name}/Implementation", version
+ ss.dependency "gRPC-Core/Tests", grpc_version
+
+ ss.source_files = ${ruby_multiline_list(grpcpp_test_util_files(libs, filegroups), 22)}
+ end
+
+ s.prepare_command = <<-END_OF_COMMAND
+ find src/cpp/ -type f -exec sed -E -i'.back' 's;#include "third_party/nanopb/(.*)";#include <nanopb/\\1>;g' {} \\\;
+ find src/cpp/ -name "*.back" -type f -delete
+ find src/core/ -regex ".*\.h" -type f -exec sed -E -i'.back' 's;#include "third_party/nanopb/(.*)";#include <nanopb/\\1>;g' {} \\\;
+ find src/core/ -name "*.back" -type f -delete
+ END_OF_COMMAND
+ end
diff --git a/templates/package.xml.template b/templates/package.xml.template
index f10f75b8c0..7f201970b3 100644
--- a/templates/package.xml.template
+++ b/templates/package.xml.template
@@ -12,24 +12,19 @@
<email>grpc-packages@google.com</email>
<active>yes</active>
</lead>
- <date>2017-08-24</date>
+ <date>2018-01-19</date>
<time>16:06:07</time>
<version>
<release>${settings.php_version.php()}</release>
<api>${settings.php_version.php()}</api>
</version>
<stability>
- <release>beta</release>
- <api>beta</api>
+ <release>${settings.php_version.php_stability()}</release>
+ <api>${settings.php_version.php_stability()}</api>
</stability>
<license>Apache 2.0</license>
<notes>
- - Channel are now by default persistent #11878
- - Some bug fixes from 1.4 branch #12109, #12123
- - Fixed hang bug when fork() was used #11814
- - License changed to Apache 2.0
- - Added support for php_namespace option in codegen plugin #11886
- - Updated gRPC C Core library version 1.6
+ - TBD
</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc
index 94cfbdda7e..f23d87ea68 100644
--- a/test/core/end2end/goaway_server_test.cc
+++ b/test/core/end2end/goaway_server_test.cc
@@ -187,7 +187,7 @@ int main(int argc, char** argv) {
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
- op->flags = 0;
+ op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY;
op->reserved = nullptr;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call1, ops,
@@ -263,7 +263,7 @@ int main(int argc, char** argv) {
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
- op->flags = 0;
+ op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY;
op->reserved = nullptr;
op++;
GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call2, ops,
diff --git a/test/core/gpr/alloc_test.cc b/test/core/gpr/alloc_test.cc
index 6074c6e6e7..bf4471c36f 100644
--- a/test/core/gpr/alloc_test.cc
+++ b/test/core/gpr/alloc_test.cc
@@ -16,8 +16,11 @@
*
*/
+#include <string.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+
#include "test/core/util/test_config.h"
static void* fake_malloc(size_t size) { return (void*)size; }
@@ -48,8 +51,19 @@ static void test_custom_allocs() {
gpr_free(i);
}
+static void test_malloc_aligned() {
+ for (size_t size = 1; size <= 256; ++size) {
+ void* ptr = gpr_malloc_aligned(size, 16);
+ GPR_ASSERT(ptr != nullptr);
+ GPR_ASSERT(((intptr_t)ptr & 0xf) == 0);
+ memset(ptr, 0, size);
+ gpr_free_aligned(ptr);
+ }
+}
+
int main(int argc, char** argv) {
grpc_test_init(argc, argv);
test_custom_allocs();
+ test_malloc_aligned();
return 0;
}
diff --git a/test/core/gpr/arena_test.cc b/test/core/gpr/arena_test.cc
index 59ea04c0ed..62a3f8bf50 100644
--- a/test/core/gpr/arena_test.cc
+++ b/test/core/gpr/arena_test.cc
@@ -53,6 +53,8 @@ static void test(const char* name, size_t init_size, const size_t* allocs,
void** ps = static_cast<void**>(gpr_zalloc(sizeof(*ps) * nallocs));
for (size_t i = 0; i < nallocs; i++) {
ps[i] = gpr_arena_alloc(a, allocs[i]);
+ // ensure the returned address is aligned
+ GPR_ASSERT(((intptr_t)ps[i] & 0xf) == 0);
// ensure no duplicate results
for (size_t j = 0; j < i; j++) {
GPR_ASSERT(ps[i] != ps[j]);
diff --git a/test/core/gpr++/BUILD b/test/core/gprpp/BUILD
index 93324a378b..1c11e0bdb5 100644
--- a/test/core/gpr++/BUILD
+++ b/test/core/gprpp/BUILD
@@ -16,7 +16,7 @@ load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_c
licenses(["notice"]) # Apache v2
-grpc_package(name = "test/core/gpr++")
+grpc_package(name = "test/core/gprpp")
grpc_cc_test(
name = "manual_constructor_test",
@@ -24,6 +24,7 @@ grpc_cc_test(
language = "C++",
deps = [
"//:gpr",
+ "//:gpr++_base",
"//test/core/util:gpr_test_util",
],
)
@@ -36,7 +37,7 @@ grpc_cc_test(
],
language = "C++",
deps = [
- "//:grpc",
+ "//:gpr++_base",
"//test/core/util:gpr_test_util",
],
)
@@ -49,7 +50,7 @@ grpc_cc_test(
],
language = "C++",
deps = [
- "//:grpc",
+ "//:inlined_vector",
"//test/core/util:gpr_test_util",
],
)
diff --git a/test/core/gpr++/inlined_vector_test.cc b/test/core/gprpp/inlined_vector_test.cc
index 09d5453a56..0e712dafe4 100644
--- a/test/core/gpr++/inlined_vector_test.cc
+++ b/test/core/gprpp/inlined_vector_test.cc
@@ -16,9 +16,9 @@
*
*/
-#include "src/core/lib/gpr++/inlined_vector.h"
+#include "src/core/lib/gprpp/inlined_vector.h"
#include <gtest/gtest.h>
-#include "src/core/lib/gpr++/memory.h"
+#include "src/core/lib/gprpp/memory.h"
#include "test/core/util/test_config.h"
namespace grpc_core {
diff --git a/test/core/gpr++/manual_constructor_test.cc b/test/core/gprpp/manual_constructor_test.cc
index e049b793f6..f06c3cab06 100644
--- a/test/core/gpr++/manual_constructor_test.cc
+++ b/test/core/gprpp/manual_constructor_test.cc
@@ -18,7 +18,7 @@
/* Test of gpr synchronization support. */
-#include "src/core/lib/gpr++/manual_constructor.h"
+#include "src/core/lib/gprpp/manual_constructor.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
@@ -26,7 +26,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
-#include "src/core/lib/gpr++/abstract.h"
+#include "src/core/lib/gprpp/abstract.h"
#include "test/core/util/test_config.h"
class A {
diff --git a/test/core/gpr++/memory_test.cc b/test/core/gprpp/memory_test.cc
index 3553e119e3..180c36fad7 100644
--- a/test/core/gpr++/memory_test.cc
+++ b/test/core/gprpp/memory_test.cc
@@ -16,7 +16,7 @@
*
*/
-#include "src/core/lib/gpr++/memory.h"
+#include "src/core/lib/gprpp/memory.h"
#include <gtest/gtest.h>
#include "test/core/util/test_config.h"
diff --git a/test/core/gpr++/orphanable_test.cc b/test/core/gprpp/orphanable_test.cc
index 4513d25da1..ff2f6d8bc2 100644
--- a/test/core/gpr++/orphanable_test.cc
+++ b/test/core/gprpp/orphanable_test.cc
@@ -16,11 +16,11 @@
*
*/
-#include "src/core/lib/gpr++/orphanable.h"
+#include "src/core/lib/gprpp/orphanable.h"
#include <gtest/gtest.h>
-#include "src/core/lib/gpr++/memory.h"
+#include "src/core/lib/gprpp/memory.h"
#include "test/core/util/test_config.h"
namespace grpc_core {
diff --git a/test/core/gpr++/ref_counted_ptr_test.cc b/test/core/gprpp/ref_counted_ptr_test.cc
index e897b2859c..f1f13f3183 100644
--- a/test/core/gpr++/ref_counted_ptr_test.cc
+++ b/test/core/gprpp/ref_counted_ptr_test.cc
@@ -16,14 +16,14 @@
*
*/
-#include "src/core/lib/gpr++/ref_counted_ptr.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include <gtest/gtest.h>
#include <grpc/support/log.h>
-#include "src/core/lib/gpr++/memory.h"
-#include "src/core/lib/gpr++/ref_counted.h"
+#include "src/core/lib/gprpp/memory.h"
+#include "src/core/lib/gprpp/ref_counted.h"
#include "test/core/util/test_config.h"
namespace grpc_core {
diff --git a/test/core/gpr++/ref_counted_test.cc b/test/core/gprpp/ref_counted_test.cc
index 568ec51c64..b1b0fee5c0 100644
--- a/test/core/gpr++/ref_counted_test.cc
+++ b/test/core/gprpp/ref_counted_test.cc
@@ -16,11 +16,11 @@
*
*/
-#include "src/core/lib/gpr++/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted.h"
#include <gtest/gtest.h>
-#include "src/core/lib/gpr++/memory.h"
+#include "src/core/lib/gprpp/memory.h"
#include "test/core/util/test_config.h"
namespace grpc_core {
diff --git a/test/cpp/cocoapods/GRPCCppTests.xcodeproj/project.pbxproj b/test/cpp/cocoapods/GRPCCppTests.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..1d332ba7ce
--- /dev/null
+++ b/test/cpp/cocoapods/GRPCCppTests.xcodeproj/project.pbxproj
@@ -0,0 +1,533 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 48;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 2D3F2189E2CDF493639A17C5 /* libPods-test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 99B1FD20127AB0F23D6AB570 /* libPods-test.a */; };
+ 5E63948A1FDB64B50051E9AA /* server_context_test_spouse_test.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5E6394891FDB64B50051E9AA /* server_context_test_spouse_test.mm */; };
+ 5EFA5F731FEDB36700EBF4B7 /* generic.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5EFA5F721FEDB36700EBF4B7 /* generic.mm */; };
+ D0F8FABF3ECF587C207C12F3 /* libPods-generic.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D0872BAEE90C8A149743DB7 /* libPods-generic.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 3D0872BAEE90C8A149743DB7 /* libPods-generic.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-generic.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5E63947F1FDB5EA10051E9AA /* test.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = test.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5E6394831FDB5EA10051E9AA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 5E6394891FDB64B50051E9AA /* server_context_test_spouse_test.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = server_context_test_spouse_test.mm; sourceTree = "<group>"; };
+ 5EFA5F701FEDB36700EBF4B7 /* generic.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = generic.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5EFA5F721FEDB36700EBF4B7 /* generic.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = generic.mm; sourceTree = "<group>"; };
+ 5EFA5F741FEDB36700EBF4B7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 8682448F311EDE94C14D551D /* Pods-test.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-test.release.xcconfig"; path = "Pods/Target Support Files/Pods-test/Pods-test.release.xcconfig"; sourceTree = "<group>"; };
+ 91EDF22ADDE71926C7BC1AF1 /* Pods-test.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-test.debug.xcconfig"; path = "Pods/Target Support Files/Pods-test/Pods-test.debug.xcconfig"; sourceTree = "<group>"; };
+ 99B1FD20127AB0F23D6AB570 /* libPods-test.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-test.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ B357AF2DC912B224C026D114 /* Pods-generic.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-generic.release.xcconfig"; path = "Pods/Target Support Files/Pods-generic/Pods-generic.release.xcconfig"; sourceTree = "<group>"; };
+ D9B4F77163CB9089C4436BF4 /* Pods-generic.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-generic.debug.xcconfig"; path = "Pods/Target Support Files/Pods-generic/Pods-generic.debug.xcconfig"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 5E63947C1FDB5EA10051E9AA /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2D3F2189E2CDF493639A17C5 /* libPods-test.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 5EFA5F6D1FEDB36700EBF4B7 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D0F8FABF3ECF587C207C12F3 /* libPods-generic.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 4439BD4D56FD5738BF780F8E /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 91EDF22ADDE71926C7BC1AF1 /* Pods-test.debug.xcconfig */,
+ 8682448F311EDE94C14D551D /* Pods-test.release.xcconfig */,
+ D9B4F77163CB9089C4436BF4 /* Pods-generic.debug.xcconfig */,
+ B357AF2DC912B224C026D114 /* Pods-generic.release.xcconfig */,
+ );
+ name = Pods;
+ sourceTree = "<group>";
+ };
+ 5E63944B1FDB5D9B0051E9AA = {
+ isa = PBXGroup;
+ children = (
+ 5E63947F1FDB5EA10051E9AA /* test.xctest */,
+ 5E6394801FDB5EA10051E9AA /* test */,
+ 4439BD4D56FD5738BF780F8E /* Pods */,
+ 5EFA5F711FEDB36700EBF4B7 /* generic */,
+ C2E6603B58413BD724AFB400 /* Frameworks */,
+ 5EFA5F701FEDB36700EBF4B7 /* generic.xctest */,
+ );
+ sourceTree = "<group>";
+ };
+ 5E6394801FDB5EA10051E9AA /* test */ = {
+ isa = PBXGroup;
+ children = (
+ 5E6394891FDB64B50051E9AA /* server_context_test_spouse_test.mm */,
+ 5E6394831FDB5EA10051E9AA /* Info.plist */,
+ );
+ path = test;
+ sourceTree = "<group>";
+ };
+ 5EFA5F711FEDB36700EBF4B7 /* generic */ = {
+ isa = PBXGroup;
+ children = (
+ 5EFA5F721FEDB36700EBF4B7 /* generic.mm */,
+ 5EFA5F741FEDB36700EBF4B7 /* Info.plist */,
+ );
+ path = generic;
+ sourceTree = "<group>";
+ };
+ C2E6603B58413BD724AFB400 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 99B1FD20127AB0F23D6AB570 /* libPods-test.a */,
+ 3D0872BAEE90C8A149743DB7 /* libPods-generic.a */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 5E63947E1FDB5EA10051E9AA /* test */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 5E6394841FDB5EA10051E9AA /* Build configuration list for PBXNativeTarget "test" */;
+ buildPhases = (
+ 6D8317CF72F9E252442662F8 /* [CP] Check Pods Manifest.lock */,
+ 5E63947B1FDB5EA10051E9AA /* Sources */,
+ 5E63947C1FDB5EA10051E9AA /* Frameworks */,
+ 5E63947D1FDB5EA10051E9AA /* Resources */,
+ B972D278DA2A2BF12386177C /* [CP] Embed Pods Frameworks */,
+ 3C2FE7A8DBA8BBCB2923B173 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = test;
+ productName = test;
+ productReference = 5E63947F1FDB5EA10051E9AA /* test.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 5EFA5F6F1FEDB36700EBF4B7 /* generic */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 5EFA5F751FEDB36700EBF4B7 /* Build configuration list for PBXNativeTarget "generic" */;
+ buildPhases = (
+ 4844599DC62113265AB660B3 /* [CP] Check Pods Manifest.lock */,
+ 5EFA5F6C1FEDB36700EBF4B7 /* Sources */,
+ 5EFA5F6D1FEDB36700EBF4B7 /* Frameworks */,
+ 5EFA5F6E1FEDB36700EBF4B7 /* Resources */,
+ 11E4716E0919C734CC6AA8C2 /* [CP] Embed Pods Frameworks */,
+ 9E149E84C3AA06289FE1F244 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = generic;
+ productName = generic;
+ productReference = 5EFA5F701FEDB36700EBF4B7 /* generic.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 5E63944C1FDB5D9B0051E9AA /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0910;
+ ORGANIZATIONNAME = gRPC;
+ TargetAttributes = {
+ 5E63947E1FDB5EA10051E9AA = {
+ CreatedOnToolsVersion = 9.1;
+ ProvisioningStyle = Automatic;
+ };
+ 5EFA5F6F1FEDB36700EBF4B7 = {
+ CreatedOnToolsVersion = 9.2;
+ ProvisioningStyle = Automatic;
+ };
+ };
+ };
+ buildConfigurationList = 5E63944F1FDB5D9B0051E9AA /* Build configuration list for PBXProject "GRPCCppTests" */;
+ compatibilityVersion = "Xcode 8.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 5E63944B1FDB5D9B0051E9AA;
+ productRefGroup = 5E63944B1FDB5D9B0051E9AA;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 5E63947E1FDB5EA10051E9AA /* test */,
+ 5EFA5F6F1FEDB36700EBF4B7 /* generic */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 5E63947D1FDB5EA10051E9AA /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 5EFA5F6E1FEDB36700EBF4B7 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 11E4716E0919C734CC6AA8C2 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-generic/Pods-generic-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 3C2FE7A8DBA8BBCB2923B173 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-test/Pods-test-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 4844599DC62113265AB660B3 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-generic-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 6D8317CF72F9E252442662F8 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-test-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 9E149E84C3AA06289FE1F244 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Copy Pods Resources";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-generic/Pods-generic-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ B972D278DA2A2BF12386177C /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-test/Pods-test-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 5E63947B1FDB5EA10051E9AA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5E63948A1FDB64B50051E9AA /* server_context_test_spouse_test.mm in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 5EFA5F6C1FEDB36700EBF4B7 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5EFA5F731FEDB36700EBF4B7 /* generic.mm in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 5E6394731FDB5D9B0051E9AA /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = ../../../include;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.1;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ USER_HEADER_SEARCH_PATHS = ../../..;
+ };
+ name = Debug;
+ };
+ 5E6394741FDB5D9B0051E9AA /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = ../../../include;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.1;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ USER_HEADER_SEARCH_PATHS = ../../..;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 5E6394851FDB5EA10051E9AA /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 91EDF22ADDE71926C7BC1AF1 /* Pods-test.debug.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = EQHXZ8M8AV;
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"${PODS_ROOT}/Headers/Public\"",
+ "\"${PODS_ROOT}/Headers/Public/BoringSSL\"",
+ "\"${PODS_ROOT}/Headers/Public/gRPC-C++\"",
+ "\"${PODS_ROOT}/Headers/Public/gRPC-Core\"",
+ "\"${PODS_ROOT}/Headers/Public/nanopb\"",
+ );
+ INFOPLIST_FILE = test/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.test;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 5E6394861FDB5EA10051E9AA /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 8682448F311EDE94C14D551D /* Pods-test.release.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = EQHXZ8M8AV;
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ "\"${PODS_ROOT}/Headers/Public\"",
+ "\"${PODS_ROOT}/Headers/Public/BoringSSL\"",
+ "\"${PODS_ROOT}/Headers/Public/gRPC-C++\"",
+ "\"${PODS_ROOT}/Headers/Public/gRPC-Core\"",
+ "\"${PODS_ROOT}/Headers/Public/nanopb\"",
+ );
+ INFOPLIST_FILE = test/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.test;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ 5EFA5F761FEDB36700EBF4B7 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = D9B4F77163CB9089C4436BF4 /* Pods-generic.debug.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = EQHXZ8M8AV;
+ INFOPLIST_FILE = generic/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.generic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 5EFA5F771FEDB36700EBF4B7 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = B357AF2DC912B224C026D114 /* Pods-generic.release.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = EQHXZ8M8AV;
+ INFOPLIST_FILE = generic/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.generic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 5E63944F1FDB5D9B0051E9AA /* Build configuration list for PBXProject "GRPCCppTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5E6394731FDB5D9B0051E9AA /* Debug */,
+ 5E6394741FDB5D9B0051E9AA /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 5E6394841FDB5EA10051E9AA /* Build configuration list for PBXNativeTarget "test" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5E6394851FDB5EA10051E9AA /* Debug */,
+ 5E6394861FDB5EA10051E9AA /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 5EFA5F751FEDB36700EBF4B7 /* Build configuration list for PBXNativeTarget "generic" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5EFA5F761FEDB36700EBF4B7 /* Debug */,
+ 5EFA5F771FEDB36700EBF4B7 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 5E63944C1FDB5D9B0051E9AA /* Project object */;
+}
diff --git a/test/cpp/cocoapods/Podfile b/test/cpp/cocoapods/Podfile
new file mode 100644
index 0000000000..8d8cdaaadd
--- /dev/null
+++ b/test/cpp/cocoapods/Podfile
@@ -0,0 +1,71 @@
+source 'https://github.com/CocoaPods/Specs.git'
+platform :ios, '8.0'
+
+install! 'cocoapods', :deterministic_uuids => false
+
+# Location of gRPC's repo root relative to this file.
+GRPC_LOCAL_SRC = '../../..'
+
+%w(
+ test
+ generic
+).each do |target_name|
+ target target_name do
+ pod 'gRPC-Core', :path => GRPC_LOCAL_SRC
+ pod 'gRPC-Core/Tests', :path => GRPC_LOCAL_SRC
+ pod 'gRPC-C++', :path => GRPC_LOCAL_SRC
+ pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true
+ end
+end
+
+# gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's
+# pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded
+# and before they are installed in the user project.
+#
+# This podspec searches for the gRPC core library headers under "$(PODS_ROOT)/gRPC-Core", where
+# Cocoapods normally places the downloaded sources. When doing local development of the libraries,
+# though, Cocoapods just takes the sources from whatever directory was specified using `:path`, and
+# doesn't copy them under $(PODS_ROOT). When using static libraries, one can sometimes rely on the
+# symbolic links to the pods headers that Cocoapods creates under "$(PODS_ROOT)/Headers". But those
+# aren't created when using dynamic frameworks. So our solution is to modify the podspec on the fly
+# to point at the local directory where the sources are.
+#
+# TODO(jcanizales): Send a PR to Cocoapods to get rid of this need.
+pre_install do |installer|
+ # This is the gRPC-Core podspec object, as initialized by its podspec file.
+ grpc_core_spec = installer.pod_targets.find{|t| t.name == 'gRPC-Core'}.root_spec
+
+ # Copied from gRPC-Core.podspec, except for the adjusted src_root:
+ src_root = "$(PODS_ROOT)/../#{GRPC_LOCAL_SRC}"
+ grpc_core_spec.pod_target_xcconfig = {
+ 'GRPC_SRC_ROOT' => src_root,
+ 'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(GRPC_SRC_ROOT)/include"',
+ 'USER_HEADER_SEARCH_PATHS' => '"$(GRPC_SRC_ROOT)"',
+ # If we don't set these two settings, `include/grpc/support/time.h` and
+ # `src/core/lib/support/string.h` shadow the system `<time.h>` and `<string.h>`, breaking the
+ # build.
+ 'USE_HEADERMAP' => 'NO',
+ 'ALWAYS_SEARCH_USER_PATHS' => 'NO',
+ }
+end
+
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ target.build_configurations.each do |config|
+ config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES'
+ end
+
+ # CocoaPods creates duplicated library targets of gRPC-Core when the test targets include
+ # non-default subspecs of gRPC-Core. All of these library targets start with prefix 'gRPC-Core'
+ # and require the same error suppresion.
+ if target.name.start_with?('gRPC-Core')
+ target.build_configurations.each do |config|
+ # TODO(zyc): Remove this setting after the issue is resolved
+ # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void
+ # function" warning
+ config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO'
+ config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_CRONET_WITH_PACKET_COALESCING=1'
+ end
+ end
+ end
+end
diff --git a/test/cpp/cocoapods/generic/Info.plist b/test/cpp/cocoapods/generic/Info.plist
new file mode 100644
index 0000000000..6c40a6cd0c
--- /dev/null
+++ b/test/cpp/cocoapods/generic/Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
diff --git a/test/cpp/cocoapods/generic/generic.mm b/test/cpp/cocoapods/generic/generic.mm
new file mode 100644
index 0000000000..30b43ec375
--- /dev/null
+++ b/test/cpp/cocoapods/generic/generic.mm
@@ -0,0 +1,244 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import <XCTest/XCTest.h>
+
+#include <sstream>
+
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/generic/async_generic_service.h>
+#include <grpc++/generic/generic_stub.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/support/slice.h>
+#include <grpc/grpc.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
+
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+using std::chrono::system_clock;
+using namespace grpc;
+
+void* tag(int i) { return (void*)(intptr_t)i; }
+
+static grpc_slice merge_slices(grpc_slice* slices, size_t nslices) {
+ size_t i;
+ size_t len = 0;
+ uint8_t* cursor;
+ grpc_slice out;
+
+ for (i = 0; i < nslices; i++) {
+ len += GRPC_SLICE_LENGTH(slices[i]);
+ }
+
+ out = grpc_slice_malloc(len);
+ cursor = GRPC_SLICE_START_PTR(out);
+
+ for (i = 0; i < nslices; i++) {
+ memcpy(cursor, GRPC_SLICE_START_PTR(slices[i]),
+ GRPC_SLICE_LENGTH(slices[i]));
+ cursor += GRPC_SLICE_LENGTH(slices[i]);
+ }
+
+ return out;
+}
+
+int byte_buffer_eq_string(ByteBuffer* bb, const char* str) {
+ int res;
+
+ std::vector<Slice> slices;
+ bb->Dump(&slices);
+ grpc_slice* c_slices = new grpc_slice[slices.size()];
+ for (int i = 0; i < slices.size(); i++) {
+ c_slices[i] = slices[i].c_slice();
+ }
+ grpc_slice a = merge_slices(c_slices, slices.size());
+ grpc_slice b = grpc_slice_from_copied_string(str);
+ res =
+ (GRPC_SLICE_LENGTH(a) == GRPC_SLICE_LENGTH(b)) &&
+ (0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b),
+ GRPC_SLICE_LENGTH(a)));
+ grpc_slice_unref(a);
+ grpc_slice_unref(b);
+ for (int i = 0; i < slices.size(); i++) {
+ grpc_slice_unref(c_slices[i]);
+ }
+ delete [] c_slices;
+
+ return res;
+}
+
+@interface GenericTest : XCTestCase
+
+@end
+
+@implementation GenericTest {
+ grpc::string server_host_;
+ CompletionQueue cli_cq_;
+ std::unique_ptr<ServerCompletionQueue> srv_cq_;
+ std::unique_ptr<GenericStub> generic_stub_;
+ std::unique_ptr<Server> server_;
+ AsyncGenericService generic_service_;
+ std::ostringstream server_address_;
+}
+
+- (void)verify_ok:(grpc::CompletionQueue*)cq
+ i:(int)i
+ expect_ok:(bool)expect_ok {
+ bool ok;
+ void* got_tag;
+ XCTAssertTrue(cq->Next(&got_tag, &ok));
+ XCTAssertEqual(expect_ok, ok);
+ XCTAssertEqual(tag(i), got_tag);
+}
+
+- (void)server_ok:(int)i { [self verify_ok:srv_cq_.get() i:i expect_ok:true]; }
+- (void)client_ok:(int)i { [self verify_ok:&cli_cq_ i:i expect_ok:true]; }
+- (void)server_fail:(int)i { [self verify_ok:srv_cq_.get() i:i expect_ok:false]; }
+- (void)client_fail:(int)i { [self verify_ok:&cli_cq_ i:i expect_ok:false]; }
+
+- (void)setUp {
+ [super setUp];
+
+ server_host_ = "localhost";
+ int port = grpc_pick_unused_port_or_die();
+ server_address_ << server_host_ << ":" << port;
+ // Setup server
+ ServerBuilder builder;
+ builder.AddListeningPort(server_address_.str(),
+ InsecureServerCredentials());
+ builder.RegisterAsyncGenericService(&generic_service_);
+ // Include a second call to RegisterAsyncGenericService to make sure that
+ // we get an error in the log, since it is not allowed to have 2 async
+ // generic services
+ builder.RegisterAsyncGenericService(&generic_service_);
+ srv_cq_ = builder.AddCompletionQueue();
+ server_ = builder.BuildAndStart();
+}
+
+- (void)tearDown {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ server_->Shutdown();
+ void* ignored_tag;
+ bool ignored_ok;
+ cli_cq_.Shutdown();
+ srv_cq_->Shutdown();
+ while (cli_cq_.Next(&ignored_tag, &ignored_ok));
+ while (srv_cq_->Next(&ignored_tag, &ignored_ok));
+ [super tearDown];
+}
+
+- (void)ResetStub {
+ std::shared_ptr<Channel> channel =
+ CreateChannel(server_address_.str(), InsecureChannelCredentials());
+ generic_stub_.reset(new GenericStub(channel));
+}
+
+- (void)SendRpc:(int)num_rpcs {
+ [self SendRpc:num_rpcs check_deadline:false deadline:gpr_inf_future(GPR_CLOCK_MONOTONIC)];
+ }
+
+- (void)SendRpc:(int)num_rpcs
+ check_deadline:(bool)check_deadline
+ deadline:(gpr_timespec)deadline {
+ const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo");
+ for (int i = 0; i < num_rpcs; i++) {
+ Status recv_status;
+
+ ClientContext cli_ctx;
+ GenericServerContext srv_ctx;
+ GenericServerAsyncReaderWriter stream(&srv_ctx);
+
+ // The string needs to be long enough to test heap-based slice.
+ /*send_request.set_message("Hello world. Hello world. Hello world.");*/
+
+ if (check_deadline) {
+ cli_ctx.set_deadline(deadline);
+ }
+
+ std::unique_ptr<GenericClientAsyncReaderWriter> call =
+ generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1));
+ [self client_ok:1];
+ Slice send_slice = Slice("hello world", 11);
+ std::unique_ptr<ByteBuffer> send_buffer =
+ std::unique_ptr<ByteBuffer>(new ByteBuffer(&send_slice, 1));
+ call->Write(*send_buffer, tag(2));
+ // Send ByteBuffer can be destroyed after calling Write.
+ send_buffer.reset();
+ [self client_ok:2];
+ call->WritesDone(tag(3));
+ [self client_ok:3];
+
+ generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(),
+ srv_cq_.get(), tag(4));
+
+ [self verify_ok:srv_cq_.get() i:4 expect_ok:true];
+ XCTAssertEqual(server_host_, srv_ctx.host().substr(0, server_host_.length()));
+ XCTAssertEqual(kMethodName, srv_ctx.method());
+
+ if (check_deadline) {
+ XCTAssertTrue(gpr_time_similar(deadline, srv_ctx.raw_deadline(),
+ gpr_time_from_millis(1000, GPR_TIMESPAN)));
+ }
+
+ ByteBuffer recv_buffer;
+ stream.Read(&recv_buffer, tag(5));
+ [self server_ok:5];
+ XCTAssertTrue(byte_buffer_eq_string(&recv_buffer, "hello world"));
+
+ send_buffer = std::unique_ptr<ByteBuffer>(new ByteBuffer(recv_buffer));
+ stream.Write(*send_buffer, tag(6));
+ send_buffer.reset();
+ [self server_ok:6];
+
+ stream.Finish(Status::OK, tag(7));
+ [self server_ok:7];
+
+ recv_buffer.Clear();
+ call->Read(&recv_buffer, tag(8));
+ [self client_ok:8];
+ XCTAssertTrue(byte_buffer_eq_string(&recv_buffer, "hello world"));
+
+ call->Finish(&recv_status, tag(9));
+ [self client_ok:9];
+
+ XCTAssertTrue(recv_status.ok());
+ }
+}
+
+- (void)testSimpleRpc {
+ [self ResetStub];
+ [self SendRpc:1];
+}
+
+- (void)testSequentialRpcs {
+ [self ResetStub];
+ [self SendRpc:10];
+}
+
++ (void)setUp {
+ grpc_test_init(0, NULL);
+}
+
+@end
+
diff --git a/test/cpp/cocoapods/test/Info.plist b/test/cpp/cocoapods/test/Info.plist
new file mode 100644
index 0000000000..6c40a6cd0c
--- /dev/null
+++ b/test/cpp/cocoapods/test/Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+</dict>
+</plist>
diff --git a/test/cpp/cocoapods/test/server_context_test_spouse_test.mm b/test/cpp/cocoapods/test/server_context_test_spouse_test.mm
new file mode 100644
index 0000000000..fd6878efbf
--- /dev/null
+++ b/test/cpp/cocoapods/test/server_context_test_spouse_test.mm
@@ -0,0 +1,100 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+// Hack TEST macro of gTest and make they conform XCTest style. We only
+// need test name (b), not test case name (a).
+#define TEST(a,b) - (void)test ## b
+#define ASSERT_TRUE XCTAssert
+#define ASSERT_EQ XCTAssertEqual
+
+#import <XCTest/XCTest.h>
+
+#include <grpc++/test/server_context_test_spouse.h>
+
+#include <cstring>
+#include <vector>
+
+#include <grpc++/impl/grpc_library.h>
+
+static grpc::internal::GrpcLibraryInitializer g_initializer;
+
+const char key1[] = "metadata-key1";
+const char key2[] = "metadata-key2";
+const char val1[] = "metadata-val1";
+const char val2[] = "metadata-val2";
+
+bool ClientMetadataContains(const grpc::ServerContext& context,
+ const grpc::string_ref& key,
+ const grpc::string_ref& value) {
+ const auto& client_metadata = context.client_metadata();
+ for (auto iter = client_metadata.begin(); iter != client_metadata.end();
+ ++iter) {
+ if (iter->first == key && iter->second == value) {
+ return true;
+ }
+ }
+ return false;
+}
+
+@interface ServerContextTestSpouseTest : XCTestCase
+
+@end
+
+@implementation ServerContextTestSpouseTest
+
+TEST(ServerContextTestSpouseTest, ClientMetadata) {
+ grpc::ServerContext context;
+ grpc::testing::ServerContextTestSpouse spouse(&context);
+
+ spouse.AddClientMetadata(key1, val1);
+ ASSERT_TRUE(ClientMetadataContains(context, key1, val1));
+
+ spouse.AddClientMetadata(key2, val2);
+ ASSERT_TRUE(ClientMetadataContains(context, key1, val1));
+ ASSERT_TRUE(ClientMetadataContains(context, key2, val2));
+}
+
+TEST(ServerContextTestSpouseTest, InitialMetadata) {
+ grpc::ServerContext context;
+ grpc::testing::ServerContextTestSpouse spouse(&context);
+ std::multimap<grpc::string, grpc::string> metadata;
+
+ context.AddInitialMetadata(key1, val1);
+ metadata.insert(std::pair<grpc::string, grpc::string>(key1, val1));
+ ASSERT_EQ(metadata, spouse.GetInitialMetadata());
+
+ context.AddInitialMetadata(key2, val2);
+ metadata.insert(std::pair<grpc::string, grpc::string>(key2, val2));
+ ASSERT_EQ(metadata, spouse.GetInitialMetadata());
+}
+
+TEST(ServerContextTestSpouseTest, TrailingMetadata) {
+ grpc::ServerContext context;
+ grpc::testing::ServerContextTestSpouse spouse(&context);
+ std::multimap<grpc::string, grpc::string> metadata;
+
+ context.AddTrailingMetadata(key1, val1);
+ metadata.insert(std::pair<grpc::string, grpc::string>(key1, val1));
+ ASSERT_EQ(metadata, spouse.GetTrailingMetadata());
+
+ context.AddTrailingMetadata(key2, val2);
+ metadata.insert(std::pair<grpc::string, grpc::string>(key2, val2));
+ ASSERT_EQ(metadata, spouse.GetTrailingMetadata());
+}
+
+@end
diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD
index 8894c68b95..27e8da1ff1 100644
--- a/test/cpp/end2end/BUILD
+++ b/test/cpp/end2end/BUILD
@@ -120,6 +120,24 @@ grpc_cc_library(
)
grpc_cc_test(
+ name = "server_early_return_test",
+ srcs = ["server_early_return_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//:grpc++",
+ "//src/proto/grpc/testing:echo_messages_proto",
+ "//src/proto/grpc/testing:echo_proto",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ "//test/cpp/util:test_util",
+ ],
+)
+
+grpc_cc_test(
name = "end2end_test",
deps = [
":end2end_test_lib",
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 730bdf1e7e..28887f8128 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -1087,31 +1087,6 @@ TEST_P(End2endTest, RpcMaxMessageSize) {
EXPECT_FALSE(s.ok());
}
-// Client sends 20 requests and the server returns CANCELLED status after
-// reading 10 requests.
-TEST_P(End2endTest, RequestStreamServerEarlyCancelTest) {
- ResetStub();
- EchoRequest request;
- EchoResponse response;
- ClientContext context;
-
- context.AddMetadata(kServerCancelAfterReads, "10");
- auto stream = stub_->RequestStream(&context, &response);
- request.set_message("hello");
- int send_messages = 20;
- while (send_messages > 10) {
- EXPECT_TRUE(stream->Write(request));
- send_messages--;
- }
- while (send_messages > 0) {
- stream->Write(request);
- send_messages--;
- }
- stream->WritesDone();
- Status s = stream->Finish();
- EXPECT_EQ(s.error_code(), StatusCode::CANCELLED);
-}
-
void ReaderThreadFunc(ClientReaderWriter<EchoRequest, EchoResponse>* stream,
gpr_event* ev) {
EchoResponse resp;
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
index 815dfd0c4f..78527587cf 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -220,30 +220,31 @@ class BalancerServiceImpl : public BalancerService {
if (client_load_reporting_interval_seconds_ > 0) {
request.Clear();
- stream->Read(&request);
- gpr_log(GPR_INFO, "LB[%p]: recv client load report msg: '%s'", this,
- request.DebugString().c_str());
- GPR_ASSERT(request.has_client_stats());
- // We need to acquire the lock here in order to prevent the notify_one
- // below from firing before its corresponding wait is executed.
- std::lock_guard<std::mutex> lock(mu_);
- client_stats_.num_calls_started +=
- request.client_stats().num_calls_started();
- client_stats_.num_calls_finished +=
- request.client_stats().num_calls_finished();
- client_stats_.num_calls_finished_with_client_failed_to_send +=
- request.client_stats()
- .num_calls_finished_with_client_failed_to_send();
- client_stats_.num_calls_finished_known_received +=
- request.client_stats().num_calls_finished_known_received();
- for (const auto& drop_token_count :
- request.client_stats().calls_finished_with_drop()) {
- client_stats_
- .drop_token_counts[drop_token_count.load_balance_token()] +=
- drop_token_count.num_calls();
+ if (stream->Read(&request)) {
+ gpr_log(GPR_INFO, "LB[%p]: recv client load report msg: '%s'", this,
+ request.DebugString().c_str());
+ GPR_ASSERT(request.has_client_stats());
+ // We need to acquire the lock here in order to prevent the notify_one
+ // below from firing before its corresponding wait is executed.
+ std::lock_guard<std::mutex> lock(mu_);
+ client_stats_.num_calls_started +=
+ request.client_stats().num_calls_started();
+ client_stats_.num_calls_finished +=
+ request.client_stats().num_calls_finished();
+ client_stats_.num_calls_finished_with_client_failed_to_send +=
+ request.client_stats()
+ .num_calls_finished_with_client_failed_to_send();
+ client_stats_.num_calls_finished_known_received +=
+ request.client_stats().num_calls_finished_known_received();
+ for (const auto& drop_token_count :
+ request.client_stats().calls_finished_with_drop()) {
+ client_stats_
+ .drop_token_counts[drop_token_count.load_balance_token()] +=
+ drop_token_count.num_calls();
+ }
+ load_report_ready_ = true;
+ load_report_cond_.notify_one();
}
- load_report_ready_ = true;
- load_report_cond_.notify_one();
}
done:
gpr_log(GPR_INFO, "LB[%p]: done", this);
diff --git a/test/cpp/end2end/server_early_return_test.cc b/test/cpp/end2end/server_early_return_test.cc
new file mode 100644
index 0000000000..6fd26fcdb6
--- /dev/null
+++ b/test/cpp/end2end/server_early_return_test.cc
@@ -0,0 +1,233 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/security/credentials.h>
+#include <grpc++/security/server_credentials.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
+
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+#include "test/cpp/util/string_ref_helper.h"
+
+#include <gtest/gtest.h>
+
+namespace grpc {
+namespace testing {
+namespace {
+
+const char kServerReturnStatusCode[] = "server_return_status_code";
+const char kServerDelayBeforeReturnUs[] = "server_delay_before_return_us";
+const char kServerReturnAfterNReads[] = "server_return_after_n_reads";
+
+class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
+ public:
+ // Unused methods are not implemented.
+
+ Status RequestStream(ServerContext* context,
+ ServerReader<EchoRequest>* reader,
+ EchoResponse* response) override {
+ int server_return_status_code =
+ GetIntValueFromMetadata(context, kServerReturnStatusCode, 0);
+ int server_delay_before_return_us =
+ GetIntValueFromMetadata(context, kServerDelayBeforeReturnUs, 0);
+ int server_return_after_n_reads =
+ GetIntValueFromMetadata(context, kServerReturnAfterNReads, 0);
+
+ EchoRequest request;
+ while (server_return_after_n_reads--) {
+ EXPECT_TRUE(reader->Read(&request));
+ }
+
+ response->set_message("response msg");
+
+ gpr_sleep_until(gpr_time_add(
+ gpr_now(GPR_CLOCK_MONOTONIC),
+ gpr_time_from_micros(server_delay_before_return_us, GPR_TIMESPAN)));
+
+ return Status(static_cast<StatusCode>(server_return_status_code), "");
+ }
+
+ Status BidiStream(
+ ServerContext* context,
+ ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
+ int server_return_status_code =
+ GetIntValueFromMetadata(context, kServerReturnStatusCode, 0);
+ int server_delay_before_return_us =
+ GetIntValueFromMetadata(context, kServerDelayBeforeReturnUs, 0);
+ int server_return_after_n_reads =
+ GetIntValueFromMetadata(context, kServerReturnAfterNReads, 0);
+
+ EchoRequest request;
+ EchoResponse response;
+ while (server_return_after_n_reads--) {
+ EXPECT_TRUE(stream->Read(&request));
+ response.set_message(request.message());
+ EXPECT_TRUE(stream->Write(response));
+ }
+
+ gpr_sleep_until(gpr_time_add(
+ gpr_now(GPR_CLOCK_MONOTONIC),
+ gpr_time_from_micros(server_delay_before_return_us, GPR_TIMESPAN)));
+
+ return Status(static_cast<StatusCode>(server_return_status_code), "");
+ }
+
+ int GetIntValueFromMetadata(ServerContext* context, const char* key,
+ int default_value) {
+ auto metadata = context->client_metadata();
+ if (metadata.find(key) != metadata.end()) {
+ std::istringstream iss(ToString(metadata.find(key)->second));
+ iss >> default_value;
+ }
+ return default_value;
+ }
+};
+
+class ServerEarlyReturnTest : public ::testing::Test {
+ protected:
+ ServerEarlyReturnTest() : picked_port_(0) {}
+
+ void SetUp() override {
+ int port = grpc_pick_unused_port_or_die();
+ picked_port_ = port;
+ server_address_ << "127.0.0.1:" << port;
+ ServerBuilder builder;
+ builder.AddListeningPort(server_address_.str(),
+ InsecureServerCredentials());
+ builder.RegisterService(&service_);
+ server_ = builder.BuildAndStart();
+
+ channel_ =
+ CreateChannel(server_address_.str(), InsecureChannelCredentials());
+ stub_ = grpc::testing::EchoTestService::NewStub(channel_);
+ }
+
+ void TearDown() override {
+ server_->Shutdown();
+ if (picked_port_ > 0) {
+ grpc_recycle_unused_port(picked_port_);
+ }
+ }
+
+ // Client sends 20 requests and the server returns after reading 10 requests.
+ // If return_cancel is true, server returns CANCELLED status. Otherwise it
+ // returns OK.
+ void DoBidiStream(bool return_cancelled) {
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+
+ context.AddMetadata(kServerReturnAfterNReads, "10");
+ if (return_cancelled) {
+ // "1" means CANCELLED
+ context.AddMetadata(kServerReturnStatusCode, "1");
+ }
+ context.AddMetadata(kServerDelayBeforeReturnUs, "10000");
+
+ auto stream = stub_->BidiStream(&context);
+
+ for (int i = 0; i < 20; i++) {
+ request.set_message(grpc::string("hello") + grpc::to_string(i));
+ bool write_ok = stream->Write(request);
+ bool read_ok = stream->Read(&response);
+ if (i < 10) {
+ EXPECT_TRUE(write_ok);
+ EXPECT_TRUE(read_ok);
+ EXPECT_EQ(response.message(), request.message());
+ } else {
+ EXPECT_FALSE(read_ok);
+ }
+ }
+
+ stream->WritesDone();
+ EXPECT_FALSE(stream->Read(&response));
+
+ Status s = stream->Finish();
+ if (return_cancelled) {
+ EXPECT_EQ(s.error_code(), StatusCode::CANCELLED);
+ } else {
+ EXPECT_TRUE(s.ok());
+ }
+ }
+
+ void DoRequestStream(bool return_cancelled) {
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+
+ context.AddMetadata(kServerReturnAfterNReads, "10");
+ if (return_cancelled) {
+ // "1" means CANCELLED
+ context.AddMetadata(kServerReturnStatusCode, "1");
+ }
+ context.AddMetadata(kServerDelayBeforeReturnUs, "10000");
+
+ auto stream = stub_->RequestStream(&context, &response);
+ for (int i = 0; i < 20; i++) {
+ request.set_message(grpc::string("hello") + grpc::to_string(i));
+ bool written = stream->Write(request);
+ if (i < 10) {
+ EXPECT_TRUE(written);
+ }
+ }
+ stream->WritesDone();
+ Status s = stream->Finish();
+ if (return_cancelled) {
+ EXPECT_EQ(s.error_code(), StatusCode::CANCELLED);
+ } else {
+ EXPECT_TRUE(s.ok());
+ }
+ }
+
+ std::shared_ptr<Channel> channel_;
+ std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
+ std::unique_ptr<Server> server_;
+ std::ostringstream server_address_;
+ TestServiceImpl service_;
+ int picked_port_;
+};
+
+TEST_F(ServerEarlyReturnTest, BidiStreamEarlyOk) { DoBidiStream(false); }
+
+TEST_F(ServerEarlyReturnTest, BidiStreamEarlyCancel) { DoBidiStream(true); }
+
+TEST_F(ServerEarlyReturnTest, RequestStreamEarlyOK) { DoRequestStream(false); }
+TEST_F(ServerEarlyReturnTest, RequestStreamEarlyCancel) {
+ DoRequestStream(true);
+}
+
+} // namespace
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc
index e4f7c08f25..875a27b5f5 100644
--- a/test/cpp/end2end/test_service_impl.cc
+++ b/test/cpp/end2end/test_service_impl.cc
@@ -181,13 +181,6 @@ Status TestServiceImpl::RequestStream(ServerContext* context,
int server_try_cancel = GetIntValueFromMetadata(
kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL);
- // If 'cancel_after_reads' is set in the metadata AND non-zero, the server
- // will cancel the RPC (by just returning Status::CANCELLED - doesn't call
- // ServerContext::TryCancel()) after reading the number of records specified
- // by the 'cancel_after_reads' value set in the metadata.
- int cancel_after_reads = GetIntValueFromMetadata(
- kServerCancelAfterReads, context->client_metadata(), 0);
-
EchoRequest request;
response->set_message("");
@@ -204,12 +197,6 @@ Status TestServiceImpl::RequestStream(ServerContext* context,
int num_msgs_read = 0;
while (reader->Read(&request)) {
- if (cancel_after_reads == 1) {
- gpr_log(GPR_INFO, "return cancel status");
- return Status::CANCELLED;
- } else if (cancel_after_reads > 0) {
- cancel_after_reads--;
- }
response->mutable_message()->append(request.message());
}
gpr_log(GPR_INFO, "Read: %d messages", num_msgs_read);
diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h
index e485769bb2..070f357139 100644
--- a/test/cpp/end2end/test_service_impl.h
+++ b/test/cpp/end2end/test_service_impl.h
@@ -31,7 +31,6 @@ namespace testing {
const int kServerDefaultResponseStreamsToSend = 3;
const char* const kServerResponseStreamsToSend = "server_responses_to_send";
-const char* const kServerCancelAfterReads = "cancel_after_reads";
const char* const kServerTryCancelRequest = "server_try_cancel";
const char* const kDebugInfoTrailerKey = "debug-info-bin";
const char* const kServerFinishAfterNReads = "server_finish_after_n_reads";
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index 7cf9d3ea7e..e3fba36a7a 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -82,6 +82,7 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
prepare_req_(prepare_req) {}
~ClientRpcContextUnaryImpl() override {}
void Start(CompletionQueue* cq, const ClientConfig& config) override {
+ GPR_ASSERT(!config.use_coalesce_api()); // not supported.
StartInternal(cq);
}
bool RunNextState(bool ok, HistogramEntry* entry) override {
@@ -349,10 +350,11 @@ class ClientRpcContextStreamingPingPongImpl : public ClientRpcContext {
next_state_(State::INVALID),
callback_(on_done),
next_issue_(next_issue),
- prepare_req_(prepare_req) {}
+ prepare_req_(prepare_req),
+ coalesce_(false) {}
~ClientRpcContextStreamingPingPongImpl() override {}
void Start(CompletionQueue* cq, const ClientConfig& config) override {
- StartInternal(cq, config.messages_per_stream());
+ StartInternal(cq, config.messages_per_stream(), config.use_coalesce_api());
}
bool RunNextState(bool ok, HistogramEntry* entry) override {
while (true) {
@@ -375,7 +377,12 @@ class ClientRpcContextStreamingPingPongImpl : public ClientRpcContext {
}
start_ = UsageTimer::Now();
next_state_ = State::WRITE_DONE;
- stream_->Write(req_, ClientRpcContext::tag(this));
+ if (coalesce_ && messages_issued_ == messages_per_stream_ - 1) {
+ stream_->WriteLast(req_, WriteOptions(),
+ ClientRpcContext::tag(this));
+ } else {
+ stream_->Write(req_, ClientRpcContext::tag(this));
+ }
return true;
case State::WRITE_DONE:
if (!ok) {
@@ -391,6 +398,11 @@ class ClientRpcContextStreamingPingPongImpl : public ClientRpcContext {
if ((messages_per_stream_ != 0) &&
(++messages_issued_ >= messages_per_stream_)) {
next_state_ = State::WRITES_DONE_DONE;
+ if (coalesce_) {
+ // WritesDone should have been called on the last Write.
+ // loop around to call Finish.
+ break;
+ }
stream_->WritesDone(ClientRpcContext::tag(this));
return true;
}
@@ -413,7 +425,7 @@ class ClientRpcContextStreamingPingPongImpl : public ClientRpcContext {
void StartNewClone(CompletionQueue* cq) override {
auto* clone = new ClientRpcContextStreamingPingPongImpl(
stub_, req_, next_issue_, prepare_req_, callback_);
- clone->StartInternal(cq, messages_per_stream_);
+ clone->StartInternal(cq, messages_per_stream_, coalesce_);
}
void TryCancel() override { context_.TryCancel(); }
@@ -449,14 +461,27 @@ class ClientRpcContextStreamingPingPongImpl : public ClientRpcContext {
// Allow a limit on number of messages in a stream
int messages_per_stream_;
int messages_issued_;
+ // Whether to use coalescing API.
+ bool coalesce_;
- void StartInternal(CompletionQueue* cq, int messages_per_stream) {
+ void StartInternal(CompletionQueue* cq, int messages_per_stream,
+ bool coalesce) {
cq_ = cq;
messages_per_stream_ = messages_per_stream;
messages_issued_ = 0;
+ coalesce_ = coalesce;
+ if (coalesce_) {
+ GPR_ASSERT(messages_per_stream_ != 0);
+ context_.set_initial_metadata_corked(true);
+ }
stream_ = prepare_req_(stub_, &context_, cq);
next_state_ = State::STREAM_IDLE;
stream_->StartCall(ClientRpcContext::tag(this));
+ if (coalesce_) {
+ // When the intial metadata is corked, the tag will not come back and we
+ // need to manually drive the state machine.
+ RunNextState(true, nullptr);
+ }
}
};
@@ -512,6 +537,7 @@ class ClientRpcContextStreamingFromClientImpl : public ClientRpcContext {
prepare_req_(prepare_req) {}
~ClientRpcContextStreamingFromClientImpl() override {}
void Start(CompletionQueue* cq, const ClientConfig& config) override {
+ GPR_ASSERT(!config.use_coalesce_api()); // not supported yet.
StartInternal(cq);
}
bool RunNextState(bool ok, HistogramEntry* entry) override {
@@ -641,6 +667,7 @@ class ClientRpcContextStreamingFromServerImpl : public ClientRpcContext {
prepare_req_(prepare_req) {}
~ClientRpcContextStreamingFromServerImpl() override {}
void Start(CompletionQueue* cq, const ClientConfig& config) override {
+ GPR_ASSERT(!config.use_coalesce_api()); // not supported
StartInternal(cq);
}
bool RunNextState(bool ok, HistogramEntry* entry) override {
@@ -753,6 +780,7 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
prepare_req_(prepare_req) {}
~ClientRpcContextGenericStreamingImpl() override {}
void Start(CompletionQueue* cq, const ClientConfig& config) override {
+ GPR_ASSERT(!config.use_coalesce_api()); // not supported yet.
StartInternal(cq, config.messages_per_stream());
}
bool RunNextState(bool ok, HistogramEntry* entry) override {
diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc
index 82a3f0042d..a2ddbeb508 100644
--- a/test/cpp/qps/client_sync.cc
+++ b/test/cpp/qps/client_sync.cc
@@ -402,6 +402,7 @@ class SynchronousStreamingBothWaysClient final
};
std::unique_ptr<Client> CreateSynchronousClient(const ClientConfig& config) {
+ GPR_ASSERT(!config.use_coalesce_api()); // not supported yet.
switch (config.rpc_type()) {
case UNARY:
return std::unique_ptr<Client>(new SynchronousUnaryClient(config));
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 2f765a6d1e..a809a27e3c 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -33,7 +33,6 @@
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/profiling/timers.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
#include "test/cpp/qps/client.h"
diff --git a/tools/buildgen/plugins/expand_version.py b/tools/buildgen/plugins/expand_version.py
index 8f56ce8fc9..facf349b0c 100755
--- a/tools/buildgen/plugins/expand_version.py
+++ b/tools/buildgen/plugins/expand_version.py
@@ -84,6 +84,13 @@ class Version:
% self.tag)
return s
+ def php_stability(self):
+ """stability string for PHP PECL package.xml file"""
+ if self.tag:
+ return 'beta'
+ else:
+ return 'stable'
+
def php_composer(self):
"""Version string for PHP Composer package"""
return '%d.%d.%d' % (self.major, self.minor, self.patch)
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index c4ed066122..5caa1d1078 100644
--- a/tools/distrib/python/grpcio_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
-VERSION = '1.9.0.dev0'
+VERSION = '1.10.0.dev0'
diff --git a/tools/distrib/run_clang_tidy.py b/tools/distrib/run_clang_tidy.py
index bc61d4e79a..337e6b43c8 100755
--- a/tools/distrib/run_clang_tidy.py
+++ b/tools/distrib/run_clang_tidy.py
@@ -26,6 +26,8 @@ import jobset
GRPC_CHECKS = [
'modernize-use-nullptr',
+ 'google-build-namespaces',
+ 'google-build-explicit-make-pair',
]
extra_args = [
diff --git a/tools/dockerfile/grpc_clang_tidy/clang_tidy_all_the_things.sh b/tools/dockerfile/grpc_clang_tidy/clang_tidy_all_the_things.sh
index 1a82dd52b7..e1932ed0bf 100755
--- a/tools/dockerfile/grpc_clang_tidy/clang_tidy_all_the_things.sh
+++ b/tools/dockerfile/grpc_clang_tidy/clang_tidy_all_the_things.sh
@@ -20,5 +20,5 @@ CLANG_TIDY=${CLANG_TIDY:-clang-tidy-5.0}
cd ${CLANG_TIDY_ROOT}
-find src/core src/cpp test/core test/cpp -name '*.h' -or -name '*.cc' -print0 \
+find src/core src/cpp test/core test/cpp -name '*.h' -print0 -or -name '*.cc' -print0 \
| xargs -0 tools/distrib/run_clang_tidy.py "$@"
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index c8118cbe82..6873256dcd 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.9.0-dev
+PROJECT_NUMBER = 1.10.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 25f8004074..2c6505ddad 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.9.0-dev
+PROJECT_NUMBER = 1.10.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -952,17 +952,6 @@ src/core/lib/compression/stream_compression_identity.h \
src/core/lib/debug/stats.h \
src/core/lib/debug/stats_data.h \
src/core/lib/debug/trace.h \
-src/core/lib/gpr++/abstract.h \
-src/core/lib/gpr++/atomic.h \
-src/core/lib/gpr++/atomic_with_atm.h \
-src/core/lib/gpr++/atomic_with_std.h \
-src/core/lib/gpr++/debug_location.h \
-src/core/lib/gpr++/inlined_vector.h \
-src/core/lib/gpr++/manual_constructor.h \
-src/core/lib/gpr++/memory.h \
-src/core/lib/gpr++/orphanable.h \
-src/core/lib/gpr++/ref_counted.h \
-src/core/lib/gpr++/ref_counted_ptr.h \
src/core/lib/gpr/arena.h \
src/core/lib/gpr/env.h \
src/core/lib/gpr/fork.h \
@@ -974,6 +963,17 @@ src/core/lib/gpr/string_windows.h \
src/core/lib/gpr/thd_internal.h \
src/core/lib/gpr/time_precise.h \
src/core/lib/gpr/tmpfile.h \
+src/core/lib/gprpp/abstract.h \
+src/core/lib/gprpp/atomic.h \
+src/core/lib/gprpp/atomic_with_atm.h \
+src/core/lib/gprpp/atomic_with_std.h \
+src/core/lib/gprpp/debug_location.h \
+src/core/lib/gprpp/inlined_vector.h \
+src/core/lib/gprpp/manual_constructor.h \
+src/core/lib/gprpp/memory.h \
+src/core/lib/gprpp/orphanable.h \
+src/core/lib/gprpp/ref_counted.h \
+src/core/lib/gprpp/ref_counted_ptr.h \
src/core/lib/http/format_request.h \
src/core/lib/http/httpcli.h \
src/core/lib/http/parser.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index aeab05eebc..00057c2897 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1068,18 +1068,6 @@ src/core/lib/debug/stats_data.cc \
src/core/lib/debug/stats_data.h \
src/core/lib/debug/trace.cc \
src/core/lib/debug/trace.h \
-src/core/lib/gpr++/README.md \
-src/core/lib/gpr++/abstract.h \
-src/core/lib/gpr++/atomic.h \
-src/core/lib/gpr++/atomic_with_atm.h \
-src/core/lib/gpr++/atomic_with_std.h \
-src/core/lib/gpr++/debug_location.h \
-src/core/lib/gpr++/inlined_vector.h \
-src/core/lib/gpr++/manual_constructor.h \
-src/core/lib/gpr++/memory.h \
-src/core/lib/gpr++/orphanable.h \
-src/core/lib/gpr++/ref_counted.h \
-src/core/lib/gpr++/ref_counted_ptr.h \
src/core/lib/gpr/README.md \
src/core/lib/gpr/alloc.cc \
src/core/lib/gpr/arena.cc \
@@ -1134,6 +1122,18 @@ src/core/lib/gpr/tmpfile_msys.cc \
src/core/lib/gpr/tmpfile_posix.cc \
src/core/lib/gpr/tmpfile_windows.cc \
src/core/lib/gpr/wrap_memcpy.cc \
+src/core/lib/gprpp/README.md \
+src/core/lib/gprpp/abstract.h \
+src/core/lib/gprpp/atomic.h \
+src/core/lib/gprpp/atomic_with_atm.h \
+src/core/lib/gprpp/atomic_with_std.h \
+src/core/lib/gprpp/debug_location.h \
+src/core/lib/gprpp/inlined_vector.h \
+src/core/lib/gprpp/manual_constructor.h \
+src/core/lib/gprpp/memory.h \
+src/core/lib/gprpp/orphanable.h \
+src/core/lib/gprpp/ref_counted.h \
+src/core/lib/gprpp/ref_counted_ptr.h \
src/core/lib/http/format_request.cc \
src/core/lib/http/format_request.h \
src/core/lib/http/httpcli.cc \
diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh
index a76721881f..b1335c1226 100644
--- a/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh
+++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh
@@ -49,7 +49,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc
--strategy=Closure=remote \
--genrule_strategy=remote \
--experimental_strict_action_env=true \
- --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/asci-toolchain/nosla-debian8-clang-fl@sha256:aa20628a902f06a11a015caa94b0432eb60690de2d2525bd046b9eea046f5d8a" }' \
+ --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/asci-toolchain/nosla-debian8-clang-fl@sha256:496193842f61c9494be68bd624e47c74d706cabf19a693c4653ffe96a97e43e3" }' \
--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/debian8_clang/0.2.0/bazel_0.7.0:toolchain \
--define GRPC_PORT_ISOLATED_RUNTIME=1 \
-c dbg \
diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh
index defe664807..42962d7f9a 100644
--- a/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh
+++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh
@@ -49,7 +49,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc
--strategy=Closure=remote \
--genrule_strategy=remote \
--experimental_strict_action_env=true \
- --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/asci-toolchain/nosla-debian8-clang-fl@sha256:aa20628a902f06a11a015caa94b0432eb60690de2d2525bd046b9eea046f5d8a" }' \
+ --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/asci-toolchain/nosla-debian8-clang-fl@sha256:496193842f61c9494be68bd624e47c74d706cabf19a693c4653ffe96a97e43e3" }' \
--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/debian8_clang/0.2.0/bazel_0.7.0:toolchain \
--define GRPC_PORT_ISOLATED_RUNTIME=1 \
-c opt \
diff --git a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh
new file mode 100644
index 0000000000..3948e6e7ce
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh
@@ -0,0 +1,58 @@
+#!/usr/bin/env bash
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -ex
+
+# A temporary solution to give Kokoro credentials.
+# The file name 4321_grpc-testing-service needs to match auth_credential in
+# the build config.
+# TODO: Use keystore.
+mkdir -p ${KOKORO_KEYSTORE_DIR}
+cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
+
+mkdir -p /tmpfs/tmp/bazel-canary
+ln -f "${KOKORO_GFILE_DIR}/bazel-canary" /tmpfs/tmp/bazel-canary/bazel
+chmod 755 "${KOKORO_GFILE_DIR}/bazel-canary"
+export PATH="/tmpfs/tmp/bazel-canary:${PATH}"
+# This should show /tmpfs/tmp/bazel-canary/bazel
+which bazel
+chmod +x "${KOKORO_GFILE_DIR}/bazel_wrapper.py"
+
+# change to grpc repo root
+cd $(dirname $0)/../../..
+
+source tools/internal_ci/helper_scripts/prepare_build_linux_rc
+
+"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \
+ --host_jvm_args=-Dbazel.DigestFunction=SHA1 \
+ test --jobs="50" \
+ --test_timeout="300,450,1200,3600" \
+ --test_output=errors \
+ --verbose_failures=true \
+ --keep_going \
+ --remote_accept_cached=true \
+ --spawn_strategy=remote \
+ --remote_local_fallback=false \
+ --remote_timeout=3600 \
+ --strategy=Javac=remote \
+ --strategy=Closure=remote \
+ --genrule_strategy=remote \
+ --experimental_strict_action_env=true \
+ --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/asci-toolchain/nosla-debian8-clang-fl@sha256:496193842f61c9494be68bd624e47c74d706cabf19a693c4653ffe96a97e43e3" }' \
+ --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/debian8_clang/0.2.0/bazel_0.7.0:toolchain \
+ --define GRPC_PORT_ISOLATED_RUNTIME=1 \
+ --copt=-fsanitize=thread \
+ --linkopt=-fsanitize=thread \
+ -- //test/...
diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py
index dbbf8a5a09..5de705a52a 100644
--- a/tools/interop_matrix/client_matrix.py
+++ b/tools/interop_matrix/client_matrix.py
@@ -107,7 +107,7 @@ LANG_RELEASE_MATRIX = {
'v1.8.2': None
},
{
- 'v1.9.1': None
+ 'v1.9.2': None
},
],
'java': [
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index edeb5a7002..f61288b70d 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -687,7 +687,7 @@
"language": "c",
"name": "gpr_manual_constructor_test",
"src": [
- "test/core/gpr++/manual_constructor_test.cc"
+ "test/core/gprpp/manual_constructor_test.cc"
],
"third_party": false,
"type": "target"
@@ -3542,7 +3542,7 @@
"language": "c++",
"name": "inlined_vector_test",
"src": [
- "test/core/gpr++/inlined_vector_test.cc"
+ "test/core/gprpp/inlined_vector_test.cc"
],
"third_party": false,
"type": "target"
@@ -3662,7 +3662,7 @@
"language": "c++",
"name": "memory_test",
"src": [
- "test/core/gpr++/memory_test.cc"
+ "test/core/gprpp/memory_test.cc"
],
"third_party": false,
"type": "target"
@@ -3740,7 +3740,7 @@
"language": "c++",
"name": "orphanable_test",
"src": [
- "test/core/gpr++/orphanable_test.cc"
+ "test/core/gprpp/orphanable_test.cc"
],
"third_party": false,
"type": "target"
@@ -3951,7 +3951,7 @@
"language": "c++",
"name": "ref_counted_ptr_test",
"src": [
- "test/core/gpr++/ref_counted_ptr_test.cc"
+ "test/core/gprpp/ref_counted_ptr_test.cc"
],
"third_party": false,
"type": "target"
@@ -3970,7 +3970,7 @@
"language": "c++",
"name": "ref_counted_test",
"src": [
- "test/core/gpr++/ref_counted_test.cc"
+ "test/core/gprpp/ref_counted_test.cc"
],
"third_party": false,
"type": "target"
@@ -4122,6 +4122,25 @@
"deps": [
"gpr",
"gpr_test_util",
+ "grpc",
+ "grpc++",
+ "grpc++_test_util",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "server_early_return_test",
+ "src": [
+ "test/cpp/end2end/server_early_return_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
"grpc++_test_util_unsecure",
"grpc++_unsecure",
"grpc_test_util_unsecure",
@@ -7906,12 +7925,6 @@
"include/grpc/support/tls_msvc.h",
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
- "src/core/lib/gpr++/abstract.h",
- "src/core/lib/gpr++/atomic.h",
- "src/core/lib/gpr++/atomic_with_atm.h",
- "src/core/lib/gpr++/atomic_with_std.h",
- "src/core/lib/gpr++/manual_constructor.h",
- "src/core/lib/gpr++/memory.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
"src/core/lib/gpr/fork.h",
@@ -7923,6 +7936,12 @@
"src/core/lib/gpr/thd_internal.h",
"src/core/lib/gpr/time_precise.h",
"src/core/lib/gpr/tmpfile.h",
+ "src/core/lib/gprpp/abstract.h",
+ "src/core/lib/gprpp/atomic.h",
+ "src/core/lib/gprpp/atomic_with_atm.h",
+ "src/core/lib/gprpp/atomic_with_std.h",
+ "src/core/lib/gprpp/manual_constructor.h",
+ "src/core/lib/gprpp/memory.h",
"src/core/lib/profiling/timers.h"
],
"is_filegroup": true,
@@ -7955,12 +7974,6 @@
"include/grpc/support/tls_msvc.h",
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
- "src/core/lib/gpr++/abstract.h",
- "src/core/lib/gpr++/atomic.h",
- "src/core/lib/gpr++/atomic_with_atm.h",
- "src/core/lib/gpr++/atomic_with_std.h",
- "src/core/lib/gpr++/manual_constructor.h",
- "src/core/lib/gpr++/memory.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
"src/core/lib/gpr/fork.h",
@@ -7972,6 +7985,12 @@
"src/core/lib/gpr/thd_internal.h",
"src/core/lib/gpr/time_precise.h",
"src/core/lib/gpr/tmpfile.h",
+ "src/core/lib/gprpp/abstract.h",
+ "src/core/lib/gprpp/atomic.h",
+ "src/core/lib/gprpp/atomic_with_atm.h",
+ "src/core/lib/gprpp/atomic_with_std.h",
+ "src/core/lib/gprpp/manual_constructor.h",
+ "src/core/lib/gprpp/memory.h",
"src/core/lib/profiling/timers.h"
],
"third_party": false,
@@ -8233,11 +8252,11 @@
"src/core/lib/compression/stream_compression_identity.h",
"src/core/lib/debug/stats.h",
"src/core/lib/debug/stats_data.h",
- "src/core/lib/gpr++/debug_location.h",
- "src/core/lib/gpr++/inlined_vector.h",
- "src/core/lib/gpr++/orphanable.h",
- "src/core/lib/gpr++/ref_counted.h",
- "src/core/lib/gpr++/ref_counted_ptr.h",
+ "src/core/lib/gprpp/debug_location.h",
+ "src/core/lib/gprpp/inlined_vector.h",
+ "src/core/lib/gprpp/orphanable.h",
+ "src/core/lib/gprpp/ref_counted.h",
+ "src/core/lib/gprpp/ref_counted_ptr.h",
"src/core/lib/http/format_request.h",
"src/core/lib/http/httpcli.h",
"src/core/lib/http/parser.h",
@@ -8376,11 +8395,11 @@
"src/core/lib/compression/stream_compression_identity.h",
"src/core/lib/debug/stats.h",
"src/core/lib/debug/stats_data.h",
- "src/core/lib/gpr++/debug_location.h",
- "src/core/lib/gpr++/inlined_vector.h",
- "src/core/lib/gpr++/orphanable.h",
- "src/core/lib/gpr++/ref_counted.h",
- "src/core/lib/gpr++/ref_counted_ptr.h",
+ "src/core/lib/gprpp/debug_location.h",
+ "src/core/lib/gprpp/inlined_vector.h",
+ "src/core/lib/gprpp/orphanable.h",
+ "src/core/lib/gprpp/ref_counted.h",
+ "src/core/lib/gprpp/ref_counted_ptr.h",
"src/core/lib/http/format_request.h",
"src/core/lib/http/httpcli.h",
"src/core/lib/http/parser.h",
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 7b23cab506..866e2c3280 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -4398,6 +4398,30 @@
"flaky": false,
"gtest": true,
"language": "c++",
+ "name": "server_early_return_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": true
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
"name": "server_request_call_test",
"platforms": [
"linux",
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index 344035478b..ae3a28bde5 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -44,14 +44,19 @@ _DEFAULT_INNER_JOBS = 2
_REPORT_SUFFIX = 'sponge_log.xml'
+def _safe_report_name(name):
+ """Reports with '+' in target name won't show correctly in ResultStore"""
+ return name.replace('+', 'p')
+
+
def _report_filename(name):
"""Generates report file name"""
- return 'report_%s_%s' % (name, _REPORT_SUFFIX)
+ return 'report_%s_%s' % (_safe_report_name(name), _REPORT_SUFFIX)
def _report_filename_internal_ci(name):
"""Generates report file name that leads to better presentation by internal CI"""
- return '%s/%s' % (name, _REPORT_SUFFIX)
+ return '%s/%s' % (_safe_report_name(name), _REPORT_SUFFIX)
def _docker_jobspec(name,
@@ -68,7 +73,7 @@ def _docker_jobspec(name,
'-j',
str(inner_jobs), '-x',
_report_filename(name), '--report_suite_name',
- '%s' % name
+ '%s' % _safe_report_name(name)
] + runtests_args,
environ=runtests_envs,
shortname='run_tests_%s' % name,
@@ -95,7 +100,7 @@ def _workspace_jobspec(name,
'-t', '-j',
str(inner_jobs), '-x',
'../%s' % _report_filename(name), '--report_suite_name',
- '%s' % name
+ '%s' % _safe_report_name(name)
] + runtests_args,
environ=env,
shortname='run_tests_%s' % name,