From 3683ada93f034f9e67da8a0b81feea4acfa26588 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 22 Jan 2018 15:37:22 +0100 Subject: [PATCH 01/25] 1.9.0-pre1 is now 1.9.0-pre2 --- BUILD | 4 ++-- build.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BUILD b/BUILD index a96c72e075f..4e4e2ca7f15 100644 --- a/BUILD +++ b/BUILD @@ -56,9 +56,9 @@ config_setting( # This should be updated along with build.yaml g_stands_for = "glossy" -core_version = "5.0.0-pre1" +core_version = "5.0.0-pre2" -version = "1.9.0-pre1" +version = "1.9.0-pre2" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 5c7dba6372f..eb408e4da31 100644 --- a/build.yaml +++ b/build.yaml @@ -12,9 +12,9 @@ settings: '#08': Use "-preN" suffixes to identify pre-release versions '#09': Per-language overrides are possible with (eg) ruby_version tag here '#10': See the expand_version.py for all the quirks here - core_version: 5.0.0-pre1 + core_version: 5.0.0-pre2 g_stands_for: glossy - version: 1.9.0-pre1 + version: 1.9.0-pre2 filegroups: - name: census public_headers: From 2dc3b1eb55acc277f7d8c4416f0fa92b98496990 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 22 Jan 2018 15:38:32 +0100 Subject: [PATCH 02/25] regenerate projects --- CMakeLists.txt | 2 +- Makefile | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/core/lib/surface/version.cc | 2 +- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 2 +- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_packages_dotnetcli.sh | 4 ++-- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 4 ++-- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- tools/doxygen/Doxyfile.core | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- 30 files changed, 35 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 103f856d357..7663efca7a5 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-pre1") +set(PACKAGE_VERSION "1.9.0-pre2") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 28487825295..e207a1be1fc 100644 --- a/Makefile +++ b/Makefile @@ -418,9 +418,9 @@ E = @echo Q = @ endif -CORE_VERSION = 5.0.0-pre1 -CPP_VERSION = 1.9.0-pre1 -CSHARP_VERSION = 1.9.0-pre1 +CORE_VERSION = 5.0.0-pre2 +CPP_VERSION = 1.9.0-pre2 +CSHARP_VERSION = 1.9.0-pre2 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 8bac3c0c8bb..f595df3bece 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-pre1' + version = '1.9.0-pre2' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 53e675c3d5d..fc35532f713 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-pre1' + version = '1.9.0-pre2' 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 d31f4b62453..1a71b9ec2dc 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-pre1' + version = '1.9.0-pre2' 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 d9d91a829cd..cbba4cef009 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.9.0-pre1' + version = '1.9.0-pre2' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index caf276f71f3..24d950353da 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2017-08-24 - 1.9.0RC1 - 1.9.0RC1 + 1.9.0RC2 + 1.9.0RC2 beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index c247dd4efb2..d752e4fbb1b 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -21,6 +21,6 @@ #include -const char* grpc_version_string(void) { return "5.0.0-pre1"; } +const char* grpc_version_string(void) { return "5.0.0-pre2"; } const char* grpc_g_stands_for(void) { return "glossy"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 7b0a70e758b..e390691dee7 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.9.0-pre1"; } +grpc::string Version() { return "1.9.0-pre2"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 3c08a6d5fe3..f653ad5f8b8 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.9.0-pre1 + 1.9.0-pre2 3.3.0 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index fe191306f81..d29855d87e1 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.9.0-pre1"; + public const string CurrentVersion = "1.9.0-pre2"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 212aa8caecb..f396bb5d882 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-pre1 +set VERSION=1.9.0-pre2 @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 64b3c16c722..ddd12a7a5f6 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-pre1" -OutputDirectory ../../artifacts -nuget pack Grpc.Tools.nuspec -Version "1.9.0-pre1" -OutputDirectory ../../artifacts +nuget pack Grpc.nuspec -Version "1.9.0-pre2" -OutputDirectory ../../artifacts +nuget pack Grpc.Tools.nuspec -Version "1.9.0-pre2" -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 4d5b53e62cf..e961648ee09 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-pre1' + v = '1.9.0-pre2' 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 17df6fda379..c653ac7423f 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-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.9.0-pre2" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index c0218d8ec4a..99ceb459fe7 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-pre1" -#define GRPC_C_VERSION_STRING @"5.0.0-pre1" +#define GRPC_OBJC_VERSION_STRING @"1.9.0-pre2" +#define GRPC_C_VERSION_STRING @"5.0.0-pre2" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 244f7b9f87e..134fd518acb 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.0RC1" +#define PHP_GRPC_VERSION "1.9.0RC2" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 846bfc34349..6b9a6f42a7e 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.0rc1""" +__version__ = """1.9.0rc2""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 2caeabcac45..b7dd6777862 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.0rc1' +VERSION = '1.9.0rc2' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 40980615cfd..77d846a50f8 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.0rc1' +VERSION = '1.9.0rc2' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index b7b1c2edc8e..fa29ec48299 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.0rc1' +VERSION = '1.9.0rc2' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index f817a37399d..d892bd80681 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.0rc1' +VERSION = '1.9.0rc2' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index f7b7f2d69be..2717bf38041 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.0rc1' +VERSION = '1.9.0rc2' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 83ae60143ed..7669087536b 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.pre1' + VERSION = '1.9.0.pre2' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 3e43a44dc82..7d02b4cbabd 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.pre1' + VERSION = '1.9.0.pre2' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 11e92b1aa7d..eec7ff87894 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.0rc1' +VERSION = '1.9.0rc2' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 4db1b797bf7..6375d920dd6 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-pre1 +PROJECT_NUMBER = 1.9.0-pre2 # 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 6b1c5c53016..604bb5b6478 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-pre1 +PROJECT_NUMBER = 1.9.0-pre2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 15fe7ba6855..43e0771c768 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 5.0.0-pre1 +PROJECT_NUMBER = 5.0.0-pre2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 34a7b3b9155..67a9336a127 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 5.0.0-pre1 +PROJECT_NUMBER = 5.0.0-pre2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From f46028f5dbc5beac240178363932749ab7ece1ea Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Fri, 1 Dec 2017 01:54:47 -0800 Subject: [PATCH 03/25] Add necessary retries for atomic state changes --- .../ext/filters/max_age/max_age_filter.cc | 88 +++++++++++++++---- 1 file changed, 73 insertions(+), 15 deletions(-) diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc index 7b86e4cd6c1..cab17acdf20 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -37,6 +37,12 @@ #define MAX_CONNECTION_IDLE_INTEGER_OPTIONS \ { DEFAULT_MAX_CONNECTION_IDLE_MS, 1, INT_MAX } +/* States for idle_state in channel_data */ +#define MAX_IDLE_STATE_INIT ((gpr_atm)0) +#define MAX_IDLE_STATE_SEEN_EXIT_IDLE ((gpr_atm)1) +#define MAX_IDLE_STATE_SEEN_ENTER_IDLE ((gpr_atm)2) +#define MAX_IDLE_STATE_TIMER_SET ((gpr_atm)3) + namespace { struct channel_data { /* We take a reference to the channel stack for the timer callback */ @@ -92,7 +98,21 @@ struct channel_data { calls, the max_idle_timer should be cancelled. */ static void increase_call_count(channel_data* chand) { if (gpr_atm_full_fetch_add(&chand->call_count, 1) == 0) { - grpc_timer_cancel(&chand->max_idle_timer); + gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state); + switch (idle_state) { + case MAX_IDLE_STATE_TIMER_SET: + /* max_idle_timer_cb may have already set idle_state to + MAX_IDLE_STATE_INIT, in this case, we don't need to set it to + MAX_IDLE_STATE_SEEN_EXIT_IDLE */ + gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_TIMER_SET, + MAX_IDLE_STATE_SEEN_EXIT_IDLE); + break; + case MAX_IDLE_STATE_SEEN_ENTER_IDLE: + gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE); + break; + default: + abort(); + } } } @@ -100,11 +120,29 @@ static void increase_call_count(channel_data* chand) { calls, the max_idle_timer should be started. */ static void decrease_call_count(channel_data* chand) { if (gpr_atm_full_fetch_add(&chand->call_count, -1) == 1) { - GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_idle_timer"); - grpc_timer_init( - &chand->max_idle_timer, - grpc_core::ExecCtx::Get()->Now() + chand->max_connection_idle, - &chand->close_max_idle_channel); + chand->last_enter_idle_time = grpc_exec_ctx_now(exec_ctx); + while (true) { + gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state); + switch (idle_state) { + case MAX_IDLE_STATE_INIT: + GRPC_CHANNEL_STACK_REF(chand->channel_stack, + "max_age max_idle_timer"); + grpc_timer_init( + exec_ctx, &chand->max_idle_timer, + grpc_exec_ctx_now(exec_ctx) + chand->max_connection_idle, + &chand->max_idle_timer_cb); + gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_TIMER_SET); + return; + case MAX_IDLE_STATE_SEEN_EXIT_IDLE: + if (gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE, + MAX_IDLE_STATE_SEEN_ENTER_IDLE)) { + return; + } + break; + default: + abort(); + } + } } } @@ -155,15 +193,35 @@ static void start_max_age_grace_timer_after_goaway_op(void* arg, static void close_max_idle_channel(void* arg, grpc_error* error) { channel_data* chand = (channel_data*)arg; if (error == GRPC_ERROR_NONE) { - /* Prevent the max idle timer from being set again */ - gpr_atm_no_barrier_fetch_add(&chand->call_count, 1); - grpc_transport_op* op = grpc_make_transport_op(nullptr); - op->goaway_error = - grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("max_idle"), - GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_NO_ERROR); - grpc_channel_element* elem = - grpc_channel_stack_element(chand->channel_stack, 0); - elem->filter->start_transport_op(elem, op); + while (true) { + gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state); + if (idle_state == MAX_IDLE_STATE_TIMER_SET) { + close_max_idle_channel(exec_ctx, chand); + /* This MAX_IDLE_STATE_INIT is a final state, we don't have to check if + * idle_state has been changed */ + gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_INIT); + break; + } else if (idle_state == MAX_IDLE_STATE_SEEN_EXIT_IDLE) { + if (gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE, + MAX_IDLE_STATE_INIT)) { + break; + } + } else if (idle_state == MAX_IDLE_STATE_SEEN_ENTER_IDLE) { + GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_idle_timer"); + grpc_timer_init( + exec_ctx, &chand->max_idle_timer, + chand->last_enter_idle_time + chand->max_connection_idle, + &chand->max_idle_timer_cb); + /* idle_state may have already been set to MAX_IDLE_STATE_SEEN_EXIT_IDLE + by increase_call_count(), in this case, we don't need to set it to + MAX_IDLE_STATE_TIMER_SET */ + gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_ENTER_IDLE, + MAX_IDLE_STATE_TIMER_SET); + break; + } else { + abort(); + } + } } else if (error != GRPC_ERROR_CANCELLED) { GRPC_LOG_IF_ERROR("close_max_idle_channel", error); } From c4431e4fcd1afc37859da8ca21736b3b67d4f154 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Fri, 1 Dec 2017 03:19:21 -0800 Subject: [PATCH 04/25] Try again when idle_state is unexpected --- .../ext/filters/max_age/max_age_filter.cc | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc index cab17acdf20..ec8aaccfa56 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -98,20 +98,23 @@ struct channel_data { calls, the max_idle_timer should be cancelled. */ static void increase_call_count(channel_data* chand) { if (gpr_atm_full_fetch_add(&chand->call_count, 1) == 0) { - gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state); - switch (idle_state) { - case MAX_IDLE_STATE_TIMER_SET: - /* max_idle_timer_cb may have already set idle_state to - MAX_IDLE_STATE_INIT, in this case, we don't need to set it to - MAX_IDLE_STATE_SEEN_EXIT_IDLE */ - gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_TIMER_SET, - MAX_IDLE_STATE_SEEN_EXIT_IDLE); - break; - case MAX_IDLE_STATE_SEEN_ENTER_IDLE: - gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE); - break; - default: - abort(); + while (true) { + gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state); + switch (idle_state) { + case MAX_IDLE_STATE_TIMER_SET: + /* max_idle_timer_cb may have already set idle_state to + MAX_IDLE_STATE_INIT, in this case, we don't need to set it to + MAX_IDLE_STATE_SEEN_EXIT_IDLE */ + gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_TIMER_SET, + MAX_IDLE_STATE_SEEN_EXIT_IDLE); + return; + case MAX_IDLE_STATE_SEEN_ENTER_IDLE: + gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE); + return; + default: + /* try again */ + break; + } } } } @@ -140,7 +143,8 @@ static void decrease_call_count(channel_data* chand) { } break; default: - abort(); + /* try again */ + break; } } } @@ -219,7 +223,7 @@ static void close_max_idle_channel(void* arg, grpc_error* error) { MAX_IDLE_STATE_TIMER_SET); break; } else { - abort(); + /* try again */ } } } else if (error != GRPC_ERROR_CANCELLED) { From d1d605ea3e52a788788a6c2ea548e9f614bd8e95 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Fri, 1 Dec 2017 17:23:50 -0800 Subject: [PATCH 05/25] Fix asan issues --- .../ext/filters/max_age/max_age_filter.cc | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc index ec8aaccfa56..a514c8a1bf5 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -91,6 +91,10 @@ struct channel_data { grpc_connectivity_state connectivity_state; /* Number of active calls */ gpr_atm call_count; + /* Current state of channel idleness and max_idle_timer */ + gpr_atm idle_state; + /* Time when the channel finished its last outstanding call, in grpc_millis */ + gpr_atm last_enter_idle_time_millis; }; } // namespace @@ -123,7 +127,8 @@ static void increase_call_count(channel_data* chand) { calls, the max_idle_timer should be started. */ static void decrease_call_count(channel_data* chand) { if (gpr_atm_full_fetch_add(&chand->call_count, -1) == 1) { - chand->last_enter_idle_time = grpc_exec_ctx_now(exec_ctx); + gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis, + (gpr_atm)grpc_exec_ctx_now(exec_ctx)); while (true) { gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state); switch (idle_state) { @@ -212,10 +217,11 @@ static void close_max_idle_channel(void* arg, grpc_error* error) { } } else if (idle_state == MAX_IDLE_STATE_SEEN_ENTER_IDLE) { GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_idle_timer"); - grpc_timer_init( - exec_ctx, &chand->max_idle_timer, - chand->last_enter_idle_time + chand->max_connection_idle, - &chand->max_idle_timer_cb); + grpc_timer_init(exec_ctx, &chand->max_idle_timer, + (grpc_millis)gpr_atm_no_barrier_load( + &chand->last_enter_idle_time_millis) + + chand->max_connection_idle, + &chand->max_idle_timer_cb); /* idle_state may have already been set to MAX_IDLE_STATE_SEEN_EXIT_IDLE by increase_call_count(), in this case, we don't need to set it to MAX_IDLE_STATE_TIMER_SET */ @@ -226,8 +232,6 @@ static void close_max_idle_channel(void* arg, grpc_error* error) { /* try again */ } } - } else if (error != GRPC_ERROR_CANCELLED) { - GRPC_LOG_IF_ERROR("close_max_idle_channel", error); } GRPC_CHANNEL_STACK_UNREF(chand->channel_stack, "max_age max_idle_timer"); } @@ -350,6 +354,9 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, chand->max_connection_idle = DEFAULT_MAX_CONNECTION_IDLE_MS == INT_MAX ? GRPC_MILLIS_INF_FUTURE : DEFAULT_MAX_CONNECTION_IDLE_MS; + chand->idle_state = MAX_IDLE_STATE_INIT; + gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis, + GRPC_MILLIS_INF_PAST); for (size_t i = 0; i < args->channel_args->num_args; ++i) { if (0 == strcmp(args->channel_args->args[i].key, GRPC_ARG_MAX_CONNECTION_AGE_MS)) { From b22befd69b550e3b0daf199f674c0d2143d1a274 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 4 Dec 2017 15:22:29 -0800 Subject: [PATCH 06/25] Document idle_state transistions --- .../ext/filters/max_age/max_age_filter.cc | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc index a514c8a1bf5..330cfff02fe 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -91,7 +91,35 @@ struct channel_data { grpc_connectivity_state connectivity_state; /* Number of active calls */ gpr_atm call_count; - /* Current state of channel idleness and max_idle_timer */ + /* 'idle_state' holds the states of max_idle_timer and channel idleness. + It can contain one of the following values: + +--------------------------------+----------------+---------+ + | idle_state | max_idle_timer | channel | + +--------------------------------+----------------+---------+ + | MAX_IDLE_STATE_INIT | unset | busy | + | MAX_IDLE_STATE_TIMER_SET | set, valid | idle | + | MAX_IDLE_STATE_SEEN_EXIT_IDLE | set, invalid | busy | + | MAX_IDLE_STATE_SEEN_ENTER_IDLE | set, invalid | idle | + +--------------------------------+----------------+---------+ + + max_idle_timer will not be cancelled (unless the channel is shutting down). + If the timer callback is called when the max_idle_timer is valid (i.e. + idle_state is MAX_IDLE_STATE_TIMER_SET), the channel will be closed due to + idleness, otherwise the channel won't be changed. + + State transitions: + + MAX_IDLE_STATE_INIT <-------3------ MAX_IDLE_STATE_SEEN_EXIT_IDLE + ^ | ^ ^ | + | | | | | + 1 2 +-----------4------------+ 6 7 + | | | | | + | v | | v + MAX_IDLE_STATE_TIMER_SET <----5------ MAX_IDLE_STATE_SEEN_ENTER_IDLE + + For 1, 3, 5 : See max_idle_timer_cb() function + For 2, 7 : See decrease_call_count() function + For 4, 6 : See increase_call_count() function */ gpr_atm idle_state; /* Time when the channel finished its last outstanding call, in grpc_millis */ gpr_atm last_enter_idle_time_millis; @@ -101,6 +129,7 @@ struct channel_data { /* Increase the nubmer of active calls. Before the increasement, if there are no calls, the max_idle_timer should be cancelled. */ static void increase_call_count(channel_data* chand) { + /* Exit idle */ if (gpr_atm_full_fetch_add(&chand->call_count, 1) == 0) { while (true) { gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state); @@ -126,6 +155,7 @@ static void increase_call_count(channel_data* chand) { /* Decrease the nubmer of active calls. After the decrement, if there are no calls, the max_idle_timer should be started. */ static void decrease_call_count(channel_data* chand) { + /* Enter idle */ if (gpr_atm_full_fetch_add(&chand->call_count, -1) == 1) { gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis, (gpr_atm)grpc_exec_ctx_now(exec_ctx)); From 6a15e4f15bb5490fb82c30e57a19e9d9d63585d1 Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 22 Jan 2018 13:00:49 -0800 Subject: [PATCH 07/25] Fix merge issues --- .../ext/filters/max_age/max_age_filter.cc | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc index 330cfff02fe..942e890407f 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -70,7 +70,7 @@ struct channel_data { grpc_millis max_connection_age_grace; /* Closure to run when the channel's idle duration reaches max_connection_idle and should be closed gracefully */ - grpc_closure close_max_idle_channel; + grpc_closure max_idle_timer_cb; /* Closure to run when the channel reaches its max age and should be closed gracefully */ grpc_closure close_max_age_channel; @@ -101,14 +101,11 @@ struct channel_data { | MAX_IDLE_STATE_SEEN_EXIT_IDLE | set, invalid | busy | | MAX_IDLE_STATE_SEEN_ENTER_IDLE | set, invalid | idle | +--------------------------------+----------------+---------+ - max_idle_timer will not be cancelled (unless the channel is shutting down). If the timer callback is called when the max_idle_timer is valid (i.e. idle_state is MAX_IDLE_STATE_TIMER_SET), the channel will be closed due to idleness, otherwise the channel won't be changed. - State transitions: - MAX_IDLE_STATE_INIT <-------3------ MAX_IDLE_STATE_SEEN_EXIT_IDLE ^ | ^ ^ | | | | | | @@ -116,7 +113,6 @@ struct channel_data { | | | | | | v | | v MAX_IDLE_STATE_TIMER_SET <----5------ MAX_IDLE_STATE_SEEN_ENTER_IDLE - For 1, 3, 5 : See max_idle_timer_cb() function For 2, 7 : See decrease_call_count() function For 4, 6 : See increase_call_count() function */ @@ -158,7 +154,7 @@ static void decrease_call_count(channel_data* chand) { /* Enter idle */ if (gpr_atm_full_fetch_add(&chand->call_count, -1) == 1) { gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis, - (gpr_atm)grpc_exec_ctx_now(exec_ctx)); + (gpr_atm)grpc_core::ExecCtx::Get()->Now()); while (true) { gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state); switch (idle_state) { @@ -166,8 +162,8 @@ static void decrease_call_count(channel_data* chand) { GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_idle_timer"); grpc_timer_init( - exec_ctx, &chand->max_idle_timer, - grpc_exec_ctx_now(exec_ctx) + chand->max_connection_idle, + &chand->max_idle_timer, + grpc_core::ExecCtx::Get()->Now() + chand->max_connection_idle, &chand->max_idle_timer_cb); gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_TIMER_SET); return; @@ -229,13 +225,25 @@ static void start_max_age_grace_timer_after_goaway_op(void* arg, "max_age start_max_age_grace_timer_after_goaway_op"); } -static void close_max_idle_channel(void* arg, grpc_error* error) { +static void close_max_idle_channel(channel_data* chand) { + /* Prevent the max idle timer from being set again */ + gpr_atm_no_barrier_fetch_add(&chand->call_count, 1); + grpc_transport_op* op = grpc_make_transport_op(nullptr); + op->goaway_error = + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING("max_idle"), + GRPC_ERROR_INT_HTTP2_ERROR, GRPC_HTTP2_NO_ERROR); + grpc_channel_element* elem = + grpc_channel_stack_element(chand->channel_stack, 0); + elem->filter->start_transport_op(elem, op); +} + +static void max_idle_timer_cb(void* arg, grpc_error* error) { channel_data* chand = (channel_data*)arg; if (error == GRPC_ERROR_NONE) { while (true) { gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state); if (idle_state == MAX_IDLE_STATE_TIMER_SET) { - close_max_idle_channel(exec_ctx, chand); + close_max_idle_channel(chand); /* This MAX_IDLE_STATE_INIT is a final state, we don't have to check if * idle_state has been changed */ gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_INIT); @@ -247,7 +255,7 @@ static void close_max_idle_channel(void* arg, grpc_error* error) { } } else if (idle_state == MAX_IDLE_STATE_SEEN_ENTER_IDLE) { GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_idle_timer"); - grpc_timer_init(exec_ctx, &chand->max_idle_timer, + grpc_timer_init(&chand->max_idle_timer, (grpc_millis)gpr_atm_no_barrier_load( &chand->last_enter_idle_time_millis) + chand->max_connection_idle, @@ -410,8 +418,8 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, value == INT_MAX ? GRPC_MILLIS_INF_FUTURE : value; } } - GRPC_CLOSURE_INIT(&chand->close_max_idle_channel, close_max_idle_channel, - chand, grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&chand->max_idle_timer_cb, max_idle_timer_cb, chand, + grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&chand->close_max_age_channel, close_max_age_channel, chand, grpc_schedule_on_exec_ctx); GRPC_CLOSURE_INIT(&chand->force_close_max_age_channel, From a041e0f3ae90e9a6248a331a9ddaab55324e16da Mon Sep 17 00:00:00 2001 From: Yuchen Zeng Date: Mon, 22 Jan 2018 18:18:00 -0800 Subject: [PATCH 08/25] Change if to switch, add more descriptions --- .../ext/filters/max_age/max_age_filter.cc | 83 +++++++++++++------ 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc index 942e890407f..a3f9780f3f6 100644 --- a/src/core/ext/filters/max_age/max_age_filter.cc +++ b/src/core/ext/filters/max_age/max_age_filter.cc @@ -91,6 +91,7 @@ struct channel_data { grpc_connectivity_state connectivity_state; /* Number of active calls */ gpr_atm call_count; + /* TODO(zyc): C++lize this state machine */ /* 'idle_state' holds the states of max_idle_timer and channel idleness. It can contain one of the following values: +--------------------------------+----------------+---------+ @@ -101,10 +102,32 @@ struct channel_data { | MAX_IDLE_STATE_SEEN_EXIT_IDLE | set, invalid | busy | | MAX_IDLE_STATE_SEEN_ENTER_IDLE | set, invalid | idle | +--------------------------------+----------------+---------+ + + MAX_IDLE_STATE_INIT: The initial and final state of 'idle_state'. The + channel has 1 or 1+ active calls, and the the timer is not set. Note that + we may put a virtual call to hold this state at channel initialization or + shutdown, so that the channel won't enter other states. + + MAX_IDLE_STATE_TIMER_SET: The state after the timer is set and no calls + have arrived after the timer is set. The channel must have 0 active call in + this state. If the timer is fired in this state, we will close the channel + due to idleness. + + MAX_IDLE_STATE_SEEN_EXIT_IDLE: The state after the timer is set and at + least one call has arrived after the timer is set. The channel must have 1 + or 1+ active calls in this state. If the timer is fired in this state, we + won't reschudle it. + + MAX_IDLE_STATE_SEEN_ENTER_IDLE: The state after the timer is set and the at + least one call has arrived after the timer is set, BUT the channel + currently has 1 or 1+ active calls. If the timer is fired in this state, we + will reschudle it. + max_idle_timer will not be cancelled (unless the channel is shutting down). If the timer callback is called when the max_idle_timer is valid (i.e. idle_state is MAX_IDLE_STATE_TIMER_SET), the channel will be closed due to idleness, otherwise the channel won't be changed. + State transitions: MAX_IDLE_STATE_INIT <-------3------ MAX_IDLE_STATE_SEEN_EXIT_IDLE ^ | ^ ^ | @@ -113,6 +136,7 @@ struct channel_data { | | | | | | v | | v MAX_IDLE_STATE_TIMER_SET <----5------ MAX_IDLE_STATE_SEEN_ENTER_IDLE + For 1, 3, 5 : See max_idle_timer_cb() function For 2, 7 : See decrease_call_count() function For 4, 6 : See increase_call_count() function */ @@ -240,34 +264,41 @@ static void close_max_idle_channel(channel_data* chand) { static void max_idle_timer_cb(void* arg, grpc_error* error) { channel_data* chand = (channel_data*)arg; if (error == GRPC_ERROR_NONE) { - while (true) { + bool try_again = true; + while (try_again) { gpr_atm idle_state = gpr_atm_acq_load(&chand->idle_state); - if (idle_state == MAX_IDLE_STATE_TIMER_SET) { - close_max_idle_channel(chand); - /* This MAX_IDLE_STATE_INIT is a final state, we don't have to check if - * idle_state has been changed */ - gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_INIT); - break; - } else if (idle_state == MAX_IDLE_STATE_SEEN_EXIT_IDLE) { - if (gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE, - MAX_IDLE_STATE_INIT)) { + switch (idle_state) { + case MAX_IDLE_STATE_TIMER_SET: + close_max_idle_channel(chand); + /* This MAX_IDLE_STATE_INIT is a final state, we don't have to check + * if idle_state has been changed */ + gpr_atm_rel_store(&chand->idle_state, MAX_IDLE_STATE_INIT); + try_again = false; + break; + case MAX_IDLE_STATE_SEEN_EXIT_IDLE: + if (gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_EXIT_IDLE, + MAX_IDLE_STATE_INIT)) { + try_again = false; + } + break; + case MAX_IDLE_STATE_SEEN_ENTER_IDLE: + GRPC_CHANNEL_STACK_REF(chand->channel_stack, + "max_age max_idle_timer"); + grpc_timer_init(&chand->max_idle_timer, + (grpc_millis)gpr_atm_no_barrier_load( + &chand->last_enter_idle_time_millis) + + chand->max_connection_idle, + &chand->max_idle_timer_cb); + /* idle_state may have already been set to + MAX_IDLE_STATE_SEEN_EXIT_IDLE by increase_call_count(), in this + case, we don't need to set it to MAX_IDLE_STATE_TIMER_SET */ + gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_ENTER_IDLE, + MAX_IDLE_STATE_TIMER_SET); + try_again = false; + break; + default: + /* try again */ break; - } - } else if (idle_state == MAX_IDLE_STATE_SEEN_ENTER_IDLE) { - GRPC_CHANNEL_STACK_REF(chand->channel_stack, "max_age max_idle_timer"); - grpc_timer_init(&chand->max_idle_timer, - (grpc_millis)gpr_atm_no_barrier_load( - &chand->last_enter_idle_time_millis) + - chand->max_connection_idle, - &chand->max_idle_timer_cb); - /* idle_state may have already been set to MAX_IDLE_STATE_SEEN_EXIT_IDLE - by increase_call_count(), in this case, we don't need to set it to - MAX_IDLE_STATE_TIMER_SET */ - gpr_atm_rel_cas(&chand->idle_state, MAX_IDLE_STATE_SEEN_ENTER_IDLE, - MAX_IDLE_STATE_TIMER_SET); - break; - } else { - /* try again */ } } } From bc953bc53fdf031992483db1f0859ad59913426a Mon Sep 17 00:00:00 2001 From: Zhouyihai Ding Date: Tue, 23 Jan 2018 14:42:45 -0800 Subject: [PATCH 09/25] php: fix call metadata leak --- src/php/ext/grpc/call.c | 16 ++++++++++++++-- src/php/ext/grpc/call.h | 3 ++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index c4997f720d1..9c0f3f8a91a 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -174,6 +174,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 +514,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); diff --git a/src/php/ext/grpc/call.h b/src/php/ext/grpc/call.h index 5bde5d53905..104ac301c13 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_ */ From 1cd156d736fd61a0416073cfe508c6801e5cd10e Mon Sep 17 00:00:00 2001 From: Zhouyihai Ding Date: Tue, 23 Jan 2018 14:53:25 -0800 Subject: [PATCH 10/25] php: php_info add grpc version --- src/php/ext/grpc/php_grpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 0f2c5b8114c..5971babc00e 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 From 5b98d0be110eb9ab4813dd992c762d896c88472e Mon Sep 17 00:00:00 2001 From: Zhouyihai Ding Date: Tue, 23 Jan 2018 14:39:48 -0800 Subject: [PATCH 11/25] php: fix channel reuse and wrapper memory leak --- src/php/ext/grpc/channel.c | 135 ++++++++++++++++++++----- src/php/ext/grpc/channel.h | 5 + src/php/ext/grpc/channel_credentials.c | 8 +- src/php/ext/grpc/php7_wrapper.h | 2 + 4 files changed, 126 insertions(+), 24 deletions(-) diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c index db59869c7f7..4054723b433 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -41,6 +41,7 @@ #include #include +#include #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 69adc4782c5..86bfdea51a2 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 d120d6e90fe..ed74b991bd9 100644 --- a/src/php/ext/grpc/channel_credentials.c +++ b/src/php/ext/grpc/channel_credentials.c @@ -59,6 +59,7 @@ static grpc_ssl_roots_override_result get_ssl_roots_override( PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_channel_credentials) if (p->wrapped != NULL) { grpc_channel_credentials_release(p->wrapped); + p->wrapped = NULL; } PHP_GRPC_FREE_WRAPPED_FUNC_END() @@ -199,8 +200,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 96091f9dadb..2f4a53611c3 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)); From 182707959c1d1325c184bcbcbc62b210f7bec20b Mon Sep 17 00:00:00 2001 From: Stanley Cheung Date: Tue, 23 Jan 2018 18:50:39 -0800 Subject: [PATCH 12/25] PHP: Update release notes for 1.9 --- package.xml | 12 +++++------- templates/package.xml.template | 16 +++++++--------- tools/buildgen/plugins/expand_version.py | 7 +++++++ 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/package.xml b/package.xml index caf276f71f3..12b7b719588 100644 --- a/package.xml +++ b/package.xml @@ -10,7 +10,7 @@ grpc-packages@google.com yes - 2017-08-24 + 2018-01-23 1.9.0RC1 @@ -22,12 +22,10 @@ Apache 2.0 -- 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 +- Updated gRPC C Core library version 1.9 +- Report grpc extension version in phpinfo() #13687 +- Fixed memory leak when handling metadata array #13660 +- Fixed memory involing persistent channels #14125 - #14130 diff --git a/templates/package.xml.template b/templates/package.xml.template index f10f75b8c06..123217989dc 100644 --- a/templates/package.xml.template +++ b/templates/package.xml.template @@ -12,24 +12,22 @@ grpc-packages@google.com yes - 2017-08-24 + 2018-01-23 ${settings.php_version.php()} ${settings.php_version.php()} - beta - beta + ${settings.php_version.php_stability()} + ${settings.php_version.php_stability()} Apache 2.0 - - 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 + - Updated gRPC C Core library version 1.9 + - Report grpc extension version in phpinfo() #13687 + - Fixed memory leak when handling metadata array #13660 + - Fixed memory involing persistent channels #14125 - #14130 diff --git a/tools/buildgen/plugins/expand_version.py b/tools/buildgen/plugins/expand_version.py index 8f56ce8fc97..facf349b0cd 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) From dea0f0bb59e73bf1201c15e2f553e14a457c58cc Mon Sep 17 00:00:00 2001 From: Zhouyihai Ding Date: Wed, 24 Jan 2018 11:05:26 -0800 Subject: [PATCH 13/25] php: fix call leaks --- src/php/ext/grpc/call.c | 9 +++++++-- src/php/ext/grpc/call_credentials.c | 11 +++++++++-- src/php/ext/grpc/channel_credentials.c | 6 +++++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index 9c0f3f8a91a..ff55c3cbfaf 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; @@ -538,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_credentials.c b/src/php/ext/grpc/call_credentials.c index a395d53614e..41c488a79cd 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_credentials.c b/src/php/ext/grpc/channel_credentials.c index ed74b991bd9..624d7cc75cc 100644 --- a/src/php/ext/grpc/channel_credentials.c +++ b/src/php/ext/grpc/channel_credentials.c @@ -57,6 +57,10 @@ 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; @@ -153,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); } From ebe5fbfbe8ff07102a7fd42e90441867a5beb8f0 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 25 Jan 2018 23:50:46 +0100 Subject: [PATCH 14/25] Revert "Merge pull request #13932 from dgquintas/conn_subchannel" This reverts commit a8891634d32ad9556921faed2707fb304304c900, reversing changes made to 47fe8507a1905c20a86df09f97c3f972d643dda5. --- .../filters/client_channel/client_channel.cc | 8 +- .../ext/filters/client_channel/lb_policy.h | 7 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 4 +- .../lb_policy/pick_first/pick_first.cc | 75 +++-- .../lb_policy/round_robin/round_robin.cc | 63 ++-- .../lb_policy/subchannel_list.cc | 5 +- .../lb_policy/subchannel_list.h | 3 +- .../ext/filters/client_channel/subchannel.cc | 296 +++++++++--------- .../ext/filters/client_channel/subchannel.h | 77 +++-- test/cpp/end2end/client_lb_end2end_test.cc | 36 --- 10 files changed, 295 insertions(+), 279 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index a8a7a37be01..428945d5ad1 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1003,7 +1003,7 @@ static void create_subchannel_call_locked(grpc_call_element* elem, grpc_error* error) { channel_data* chand = (channel_data*)elem->channel_data; call_data* calld = (call_data*)elem->call_data; - const grpc_core::ConnectedSubchannel::CallArgs call_args = { + const grpc_connected_subchannel_call_args call_args = { calld->pollent, // pollent calld->path, // path calld->call_start_time, // start_time @@ -1012,8 +1012,8 @@ static void create_subchannel_call_locked(grpc_call_element* elem, calld->pick.subchannel_call_context, // context calld->call_combiner // call_combiner }; - grpc_error* new_error = calld->pick.connected_subchannel->CreateCall( - call_args, &calld->subchannel_call); + grpc_error* new_error = grpc_connected_subchannel_create_call( + calld->pick.connected_subchannel, &call_args, &calld->subchannel_call); if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_DEBUG, "chand=%p calld=%p: create subchannel_call=%p: error=%s", chand, calld, calld->subchannel_call, grpc_error_string(new_error)); @@ -1463,7 +1463,7 @@ static void cc_destroy_call_elem(grpc_call_element* elem, } GPR_ASSERT(calld->waiting_for_pick_batches_count == 0); if (calld->pick.connected_subchannel != nullptr) { - calld->pick.connected_subchannel.reset(); + GRPC_CONNECTED_SUBCHANNEL_UNREF(calld->pick.connected_subchannel, "picked"); } for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) { if (calld->pick.subchannel_call_context[i].value != nullptr) { diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index e19726efb3b..ea70de068e3 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -55,9 +55,9 @@ typedef struct grpc_lb_policy_pick_state { grpc_linked_mdelem lb_token_mdelem_storage; /// Closure to run when pick is complete, if not completed synchronously. grpc_closure* on_complete; - /// Will be set to the selected subchannel, or nullptr on failure or when + /// Will be set to the selected subchannel, or NULL on failure or when /// the LB policy decides to drop the call. - grpc_core::RefCountedPtr connected_subchannel; + grpc_connected_subchannel* connected_subchannel; /// Will be populated with context to pass to the subchannel call, if needed. grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT]; /// Upon success, \a *user_data will be set to whatever opaque information @@ -153,8 +153,7 @@ void grpc_lb_policy_shutdown_locked(grpc_lb_policy* policy, int grpc_lb_policy_pick_locked(grpc_lb_policy* policy, grpc_lb_policy_pick_state* pick); -/** Perform a connected subchannel ping (see \a - grpc_core::ConnectedSubchannel::Ping) +/** Perform a connected subchannel ping (see \a grpc_connected_subchannel_ping) against one of the connected subchannels managed by \a policy. */ void grpc_lb_policy_ping_one_locked(grpc_lb_policy* policy, grpc_closure* on_initiate, 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 6c29cd82180..629f8ac58ee 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 @@ -939,7 +939,7 @@ static void glb_shutdown_locked(grpc_lb_policy* pol, } gpr_free(pp); } else { - pp->pick->connected_subchannel.reset(); + pp->pick->connected_subchannel = nullptr; GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error)); } pp = next; @@ -976,7 +976,7 @@ static void glb_cancel_pick_locked(grpc_lb_policy* pol, while (pp != nullptr) { pending_pick* next = pp->next; if (pp->pick == pick) { - pick->connected_subchannel.reset(); + pick->connected_subchannel = nullptr; GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Pick Cancelled", &error, 1)); diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 725b78d4787..60385272cf5 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -81,7 +81,7 @@ static void pf_shutdown_locked(grpc_lb_policy* pol, GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); } } else { - pick->connected_subchannel.reset(); + pick->connected_subchannel = nullptr; GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error)); } } @@ -111,7 +111,7 @@ static void pf_cancel_pick_locked(grpc_lb_policy* pol, while (pp != nullptr) { grpc_lb_policy_pick_state* next = pp->next; if (pp == pick) { - pick->connected_subchannel.reset(); + pick->connected_subchannel = nullptr; GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Pick Cancelled", &error, 1)); @@ -176,7 +176,8 @@ static int pf_pick_locked(grpc_lb_policy* pol, pick_first_lb_policy* p = (pick_first_lb_policy*)pol; // If we have a selected subchannel already, return synchronously. if (p->selected != nullptr) { - pick->connected_subchannel = p->selected->connected_subchannel; + pick->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF( + p->selected->connected_subchannel, "picked"); return 1; } // No subchannel selected yet, so handle asynchronously. @@ -216,7 +217,8 @@ static void pf_ping_one_locked(grpc_lb_policy* pol, grpc_closure* on_initiate, grpc_closure* on_ack) { pick_first_lb_policy* p = (pick_first_lb_policy*)pol; if (p->selected) { - p->selected->connected_subchannel->Ping(on_initiate, on_ack); + grpc_connected_subchannel_ping(p->selected->connected_subchannel, + on_initiate, on_ack); } else { GRPC_CLOSURE_SCHED(on_initiate, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected")); @@ -295,7 +297,8 @@ static void pf_update_locked(grpc_lb_policy* policy, subchannel_list->num_subchannels); } if (p->selected->connected_subchannel != nullptr) { - sd->connected_subchannel = p->selected->connected_subchannel; + sd->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF( + p->selected->connected_subchannel, "pf_update_includes_selected"); } p->selected = sd; if (p->subchannel_list != nullptr) { @@ -407,8 +410,8 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) { // re-resolution is introduced. But we need to investigate whether we // really want to take any action instead of waiting for the selected // subchannel reconnecting. - GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN); - if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { + if (sd->curr_connectivity_state == GRPC_CHANNEL_SHUTDOWN || + sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { // If the selected channel goes bad, request a re-resolution. grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE, @@ -416,19 +419,20 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) { p->started_picking = false; grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_pick_first_trace, GRPC_ERROR_NONE); - // in transient failure. Rely on re-resolution to recover. - p->selected = nullptr; - grpc_lb_subchannel_data_stop_connectivity_watch(sd); - grpc_lb_subchannel_list_unref_for_connectivity_watch( - sd->subchannel_list, "pf_selected_shutdown"); - grpc_lb_subchannel_data_unref_subchannel( - sd, "pf_selected_shutdown"); // Unrefs connected subchannel } else { grpc_connectivity_state_set(&p->state_tracker, sd->curr_connectivity_state, GRPC_ERROR_REF(error), "selected_changed"); + } + if (sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN) { // Renew notification. grpc_lb_subchannel_data_start_connectivity_watch(sd); + } else { + p->selected = nullptr; + grpc_lb_subchannel_data_stop_connectivity_watch(sd); + grpc_lb_subchannel_list_unref_for_connectivity_watch( + sd->subchannel_list, "pf_selected_shutdown"); + grpc_lb_subchannel_data_unref_subchannel(sd, "pf_selected_shutdown"); } } return; @@ -446,8 +450,6 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) { case GRPC_CHANNEL_READY: { // Case 2. Promote p->latest_pending_subchannel_list to // p->subchannel_list. - sd->connected_subchannel = - grpc_subchannel_get_connected_subchannel(sd->subchannel); if (sd->subchannel_list == p->latest_pending_subchannel_list) { GPR_ASSERT(p->subchannel_list != nullptr); grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list, @@ -458,6 +460,9 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) { // Cases 1 and 2. grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_READY, GRPC_ERROR_NONE, "connecting_ready"); + sd->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF( + grpc_subchannel_get_connected_subchannel(sd->subchannel), + "connected"); p->selected = sd; if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", (void*)p, @@ -469,7 +474,8 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) { grpc_lb_policy_pick_state* pick; while ((pick = p->pending_picks)) { p->pending_picks = pick->next; - pick->connected_subchannel = p->selected->connected_subchannel; + pick->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF( + p->selected->connected_subchannel, "picked"); if (grpc_lb_pick_first_trace.enabled()) { gpr_log(GPR_INFO, "Servicing pending pick with selected subchannel %p", @@ -514,8 +520,39 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) { grpc_lb_subchannel_data_start_connectivity_watch(sd); break; } - case GRPC_CHANNEL_SHUTDOWN: - GPR_UNREACHABLE_CODE(break); + case GRPC_CHANNEL_SHUTDOWN: { + grpc_lb_subchannel_data_stop_connectivity_watch(sd); + grpc_lb_subchannel_data_unref_subchannel(sd, "pf_candidate_shutdown"); + // Advance to next subchannel and check its state. + grpc_lb_subchannel_data* original_sd = sd; + do { + sd->subchannel_list->checking_subchannel = + (sd->subchannel_list->checking_subchannel + 1) % + sd->subchannel_list->num_subchannels; + sd = &sd->subchannel_list + ->subchannels[sd->subchannel_list->checking_subchannel]; + } while (sd->subchannel == nullptr && sd != original_sd); + if (sd == original_sd) { + grpc_lb_subchannel_list_unref_for_connectivity_watch( + sd->subchannel_list, "pf_exhausted_subchannels"); + if (sd->subchannel_list == p->subchannel_list) { + grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_IDLE, + GRPC_ERROR_NONE, + "exhausted_subchannels+reresolve"); + p->started_picking = false; + grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_pick_first_trace, + GRPC_ERROR_NONE); + } + } else { + if (sd->subchannel_list == p->subchannel_list) { + grpc_connectivity_state_set( + &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_REF(error), "subchannel_failed"); + } + // Reuses the connectivity refs from the previous watch. + grpc_lb_subchannel_data_start_connectivity_watch(sd); + } + } } } 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 e217a0b0c00..c4e98206e95 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 @@ -128,7 +128,7 @@ static void update_last_ready_subchannel_index_locked(round_robin_lb_policy* p, (void*)p, (unsigned long)last_ready_index, (void*)p->subchannel_list->subchannels[last_ready_index].subchannel, (void*)p->subchannel_list->subchannels[last_ready_index] - .connected_subchannel.get()); + .connected_subchannel); } } @@ -163,7 +163,7 @@ static void rr_shutdown_locked(grpc_lb_policy* pol, GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); } } else { - pick->connected_subchannel.reset(); + pick->connected_subchannel = nullptr; GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error)); } } @@ -193,7 +193,7 @@ static void rr_cancel_pick_locked(grpc_lb_policy* pol, while (pp != nullptr) { grpc_lb_policy_pick_state* next = pp->next; if (pp == pick) { - pick->connected_subchannel.reset(); + pick->connected_subchannel = nullptr; GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Pick cancelled", &error, 1)); @@ -217,7 +217,7 @@ static void rr_cancel_picks_locked(grpc_lb_policy* pol, grpc_lb_policy_pick_state* next = pick->next; if ((pick->initial_metadata_flags & initial_metadata_flags_mask) == initial_metadata_flags_eq) { - pick->connected_subchannel.reset(); + pick->connected_subchannel = nullptr; GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Pick cancelled", &error, 1)); @@ -263,7 +263,8 @@ static int rr_pick_locked(grpc_lb_policy* pol, /* readily available, report right away */ grpc_lb_subchannel_data* sd = &p->subchannel_list->subchannels[next_ready_index]; - pick->connected_subchannel = sd->connected_subchannel; + pick->connected_subchannel = + GRPC_CONNECTED_SUBCHANNEL_REF(sd->connected_subchannel, "rr_picked"); if (pick->user_data != nullptr) { *pick->user_data = sd->user_data; } @@ -272,8 +273,8 @@ static int rr_pick_locked(grpc_lb_policy* pol, GPR_DEBUG, "[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, " "index %" PRIuPTR ")", - p, sd->subchannel, pick->connected_subchannel.get(), - sd->subchannel_list, next_ready_index); + p, sd->subchannel, pick->connected_subchannel, sd->subchannel_list, + next_ready_index); } /* only advance the last picked pointer if the selection was used */ update_last_ready_subchannel_index_locked(p, next_ready_index); @@ -291,14 +292,15 @@ static int rr_pick_locked(grpc_lb_policy* pol, static void update_state_counters_locked(grpc_lb_subchannel_data* sd) { grpc_lb_subchannel_list* subchannel_list = sd->subchannel_list; - GPR_ASSERT(sd->prev_connectivity_state != GRPC_CHANNEL_SHUTDOWN); - GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN); if (sd->prev_connectivity_state == GRPC_CHANNEL_READY) { GPR_ASSERT(subchannel_list->num_ready > 0); --subchannel_list->num_ready; } else if (sd->prev_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { GPR_ASSERT(subchannel_list->num_transient_failures > 0); --subchannel_list->num_transient_failures; + } else if (sd->prev_connectivity_state == GRPC_CHANNEL_SHUTDOWN) { + GPR_ASSERT(subchannel_list->num_shutdown > 0); + --subchannel_list->num_shutdown; } else if (sd->prev_connectivity_state == GRPC_CHANNEL_IDLE) { GPR_ASSERT(subchannel_list->num_idle > 0); --subchannel_list->num_idle; @@ -308,6 +310,8 @@ static void update_state_counters_locked(grpc_lb_subchannel_data* sd) { ++subchannel_list->num_ready; } else if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { ++subchannel_list->num_transient_failures; + } else if (sd->curr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) { + ++subchannel_list->num_shutdown; } else if (sd->curr_connectivity_state == GRPC_CHANNEL_IDLE) { ++subchannel_list->num_idle; } @@ -407,7 +411,6 @@ static void rr_connectivity_changed_locked(void* arg, grpc_error* error) { // either the current or latest pending subchannel lists. GPR_ASSERT(sd->subchannel_list == p->subchannel_list || sd->subchannel_list == p->latest_pending_subchannel_list); - GPR_ASSERT(sd->pending_connectivity_state_unsafe != GRPC_CHANNEL_SHUTDOWN); // Now that we're inside the combiner, copy the pending connectivity // state (which was set by the connectivity state watcher) to // curr_connectivity_state, which is what we use inside of the combiner. @@ -415,17 +418,18 @@ static void rr_connectivity_changed_locked(void* arg, grpc_error* error) { // Update state counters and new overall state. update_state_counters_locked(sd); update_lb_connectivity_status_locked(sd, GRPC_ERROR_REF(error)); - // If the sd's new state is TRANSIENT_FAILURE, unref the *connected* - // subchannel, if any. - switch (sd->curr_connectivity_state) { - case GRPC_CHANNEL_TRANSIENT_FAILURE: { - sd->connected_subchannel.reset(); - break; - } - case GRPC_CHANNEL_READY: { + // If the sd's new state is SHUTDOWN, unref the subchannel. + if (sd->curr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) { + grpc_lb_subchannel_data_stop_connectivity_watch(sd); + grpc_lb_subchannel_data_unref_subchannel(sd, "rr_connectivity_shutdown"); + grpc_lb_subchannel_list_unref_for_connectivity_watch( + sd->subchannel_list, "rr_connectivity_shutdown"); + } else { // sd not in SHUTDOWN + if (sd->curr_connectivity_state == GRPC_CHANNEL_READY) { if (sd->connected_subchannel == nullptr) { - sd->connected_subchannel = - grpc_subchannel_get_connected_subchannel(sd->subchannel); + sd->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF( + grpc_subchannel_get_connected_subchannel(sd->subchannel), + "connected"); } if (sd->subchannel_list != p->subchannel_list) { // promote sd->subchannel_list to p->subchannel_list. @@ -468,7 +472,8 @@ static void rr_connectivity_changed_locked(void* arg, grpc_error* error) { grpc_lb_policy_pick_state* pick; while ((pick = p->pending_picks)) { p->pending_picks = pick->next; - pick->connected_subchannel = selected->connected_subchannel; + pick->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF( + selected->connected_subchannel, "rr_picked"); if (pick->user_data != nullptr) { *pick->user_data = selected->user_data; } @@ -481,15 +486,10 @@ static void rr_connectivity_changed_locked(void* arg, grpc_error* error) { } GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE); } - break; } - case GRPC_CHANNEL_SHUTDOWN: - GPR_UNREACHABLE_CODE(return ); - case GRPC_CHANNEL_CONNECTING: - case GRPC_CHANNEL_IDLE:; // fallthrough + // Renew notification. + grpc_lb_subchannel_data_start_connectivity_watch(sd); } - // Renew notification. - grpc_lb_subchannel_data_start_connectivity_watch(sd); } static grpc_connectivity_state rr_check_connectivity_locked( @@ -513,9 +513,10 @@ static void rr_ping_one_locked(grpc_lb_policy* pol, grpc_closure* on_initiate, if (next_ready_index < p->subchannel_list->num_subchannels) { grpc_lb_subchannel_data* selected = &p->subchannel_list->subchannels[next_ready_index]; - grpc_core::RefCountedPtr target = - selected->connected_subchannel; - target->Ping(on_initiate, on_ack); + grpc_connected_subchannel* target = GRPC_CONNECTED_SUBCHANNEL_REF( + selected->connected_subchannel, "rr_ping"); + grpc_connected_subchannel_ping(target, on_initiate, on_ack); + GRPC_CONNECTED_SUBCHANNEL_UNREF(target, "rr_ping"); } else { GRPC_CLOSURE_SCHED(on_initiate, GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Round Robin not connected")); diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc index fa2ffcc7966..5ce1298afc4 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc @@ -42,7 +42,10 @@ void grpc_lb_subchannel_data_unref_subchannel(grpc_lb_subchannel_data* sd, } GRPC_SUBCHANNEL_UNREF(sd->subchannel, reason); sd->subchannel = nullptr; - sd->connected_subchannel.reset(); + if (sd->connected_subchannel != nullptr) { + GRPC_CONNECTED_SUBCHANNEL_UNREF(sd->connected_subchannel, reason); + sd->connected_subchannel = nullptr; + } if (sd->user_data != nullptr) { GPR_ASSERT(sd->user_data_vtable != nullptr); sd->user_data_vtable->destroy(sd->user_data); 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 f4e345def6b..0f8cea9347e 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,6 @@ #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/transport/connectivity_state.h" // TODO(roth): This code is intended to be shared between pick_first and @@ -44,7 +43,7 @@ typedef struct { grpc_lb_subchannel_list* subchannel_list; /** subchannel itself */ grpc_subchannel* subchannel; - grpc_core::RefCountedPtr connected_subchannel; + grpc_connected_subchannel* connected_subchannel; /** Is a connectivity notification pending? */ bool connectivity_notification_pending; /** notification that connectivity has changed on subchannel */ diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index bb43651d0c3..83aaa09445b 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -56,6 +56,10 @@ #define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120 #define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2 +#define GET_CONNECTED_SUBCHANNEL(subchannel, barrier) \ + ((grpc_connected_subchannel*)(gpr_atm_##barrier##_load( \ + &(subchannel)->connected_subchannel))) + namespace { struct state_watcher { grpc_closure closure; @@ -95,7 +99,7 @@ struct grpc_subchannel { grpc_connect_out_args connecting_result; /** callback for connection finishing */ - grpc_closure on_connected; + grpc_closure connected; /** callback for our alarm */ grpc_closure on_alarm; @@ -104,13 +108,12 @@ struct grpc_subchannel { being setup */ grpc_pollset_set* pollset_set; + /** active connection, or null; of type grpc_connected_subchannel */ + gpr_atm connected_subchannel; + /** mutex protecting remaining elements */ gpr_mu mu; - /** active connection, or null; of type grpc_core::ConnectedSubchannel - */ - grpc_core::RefCountedPtr connected_subchannel; - /** have we seen a disconnection? */ bool disconnected; /** are we connecting */ @@ -134,15 +137,16 @@ struct grpc_subchannel { }; struct grpc_subchannel_call { - grpc_core::ConnectedSubchannel* connection; + grpc_connected_subchannel* connection; grpc_closure* schedule_closure_after_destroy; }; #define SUBCHANNEL_CALL_TO_CALL_STACK(call) ((grpc_call_stack*)((call) + 1)) +#define CHANNEL_STACK_FROM_CONNECTION(con) ((grpc_channel_stack*)(con)) #define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \ (((grpc_subchannel_call*)(callstack)) - 1) -static void on_subchannel_connected(void* subchannel, grpc_error* error); +static void subchannel_connected(void* subchannel, grpc_error* error); #ifndef NDEBUG #define REF_REASON reason @@ -160,9 +164,20 @@ static void on_subchannel_connected(void* subchannel, grpc_error* error); */ static void connection_destroy(void* arg, grpc_error* error) { - grpc_channel_stack* stk = (grpc_channel_stack*)arg; - grpc_channel_stack_destroy(stk); - gpr_free(stk); + grpc_connected_subchannel* c = (grpc_connected_subchannel*)arg; + grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CONNECTION(c)); + gpr_free(c); +} + +grpc_connected_subchannel* grpc_connected_subchannel_ref( + grpc_connected_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + GRPC_CHANNEL_STACK_REF(CHANNEL_STACK_FROM_CONNECTION(c), REF_REASON); + return c; +} + +void grpc_connected_subchannel_unref( + grpc_connected_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + GRPC_CHANNEL_STACK_UNREF(CHANNEL_STACK_FROM_CONNECTION(c), REF_REASON); } /* @@ -229,13 +244,18 @@ grpc_subchannel* grpc_subchannel_ref_from_weak_ref( } static void disconnect(grpc_subchannel* c) { + grpc_connected_subchannel* con; grpc_subchannel_index_unregister(c->key, c); gpr_mu_lock(&c->mu); GPR_ASSERT(!c->disconnected); c->disconnected = true; grpc_connector_shutdown(c->connector, GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Subchannel disconnected")); - c->connected_subchannel.reset(); + con = GET_CONNECTED_SUBCHANNEL(c, no_barrier); + if (con != nullptr) { + GRPC_CONNECTED_SUBCHANNEL_UNREF(con, "connection"); + gpr_atm_no_barrier_store(&c->connected_subchannel, (gpr_atm)0xdeadbeef); + } gpr_mu_unlock(&c->mu); } @@ -355,7 +375,7 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, if (new_args != nullptr) grpc_channel_args_destroy(new_args); c->root_external_state_watcher.next = c->root_external_state_watcher.prev = &c->root_external_state_watcher; - GRPC_CLOSURE_INIT(&c->on_connected, on_subchannel_connected, c, + GRPC_CLOSURE_INIT(&c->connected, subchannel_connected, c, grpc_schedule_on_exec_ctx); grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE, "subchannel"); @@ -379,7 +399,7 @@ static void continue_connect_locked(grpc_subchannel* c) { grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, "state_change"); grpc_connector_connect(c->connector, &args, &c->connecting_result, - &c->on_connected); + &c->connected); } grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel* c, @@ -439,7 +459,7 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) { return; } - if (c->connected_subchannel != nullptr) { + if (GET_CONNECTED_SUBCHANNEL(c, no_barrier) != nullptr) { /* Already connected: don't restart */ return; } @@ -461,10 +481,9 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) { const grpc_millis time_til_next = c->next_attempt_deadline - grpc_core::ExecCtx::Get()->Now(); if (time_til_next <= 0) { - gpr_log(GPR_INFO, "Subchannel %p: Retry immediately", c); + gpr_log(GPR_INFO, "Retry immediately"); } else { - gpr_log(GPR_INFO, "Subchannel %p: Retry in %" PRIdPTR " milliseconds", c, - time_til_next); + gpr_log(GPR_INFO, "Retry in %" PRIdPTR " milliseconds", time_til_next); } GRPC_CLOSURE_INIT(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx); grpc_timer_init(&c->alarm, c->next_attempt_deadline, &c->on_alarm); @@ -508,56 +527,75 @@ void grpc_subchannel_notify_on_state_change( } } -static void on_connected_subchannel_connectivity_changed(void* p, - grpc_error* error) { - state_watcher* connected_subchannel_watcher = (state_watcher*)p; - grpc_subchannel* c = connected_subchannel_watcher->subchannel; +void grpc_connected_subchannel_process_transport_op( + grpc_connected_subchannel* con, grpc_transport_op* op) { + grpc_channel_stack* channel_stack = CHANNEL_STACK_FROM_CONNECTION(con); + grpc_channel_element* top_elem = grpc_channel_stack_element(channel_stack, 0); + top_elem->filter->start_transport_op(top_elem, op); +} + +static void subchannel_on_child_state_changed(void* p, grpc_error* error) { + state_watcher* sw = (state_watcher*)p; + grpc_subchannel* c = sw->subchannel; gpr_mu* mu = &c->mu; gpr_mu_lock(mu); - switch (connected_subchannel_watcher->connectivity_state) { - case GRPC_CHANNEL_TRANSIENT_FAILURE: - case GRPC_CHANNEL_SHUTDOWN: { - if (!c->disconnected && c->connected_subchannel != nullptr) { - if (grpc_trace_stream_refcount.enabled()) { - gpr_log(GPR_INFO, - "Connected subchannel %p of subchannel %p has gone into %s. " - "Attempting to reconnect.", - c->connected_subchannel.get(), c, - grpc_connectivity_state_name( - connected_subchannel_watcher->connectivity_state)); - } - c->connected_subchannel.reset(); - grpc_connectivity_state_set(&c->state_tracker, - GRPC_CHANNEL_TRANSIENT_FAILURE, - GRPC_ERROR_REF(error), "reflect_child"); - c->backoff_begun = false; - c->backoff->Reset(); - maybe_start_connecting_locked(c); - } else { - connected_subchannel_watcher->connectivity_state = - GRPC_CHANNEL_SHUTDOWN; - } - break; - } - default: { - grpc_connectivity_state_set( - &c->state_tracker, connected_subchannel_watcher->connectivity_state, - GRPC_ERROR_REF(error), "reflect_child"); - GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher"); - c->connected_subchannel->NotifyOnStateChange( - nullptr, &connected_subchannel_watcher->connectivity_state, - &connected_subchannel_watcher->closure); - connected_subchannel_watcher = nullptr; - } + /* if we failed just leave this closure */ + if (sw->connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) { + /* any errors on a subchannel ==> we're done, create a new one */ + sw->connectivity_state = GRPC_CHANNEL_SHUTDOWN; + } + grpc_connectivity_state_set(&c->state_tracker, sw->connectivity_state, + GRPC_ERROR_REF(error), "reflect_child"); + if (sw->connectivity_state != GRPC_CHANNEL_SHUTDOWN) { + grpc_connected_subchannel_notify_on_state_change( + GET_CONNECTED_SUBCHANNEL(c, no_barrier), nullptr, + &sw->connectivity_state, &sw->closure); + GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher"); + sw = nullptr; } + gpr_mu_unlock(mu); GRPC_SUBCHANNEL_WEAK_UNREF(c, "state_watcher"); - gpr_free(connected_subchannel_watcher); + gpr_free(sw); +} + +static void connected_subchannel_state_op(grpc_connected_subchannel* con, + grpc_pollset_set* interested_parties, + grpc_connectivity_state* state, + grpc_closure* closure) { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + grpc_channel_element* elem; + op->connectivity_state = state; + op->on_connectivity_state_change = closure; + op->bind_pollset_set = interested_parties; + elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(con), 0); + elem->filter->start_transport_op(elem, op); +} + +void grpc_connected_subchannel_notify_on_state_change( + grpc_connected_subchannel* con, grpc_pollset_set* interested_parties, + grpc_connectivity_state* state, grpc_closure* closure) { + connected_subchannel_state_op(con, interested_parties, state, closure); +} + +void grpc_connected_subchannel_ping(grpc_connected_subchannel* con, + grpc_closure* on_initiate, + grpc_closure* on_ack) { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + grpc_channel_element* elem; + op->send_ping.on_initiate = on_initiate; + op->send_ping.on_ack = on_ack; + elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(con), 0); + elem->filter->start_transport_op(elem, op); } static bool publish_transport_locked(grpc_subchannel* c) { + grpc_connected_subchannel* con; + grpc_channel_stack* stk; + state_watcher* sw_subchannel; + /* construct channel stack */ grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); grpc_channel_stack_builder_set_channel_arguments( @@ -569,9 +607,8 @@ static bool publish_transport_locked(grpc_subchannel* c) { grpc_channel_stack_builder_destroy(builder); return false; } - grpc_channel_stack* stk; grpc_error* error = grpc_channel_stack_builder_finish( - builder, 0, 1, connection_destroy, nullptr, (void**)&stk); + builder, 0, 1, connection_destroy, nullptr, (void**)&con); if (error != GRPC_ERROR_NONE) { grpc_transport_destroy(c->connecting_result.transport); gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", @@ -579,37 +616,38 @@ static bool publish_transport_locked(grpc_subchannel* c) { GRPC_ERROR_UNREF(error); return false; } + stk = CHANNEL_STACK_FROM_CONNECTION(con); memset(&c->connecting_result, 0, sizeof(c->connecting_result)); /* initialize state watcher */ - state_watcher* connected_subchannel_watcher = - (state_watcher*)gpr_zalloc(sizeof(*connected_subchannel_watcher)); - connected_subchannel_watcher->subchannel = c; - connected_subchannel_watcher->connectivity_state = GRPC_CHANNEL_READY; - GRPC_CLOSURE_INIT(&connected_subchannel_watcher->closure, - on_connected_subchannel_connectivity_changed, - connected_subchannel_watcher, grpc_schedule_on_exec_ctx); + sw_subchannel = (state_watcher*)gpr_malloc(sizeof(*sw_subchannel)); + sw_subchannel->subchannel = c; + sw_subchannel->connectivity_state = GRPC_CHANNEL_READY; + GRPC_CLOSURE_INIT(&sw_subchannel->closure, subchannel_on_child_state_changed, + sw_subchannel, grpc_schedule_on_exec_ctx); if (c->disconnected) { - gpr_free(connected_subchannel_watcher); + gpr_free(sw_subchannel); grpc_channel_stack_destroy(stk); - gpr_free(stk); + gpr_free(con); return false; } /* publish */ - c->connected_subchannel.reset( - grpc_core::New(stk)); - gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", - c->connected_subchannel.get(), c); + /* TODO(ctiller): this full barrier seems to clear up a TSAN failure. + I'd have expected the rel_cas below to be enough, but + seemingly it's not. + Re-evaluate if we really need this. */ + gpr_atm_full_barrier(); + GPR_ASSERT(gpr_atm_rel_cas(&c->connected_subchannel, 0, (gpr_atm)con)); /* setup subchannel watching connected subchannel for changes; subchannel ref for connecting is donated to the state watcher */ GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher"); GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); - c->connected_subchannel->NotifyOnStateChange( - c->pollset_set, &connected_subchannel_watcher->connectivity_state, - &connected_subchannel_watcher->closure); + grpc_connected_subchannel_notify_on_state_change( + con, c->pollset_set, &sw_subchannel->connectivity_state, + &sw_subchannel->closure); /* signal completion */ grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_READY, @@ -617,11 +655,11 @@ static bool publish_transport_locked(grpc_subchannel* c) { return true; } -static void on_subchannel_connected(void* arg, grpc_error* error) { +static void subchannel_connected(void* arg, grpc_error* error) { grpc_subchannel* c = (grpc_subchannel*)arg; grpc_channel_args* delete_channel_args = c->connecting_result.channel_args; - GRPC_SUBCHANNEL_WEAK_REF(c, "on_subchannel_connected"); + GRPC_SUBCHANNEL_WEAK_REF(c, "connected"); gpr_mu_lock(&c->mu); c->connecting = false; if (c->connecting_result.transport != nullptr && @@ -656,10 +694,10 @@ static void subchannel_call_destroy(void* call, grpc_error* error) { grpc_subchannel_call* c = (grpc_subchannel_call*)call; GPR_ASSERT(c->schedule_closure_after_destroy != nullptr); GPR_TIMER_BEGIN("grpc_subchannel_call_unref.destroy", 0); - grpc_core::ConnectedSubchannel* connection = c->connection; + grpc_connected_subchannel* connection = c->connection; grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(c), nullptr, c->schedule_closure_after_destroy); - connection->Unref(DEBUG_LOCATION, "subchannel_call"); + GRPC_CONNECTED_SUBCHANNEL_UNREF(connection, "subchannel_call"); GPR_TIMER_END("grpc_subchannel_call_unref.destroy", 0); } @@ -690,12 +728,9 @@ void grpc_subchannel_call_process_op(grpc_subchannel_call* call, GPR_TIMER_END("grpc_subchannel_call_process_op", 0); } -grpc_core::RefCountedPtr -grpc_subchannel_get_connected_subchannel(grpc_subchannel* c) { - gpr_mu_lock(&c->mu); - auto copy = c->connected_subchannel; - gpr_mu_unlock(&c->mu); - return copy; +grpc_connected_subchannel* grpc_subchannel_get_connected_subchannel( + grpc_subchannel* c) { + return GET_CONNECTED_SUBCHANNEL(c, acq); } const grpc_subchannel_key* grpc_subchannel_get_key( @@ -703,6 +738,36 @@ const grpc_subchannel_key* grpc_subchannel_get_key( return subchannel->key; } +grpc_error* grpc_connected_subchannel_create_call( + grpc_connected_subchannel* con, + const grpc_connected_subchannel_call_args* args, + grpc_subchannel_call** call) { + grpc_channel_stack* chanstk = CHANNEL_STACK_FROM_CONNECTION(con); + *call = (grpc_subchannel_call*)gpr_arena_alloc( + args->arena, sizeof(grpc_subchannel_call) + chanstk->call_stack_size); + grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); + (*call)->connection = GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call"); + const grpc_call_element_args call_args = { + callstk, /* call_stack */ + nullptr, /* server_transport_data */ + args->context, /* context */ + args->path, /* path */ + args->start_time, /* start_time */ + args->deadline, /* deadline */ + args->arena, /* arena */ + args->call_combiner /* call_combiner */ + }; + grpc_error* error = grpc_call_stack_init(chanstk, 1, subchannel_call_destroy, + *call, &call_args); + if (error != GRPC_ERROR_NONE) { + const char* error_string = grpc_error_string(error); + gpr_log(GPR_ERROR, "error: %s", error_string); + return error; + } + grpc_call_stack_set_pollset_or_pollset_set(callstk, args->pollent); + return GRPC_ERROR_NONE; +} + grpc_call_stack* grpc_subchannel_call_get_call_stack( grpc_subchannel_call* subchannel_call) { return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call); @@ -738,64 +803,3 @@ grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) { (char*)GRPC_ARG_SUBCHANNEL_ADDRESS, addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup("")); } - -namespace grpc_core { -ConnectedSubchannel::ConnectedSubchannel(grpc_channel_stack* channel_stack) - : grpc_core::RefCountedWithTracing(&grpc_trace_stream_refcount), - channel_stack_(channel_stack) {} - -ConnectedSubchannel::~ConnectedSubchannel() { - GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor"); -} - -void ConnectedSubchannel::NotifyOnStateChange( - grpc_pollset_set* interested_parties, grpc_connectivity_state* state, - grpc_closure* closure) { - grpc_transport_op* op = grpc_make_transport_op(nullptr); - grpc_channel_element* elem; - op->connectivity_state = state; - op->on_connectivity_state_change = closure; - op->bind_pollset_set = interested_parties; - elem = grpc_channel_stack_element(channel_stack_, 0); - elem->filter->start_transport_op(elem, op); -} - -void ConnectedSubchannel::Ping(grpc_closure* on_initiate, - grpc_closure* on_ack) { - grpc_transport_op* op = grpc_make_transport_op(nullptr); - grpc_channel_element* elem; - op->send_ping.on_initiate = on_initiate; - op->send_ping.on_ack = on_ack; - elem = grpc_channel_stack_element(channel_stack_, 0); - elem->filter->start_transport_op(elem, op); -} - -grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, - grpc_subchannel_call** call) { - *call = (grpc_subchannel_call*)gpr_arena_alloc( - args.arena, - sizeof(grpc_subchannel_call) + channel_stack_->call_stack_size); - grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); - Ref(DEBUG_LOCATION, "subchannel_call"); - (*call)->connection = this; - const grpc_call_element_args call_args = { - callstk, /* call_stack */ - nullptr, /* server_transport_data */ - args.context, /* context */ - args.path, /* path */ - args.start_time, /* start_time */ - args.deadline, /* deadline */ - args.arena, /* arena */ - args.call_combiner /* call_combiner */ - }; - grpc_error* error = grpc_call_stack_init( - channel_stack_, 1, subchannel_call_destroy, *call, &call_args); - if (error != GRPC_ERROR_NONE) { - const char* error_string = grpc_error_string(error); - gpr_log(GPR_ERROR, "error: %s", error_string); - return error; - } - grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent); - return GRPC_ERROR_NONE; -} -} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index f2a5c1e2732..65d78252beb 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -34,6 +34,7 @@ /** A (sub-)channel that knows how to connect to exactly one target address. Provides a target for load balancing. */ typedef struct grpc_subchannel grpc_subchannel; +typedef struct grpc_connected_subchannel grpc_connected_subchannel; typedef struct grpc_subchannel_call grpc_subchannel_call; typedef struct grpc_subchannel_args grpc_subchannel_args; typedef struct grpc_subchannel_key grpc_subchannel_key; @@ -49,6 +50,10 @@ typedef struct grpc_subchannel_key grpc_subchannel_key; grpc_subchannel_weak_ref((p), __FILE__, __LINE__, (r)) #define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) \ grpc_subchannel_weak_unref((p), __FILE__, __LINE__, (r)) +#define GRPC_CONNECTED_SUBCHANNEL_REF(p, r) \ + grpc_connected_subchannel_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_CONNECTED_SUBCHANNEL_UNREF(p, r) \ + grpc_connected_subchannel_unref((p), __FILE__, __LINE__, (r)) #define GRPC_SUBCHANNEL_CALL_REF(p, r) \ grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r)) #define GRPC_SUBCHANNEL_CALL_UNREF(p, r) \ @@ -62,39 +67,14 @@ typedef struct grpc_subchannel_key grpc_subchannel_key; #define GRPC_SUBCHANNEL_UNREF(p, r) grpc_subchannel_unref((p)) #define GRPC_SUBCHANNEL_WEAK_REF(p, r) grpc_subchannel_weak_ref((p)) #define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) grpc_subchannel_weak_unref((p)) +#define GRPC_CONNECTED_SUBCHANNEL_REF(p, r) grpc_connected_subchannel_ref((p)) +#define GRPC_CONNECTED_SUBCHANNEL_UNREF(p, r) \ + grpc_connected_subchannel_unref((p)) #define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p)) #define GRPC_SUBCHANNEL_CALL_UNREF(p, r) grpc_subchannel_call_unref((p)) #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS #endif -namespace grpc_core { -class ConnectedSubchannel : public grpc_core::RefCountedWithTracing { - public: - struct CallArgs { - grpc_polling_entity* pollent; - grpc_slice path; - gpr_timespec start_time; - grpc_millis deadline; - gpr_arena* arena; - grpc_call_context_element* context; - grpc_call_combiner* call_combiner; - }; - - explicit ConnectedSubchannel(grpc_channel_stack* channel_stack); - ~ConnectedSubchannel(); - - grpc_channel_stack* channel_stack() { return channel_stack_; } - void NotifyOnStateChange(grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, - grpc_closure* closure); - void Ping(grpc_closure* on_initiate, grpc_closure* on_ack); - grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call); - - private: - grpc_channel_stack* channel_stack_; -}; -} // namespace grpc_core - grpc_subchannel* grpc_subchannel_ref( grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); grpc_subchannel* grpc_subchannel_ref_from_weak_ref( @@ -105,11 +85,35 @@ grpc_subchannel* grpc_subchannel_weak_ref( grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); void grpc_subchannel_weak_unref( grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +grpc_connected_subchannel* grpc_connected_subchannel_ref( + grpc_connected_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_connected_subchannel_unref( + grpc_connected_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); void grpc_subchannel_call_ref( grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); void grpc_subchannel_call_unref( grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +/** construct a subchannel call */ +typedef struct { + grpc_polling_entity* pollent; + grpc_slice path; + gpr_timespec start_time; + grpc_millis deadline; + gpr_arena* arena; + grpc_call_context_element* context; + grpc_call_combiner* call_combiner; +} grpc_connected_subchannel_call_args; + +grpc_error* grpc_connected_subchannel_create_call( + grpc_connected_subchannel* connected_subchannel, + const grpc_connected_subchannel_call_args* args, + grpc_subchannel_call** subchannel_call); + +/** process a transport level op */ +void grpc_connected_subchannel_process_transport_op( + grpc_connected_subchannel* subchannel, grpc_transport_op* op); + /** poll the current connectivity state of a channel */ grpc_connectivity_state grpc_subchannel_check_connectivity( grpc_subchannel* channel, grpc_error** error); @@ -119,12 +123,17 @@ grpc_connectivity_state grpc_subchannel_check_connectivity( void grpc_subchannel_notify_on_state_change( grpc_subchannel* channel, grpc_pollset_set* interested_parties, grpc_connectivity_state* state, grpc_closure* notify); - -/** retrieve the grpc_core::ConnectedSubchannel - or nullptr if not connected - * (which may happen before it initially connects or during transient failures) - * */ -grpc_core::RefCountedPtr -grpc_subchannel_get_connected_subchannel(grpc_subchannel* c); +void grpc_connected_subchannel_notify_on_state_change( + grpc_connected_subchannel* channel, grpc_pollset_set* interested_parties, + grpc_connectivity_state* state, grpc_closure* notify); +void grpc_connected_subchannel_ping(grpc_connected_subchannel* channel, + grpc_closure* on_initiate, + grpc_closure* on_ack); + +/** retrieve the grpc_connected_subchannel - or NULL if called before + the subchannel becomes connected */ +grpc_connected_subchannel* grpc_subchannel_get_connected_subchannel( + grpc_subchannel* subchannel); /** return the subchannel index key for \a subchannel */ const grpc_subchannel_key* grpc_subchannel_get_key( diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 328ad860615..7f82330ebe0 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -676,42 +676,6 @@ TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) { GPR_ASSERT(gpr_time_cmp(deadline, now) > 0); } -TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { - const int kNumServers = 3; - StartServers(kNumServers); - const auto ports = GetServersPorts(); - ResetStub(ports, "round_robin"); - SetNextResolution(ports); - for (size_t i = 0; i < kNumServers; ++i) WaitForServer(i); - for (size_t i = 0; i < servers_.size(); ++i) { - CheckRpcSendOk(); - EXPECT_EQ(1, servers_[i]->service_.request_count()) << "for backend #" << i; - } - // One request should have gone to each server. - for (size_t i = 0; i < servers_.size(); ++i) { - EXPECT_EQ(1, servers_[i]->service_.request_count()); - } - const auto pre_death = servers_[0]->service_.request_count(); - // Kill the first server. - servers_[0]->Shutdown(true); - // Client request still succeed. May need retrying if RR had returned a pick - // before noticing the change in the server's connectivity. - while (!SendRpc()) - ; // Retry until success. - // Send a bunch of RPCs that should succeed. - for (int i = 0; i < 10 * kNumServers; ++i) CheckRpcSendOk(); - const auto post_death = servers_[0]->service_.request_count(); - // No requests have gone to the deceased server. - EXPECT_EQ(pre_death, post_death); - // Bring the first server back up. - servers_[0].reset(new ServerData(server_host_, ports[0])); - // Requests should start arriving at the first server either right away (if - // the server managed to start before the RR policy retried the subchannel) or - // after the subchannel retry delay otherwise (RR's subchannel retried before - // the server was fully back up). - WaitForServer(0); -} - } // namespace } // namespace testing } // namespace grpc From 1dc0833bed2b62c520c1382462413c8054aed595 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Thu, 25 Jan 2018 16:52:51 -0800 Subject: [PATCH 15/25] Don't segfault on header replay --- CMakeLists.txt | 30 ++++ Makefile | 24 ++++ src/core/lib/surface/call.cc | 1 + test/core/bad_client/gen_build_yaml.py | 1 + test/core/bad_client/generate_tests.bzl | 1 + .../core/bad_client/tests/duplicate_header.cc | 134 ++++++++++++++++++ .../generated/sources_and_headers.json | 18 +++ tools/run_tests/generated/tests.json | 26 ++++ 8 files changed, 235 insertions(+) create mode 100644 test/core/bad_client/tests/duplicate_header.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 7663efca7a5..3f3b2889a37 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -389,6 +389,7 @@ endif() add_dependencies(buildtests_c public_headers_must_be_c89) add_dependencies(buildtests_c badreq_bad_client_test) add_dependencies(buildtests_c connection_prefix_bad_client_test) +add_dependencies(buildtests_c duplicate_header_bad_client_test) add_dependencies(buildtests_c head_of_line_blocking_bad_client_test) add_dependencies(buildtests_c headers_bad_client_test) add_dependencies(buildtests_c initial_settings_frame_bad_client_test) @@ -12312,6 +12313,35 @@ target_link_libraries(connection_prefix_bad_client_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(duplicate_header_bad_client_test + test/core/bad_client/tests/duplicate_header.cc +) + + +target_include_directories(duplicate_header_bad_client_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} +) + +target_link_libraries(duplicate_header_bad_client_test + ${_gRPC_SSL_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + bad_client_test + grpc_test_util_unsecure + grpc_unsecure + gpr_test_util + gpr +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(head_of_line_blocking_bad_client_test test/core/bad_client/tests/head_of_line_blocking.cc ) diff --git a/Makefile b/Makefile index e207a1be1fc..fb211f380af 100644 --- a/Makefile +++ b/Makefile @@ -1233,6 +1233,7 @@ boringssl_tab_test: $(BINDIR)/$(CONFIG)/boringssl_tab_test boringssl_v3name_test: $(BINDIR)/$(CONFIG)/boringssl_v3name_test badreq_bad_client_test: $(BINDIR)/$(CONFIG)/badreq_bad_client_test connection_prefix_bad_client_test: $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test +duplicate_header_bad_client_test: $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test head_of_line_blocking_bad_client_test: $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test headers_bad_client_test: $(BINDIR)/$(CONFIG)/headers_bad_client_test initial_settings_frame_bad_client_test: $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test @@ -1485,6 +1486,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \ $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ + $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test \ $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test \ $(BINDIR)/$(CONFIG)/headers_bad_client_test \ $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \ @@ -2023,6 +2025,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/badreq_bad_client_test || ( echo test badreq_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing connection_prefix_bad_client_test" $(Q) $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test || ( echo test connection_prefix_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing duplicate_header_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test || ( echo test duplicate_header_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing head_of_line_blocking_bad_client_test" $(Q) $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test || ( echo test head_of_line_blocking_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing headers_bad_client_test" @@ -18726,6 +18730,26 @@ ifneq ($(NO_DEPS),true) endif +DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC = \ + test/core/bad_client/tests/duplicate_header.cc \ + +DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DUPLICATE_HEADER_BAD_CLIENT_TEST_SRC)))) + + +$(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test + +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/duplicate_header.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_duplicate_header_bad_client_test: $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS:.o=.dep) + +ifneq ($(NO_DEPS),true) +-include $(DUPLICATE_HEADER_BAD_CLIENT_TEST_OBJS:.o=.dep) +endif + + HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC = \ test/core/bad_client/tests/head_of_line_blocking.cc \ diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 8a579cabe7d..a337c3282e3 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -1081,6 +1081,7 @@ static grpc_stream_compression_algorithm decode_stream_compression( static void publish_app_metadata(grpc_call* call, grpc_metadata_batch* b, int is_trailing) { if (b->list.count == 0) return; + if (is_trailing && call->buffered_metadata[1] == nullptr) return; GPR_TIMER_BEGIN("publish_app_metadata", 0); grpc_metadata_array* dest; grpc_metadata* mdusr; diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index 14c8a27334b..c0922fc3c43 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -27,6 +27,7 @@ default_test_options = TestOptions(False, 1.0) BAD_CLIENT_TESTS = { 'badreq': default_test_options, 'connection_prefix': default_test_options._replace(cpu_cost=0.2), + 'duplicate_header': default_test_options, 'headers': default_test_options._replace(cpu_cost=0.2), 'initial_settings_frame': default_test_options._replace(cpu_cost=0.2), 'head_of_line_blocking': default_test_options, diff --git a/test/core/bad_client/generate_tests.bzl b/test/core/bad_client/generate_tests.bzl index 022edf3ff34..0dbf5013d4a 100755 --- a/test/core/bad_client/generate_tests.bzl +++ b/test/core/bad_client/generate_tests.bzl @@ -25,6 +25,7 @@ def test_options(): BAD_CLIENT_TESTS = { 'badreq': test_options(), 'connection_prefix': test_options(), + 'duplicate_header': test_options(), 'headers': test_options(), 'initial_settings_frame': test_options(), 'head_of_line_blocking': test_options(), diff --git a/test/core/bad_client/tests/duplicate_header.cc b/test/core/bad_client/tests/duplicate_header.cc new file mode 100644 index 00000000000..0d689bbb7e2 --- /dev/null +++ b/test/core/bad_client/tests/duplicate_header.cc @@ -0,0 +1,134 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "test/core/bad_client/bad_client.h" + +#include + +#include + +#include "src/core/lib/surface/server.h" +#include "test/core/end2end/cq_verifier.h" + +#define PFX_STR \ + "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \ + "\x00\x00\x00\x04\x00\x00\x00\x00\x00" /* settings frame */ + +#define HEADER_STR \ + "\x00\x00\xc9\x01\x04\x00\x00\x00\x01" /* headers: generated from \ + simple_request.headers in this \ + directory */ \ + "\x10\x05:path\x08/foo/bar" \ + "\x10\x07:scheme\x04http" \ + "\x10\x07:method\x04POST" \ + "\x10\x0a:authority\x09localhost" \ + "\x10\x0c" \ + "content-type\x10" \ + "application/grpc" \ + "\x10\x14grpc-accept-encoding\x15" \ + "deflate,identity,gzip" \ + "\x10\x02te\x08trailers" \ + "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)" + +#define PAYLOAD_STR \ + "\x00\x00\x20\x00\x00\x00\x00\x00\x01" \ + "\x00\x00\x00\x00" + +static void* tag(intptr_t t) { return (void*)t; } + +static void verifier(grpc_server* server, grpc_completion_queue* cq, + void* registered_method) { + grpc_call_error error; + grpc_call* s; + grpc_call_details call_details; + grpc_byte_buffer* request_payload_recv = nullptr; + grpc_op* op; + grpc_op ops[6]; + cq_verifier* cqv = cq_verifier_create(cq); + grpc_metadata_array request_metadata_recv; + int was_cancelled = 2; + + grpc_call_details_init(&call_details); + grpc_metadata_array_init(&request_metadata_recv); + + error = grpc_server_request_call(server, &s, &call_details, + &request_metadata_recv, cq, cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.host, "localhost")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo/bar")); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = nullptr; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; + grpc_slice status_details = grpc_slice_from_static_string("xyz"); + op->data.send_status_from_server.status_details = &status_details; + op->flags = 0; + op->reserved = nullptr; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + grpc_call_unref(s); + cq_verifier_destroy(cqv); +} + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + + /* Verify that sending multiple headers doesn't segfault */ + GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, + PFX_STR HEADER_STR HEADER_STR PAYLOAD_STR, 0); + GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, + PFX_STR HEADER_STR HEADER_STR HEADER_STR PAYLOAD_STR, + 0); + grpc_shutdown(); + return 0; +} diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 982d9ef6496..dc95ddf16fe 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -4960,6 +4960,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "bad_client_test", + "gpr", + "gpr_test_util", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c", + "name": "duplicate_header_bad_client_test", + "src": [ + "test/core/bad_client/tests/duplicate_header.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "bad_client_test", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 7b23cab5066..05a3a20b08b 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -4674,6 +4674,32 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [ + "uv" + ], + "flaky": false, + "gtest": false, + "language": "c", + "name": "duplicate_header_bad_client_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": true + }, { "args": [], "benchmark": false, From 53f88d77ec17bcdcfd485b766d7f66032f407316 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Fri, 26 Jan 2018 15:18:46 -0800 Subject: [PATCH 16/25] Bump version to 1.9.0-pre3 --- BUILD | 4 ++-- build.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BUILD b/BUILD index 4e4e2ca7f15..f676efc2b71 100644 --- a/BUILD +++ b/BUILD @@ -56,9 +56,9 @@ config_setting( # This should be updated along with build.yaml g_stands_for = "glossy" -core_version = "5.0.0-pre2" +core_version = "5.0.0-pre3" -version = "1.9.0-pre2" +version = "1.9.0-pre3" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index eb408e4da31..73a85484761 100644 --- a/build.yaml +++ b/build.yaml @@ -12,9 +12,9 @@ settings: '#08': Use "-preN" suffixes to identify pre-release versions '#09': Per-language overrides are possible with (eg) ruby_version tag here '#10': See the expand_version.py for all the quirks here - core_version: 5.0.0-pre2 + core_version: 5.0.0-pre3 g_stands_for: glossy - version: 1.9.0-pre2 + version: 1.9.0-pre3 filegroups: - name: census public_headers: From 812e5da193167c45127c81d40de309fdb5da78af Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Fri, 26 Jan 2018 15:19:13 -0800 Subject: [PATCH 17/25] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/core/lib/surface/version.cc | 2 +- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 2 +- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_packages_dotnetcli.sh | 4 ++-- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 4 ++-- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- tools/doxygen/Doxyfile.core | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- 30 files changed, 35 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f3b2889a37..21383ed8f54 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-pre2") +set(PACKAGE_VERSION "1.9.0-pre3") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index fb211f380af..70c05e36081 100644 --- a/Makefile +++ b/Makefile @@ -418,9 +418,9 @@ E = @echo Q = @ endif -CORE_VERSION = 5.0.0-pre2 -CPP_VERSION = 1.9.0-pre2 -CSHARP_VERSION = 1.9.0-pre2 +CORE_VERSION = 5.0.0-pre3 +CPP_VERSION = 1.9.0-pre3 +CSHARP_VERSION = 1.9.0-pre3 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f595df3bece..e3de8960c17 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-pre2' + version = '1.9.0-pre3' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index fc35532f713..92f8671258e 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-pre2' + version = '1.9.0-pre3' 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 1a71b9ec2dc..5b7ad7a02cc 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-pre2' + version = '1.9.0-pre3' 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 cbba4cef009..87dc6b9da3d 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.9.0-pre2' + version = '1.9.0-pre3' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 43f36a898a8..306444529a8 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-23 - 1.9.0RC2 - 1.9.0RC2 + 1.9.0RC3 + 1.9.0RC3 beta diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index d752e4fbb1b..9a53f3333a3 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -21,6 +21,6 @@ #include -const char* grpc_version_string(void) { return "5.0.0-pre2"; } +const char* grpc_version_string(void) { return "5.0.0-pre3"; } const char* grpc_g_stands_for(void) { return "glossy"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index e390691dee7..39d52f2fe8d 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.9.0-pre2"; } +grpc::string Version() { return "1.9.0-pre3"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index f653ad5f8b8..b4068a96c98 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.9.0-pre2 + 1.9.0-pre3 3.3.0 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index d29855d87e1..d0c913db1f5 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.9.0-pre2"; + public const string CurrentVersion = "1.9.0-pre3"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index f396bb5d882..971444e368f 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-pre2 +set VERSION=1.9.0-pre3 @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 ddd12a7a5f6..c75fd5e85a7 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-pre2" -OutputDirectory ../../artifacts -nuget pack Grpc.Tools.nuspec -Version "1.9.0-pre2" -OutputDirectory ../../artifacts +nuget pack Grpc.nuspec -Version "1.9.0-pre3" -OutputDirectory ../../artifacts +nuget pack Grpc.Tools.nuspec -Version "1.9.0-pre3" -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 e961648ee09..a28956e5b43 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-pre2' + v = '1.9.0-pre3' 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 c653ac7423f..0fbe941f97b 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-pre2" +#define GRPC_OBJC_VERSION_STRING @"1.9.0-pre3" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 99ceb459fe7..1fe398fe1e5 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-pre2" -#define GRPC_C_VERSION_STRING @"5.0.0-pre2" +#define GRPC_OBJC_VERSION_STRING @"1.9.0-pre3" +#define GRPC_C_VERSION_STRING @"5.0.0-pre3" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 134fd518acb..37e11cff271 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.0RC2" +#define PHP_GRPC_VERSION "1.9.0RC3" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 6b9a6f42a7e..044dfe632fd 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.0rc2""" +__version__ = """1.9.0rc3""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index b7dd6777862..9055acc0875 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.0rc2' +VERSION = '1.9.0rc3' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index 77d846a50f8..d4294f2ef88 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.0rc2' +VERSION = '1.9.0rc3' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index fa29ec48299..13506b35fbd 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.0rc2' +VERSION = '1.9.0rc3' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index d892bd80681..f5b5ee63b10 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.0rc2' +VERSION = '1.9.0rc3' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 2717bf38041..1ba25239e9f 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.0rc2' +VERSION = '1.9.0rc3' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 7669087536b..caf23513e10 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.pre2' + VERSION = '1.9.0.pre3' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 7d02b4cbabd..09971234811 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.pre2' + VERSION = '1.9.0.pre3' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index eec7ff87894..f9a53baa2c3 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.0rc2' +VERSION = '1.9.0rc3' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 6375d920dd6..585d1a8c7d9 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-pre2 +PROJECT_NUMBER = 1.9.0-pre3 # 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 604bb5b6478..25084927509 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-pre2 +PROJECT_NUMBER = 1.9.0-pre3 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 43e0771c768..5c0a3ef31ad 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 5.0.0-pre2 +PROJECT_NUMBER = 5.0.0-pre3 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 67a9336a127..23e1c4cda40 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 5.0.0-pre2 +PROJECT_NUMBER = 5.0.0-pre3 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From bfcc99429becc2bc89b4919d067012314eb76f11 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Mon, 29 Jan 2018 13:19:33 -0800 Subject: [PATCH 18/25] Bump minimum Cython version to 0.27 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c976cef4cb8..53768c6822f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ # GRPC Python setup requirements coverage>=4.0 -cython>=0.23 +cython>=0.27 enum34>=1.0.4 futures>=2.2.0 protobuf>=3.5.0.post1 From b6f737ee7d9236511ed0f738fa7b6e7e2778b651 Mon Sep 17 00:00:00 2001 From: Cameron Taggart Date: Mon, 29 Jan 2018 22:11:01 -0500 Subject: [PATCH 19/25] use SourceLink.Create.CommandLine instead of Embed --- src/csharp/Grpc.Core/SourceLink.csproj.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core/SourceLink.csproj.include b/src/csharp/Grpc.Core/SourceLink.csproj.include index 02ae79fb893..0ec273f57e6 100755 --- a/src/csharp/Grpc.Core/SourceLink.csproj.include +++ b/src/csharp/Grpc.Core/SourceLink.csproj.include @@ -13,7 +13,7 @@ - + From 2338ec169ccc96bb807b2de1fb3f8c063c271a33 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Wed, 31 Jan 2018 16:21:40 -0800 Subject: [PATCH 20/25] Promote 1.9.0-pre3 to 1.9.0 --- BUILD | 4 ++-- build.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BUILD b/BUILD index f676efc2b71..8456c06e59f 100644 --- a/BUILD +++ b/BUILD @@ -56,9 +56,9 @@ config_setting( # This should be updated along with build.yaml g_stands_for = "glossy" -core_version = "5.0.0-pre3" +core_version = "5.0.0" -version = "1.9.0-pre3" +version = "1.9.0" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/build.yaml b/build.yaml index 73a85484761..23670183602 100644 --- a/build.yaml +++ b/build.yaml @@ -12,9 +12,9 @@ settings: '#08': Use "-preN" suffixes to identify pre-release versions '#09': Per-language overrides are possible with (eg) ruby_version tag here '#10': See the expand_version.py for all the quirks here - core_version: 5.0.0-pre3 + core_version: 5.0.0 g_stands_for: glossy - version: 1.9.0-pre3 + version: 1.9.0 filegroups: - name: census public_headers: From e05ca2204e8f8f4a77808c7280009dfaf179c2c5 Mon Sep 17 00:00:00 2001 From: Mehrdad Afshari Date: Wed, 31 Jan 2018 16:22:58 -0800 Subject: [PATCH 21/25] Regenerate projects --- CMakeLists.txt | 2 +- Makefile | 6 +++--- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 8 ++++---- src/core/lib/surface/version.cc | 2 +- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 2 +- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_packages_dotnetcli.sh | 4 ++-- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 4 ++-- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- tools/doxygen/Doxyfile.core | 2 +- tools/doxygen/Doxyfile.core.internal | 2 +- 30 files changed, 37 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 21383ed8f54..0a9f6dc5841 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-pre3") +set(PACKAGE_VERSION "1.9.0") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 70c05e36081..8556b216f2f 100644 --- a/Makefile +++ b/Makefile @@ -418,9 +418,9 @@ E = @echo Q = @ endif -CORE_VERSION = 5.0.0-pre3 -CPP_VERSION = 1.9.0-pre3 -CSHARP_VERSION = 1.9.0-pre3 +CORE_VERSION = 5.0.0 +CPP_VERSION = 1.9.0 +CSHARP_VERSION = 1.9.0 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index e3de8960c17..42b0c0e070c 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-pre3' + version = '1.9.0' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 92f8671258e..1f021d1c2b3 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-pre3' + version = '1.9.0' 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 5b7ad7a02cc..524e1e34162 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-pre3' + version = '1.9.0' 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 87dc6b9da3d..b52cf43e8f9 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.9.0-pre3' + version = '1.9.0' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index 306444529a8..ac2c5973186 100644 --- a/package.xml +++ b/package.xml @@ -13,12 +13,12 @@ 2018-01-23 - 1.9.0RC3 - 1.9.0RC3 + 1.9.0 + 1.9.0 - beta - beta + stable + stable Apache 2.0 diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc index 9a53f3333a3..fc66d023ea5 100644 --- a/src/core/lib/surface/version.cc +++ b/src/core/lib/surface/version.cc @@ -21,6 +21,6 @@ #include -const char* grpc_version_string(void) { return "5.0.0-pre3"; } +const char* grpc_version_string(void) { return "5.0.0"; } const char* grpc_g_stands_for(void) { return "glossy"; } diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 39d52f2fe8d..185172b9e7f 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.9.0-pre3"; } +grpc::string Version() { return "1.9.0"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index b4068a96c98..8e906ed0c49 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.9.0-pre3 + 1.9.0 3.3.0 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index d0c913db1f5..e320bd3c4f9 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -38,6 +38,6 @@ namespace Grpc.Core /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.9.0-pre3"; + public const string CurrentVersion = "1.9.0"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index 971444e368f..ab43d3ccbae 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-pre3 +set VERSION=1.9.0 @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 c75fd5e85a7..82335c8bbe0 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-pre3" -OutputDirectory ../../artifacts -nuget pack Grpc.Tools.nuspec -Version "1.9.0-pre3" -OutputDirectory ../../artifacts +nuget pack Grpc.nuspec -Version "1.9.0" -OutputDirectory ../../artifacts +nuget pack Grpc.Tools.nuspec -Version "1.9.0" -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 a28956e5b43..8e075f69cf4 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-pre3' + v = '1.9.0' 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 0fbe941f97b..b00dd022089 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-pre3" +#define GRPC_OBJC_VERSION_STRING @"1.9.0" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 1fe398fe1e5..9a117c3050d 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-pre3" -#define GRPC_C_VERSION_STRING @"5.0.0-pre3" +#define GRPC_OBJC_VERSION_STRING @"1.9.0" +#define GRPC_C_VERSION_STRING @"5.0.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index 37e11cff271..e2dfc4057b6 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.0RC3" +#define PHP_GRPC_VERSION "1.9.0" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index 044dfe632fd..f7ba4661cc0 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.0rc3""" +__version__ = """1.9.0""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index 9055acc0875..dfb490659aa 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.0rc3' +VERSION = '1.9.0' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index d4294f2ef88..b29f5c7b2e2 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.0rc3' +VERSION = '1.9.0' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 13506b35fbd..59691311b61 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.0rc3' +VERSION = '1.9.0' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index f5b5ee63b10..7bf045d233b 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.0rc3' +VERSION = '1.9.0' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 1ba25239e9f..997f1821012 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.0rc3' +VERSION = '1.9.0' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index caf23513e10..4348b79fca1 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.pre3' + VERSION = '1.9.0' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 09971234811..0b899ebe799 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.pre3' + VERSION = '1.9.0' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index f9a53baa2c3..1ef36b12b8c 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.0rc3' +VERSION = '1.9.0' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 585d1a8c7d9..afd4a6289c4 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-pre3 +PROJECT_NUMBER = 1.9.0 # 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 25084927509..a01cf14cb2f 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-pre3 +PROJECT_NUMBER = 1.9.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 5c0a3ef31ad..060d00a4794 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 5.0.0-pre3 +PROJECT_NUMBER = 5.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 23e1c4cda40..ef91f4f560d 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 5.0.0-pre3 +PROJECT_NUMBER = 5.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a From f9bd4d71524fdf9fbed7801768d5aa1cbab73e4e Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Thu, 1 Feb 2018 15:02:31 -0800 Subject: [PATCH 22/25] Add release branch performance job --- .../linux/grpc_full_performance_release.cfg | 25 ++++++++ .../linux/grpc_full_performance_release.sh | 59 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 tools/internal_ci/linux/grpc_full_performance_release.cfg create mode 100755 tools/internal_ci/linux/grpc_full_performance_release.sh diff --git a/tools/internal_ci/linux/grpc_full_performance_release.cfg b/tools/internal_ci/linux/grpc_full_performance_release.cfg new file mode 100644 index 00000000000..e9a4bcdcaf3 --- /dev/null +++ b/tools/internal_ci/linux/grpc_full_performance_release.cfg @@ -0,0 +1,25 @@ +# 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_full_performance_release.sh" +timeout_mins: 600 +action { + define_artifacts { + regex: "**/*sponge_log.xml" + regex: "**/perf_reports/**" + } +} diff --git a/tools/internal_ci/linux/grpc_full_performance_release.sh b/tools/internal_ci/linux/grpc_full_performance_release.sh new file mode 100755 index 00000000000..a31cea281fe --- /dev/null +++ b/tools/internal_ci/linux/grpc_full_performance_release.sh @@ -0,0 +1,59 @@ +#!/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 + +# Enter the gRPC repo root +cd $(dirname $0)/../../.. + +source tools/internal_ci/helper_scripts/prepare_build_linux_perf_multilang_rc + +# run 8core client vs 8core server +tools/run_tests/run_performance_tests.py \ + -l c++ csharp ruby java python go php7 php7_protobuf_c \ + --netperf \ + --category scalable \ + --remote_worker_host grpc-kokoro-performance-server-8core grpc-kokoro-performance-client-8core grpc-kokoro-performance-client2-8core \ + -u kbuilder \ + --bq_result_table performance_released.performance_experiment \ + --xml_report reports/8core/sponge_log.xml \ + || EXIT_CODE=1 + +# prevent pushing leftover build files to remote hosts in the next step. +git clean -fdxq -e reports + +# scalability with 32cores (and upload to a different BQ table) +tools/run_tests/run_performance_tests.py \ + -l c++ java csharp go \ + --netperf \ + --category scalable \ + --remote_worker_host grpc-kokoro-performance-server-32core grpc-kokoro-performance-client-32core grpc-kokoro-performance-client2-32core \ + -u kbuilder \ + --bq_result_table performance_released.performance_experiment_32core \ + --xml_report reports/32core/sponge_log.xml \ + || EXIT_CODE=1 + +# prevent pushing leftover build files to remote hosts in the next step. +git clean -fdxq -e reports + +# selected scenarios on Windows +tools/run_tests/run_performance_tests.py \ + -l csharp \ + --category scalable \ + --remote_worker_host grpc-kokoro-performance-windows1 grpc-kokoro-performance-windows2 \ + --bq_result_table performance_released.performance_experiment_windows \ + --xml_report reports/windows/sponge_log.xml \ + || EXIT_CODE=1 + +exit $EXIT_CODE From ade367d6c41ffca22424405300d057aebc0e522d Mon Sep 17 00:00:00 2001 From: Matt Kwong Date: Thu, 1 Feb 2018 15:03:25 -0800 Subject: [PATCH 23/25] Kokoro performance job uploads to same BQ table as Jenkins --- tools/internal_ci/linux/grpc_full_performance_master.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/internal_ci/linux/grpc_full_performance_master.sh b/tools/internal_ci/linux/grpc_full_performance_master.sh index 18468395f6f..4eddc187314 100755 --- a/tools/internal_ci/linux/grpc_full_performance_master.sh +++ b/tools/internal_ci/linux/grpc_full_performance_master.sh @@ -26,7 +26,7 @@ tools/run_tests/run_performance_tests.py \ --category scalable \ --remote_worker_host grpc-kokoro-performance-server-8core grpc-kokoro-performance-client-8core grpc-kokoro-performance-client2-8core \ -u kbuilder \ - --bq_result_table performance_test.kokoro_performance_experiment \ + --bq_result_table performance_test.performance_experiment \ --xml_report reports/8core/sponge_log.xml \ || EXIT_CODE=1 @@ -40,7 +40,7 @@ tools/run_tests/run_performance_tests.py \ --category scalable \ --remote_worker_host grpc-kokoro-performance-server-32core grpc-kokoro-performance-client-32core grpc-kokoro-performance-client2-32core \ -u kbuilder \ - --bq_result_table performance_test.kokoro_performance_experiment_32core \ + --bq_result_table performance_test.performance_experiment_32core \ --xml_report reports/32core/sponge_log.xml \ || EXIT_CODE=1 @@ -52,7 +52,7 @@ tools/run_tests/run_performance_tests.py \ -l csharp \ --category scalable \ --remote_worker_host grpc-kokoro-performance-windows1 grpc-kokoro-performance-windows2 \ - --bq_result_table performance_test.kokoro_performance_experiment_windows \ + --bq_result_table performance_test.performance_experiment_windows \ --xml_report reports/windows/sponge_log.xml \ || EXIT_CODE=1 From f069dd4498f92932dd458d16e2dcc7632d10cb70 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Mon, 5 Feb 2018 09:15:05 -0800 Subject: [PATCH 24/25] Add refcounts for async callbacks in auth and client filters. --- src/core/ext/filters/client_channel/client_channel.cc | 3 +++ src/core/lib/security/transport/client_auth_filter.cc | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index bb29f65af97..8c154881af0 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1095,6 +1095,7 @@ static void pick_callback_done_locked(void* arg, grpc_error* error) { chand, calld); } async_pick_done_locked(elem, GRPC_ERROR_REF(error)); + GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback"); } // Takes a ref to chand->lb_policy and calls grpc_lb_policy_pick_locked(). @@ -1134,6 +1135,7 @@ static bool pick_callback_start_locked(grpc_call_element* elem) { GRPC_CLOSURE_INIT(&calld->lb_pick_closure, pick_callback_done_locked, elem, grpc_combiner_scheduler(chand->combiner)); calld->pick.on_complete = &calld->lb_pick_closure; + GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback"); const bool pick_done = grpc_lb_policy_pick_locked(chand->lb_policy, &calld->pick); if (pick_done) { @@ -1142,6 +1144,7 @@ static bool pick_callback_start_locked(grpc_call_element* elem) { gpr_log(GPR_DEBUG, "chand=%p calld=%p: pick completed synchronously", chand, calld); } + GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback"); } else { GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback_cancel"); grpc_call_combiner_set_notify_on_cancel( diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 6d7f89873b3..948775b71cf 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -118,6 +118,7 @@ static void on_credentials_metadata(void* arg, grpc_error* input_error) { grpc_transport_stream_op_batch_finish_with_failure(batch, error, calld->call_combiner); } + GRPC_CALL_STACK_UNREF(calld->owning_call, "get_request_metadata"); } void grpc_auth_metadata_context_build( @@ -208,7 +209,7 @@ static void send_security_metadata(grpc_call_element* elem, chand->auth_context, &calld->auth_md_context); GPR_ASSERT(calld->pollent != nullptr); - + GRPC_CALL_STACK_REF(calld->owning_call, "get_request_metadata"); GRPC_CLOSURE_INIT(&calld->async_result_closure, on_credentials_metadata, batch, grpc_schedule_on_exec_ctx); grpc_error* error = GRPC_ERROR_NONE; @@ -250,6 +251,7 @@ static void on_host_checked(void* arg, grpc_error* error) { calld->call_combiner); gpr_free(error_msg); } + GRPC_CALL_STACK_UNREF(calld->owning_call, "check_call_host"); } static void cancel_check_call_host(void* arg, grpc_error* error) { @@ -312,6 +314,7 @@ static void auth_start_transport_stream_op_batch( } if (calld->have_host) { batch->handler_private.extra_arg = elem; + GRPC_CALL_STACK_REF(calld->owning_call, "check_call_host"); GRPC_CLOSURE_INIT(&calld->async_result_closure, on_host_checked, batch, grpc_schedule_on_exec_ctx); char* call_host = grpc_slice_to_c_string(calld->host); From 1a8565d37918a5bcd0f794edc43dc958dfe40ab1 Mon Sep 17 00:00:00 2001 From: Ken Payson Date: Mon, 5 Feb 2018 14:24:52 -0800 Subject: [PATCH 25/25] Bump version to 1.9.1 --- BUILD | 2 +- CMakeLists.txt | 2 +- Makefile | 4 ++-- build.yaml | 2 +- gRPC-Core.podspec | 2 +- gRPC-ProtoRPC.podspec | 2 +- gRPC-RxLibrary.podspec | 2 +- gRPC.podspec | 2 +- package.xml | 4 ++-- src/cpp/common/version_cc.cc | 2 +- src/csharp/Grpc.Core/Version.csproj.include | 2 +- src/csharp/Grpc.Core/VersionInfo.cs | 4 ++-- src/csharp/build_packages_dotnetcli.bat | 2 +- src/csharp/build_packages_dotnetcli.sh | 4 ++-- src/objective-c/!ProtoCompiler-gRPCPlugin.podspec | 2 +- src/objective-c/GRPCClient/private/version.h | 2 +- src/objective-c/tests/version.h | 2 +- src/php/composer.json | 2 +- src/php/ext/grpc/version.h | 2 +- src/python/grpcio/grpc/_grpcio_metadata.py | 2 +- src/python/grpcio/grpc_version.py | 2 +- src/python/grpcio_health_checking/grpc_version.py | 2 +- src/python/grpcio_reflection/grpc_version.py | 2 +- src/python/grpcio_testing/grpc_version.py | 2 +- src/python/grpcio_tests/grpc_version.py | 2 +- src/ruby/lib/grpc/version.rb | 2 +- src/ruby/tools/version.rb | 2 +- tools/distrib/python/grpcio_tools/grpc_version.py | 2 +- tools/doxygen/Doxyfile.c++ | 2 +- tools/doxygen/Doxyfile.c++.internal | 2 +- 30 files changed, 34 insertions(+), 34 deletions(-) diff --git a/BUILD b/BUILD index 8456c06e59f..1c50035ebac 100644 --- a/BUILD +++ b/BUILD @@ -58,7 +58,7 @@ g_stands_for = "glossy" core_version = "5.0.0" -version = "1.9.0" +version = "1.9.1" GPR_PUBLIC_HDRS = [ "include/grpc/support/alloc.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a9f6dc5841..3e1e7f23216 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") +set(PACKAGE_VERSION "1.9.1") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") diff --git a/Makefile b/Makefile index 8556b216f2f..b2276f41e4e 100644 --- a/Makefile +++ b/Makefile @@ -419,8 +419,8 @@ Q = @ endif CORE_VERSION = 5.0.0 -CPP_VERSION = 1.9.0 -CSHARP_VERSION = 1.9.0 +CPP_VERSION = 1.9.1 +CSHARP_VERSION = 1.9.1 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/build.yaml b/build.yaml index 23670183602..8bc49a3962e 100644 --- a/build.yaml +++ b/build.yaml @@ -14,7 +14,7 @@ settings: '#10': See the expand_version.py for all the quirks here core_version: 5.0.0 g_stands_for: glossy - version: 1.9.0 + version: 1.9.1 filegroups: - name: census public_headers: diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 42b0c0e070c..93c1de00f28 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' + version = '1.9.1' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'https://grpc.io' diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 1f021d1c2b3..f90fba45974 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' + version = '1.9.1' 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 524e1e34162..94188c5e2b2 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' + version = '1.9.1' 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 b52cf43e8f9..40fc5ba3573 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -20,7 +20,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '1.9.0' + version = '1.9.1' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'https://grpc.io' diff --git a/package.xml b/package.xml index ac2c5973186..c95e24286f1 100644 --- a/package.xml +++ b/package.xml @@ -13,8 +13,8 @@ 2018-01-23 - 1.9.0 - 1.9.0 + 1.9.1 + 1.9.1 stable diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc index 185172b9e7f..d6fb8af8af0 100644 --- a/src/cpp/common/version_cc.cc +++ b/src/cpp/common/version_cc.cc @@ -22,5 +22,5 @@ #include namespace grpc { -grpc::string Version() { return "1.9.0"; } +grpc::string Version() { return "1.9.1"; } } // namespace grpc diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include index 8e906ed0c49..e8d449baa46 100755 --- a/src/csharp/Grpc.Core/Version.csproj.include +++ b/src/csharp/Grpc.Core/Version.csproj.include @@ -1,7 +1,7 @@ - 1.9.0 + 1.9.1 3.3.0 diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs index e320bd3c4f9..7e130c71e04 100644 --- a/src/csharp/Grpc.Core/VersionInfo.cs +++ b/src/csharp/Grpc.Core/VersionInfo.cs @@ -33,11 +33,11 @@ namespace Grpc.Core /// /// Current AssemblyFileVersion of gRPC C# assemblies /// - public const string CurrentAssemblyFileVersion = "1.9.0.0"; + public const string CurrentAssemblyFileVersion = "1.9.1.0"; /// /// Current version of gRPC C# /// - public const string CurrentVersion = "1.9.0"; + public const string CurrentVersion = "1.9.1"; } } diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat index ab43d3ccbae..de3effd7874 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 +set VERSION=1.9.1 @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 82335c8bbe0..b1b4b991a7a 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" -OutputDirectory ../../artifacts -nuget pack Grpc.Tools.nuspec -Version "1.9.0" -OutputDirectory ../../artifacts +nuget pack Grpc.nuspec -Version "1.9.1" -OutputDirectory ../../artifacts +nuget pack Grpc.Tools.nuspec -Version "1.9.1" -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 8e075f69cf4..fe791c146d0 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' + v = '1.9.1' 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 b00dd022089..c768bf666d0 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" +#define GRPC_OBJC_VERSION_STRING @"1.9.1" diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h index 9a117c3050d..882adbae374 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" +#define GRPC_OBJC_VERSION_STRING @"1.9.1" #define GRPC_C_VERSION_STRING @"5.0.0" diff --git a/src/php/composer.json b/src/php/composer.json index 43833980f9d..3b61a998bda 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.9.1", "require": { "php": ">=5.5.0", "google/protobuf": "^v3.3.0" diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h index e2dfc4057b6..90315d5be92 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.0" +#define PHP_GRPC_VERSION "1.9.1" #endif /* VERSION_H */ diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py index f7ba4661cc0..8be41427a5d 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""" +__version__ = """1.9.1""" diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py index dfb490659aa..4a903eafa63 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' +VERSION = '1.9.1' diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py index b29f5c7b2e2..dc5bc27a88c 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' +VERSION = '1.9.1' diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py index 59691311b61..0a09c46939a 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' +VERSION = '1.9.1' diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py index 7bf045d233b..ff389ef2e5d 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' +VERSION = '1.9.1' diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py index 997f1821012..dc8d737791c 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' +VERSION = '1.9.1' diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 4348b79fca1..310ca49f136 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' + VERSION = '1.9.1' end diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb index 0b899ebe799..71e9c852043 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' + VERSION = '1.9.1' end end diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py index 1ef36b12b8c..a78a259ff4f 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' +VERSION = '1.9.1' diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index afd4a6289c4..ee4781b4477 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 +PROJECT_NUMBER = 1.9.1 # 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 a01cf14cb2f..5b1db66cfa0 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 +PROJECT_NUMBER = 1.9.1 # 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