aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Lizan Zhou <zlizan@google.com>2018-09-21 15:59:00 -0700
committerGravatar Lizan Zhou <zlizan@google.com>2018-09-21 15:59:00 -0700
commit91e15f65dcdcb7880c60f04c9fe97bdae1878de7 (patch)
tree0cd9d832ac5558083b6095647527135b2bf5d6ce
parent9af7c7258987280bc6305b329e709400cde0e799 (diff)
parent12f42765cf3ea707a8adf94e56160cc9f069677b (diff)
Merge remote-tracking branch 'upstream/master' into fake_handshaker
-rw-r--r--BUILD3
-rw-r--r--CMakeLists.txt9
-rw-r--r--Makefile10
-rw-r--r--build.yaml4
-rw-r--r--config.m41
-rw-r--r--config.w321
-rw-r--r--gRPC-C++.podspec2
-rw-r--r--gRPC-Core.podspec3
-rw-r--r--grpc.gemspec2
-rw-r--r--grpc.gyp6
-rw-r--r--include/grpc/grpc.h3
-rw-r--r--include/grpc/grpc_security.h4
-rw-r--r--include/grpc/impl/codegen/grpc_types.h15
-rw-r--r--include/grpcpp/alarm.h27
-rw-r--r--include/grpcpp/impl/codegen/callback_common.h93
-rw-r--r--include/grpcpp/impl/codegen/client_callback.h2
-rw-r--r--package.xml2
-rw-r--r--src/compiler/cpp_generator.cc148
-rw-r--r--src/core/ext/filters/client_channel/subchannel_index.cc6
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.cc17
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_mapping.cc39
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_mapping.h38
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_table.cc29
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_table.h9
-rw-r--r--src/core/ext/transport/chttp2/transport/parsing.cc133
-rw-r--r--src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc3
-rw-r--r--src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc3
-rw-r--r--src/core/lib/surface/completion_queue.cc34
-rw-r--r--src/core/lib/surface/completion_queue.h19
-rw-r--r--src/core/lib/surface/completion_queue_factory.cc6
-rw-r--r--src/core/lib/transport/metadata.cc18
-rw-r--r--src/core/lib/transport/metadata.h3
-rw-r--r--src/core/lib/transport/metadata_batch.cc4
-rw-r--r--src/core/lib/transport/metadata_batch.h2
-rw-r--r--src/core/lib/transport/static_metadata.cc27
-rw-r--r--src/core/lib/transport/static_metadata.h2
-rw-r--r--src/cpp/client/channel_cc.cc10
-rw-r--r--src/cpp/common/alarm.cc47
-rw-r--r--src/cpp/common/callback_common.cc149
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py1
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.h6
-rw-r--r--src/ruby/lib/grpc/generic/rpc_desc.rb6
-rw-r--r--src/ruby/spec/client_auth_spec.rb10
-rw-r--r--src/ruby/spec/generic/client_stub_spec.rb22
-rw-r--r--src/ruby/spec/generic/rpc_server_spec.rb6
-rw-r--r--src/ruby/spec/support/services.rb50
-rw-r--r--test/core/end2end/inproc_callback_test.cc31
-rw-r--r--test/core/surface/completion_queue_test.cc25
-rw-r--r--test/core/transport/chttp2/hpack_encoder_test.cc2
-rw-r--r--test/core/transport/metadata_test.cc5
-rw-r--r--test/cpp/codegen/compiler_test_golden50
-rw-r--r--test/cpp/common/alarm_test.cc106
-rw-r--r--test/cpp/end2end/async_end2end_test.cc2
-rw-r--r--test/cpp/end2end/client_callback_end2end_test.cc113
-rw-r--r--test/cpp/end2end/client_lb_end2end_test.cc41
-rw-r--r--test/cpp/microbenchmarks/bm_chttp2_hpack.cc74
-rw-r--r--test/cpp/microbenchmarks/fullstack_fixtures.h1
-rw-r--r--test/cpp/microbenchmarks/helpers.h1
-rwxr-xr-xtools/codegen/core/gen_static_metadata.py279
-rw-r--r--tools/doxygen/Doxyfile.c++.internal1
-rw-r--r--tools/doxygen/Doxyfile.core.internal2
-rw-r--r--tools/run_tests/generated/sources_and_headers.json4
62 files changed, 1217 insertions, 554 deletions
diff --git a/BUILD b/BUILD
index 271e57e36c..76d78d737f 100644
--- a/BUILD
+++ b/BUILD
@@ -119,7 +119,6 @@ GRPCXX_SRCS = [
"src/cpp/client/credentials_cc.cc",
"src/cpp/client/generic_stub.cc",
"src/cpp/common/alarm.cc",
- "src/cpp/common/callback_common.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/channel_filter.cc",
"src/cpp/common/completion_queue_cc.cc",
@@ -1575,6 +1574,7 @@ grpc_cc_library(
"src/core/ext/transport/chttp2/transport/frame_window_update.cc",
"src/core/ext/transport/chttp2/transport/hpack_encoder.cc",
"src/core/ext/transport/chttp2/transport/hpack_parser.cc",
+ "src/core/ext/transport/chttp2/transport/hpack_mapping.cc",
"src/core/ext/transport/chttp2/transport/hpack_table.cc",
"src/core/ext/transport/chttp2/transport/http2_settings.cc",
"src/core/ext/transport/chttp2/transport/huffsyms.cc",
@@ -1599,6 +1599,7 @@ grpc_cc_library(
"src/core/ext/transport/chttp2/transport/frame_window_update.h",
"src/core/ext/transport/chttp2/transport/hpack_encoder.h",
"src/core/ext/transport/chttp2/transport/hpack_parser.h",
+ "src/core/ext/transport/chttp2/transport/hpack_mapping.h",
"src/core/ext/transport/chttp2/transport/hpack_table.h",
"src/core/ext/transport/chttp2/transport/http2_settings.h",
"src/core/ext/transport/chttp2/transport/huffsyms.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c358e9bd43..124bd0dc60 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1105,6 +1105,7 @@ add_library(grpc
src/core/ext/transport/chttp2/transport/frame_settings.cc
src/core/ext/transport/chttp2/transport/frame_window_update.cc
src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc
src/core/ext/transport/chttp2/transport/hpack_parser.cc
src/core/ext/transport/chttp2/transport/hpack_table.cc
src/core/ext/transport/chttp2/transport/http2_settings.cc
@@ -1516,6 +1517,7 @@ add_library(grpc_cronet
src/core/ext/transport/chttp2/transport/frame_settings.cc
src/core/ext/transport/chttp2/transport/frame_window_update.cc
src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc
src/core/ext/transport/chttp2/transport/hpack_parser.cc
src/core/ext/transport/chttp2/transport/hpack_table.cc
src/core/ext/transport/chttp2/transport/http2_settings.cc
@@ -1929,6 +1931,7 @@ add_library(grpc_test_util
src/core/ext/transport/chttp2/transport/frame_settings.cc
src/core/ext/transport/chttp2/transport/frame_window_update.cc
src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc
src/core/ext/transport/chttp2/transport/hpack_parser.cc
src/core/ext/transport/chttp2/transport/hpack_table.cc
src/core/ext/transport/chttp2/transport/http2_settings.cc
@@ -2239,6 +2242,7 @@ add_library(grpc_test_util_unsecure
src/core/ext/transport/chttp2/transport/frame_settings.cc
src/core/ext/transport/chttp2/transport/frame_window_update.cc
src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc
src/core/ext/transport/chttp2/transport/hpack_parser.cc
src/core/ext/transport/chttp2/transport/hpack_table.cc
src/core/ext/transport/chttp2/transport/http2_settings.cc
@@ -2507,6 +2511,7 @@ add_library(grpc_unsecure
src/core/ext/transport/chttp2/transport/frame_settings.cc
src/core/ext/transport/chttp2/transport/frame_window_update.cc
src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc
src/core/ext/transport/chttp2/transport/hpack_parser.cc
src/core/ext/transport/chttp2/transport/hpack_table.cc
src/core/ext/transport/chttp2/transport/http2_settings.cc
@@ -2773,7 +2778,6 @@ add_library(grpc++
src/cpp/client/credentials_cc.cc
src/cpp/client/generic_stub.cc
src/cpp/common/alarm.cc
- src/cpp/common/callback_common.cc
src/cpp/common/channel_arguments.cc
src/cpp/common/channel_filter.cc
src/cpp/common/completion_queue_cc.cc
@@ -3135,7 +3139,6 @@ add_library(grpc++_cronet
src/cpp/client/credentials_cc.cc
src/cpp/client/generic_stub.cc
src/cpp/common/alarm.cc
- src/cpp/common/callback_common.cc
src/cpp/common/channel_arguments.cc
src/cpp/common/channel_filter.cc
src/cpp/common/completion_queue_cc.cc
@@ -3178,6 +3181,7 @@ add_library(grpc++_cronet
src/core/ext/transport/chttp2/transport/frame_settings.cc
src/core/ext/transport/chttp2/transport/frame_window_update.cc
src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc
src/core/ext/transport/chttp2/transport/hpack_parser.cc
src/core/ext/transport/chttp2/transport/hpack_table.cc
src/core/ext/transport/chttp2/transport/http2_settings.cc
@@ -4261,7 +4265,6 @@ add_library(grpc++_unsecure
src/cpp/client/credentials_cc.cc
src/cpp/client/generic_stub.cc
src/cpp/common/alarm.cc
- src/cpp/common/callback_common.cc
src/cpp/common/channel_arguments.cc
src/cpp/common/channel_filter.cc
src/cpp/common/completion_queue_cc.cc
diff --git a/Makefile b/Makefile
index 2f2537228c..65ff9972bf 100644
--- a/Makefile
+++ b/Makefile
@@ -352,6 +352,7 @@ CXXFLAGS += -std=c++11
ifeq ($(SYSTEM),Darwin)
CXXFLAGS += -stdlib=libc++
endif
+CXXFLAGS += -Wnon-virtual-dtor
CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1 -Wno-deprecated-declarations -Ithird_party/nanopb -DPB_FIELD_32BIT
COREFLAGS += -fno-rtti -fno-exceptions
LDFLAGS += -g
@@ -3614,6 +3615,7 @@ LIBGRPC_SRC = \
src/core/ext/transport/chttp2/transport/frame_settings.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
src/core/ext/transport/chttp2/transport/hpack_table.cc \
src/core/ext/transport/chttp2/transport/http2_settings.cc \
@@ -4024,6 +4026,7 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/transport/chttp2/transport/frame_settings.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
src/core/ext/transport/chttp2/transport/hpack_table.cc \
src/core/ext/transport/chttp2/transport/http2_settings.cc \
@@ -4435,6 +4438,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/transport/chttp2/transport/frame_settings.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
src/core/ext/transport/chttp2/transport/hpack_table.cc \
src/core/ext/transport/chttp2/transport/http2_settings.cc \
@@ -4736,6 +4740,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/transport/chttp2/transport/frame_settings.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
src/core/ext/transport/chttp2/transport/hpack_table.cc \
src/core/ext/transport/chttp2/transport/http2_settings.cc \
@@ -4982,6 +4987,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/transport/chttp2/transport/frame_settings.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
src/core/ext/transport/chttp2/transport/hpack_table.cc \
src/core/ext/transport/chttp2/transport/http2_settings.cc \
@@ -5228,7 +5234,6 @@ LIBGRPC++_SRC = \
src/cpp/client/credentials_cc.cc \
src/cpp/client/generic_stub.cc \
src/cpp/common/alarm.cc \
- src/cpp/common/callback_common.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/channel_filter.cc \
src/cpp/common/completion_queue_cc.cc \
@@ -5598,7 +5603,6 @@ LIBGRPC++_CRONET_SRC = \
src/cpp/client/credentials_cc.cc \
src/cpp/client/generic_stub.cc \
src/cpp/common/alarm.cc \
- src/cpp/common/callback_common.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/channel_filter.cc \
src/cpp/common/completion_queue_cc.cc \
@@ -5641,6 +5645,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/ext/transport/chttp2/transport/frame_settings.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
src/core/ext/transport/chttp2/transport/hpack_table.cc \
src/core/ext/transport/chttp2/transport/http2_settings.cc \
@@ -6682,7 +6687,6 @@ LIBGRPC++_UNSECURE_SRC = \
src/cpp/client/credentials_cc.cc \
src/cpp/client/generic_stub.cc \
src/cpp/common/alarm.cc \
- src/cpp/common/callback_common.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/channel_filter.cc \
src/cpp/common/completion_queue_cc.cc \
diff --git a/build.yaml b/build.yaml
index d6e67aa7ee..60600b7dce 100644
--- a/build.yaml
+++ b/build.yaml
@@ -936,6 +936,7 @@ filegroups:
- src/core/ext/transport/chttp2/transport/frame_settings.h
- src/core/ext/transport/chttp2/transport/frame_window_update.h
- src/core/ext/transport/chttp2/transport/hpack_encoder.h
+ - src/core/ext/transport/chttp2/transport/hpack_mapping.h
- src/core/ext/transport/chttp2/transport/hpack_parser.h
- src/core/ext/transport/chttp2/transport/hpack_table.h
- src/core/ext/transport/chttp2/transport/http2_settings.h
@@ -957,6 +958,7 @@ filegroups:
- src/core/ext/transport/chttp2/transport/frame_settings.cc
- src/core/ext/transport/chttp2/transport/frame_window_update.cc
- src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+ - src/core/ext/transport/chttp2/transport/hpack_mapping.cc
- src/core/ext/transport/chttp2/transport/hpack_parser.cc
- src/core/ext/transport/chttp2/transport/hpack_table.cc
- src/core/ext/transport/chttp2/transport/http2_settings.cc
@@ -1327,7 +1329,6 @@ filegroups:
- src/cpp/client/credentials_cc.cc
- src/cpp/client/generic_stub.cc
- src/cpp/common/alarm.cc
- - src/cpp/common/callback_common.cc
- src/cpp/common/channel_arguments.cc
- src/cpp/common/channel_filter.cc
- src/cpp/common/completion_queue_cc.cc
@@ -5859,6 +5860,7 @@ defaults:
COREFLAGS: -fno-rtti -fno-exceptions
CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1
-Wno-deprecated-declarations -Ithird_party/nanopb -DPB_FIELD_32BIT
+ CXXFLAGS: -Wnon-virtual-dtor
LDFLAGS: -g
zlib:
CFLAGS: -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration
diff --git a/config.m4 b/config.m4
index af3624cdd1..a6ce55e0a9 100644
--- a/config.m4
+++ b/config.m4
@@ -249,6 +249,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/transport/chttp2/transport/frame_settings.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
+ src/core/ext/transport/chttp2/transport/hpack_mapping.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
src/core/ext/transport/chttp2/transport/hpack_table.cc \
src/core/ext/transport/chttp2/transport/http2_settings.cc \
diff --git a/config.w32 b/config.w32
index ad91ee40bd..333986c50a 100644
--- a/config.w32
+++ b/config.w32
@@ -224,6 +224,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\transport\\chttp2\\transport\\frame_settings.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\frame_window_update.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\hpack_encoder.cc " +
+ "src\\core\\ext\\transport\\chttp2\\transport\\hpack_mapping.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\hpack_parser.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\hpack_table.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\http2_settings.cc " +
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index 03ec223279..d45e0c519b 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -190,7 +190,6 @@ Pod::Spec.new do |s|
'src/cpp/client/credentials_cc.cc',
'src/cpp/client/generic_stub.cc',
'src/cpp/common/alarm.cc',
- 'src/cpp/common/callback_common.cc',
'src/cpp/common/channel_arguments.cc',
'src/cpp/common/channel_filter.cc',
'src/cpp/common/completion_queue_cc.cc',
@@ -255,6 +254,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/frame_settings.h',
'src/core/ext/transport/chttp2/transport/frame_window_update.h',
'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_mapping.h',
'src/core/ext/transport/chttp2/transport/hpack_parser.h',
'src/core/ext/transport/chttp2/transport/hpack_table.h',
'src/core/ext/transport/chttp2/transport/http2_settings.h',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 5a82a4200a..1efa71a19e 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -263,6 +263,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/frame_settings.h',
'src/core/ext/transport/chttp2/transport/frame_window_update.h',
'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_mapping.h',
'src/core/ext/transport/chttp2/transport/hpack_parser.h',
'src/core/ext/transport/chttp2/transport/hpack_table.h',
'src/core/ext/transport/chttp2/transport/http2_settings.h',
@@ -681,6 +682,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/frame_settings.cc',
'src/core/ext/transport/chttp2/transport/frame_window_update.cc',
'src/core/ext/transport/chttp2/transport/hpack_encoder.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc',
'src/core/ext/transport/chttp2/transport/hpack_parser.cc',
'src/core/ext/transport/chttp2/transport/hpack_table.cc',
'src/core/ext/transport/chttp2/transport/http2_settings.cc',
@@ -866,6 +868,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/frame_settings.h',
'src/core/ext/transport/chttp2/transport/frame_window_update.h',
'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
+ 'src/core/ext/transport/chttp2/transport/hpack_mapping.h',
'src/core/ext/transport/chttp2/transport/hpack_parser.h',
'src/core/ext/transport/chttp2/transport/hpack_table.h',
'src/core/ext/transport/chttp2/transport/http2_settings.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index c8e58faec9..f5cbf79624 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -195,6 +195,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/transport/frame_settings.h )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_window_update.h )
s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder.h )
+ s.files += %w( src/core/ext/transport/chttp2/transport/hpack_mapping.h )
s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser.h )
s.files += %w( src/core/ext/transport/chttp2/transport/hpack_table.h )
s.files += %w( src/core/ext/transport/chttp2/transport/http2_settings.h )
@@ -617,6 +618,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/transport/frame_settings.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_window_update.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/hpack_encoder.cc )
+ s.files += %w( src/core/ext/transport/chttp2/transport/hpack_mapping.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/hpack_parser.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/hpack_table.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/http2_settings.cc )
diff --git a/grpc.gyp b/grpc.gyp
index b8aae44de3..15d20053f4 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -441,6 +441,7 @@
'src/core/ext/transport/chttp2/transport/frame_settings.cc',
'src/core/ext/transport/chttp2/transport/frame_window_update.cc',
'src/core/ext/transport/chttp2/transport/hpack_encoder.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc',
'src/core/ext/transport/chttp2/transport/hpack_parser.cc',
'src/core/ext/transport/chttp2/transport/hpack_table.cc',
'src/core/ext/transport/chttp2/transport/http2_settings.cc',
@@ -825,6 +826,7 @@
'src/core/ext/transport/chttp2/transport/frame_settings.cc',
'src/core/ext/transport/chttp2/transport/frame_window_update.cc',
'src/core/ext/transport/chttp2/transport/hpack_encoder.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc',
'src/core/ext/transport/chttp2/transport/hpack_parser.cc',
'src/core/ext/transport/chttp2/transport/hpack_table.cc',
'src/core/ext/transport/chttp2/transport/http2_settings.cc',
@@ -1060,6 +1062,7 @@
'src/core/ext/transport/chttp2/transport/frame_settings.cc',
'src/core/ext/transport/chttp2/transport/frame_window_update.cc',
'src/core/ext/transport/chttp2/transport/hpack_encoder.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc',
'src/core/ext/transport/chttp2/transport/hpack_parser.cc',
'src/core/ext/transport/chttp2/transport/hpack_table.cc',
'src/core/ext/transport/chttp2/transport/http2_settings.cc',
@@ -1252,6 +1255,7 @@
'src/core/ext/transport/chttp2/transport/frame_settings.cc',
'src/core/ext/transport/chttp2/transport/frame_window_update.cc',
'src/core/ext/transport/chttp2/transport/hpack_encoder.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc',
'src/core/ext/transport/chttp2/transport/hpack_parser.cc',
'src/core/ext/transport/chttp2/transport/hpack_table.cc',
'src/core/ext/transport/chttp2/transport/http2_settings.cc',
@@ -1381,7 +1385,6 @@
'src/cpp/client/credentials_cc.cc',
'src/cpp/client/generic_stub.cc',
'src/cpp/common/alarm.cc',
- 'src/cpp/common/callback_common.cc',
'src/cpp/common/channel_arguments.cc',
'src/cpp/common/channel_filter.cc',
'src/cpp/common/completion_queue_cc.cc',
@@ -1529,7 +1532,6 @@
'src/cpp/client/credentials_cc.cc',
'src/cpp/client/generic_stub.cc',
'src/cpp/common/alarm.cc',
- 'src/cpp/common/callback_common.cc',
'src/cpp/common/channel_arguments.cc',
'src/cpp/common/channel_filter.cc',
'src/cpp/common/completion_queue_cc.cc',
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 3ef95ff462..787d6ae6d7 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -111,7 +111,8 @@ GRPCAPI grpc_completion_queue* grpc_completion_queue_create_for_pluck(
of GRPC_CQ_CALLBACK and grpc_cq_polling_type of GRPC_CQ_DEFAULT_POLLING.
This function is experimental. */
GRPCAPI grpc_completion_queue* grpc_completion_queue_create_for_callback(
- void* shutdown_callback, void* reserved);
+ grpc_experimental_completion_queue_functor* shutdown_callback,
+ void* reserved);
/** Create a completion queue */
GRPCAPI grpc_completion_queue* grpc_completion_queue_create(
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index 02d87a493a..de90971cc5 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -532,14 +532,14 @@ typedef struct grpc_alts_credentials_options grpc_alts_credentials_options;
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI grpc_alts_credentials_options*
-grpc_alts_credentials_client_options_create();
+grpc_alts_credentials_client_options_create(void);
/**
* This method creates a grpc ALTS credentials server options instance.
* It is used for experimental purpose for now and subject to change.
*/
GRPCAPI grpc_alts_credentials_options*
-grpc_alts_credentials_server_options_create();
+grpc_alts_credentials_server_options_create(void);
/**
* This method adds a target service account to grpc client's ALTS credentials
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 5f3b96f40b..9ed5b3c1d4 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -660,6 +660,19 @@ typedef enum {
GRPC_CQ_CALLBACK
} grpc_cq_completion_type;
+/** EXPERIMENTAL: Specifies an interface class to be used as a tag
+ for callback-based completion queues. This can be used directly,
+ as the first element of a struct in C, or as a base class in C++.
+ Its "run" value should be assigned to some non-member function, such as
+ a static method. */
+typedef struct grpc_experimental_completion_queue_functor {
+ /** The run member specifies a function that will be called when this
+ tag is extracted from the completion queue. Its arguments will be a
+ pointer to this functor and a boolean that indicates whether the
+ operation succeeded (non-zero) or failed (zero) */
+ void (*functor_run)(struct grpc_experimental_completion_queue_functor*, int);
+} grpc_experimental_completion_queue_functor;
+
/* The upgrade to version 2 is currently experimental. */
#define GRPC_CQ_CURRENT_VERSION 2
@@ -678,7 +691,7 @@ typedef struct grpc_completion_queue_attributes {
/* EXPERIMENTAL: START OF VERSION 2 CQ ATTRIBUTES */
/** When creating a callbackable CQ, pass in a functor to get invoked when
* shutdown is complete */
- void* cq_shutdown_cb;
+ grpc_experimental_completion_queue_functor* cq_shutdown_cb;
/* END OF VERSION 2 CQ ATTRIBUTES */
} grpc_completion_queue_attributes;
diff --git a/include/grpcpp/alarm.h b/include/grpcpp/alarm.h
index f484610a6e..365feb4eb9 100644
--- a/include/grpcpp/alarm.h
+++ b/include/grpcpp/alarm.h
@@ -21,6 +21,8 @@
#ifndef GRPCPP_ALARM_H
#define GRPCPP_ALARM_H
+#include <functional>
+
#include <grpc/grpc.h>
#include <grpcpp/impl/codegen/completion_queue.h>
#include <grpcpp/impl/codegen/completion_queue_tag.h>
@@ -76,8 +78,33 @@ class Alarm : private GrpcLibraryCodegen {
/// has already fired has no effect.
void Cancel();
+ /// NOTE: class experimental_type is not part of the public API of this class
+ /// TODO(vjpai): Move these contents to the public API of Alarm when
+ /// they are no longer experimental
+ class experimental_type {
+ public:
+ explicit experimental_type(Alarm* alarm) : alarm_(alarm) {}
+
+ /// Set an alarm to invoke callback \a f. The argument to the callback
+ /// states whether the alarm expired at \a deadline (true) or was cancelled
+ /// (false)
+ template <typename T>
+ void Set(const T& deadline, std::function<void(bool)> f) {
+ alarm_->SetInternal(TimePoint<T>(deadline).raw_time(), std::move(f));
+ }
+
+ private:
+ Alarm* alarm_;
+ };
+
+ /// NOTE: The function experimental() is not stable public API. It is a view
+ /// to the experimental components of this class. It may be changed or removed
+ /// at any time.
+ experimental_type experimental() { return experimental_type(this); }
+
private:
void SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag);
+ void SetInternal(gpr_timespec deadline, std::function<void(bool)> f);
internal::CompletionQueueTag* alarm_;
};
diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h
index 8b3ad66a8d..ca2f867d04 100644
--- a/include/grpcpp/impl/codegen/callback_common.h
+++ b/include/grpcpp/impl/codegen/callback_common.h
@@ -21,25 +21,36 @@
#include <functional>
+#include <grpc/impl/codegen/grpc_types.h>
#include <grpcpp/impl/codegen/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/status.h>
-// Forward declarations
-namespace grpc_core {
-class CQCallbackInterface;
-};
-
namespace grpc {
namespace internal {
+/// An exception-safe way of invoking a user-specified callback function
+template <class Func, class Arg>
+void CatchingCallback(Func&& func, Arg&& arg) {
+#if GRPC_ALLOW_EXCEPTIONS
+ try {
+ func(arg);
+ } catch (...) {
+ // nothing to return or change here, just don't crash the library
+ }
+#else // GRPC_ALLOW_EXCEPTIONS
+ func(arg);
+#endif // GRPC_ALLOW_EXCEPTIONS
+}
+
// The contract on these tags is that they are single-shot. They must be
// constructed and then fired at exactly one point. There is no expectation
// that they can be reused without reconstruction.
-class CallbackWithStatusTag {
+class CallbackWithStatusTag
+ : public grpc_experimental_completion_queue_functor {
public:
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
@@ -54,24 +65,49 @@ class CallbackWithStatusTag {
static void operator delete(void*, void*) { assert(0); }
CallbackWithStatusTag(grpc_call* call, std::function<void(Status)> f,
- CompletionQueueTag* ops);
+ CompletionQueueTag* ops)
+ : call_(call), func_(std::move(f)), ops_(ops) {
+ g_core_codegen_interface->grpc_call_ref(call);
+ functor_run = &CallbackWithStatusTag::StaticRun;
+ }
~CallbackWithStatusTag() {}
- void* tag() { return static_cast<void*>(impl_); }
- Status* status_ptr() { return status_; }
- CompletionQueueTag* ops() { return ops_; }
+ Status* status_ptr() { return &status_; }
// force_run can not be performed on a tag if operations using this tag
// have been sent to PerformOpsOnCall. It is intended for error conditions
// that are detected before the operations are internally processed.
- void force_run(Status s);
+ void force_run(Status s) {
+ status_ = std::move(s);
+ Run(true);
+ }
private:
- grpc_core::CQCallbackInterface* impl_;
- Status* status_;
+ grpc_call* call_;
+ std::function<void(Status)> func_;
CompletionQueueTag* ops_;
+ Status status_;
+
+ static void StaticRun(grpc_experimental_completion_queue_functor* cb,
+ int ok) {
+ static_cast<CallbackWithStatusTag*>(cb)->Run(static_cast<bool>(ok));
+ }
+ void Run(bool ok) {
+ void* ignored = ops_;
+
+ GPR_CODEGEN_ASSERT(ops_->FinalizeResult(&ignored, &ok));
+ GPR_CODEGEN_ASSERT(ignored == ops_);
+
+ // Last use of func_ or status_, so ok to move them out
+ CatchingCallback(std::move(func_), std::move(status_));
+
+ func_ = nullptr; // reset to clear this out for sure
+ status_ = Status(); // reset to clear this out for sure
+ g_core_codegen_interface->grpc_call_unref(call_);
+ }
};
-class CallbackWithSuccessTag {
+class CallbackWithSuccessTag
+ : public grpc_experimental_completion_queue_functor {
public:
// always allocated against a call arena, no memory free required
static void operator delete(void* ptr, std::size_t size) {
@@ -86,19 +122,40 @@ class CallbackWithSuccessTag {
static void operator delete(void*, void*) { assert(0); }
CallbackWithSuccessTag(grpc_call* call, std::function<void(bool)> f,
- CompletionQueueTag* ops);
+ CompletionQueueTag* ops)
+ : call_(call), func_(std::move(f)), ops_(ops) {
+ g_core_codegen_interface->grpc_call_ref(call);
+ functor_run = &CallbackWithSuccessTag::StaticRun;
+ }
- void* tag() { return static_cast<void*>(impl_); }
CompletionQueueTag* ops() { return ops_; }
// force_run can not be performed on a tag if operations using this tag
// have been sent to PerformOpsOnCall. It is intended for error conditions
// that are detected before the operations are internally processed.
- void force_run(bool ok);
+ void force_run(bool ok) { Run(ok); }
private:
- grpc_core::CQCallbackInterface* impl_;
+ grpc_call* call_;
+ std::function<void(bool)> func_;
CompletionQueueTag* ops_;
+
+ static void StaticRun(grpc_experimental_completion_queue_functor* cb,
+ int ok) {
+ static_cast<CallbackWithSuccessTag*>(cb)->Run(static_cast<bool>(ok));
+ }
+ void Run(bool ok) {
+ void* ignored = ops_;
+ bool new_ok = ok;
+ GPR_CODEGEN_ASSERT(ops_->FinalizeResult(&ignored, &new_ok));
+ GPR_CODEGEN_ASSERT(ignored == ops_);
+
+ // Last use of func_, so ok to move it out for rvalue call above
+ CatchingCallback(std::move(func_), ok);
+
+ func_ = nullptr; // reset to clear this out for sure
+ g_core_codegen_interface->grpc_call_unref(call_);
+ }
};
} // namespace internal
diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h
index fc81c8aa0a..4d4faea063 100644
--- a/include/grpcpp/impl/codegen/client_callback.h
+++ b/include/grpcpp/impl/codegen/client_callback.h
@@ -84,7 +84,7 @@ class CallbackUnaryCallImpl {
ops->AllowNoMessage();
ops->ClientSendClose();
ops->ClientRecvStatus(context, tag->status_ptr());
- ops->set_cq_tag(tag->tag());
+ ops->set_cq_tag(tag);
call.PerformOps(ops);
}
};
diff --git a/package.xml b/package.xml
index 9c0e078e92..1e8ae8bb6a 100644
--- a/package.xml
+++ b/package.xml
@@ -200,6 +200,7 @@
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_settings.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_window_update.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_encoder.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_mapping.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_parser.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_table.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/http2_settings.h" role="src" />
@@ -622,6 +623,7 @@
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_settings.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_window_update.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_encoder.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_mapping.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_parser.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/hpack_table.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/http2_settings.cc" role="src" />
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index 1e0c36451b..56716493dc 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -128,6 +128,7 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file,
"");
}
static const char* headers_strs[] = {
+ "functional",
"grpcpp/impl/codegen/async_generic_service.h",
"grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/async_unary_call.h",
@@ -547,6 +548,116 @@ void PrintHeaderClientMethod(grpc_generator::Printer* printer,
}
}
+void PrintHeaderClientMethodCallbackInterfacesStart(
+ grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* vars) {
+ // This declares the interface for the callback-based API. The components
+ // are pure; even though this is new (post-1.0) API, it can be pure because
+ // it is an entirely new interface that happens to be scoped within
+ // StubInterface, not new additions to StubInterface itself
+ printer->Print("class experimental_async_interface {\n");
+ // All methods in this new interface are public. There is no need for private
+ // "Raw" methods since the callback-based API returns unowned raw pointers
+ printer->Print(" public:\n");
+ printer->Indent();
+ printer->Print("virtual ~experimental_async_interface() {}\n");
+}
+
+void PrintHeaderClientMethodCallbackInterfaces(
+ grpc_generator::Printer* printer, const grpc_generator::Method* method,
+ std::map<grpc::string, grpc::string>* vars, bool is_public) {
+ // Reserve is_public for future expansion
+ assert(is_public);
+
+ (*vars)["Method"] = method->name();
+ (*vars)["Request"] = method->input_type_name();
+ (*vars)["Response"] = method->output_type_name();
+
+ if (method->NoStreaming()) {
+ printer->Print(*vars,
+ "virtual void $Method$(::grpc::ClientContext* context, "
+ "const $Request$* request, $Response$* response, "
+ "std::function<void(::grpc::Status)>) = 0;\n");
+ } else if (ClientOnlyStreaming(method)) {
+ // TODO(vjpai): Add support for client-side streaming
+ } else if (ServerOnlyStreaming(method)) {
+ // TODO(vjpai): Add support for server-side streaming
+ } else if (method->BidiStreaming()) {
+ // TODO(vjpai): Add support for bidi streaming
+ }
+}
+
+void PrintHeaderClientMethodCallbackInterfacesEnd(
+ grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* vars) {
+ printer->Outdent();
+ printer->Print("};\n");
+
+ // Declare a function to give the async stub contents. It can't be pure
+ // since this is a new API in StubInterface, but it is meaningless by default
+ // (since any stub that wants to use it must have its own implementation of
+ // the callback functions therein), so make the default return value nullptr.
+ // Intentionally include the word "class" to avoid possible shadowing.
+ printer->Print(
+ "virtual class experimental_async_interface* experimental_async() { "
+ "return nullptr; }\n");
+}
+
+void PrintHeaderClientMethodCallbackStart(
+ grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* vars) {
+ // This declares the stub entry for the callback-based API.
+ printer->Print("class experimental_async final :\n");
+ printer->Print(" public StubInterface::experimental_async_interface {\n");
+ printer->Print(" public:\n");
+ printer->Indent();
+}
+
+void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer,
+ const grpc_generator::Method* method,
+ std::map<grpc::string, grpc::string>* vars,
+ bool is_public) {
+ // Reserve is_public for future expansion
+ assert(is_public);
+
+ (*vars)["Method"] = method->name();
+ (*vars)["Request"] = method->input_type_name();
+ (*vars)["Response"] = method->output_type_name();
+
+ if (method->NoStreaming()) {
+ printer->Print(*vars,
+ "void $Method$(::grpc::ClientContext* context, "
+ "const $Request$* request, $Response$* response, "
+ "std::function<void(::grpc::Status)>) override;\n");
+ } else if (ClientOnlyStreaming(method)) {
+ // TODO(vjpai): Add support for client-side streaming
+ } else if (ServerOnlyStreaming(method)) {
+ // TODO(vjpai): Add support for server-side streaming
+ } else if (method->BidiStreaming()) {
+ // TODO(vjpai): Add support for bidi streaming
+ }
+}
+
+void PrintHeaderClientMethodCallbackEnd(
+ grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* vars) {
+ printer->Outdent();
+ printer->Print(" private:\n");
+ printer->Indent();
+ printer->Print("friend class Stub;\n");
+ printer->Print("explicit experimental_async(Stub* stub): stub_(stub) { }\n");
+ // include a function with a dummy use of stub_ to avoid an unused
+ // private member warning for service with no methods
+ printer->Print("Stub* stub() { return stub_; }\n");
+ printer->Print("Stub* stub_;\n");
+ printer->Outdent();
+ printer->Print("};\n");
+
+ printer->Print(
+ "class experimental_async_interface* experimental_async() override { "
+ "return &async_stub_; }\n");
+}
+
void PrintHeaderClientMethodData(grpc_generator::Printer* printer,
const grpc_generator::Method* method,
std::map<grpc::string, grpc::string>* vars) {
@@ -951,6 +1062,14 @@ void PrintHeaderService(grpc_generator::Printer* printer,
true);
printer->Print(service->method(i)->GetTrailingComments("//").c_str());
}
+ PrintHeaderClientMethodCallbackInterfacesStart(printer, vars);
+ for (int i = 0; i < service->method_count(); ++i) {
+ printer->Print(service->method(i)->GetLeadingComments("//").c_str());
+ PrintHeaderClientMethodCallbackInterfaces(printer, service->method(i).get(),
+ vars, true);
+ printer->Print(service->method(i)->GetTrailingComments("//").c_str());
+ }
+ PrintHeaderClientMethodCallbackInterfacesEnd(printer, vars);
printer->Outdent();
printer->Print("private:\n");
printer->Indent();
@@ -970,10 +1089,17 @@ void PrintHeaderService(grpc_generator::Printer* printer,
for (int i = 0; i < service->method_count(); ++i) {
PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
}
+ PrintHeaderClientMethodCallbackStart(printer, vars);
+ for (int i = 0; i < service->method_count(); ++i) {
+ PrintHeaderClientMethodCallback(printer, service->method(i).get(), vars,
+ true);
+ }
+ PrintHeaderClientMethodCallbackEnd(printer, vars);
printer->Outdent();
printer->Print("\n private:\n");
printer->Indent();
printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
+ printer->Print("class experimental_async async_stub_{this};\n");
for (int i = 0; i < service->method_count(); ++i) {
PrintHeaderClientMethod(printer, service->method(i).get(), vars, false);
}
@@ -1199,10 +1325,12 @@ grpc::string GetSourceIncludes(grpc_generator::File* file,
std::map<grpc::string, grpc::string> vars;
static const char* headers_strs[] = {
+ "functional",
"grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/async_unary_call.h",
"grpcpp/impl/codegen/channel_interface.h",
"grpcpp/impl/codegen/client_unary_call.h",
+ "grpcpp/impl/codegen/client_callback.h",
"grpcpp/impl/codegen/method_handler_impl.h",
"grpcpp/impl/codegen/rpc_service_method.h",
"grpcpp/impl/codegen/service_type.h",
@@ -1247,6 +1375,17 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
" return ::grpc::internal::BlockingUnaryCall"
"(channel_.get(), rpcmethod_$Method$_, "
"context, request, response);\n}\n\n");
+
+ printer->Print(*vars,
+ "void $ns$$Service$::Stub::experimental_async::$Method$("
+ "::grpc::ClientContext* context, "
+ "const $Request$* request, $Response$* response, "
+ "std::function<void(::grpc::Status)> f) {\n");
+ printer->Print(*vars,
+ " return ::grpc::internal::CallbackUnaryCall"
+ "(stub_->channel_.get(), stub_->rpcmethod_$Method$_, "
+ "context, request, response, std::move(f));\n}\n\n");
+
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start;
@@ -1277,6 +1416,9 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"rpcmethod_$Method$_, "
"context, response);\n"
"}\n\n");
+
+ // TODO(vjpai): Add callback version
+
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start;
@@ -1308,6 +1450,9 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"rpcmethod_$Method$_, "
"context, request);\n"
"}\n\n");
+
+ // TODO(vjpai): Add callback version
+
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start;
@@ -1339,6 +1484,9 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"rpcmethod_$Method$_, "
"context);\n"
"}\n\n");
+
+ // TODO(vjpai): Add callback version
+
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
(*vars)["AsyncStart"] = async_prefix.start;
diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc
index f2b6c24e8e..1c23a6c4be 100644
--- a/src/core/ext/filters/client_channel/subchannel_index.cc
+++ b/src/core/ext/filters/client_channel/subchannel_index.cc
@@ -42,7 +42,7 @@ struct grpc_subchannel_key {
grpc_subchannel_args args;
};
-static gpr_atm g_force_creation = false;
+static bool g_force_creation = false;
static grpc_subchannel_key* create_key(
const grpc_subchannel_args* args,
@@ -74,7 +74,7 @@ static grpc_subchannel_key* subchannel_key_copy(grpc_subchannel_key* k) {
int grpc_subchannel_key_compare(const grpc_subchannel_key* a,
const grpc_subchannel_key* b) {
// To pretend the keys are different, return a non-zero value.
- if (GPR_UNLIKELY(gpr_atm_no_barrier_load(&g_force_creation))) return 1;
+ if (GPR_UNLIKELY(g_force_creation)) return 1;
int c = GPR_ICMP(a->args.filter_count, b->args.filter_count);
if (c != 0) return c;
if (a->args.filter_count > 0) {
@@ -251,5 +251,5 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key,
}
void grpc_subchannel_index_test_only_set_force_creation(bool force_creation) {
- gpr_atm_no_barrier_store(&g_force_creation, force_creation);
+ g_force_creation = force_creation;
}
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
index 0eaf63f133..920d52770f 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
@@ -525,7 +525,7 @@ static void hpack_enc(grpc_chttp2_hpack_compressor* c, grpc_mdelem elem,
/* should this elem be in the table? */
size_t decoder_space_usage =
- grpc_mdelem_get_size_in_hpack_table(elem, st->use_true_binary_metadata);
+ grpc_chttp2_get_size_in_hpack_table(elem, st->use_true_binary_metadata);
bool should_add_elem = elem_interned &&
decoder_space_usage < MAX_DECODER_SPACE_USAGE &&
c->filter_elems[HASH_FRAGMENT_1(elem_hash)] >=
@@ -688,11 +688,22 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor* c,
emit_advertise_table_size_change(c, &st);
}
for (size_t i = 0; i < extra_headers_size; ++i) {
- hpack_enc(c, *extra_headers[i], &st);
+ grpc_mdelem md = *extra_headers[i];
+ uint8_t static_index = grpc_chttp2_get_static_hpack_table_index(md);
+ if (static_index) {
+ emit_indexed(c, static_index, &st);
+ } else {
+ hpack_enc(c, md, &st);
+ }
}
grpc_metadata_batch_assert_ok(metadata);
for (grpc_linked_mdelem* l = metadata->list.head; l; l = l->next) {
- hpack_enc(c, l->md, &st);
+ uint8_t static_index = grpc_chttp2_get_static_hpack_table_index(l->md);
+ if (static_index) {
+ emit_indexed(c, static_index, &st);
+ } else {
+ hpack_enc(c, l->md, &st);
+ }
}
grpc_millis deadline = metadata->deadline;
if (deadline != GRPC_MILLIS_INF_FUTURE) {
diff --git a/src/core/ext/transport/chttp2/transport/hpack_mapping.cc b/src/core/ext/transport/chttp2/transport/hpack_mapping.cc
new file mode 100644
index 0000000000..fd529f0fd4
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/hpack_mapping.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * WARNING: Auto-generated code.
+ *
+ * To make changes to this file, change
+ * tools/codegen/core/gen_static_metadata.py, and then re-run it.
+ *
+ * This file contains the mapping from the index of each metadata element in the
+ * grpc static metadata table to the index of that element in the hpack static
+ * metadata table. If the element is not contained in the static hpack table,
+ * then the returned index is 0.
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/ext/transport/chttp2/transport/hpack_mapping.h"
+
+const uint8_t grpc_hpack_static_mdelem_indices[GRPC_STATIC_MDELEM_COUNT] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 8, 13, 6, 7, 0, 1, 2, 0, 4,
+ 5, 9, 10, 11, 12, 14, 15, 0, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 0, 0, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
diff --git a/src/core/ext/transport/chttp2/transport/hpack_mapping.h b/src/core/ext/transport/chttp2/transport/hpack_mapping.h
new file mode 100644
index 0000000000..ebcd65bd9f
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/hpack_mapping.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * WARNING: Auto-generated code.
+ *
+ * To make changes to this file, change
+ * tools/codegen/core/gen_static_metadata.py, and then re-run it.
+ *
+ * This file contains the mapping from the index of each metadata element in the
+ * grpc static metadata table to the index of that element in the hpack static
+ * metadata table. If the element is not contained in the static hpack table,
+ * then the returned index is 0.
+ */
+
+#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_MAPPING_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_MAPPING_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/transport/static_metadata.h"
+
+extern const uint8_t grpc_hpack_static_mdelem_indices[GRPC_STATIC_MDELEM_COUNT];
+
+#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_MAPPING_H */
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc
index 7929258356..117679ab75 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc
@@ -27,8 +27,10 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+#include "src/core/ext/transport/chttp2/transport/hpack_mapping.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/murmur_hash.h"
+#include "src/core/lib/transport/static_metadata.h"
extern grpc_core::TraceFlag grpc_http_trace;
@@ -366,3 +368,30 @@ grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
return r;
}
+
+static size_t get_base64_encoded_size(size_t raw_length) {
+ static const uint8_t tail_xtra[3] = {0, 2, 3};
+ return raw_length / 3 * 4 + tail_xtra[raw_length % 3];
+}
+
+size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem,
+ bool use_true_binary_metadata) {
+ size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
+ size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem));
+ if (grpc_is_binary_header(GRPC_MDKEY(elem))) {
+ return overhead_and_key + (use_true_binary_metadata
+ ? value_len + 1
+ : get_base64_encoded_size(value_len));
+ } else {
+ return overhead_and_key + value_len;
+ }
+}
+
+uint8_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md) {
+ if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) {
+ return grpc_hpack_static_mdelem_indices[GRPC_MDELEM_DATA(md) -
+ grpc_static_mdelem_table];
+ } else {
+ return 0;
+ }
+}
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.h b/src/core/ext/transport/chttp2/transport/hpack_table.h
index 98026a4ba4..a0ffc6fab7 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.h
@@ -83,6 +83,15 @@ grpc_mdelem grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl* tbl,
/* add a table entry to the index */
grpc_error* grpc_chttp2_hptbl_add(grpc_chttp2_hptbl* tbl,
grpc_mdelem md) GRPC_MUST_USE_RESULT;
+
+size_t grpc_chttp2_get_size_in_hpack_table(grpc_mdelem elem,
+ bool use_true_binary_metadata);
+
+/* Returns the static hpack table index that corresponds to /a elem. Returns 0
+ if /a elem is not statically stored or if it is not in the static hpack
+ table */
+uint8_t grpc_chttp2_get_static_hpack_table_index(grpc_mdelem md);
+
/* Find a key/value pair in the table... returns the index in the table of the
most similar entry, or 0 if the value was not found */
typedef struct {
diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc
index 1e491d2ef8..8e9aa613a6 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.cc
+++ b/src/core/ext/transport/chttp2/transport/parsing.cc
@@ -409,67 +409,81 @@ static void on_initial_header(void* tp, grpc_mdelem md) {
gpr_free(value);
}
- if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
- !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
- /* TODO(ctiller): check for a status like " 0" */
- s->seen_error = true;
- }
+ if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) {
+ // We don't use grpc_mdelem_eq here to avoid executing additional
+ // instructions. The reasoning is if the payload is not equal, we already
+ // know that the metadata elements are not equal because the md is
+ // confirmed to be static. If we had used grpc_mdelem_eq here, then if the
+ // payloads are not equal, grpc_mdelem_eq executes more instructions to
+ // determine if they're equal or not.
+ if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload ||
+ md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) {
+ s->seen_error = true;
+ }
+ } else {
+ if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
+ !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
+ /* TODO(ctiller): check for a status like " 0" */
+ s->seen_error = true;
+ }
- if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) {
- grpc_millis* cached_timeout =
- static_cast<grpc_millis*>(grpc_mdelem_get_user_data(md, free_timeout));
- grpc_millis timeout;
- if (cached_timeout != nullptr) {
- timeout = *cached_timeout;
- } else {
- if (GPR_UNLIKELY(
- !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) {
- char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
- gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
- gpr_free(val);
- timeout = GRPC_MILLIS_INF_FUTURE;
+ if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) {
+ grpc_millis* cached_timeout = static_cast<grpc_millis*>(
+ grpc_mdelem_get_user_data(md, free_timeout));
+ grpc_millis timeout;
+ if (cached_timeout != nullptr) {
+ timeout = *cached_timeout;
+ } else {
+ if (GPR_UNLIKELY(
+ !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) {
+ char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
+ gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
+ gpr_free(val);
+ timeout = GRPC_MILLIS_INF_FUTURE;
+ }
+ if (GRPC_MDELEM_IS_INTERNED(md)) {
+ /* store the result */
+ cached_timeout =
+ static_cast<grpc_millis*>(gpr_malloc(sizeof(grpc_millis)));
+ *cached_timeout = timeout;
+ grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
+ }
}
- if (GRPC_MDELEM_IS_INTERNED(md)) {
- /* store the result */
- cached_timeout =
- static_cast<grpc_millis*>(gpr_malloc(sizeof(grpc_millis)));
- *cached_timeout = timeout;
- grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
+ if (timeout != GRPC_MILLIS_INF_FUTURE) {
+ grpc_chttp2_incoming_metadata_buffer_set_deadline(
+ &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout);
}
+ GRPC_MDELEM_UNREF(md);
+ return;
}
- if (timeout != GRPC_MILLIS_INF_FUTURE) {
- grpc_chttp2_incoming_metadata_buffer_set_deadline(
- &s->metadata_buffer[0], grpc_core::ExecCtx::Get()->Now() + timeout);
- }
+ }
+
+ const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);
+ const size_t metadata_size_limit =
+ t->settings[GRPC_ACKED_SETTINGS]
+ [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
+ if (new_size > metadata_size_limit) {
+ gpr_log(GPR_DEBUG,
+ "received initial metadata size exceeds limit (%" PRIuPTR
+ " vs. %" PRIuPTR ")",
+ new_size, metadata_size_limit);
+ grpc_chttp2_cancel_stream(
+ t, s,
+ grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "received initial metadata size exceeds limit"),
+ GRPC_ERROR_INT_GRPC_STATUS,
+ GRPC_STATUS_RESOURCE_EXHAUSTED));
+ grpc_chttp2_parsing_become_skip_parser(t);
+ s->seen_error = true;
GRPC_MDELEM_UNREF(md);
} else {
- const size_t new_size = s->metadata_buffer[0].size + GRPC_MDELEM_LENGTH(md);
- const size_t metadata_size_limit =
- t->settings[GRPC_ACKED_SETTINGS]
- [GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE];
- if (new_size > metadata_size_limit) {
- gpr_log(GPR_DEBUG,
- "received initial metadata size exceeds limit (%" PRIuPTR
- " vs. %" PRIuPTR ")",
- new_size, metadata_size_limit);
- grpc_chttp2_cancel_stream(
- t, s,
- grpc_error_set_int(
- GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "received initial metadata size exceeds limit"),
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED));
+ grpc_error* error =
+ grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md);
+ if (error != GRPC_ERROR_NONE) {
+ grpc_chttp2_cancel_stream(t, s, error);
grpc_chttp2_parsing_become_skip_parser(t);
s->seen_error = true;
GRPC_MDELEM_UNREF(md);
- } else {
- grpc_error* error =
- grpc_chttp2_incoming_metadata_buffer_add(&s->metadata_buffer[0], md);
- if (error != GRPC_ERROR_NONE) {
- grpc_chttp2_cancel_stream(t, s, error);
- grpc_chttp2_parsing_become_skip_parser(t);
- s->seen_error = true;
- GRPC_MDELEM_UNREF(md);
- }
}
}
}
@@ -491,8 +505,19 @@ static void on_trailing_header(void* tp, grpc_mdelem md) {
gpr_free(value);
}
- if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
- !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
+ if (GRPC_MDELEM_STORAGE(md) == GRPC_MDELEM_STORAGE_STATIC) {
+ // We don't use grpc_mdelem_eq here to avoid executing additional
+ // instructions. The reasoning is if the payload is not equal, we already
+ // know that the metadata elements are not equal because the md is
+ // confirmed to be static. If we had used grpc_mdelem_eq here, then if the
+ // payloads are not equal, grpc_mdelem_eq executes more instructions to
+ // determine if they're equal or not.
+ if (md.payload == GRPC_MDELEM_GRPC_STATUS_1.payload ||
+ md.payload == GRPC_MDELEM_GRPC_STATUS_2.payload) {
+ s->seen_error = true;
+ }
+ } else if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
+ !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
/* TODO(ctiller): check for a status like " 0" */
s->seen_error = true;
}
diff --git a/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc b/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc
index 0a39c6c485..118d18d119 100644
--- a/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc
+++ b/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc
@@ -72,7 +72,8 @@ static void target_service_account_destroy(
static const grpc_alts_credentials_options_vtable vtable = {
alts_client_options_copy, alts_client_options_destroy};
-grpc_alts_credentials_options* grpc_alts_credentials_client_options_create() {
+grpc_alts_credentials_options* grpc_alts_credentials_client_options_create(
+ void) {
auto client_options = static_cast<grpc_alts_credentials_client_options*>(
gpr_zalloc(sizeof(grpc_alts_credentials_client_options)));
client_options->base.vtable = &vtable;
diff --git a/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc b/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc
index 62aa7a620a..1a59c45675 100644
--- a/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc
+++ b/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc
@@ -36,7 +36,8 @@ static void alts_server_options_destroy(
static const grpc_alts_credentials_options_vtable vtable = {
alts_server_options_copy, alts_server_options_destroy};
-grpc_alts_credentials_options* grpc_alts_credentials_server_options_create() {
+grpc_alts_credentials_options* grpc_alts_credentials_server_options_create(
+ void) {
grpc_alts_credentials_server_options* server_options =
static_cast<grpc_alts_credentials_server_options*>(
gpr_zalloc(sizeof(*server_options)));
diff --git a/src/core/lib/surface/completion_queue.cc b/src/core/lib/surface/completion_queue.cc
index c2cf450e94..5dc9991f70 100644
--- a/src/core/lib/surface/completion_queue.cc
+++ b/src/core/lib/surface/completion_queue.cc
@@ -184,7 +184,8 @@ static const cq_poller_vtable g_poller_vtable_by_poller_type[] = {
typedef struct cq_vtable {
grpc_cq_completion_type cq_completion_type;
size_t data_size;
- void (*init)(void* data, grpc_core::CQCallbackInterface* shutdown_callback);
+ void (*init)(void* data,
+ grpc_experimental_completion_queue_functor* shutdown_callback);
void (*shutdown)(grpc_completion_queue* cq);
void (*destroy)(void* data);
bool (*begin_op)(grpc_completion_queue* cq, void* tag);
@@ -267,7 +268,7 @@ typedef struct cq_callback_data {
bool shutdown_called;
/** A callback that gets invoked when the CQ completes shutdown */
- grpc_core::CQCallbackInterface* shutdown_callback;
+ grpc_experimental_completion_queue_functor* shutdown_callback;
} cq_callback_data;
/* Completion queue structure */
@@ -333,12 +334,12 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag,
gpr_timespec deadline, void* reserved);
// Note that cq_init_next and cq_init_pluck do not use the shutdown_callback
-static void cq_init_next(void* data,
- grpc_core::CQCallbackInterface* shutdown_callback);
-static void cq_init_pluck(void* data,
- grpc_core::CQCallbackInterface* shutdown_callback);
-static void cq_init_callback(void* data,
- grpc_core::CQCallbackInterface* shutdown_callback);
+static void cq_init_next(
+ void* data, grpc_experimental_completion_queue_functor* shutdown_callback);
+static void cq_init_pluck(
+ void* data, grpc_experimental_completion_queue_functor* shutdown_callback);
+static void cq_init_callback(
+ void* data, grpc_experimental_completion_queue_functor* shutdown_callback);
static void cq_destroy_next(void* data);
static void cq_destroy_pluck(void* data);
static void cq_destroy_callback(void* data);
@@ -462,7 +463,7 @@ static long cq_event_queue_num_items(grpc_cq_event_queue* q) {
grpc_completion_queue* grpc_completion_queue_create_internal(
grpc_cq_completion_type completion_type, grpc_cq_polling_type polling_type,
- grpc_core::CQCallbackInterface* shutdown_callback) {
+ grpc_experimental_completion_queue_functor* shutdown_callback) {
GPR_TIMER_SCOPE("grpc_completion_queue_create_internal", 0);
grpc_completion_queue* cq;
@@ -497,8 +498,8 @@ grpc_completion_queue* grpc_completion_queue_create_internal(
return cq;
}
-static void cq_init_next(void* data,
- grpc_core::CQCallbackInterface* shutdown_callback) {
+static void cq_init_next(
+ void* data, grpc_experimental_completion_queue_functor* shutdown_callback) {
cq_next_data* cqd = static_cast<cq_next_data*>(data);
/* Initial count is dropped by grpc_completion_queue_shutdown */
gpr_atm_no_barrier_store(&cqd->pending_events, 1);
@@ -513,8 +514,8 @@ static void cq_destroy_next(void* data) {
cq_event_queue_destroy(&cqd->queue);
}
-static void cq_init_pluck(void* data,
- grpc_core::CQCallbackInterface* shutdown_callback) {
+static void cq_init_pluck(
+ void* data, grpc_experimental_completion_queue_functor* shutdown_callback) {
cq_pluck_data* cqd = static_cast<cq_pluck_data*>(data);
/* Initial count is dropped by grpc_completion_queue_shutdown */
gpr_atm_no_barrier_store(&cqd->pending_events, 1);
@@ -532,7 +533,7 @@ static void cq_destroy_pluck(void* data) {
}
static void cq_init_callback(
- void* data, grpc_core::CQCallbackInterface* shutdown_callback) {
+ void* data, grpc_experimental_completion_queue_functor* shutdown_callback) {
cq_callback_data* cqd = static_cast<cq_callback_data*>(data);
/* Initial count is dropped by grpc_completion_queue_shutdown */
gpr_atm_no_barrier_store(&cqd->pending_events, 1);
@@ -859,7 +860,8 @@ static void cq_end_op_for_callback(
GRPC_ERROR_UNREF(error);
- (static_cast<grpc_core::CQCallbackInterface*>(tag))->Run(is_success);
+ auto* functor = static_cast<grpc_experimental_completion_queue_functor*>(tag);
+ (*functor->functor_run)(functor, is_success);
}
void grpc_cq_end_op(grpc_completion_queue* cq, void* tag, grpc_error* error,
@@ -1343,7 +1345,7 @@ static void cq_finish_shutdown_callback(grpc_completion_queue* cq) {
GPR_ASSERT(cqd->shutdown_called);
cq->poller_vtable->shutdown(POLLSET_FROM_CQ(cq), &cq->pollset_shutdown_done);
- callback->Run(true);
+ (*callback->functor_run)(callback, true);
}
static void cq_shutdown_callback(grpc_completion_queue* cq) {
diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h
index a7c524d8e8..d60fe6d6ef 100644
--- a/src/core/lib/surface/completion_queue.h
+++ b/src/core/lib/surface/completion_queue.h
@@ -48,23 +48,6 @@ typedef struct grpc_cq_completion {
uintptr_t next;
} grpc_cq_completion;
-/// For callback CQs, the tag that is passed in for an operation must
-/// actually be a pointer to an implementation of the following class.
-/// When the operation completes, the tag will be typecasted from void*
-/// to grpc_core::CQCallbackInterface* and then the Run method will be
-/// invoked on it. In practice, the language binding (e.g., C++ API
-/// implementation) is responsible for providing and using an implementation
-/// of this abstract base class.
-namespace grpc_core {
-class CQCallbackInterface {
- public:
- virtual ~CQCallbackInterface() {}
- virtual void Run(bool) GRPC_ABSTRACT;
-
- GRPC_ABSTRACT_BASE_CLASS
-};
-} // namespace grpc_core
-
#ifndef NDEBUG
void grpc_cq_internal_ref(grpc_completion_queue* cc, const char* reason,
const char* file, int line);
@@ -106,6 +89,6 @@ int grpc_get_cq_poll_num(grpc_completion_queue* cc);
grpc_completion_queue* grpc_completion_queue_create_internal(
grpc_cq_completion_type completion_type, grpc_cq_polling_type polling_type,
- grpc_core::CQCallbackInterface* shutdown_callback);
+ grpc_experimental_completion_queue_functor* shutdown_callback);
#endif /* GRPC_CORE_LIB_SURFACE_COMPLETION_QUEUE_H */
diff --git a/src/core/lib/surface/completion_queue_factory.cc b/src/core/lib/surface/completion_queue_factory.cc
index ed92dd7eba..2616c156e4 100644
--- a/src/core/lib/surface/completion_queue_factory.cc
+++ b/src/core/lib/surface/completion_queue_factory.cc
@@ -31,8 +31,7 @@ static grpc_completion_queue* default_create(
const grpc_completion_queue_factory* factory,
const grpc_completion_queue_attributes* attr) {
return grpc_completion_queue_create_internal(
- attr->cq_completion_type, attr->cq_polling_type,
- static_cast<grpc_core::CQCallbackInterface*>(attr->cq_shutdown_cb));
+ attr->cq_completion_type, attr->cq_polling_type, attr->cq_shutdown_cb);
}
static grpc_completion_queue_factory_vtable default_vtable = {default_create};
@@ -73,7 +72,8 @@ grpc_completion_queue* grpc_completion_queue_create_for_pluck(void* reserved) {
}
grpc_completion_queue* grpc_completion_queue_create_for_callback(
- void* shutdown_callback, void* reserved) {
+ grpc_experimental_completion_queue_functor* shutdown_callback,
+ void* reserved) {
GPR_ASSERT(!reserved);
grpc_completion_queue_attributes attr = {
2, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING, shutdown_callback};
diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc
index d10194a2fe..d164502280 100644
--- a/src/core/lib/transport/metadata.cc
+++ b/src/core/lib/transport/metadata.cc
@@ -342,24 +342,6 @@ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata) {
changed ? nullptr : reinterpret_cast<grpc_mdelem_data*>(metadata));
}
-static size_t get_base64_encoded_size(size_t raw_length) {
- static const uint8_t tail_xtra[3] = {0, 2, 3};
- return raw_length / 3 * 4 + tail_xtra[raw_length % 3];
-}
-
-size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem,
- bool use_true_binary_metadata) {
- size_t overhead_and_key = 32 + GRPC_SLICE_LENGTH(GRPC_MDKEY(elem));
- size_t value_len = GRPC_SLICE_LENGTH(GRPC_MDVALUE(elem));
- if (grpc_is_binary_header(GRPC_MDKEY(elem))) {
- return overhead_and_key + (use_true_binary_metadata
- ? value_len + 1
- : get_base64_encoded_size(value_len));
- } else {
- return overhead_and_key + value_len;
- }
-}
-
grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) {
switch (GRPC_MDELEM_STORAGE(gmd)) {
case GRPC_MDELEM_STORAGE_EXTERNAL:
diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h
index 78df4bc3a3..338082276c 100644
--- a/src/core/lib/transport/metadata.h
+++ b/src/core/lib/transport/metadata.h
@@ -125,9 +125,6 @@ grpc_mdelem grpc_mdelem_create(
bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b);
-size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem elem,
- bool use_true_binary_metadata);
-
/* Mutator and accessor for grpc_mdelem user data. The destructor function
is used as a type tag and is checked during user_data fetch. */
void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*if_destroy_func)(void*));
diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc
index 49740fcd1e..761aad19c4 100644
--- a/src/core/lib/transport/metadata_batch.cc
+++ b/src/core/lib/transport/metadata_batch.cc
@@ -105,7 +105,7 @@ static grpc_error* maybe_link_callout(grpc_metadata_batch* batch,
return GRPC_ERROR_NONE;
}
if (batch->idx.array[idx] == nullptr) {
- if (grpc_static_callout_is_default[idx]) ++batch->list.default_count;
+ ++batch->list.default_count;
batch->idx.array[idx] = storage;
return GRPC_ERROR_NONE;
}
@@ -121,7 +121,7 @@ static void maybe_unlink_callout(grpc_metadata_batch* batch,
if (idx == GRPC_BATCH_CALLOUTS_COUNT) {
return;
}
- if (grpc_static_callout_is_default[idx]) --batch->list.default_count;
+ --batch->list.default_count;
GPR_ASSERT(batch->idx.array[idx] != nullptr);
batch->idx.array[idx] = nullptr;
}
diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h
index 7068750b6f..0bcbb32d1f 100644
--- a/src/core/lib/transport/metadata_batch.h
+++ b/src/core/lib/transport/metadata_batch.h
@@ -82,6 +82,7 @@ void grpc_metadata_batch_set_value(grpc_linked_mdelem* storage,
grpc_error* grpc_metadata_batch_link_head(grpc_metadata_batch* batch,
grpc_linked_mdelem* storage)
GRPC_MUST_USE_RESULT;
+
/** Add \a storage to the end of \a batch. storage->md is
assumed to be valid.
\a storage is owned by the caller and must survive for the
@@ -100,6 +101,7 @@ grpc_error* grpc_metadata_batch_link_tail(grpc_metadata_batch* batch,
grpc_error* grpc_metadata_batch_add_head(
grpc_metadata_batch* batch, grpc_linked_mdelem* storage,
grpc_mdelem elem_to_add) GRPC_MUST_USE_RESULT;
+
/** Add \a elem_to_add as the last element in \a batch, using
\a storage as backing storage for the linked list element.
\a storage is owned by the caller and must survive for the
diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc
index 6a5144f21a..ed88aa3f28 100644
--- a/src/core/lib/transport/static_metadata.cc
+++ b/src/core/lib/transport/static_metadata.cc
@@ -568,33 +568,6 @@ grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
{&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}},
};
-bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = {
- true, // :path
- true, // :method
- true, // :status
- true, // :authority
- true, // :scheme
- true, // te
- true, // grpc-message
- true, // grpc-status
- true, // grpc-payload-bin
- true, // grpc-encoding
- true, // grpc-accept-encoding
- true, // grpc-server-stats-bin
- true, // grpc-tags-bin
- true, // grpc-trace-bin
- true, // content-type
- true, // content-encoding
- true, // accept-encoding
- true, // grpc-internal-encoding-request
- true, // grpc-internal-stream-encoding-request
- true, // user-agent
- true, // host
- true, // lb-token
- true, // grpc-previous-rpc-attempts
- true, // grpc-retry-pushback-ms
-};
-
const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78,
79, 80, 81, 82};
diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h
index b3a10f5873..1e95f4e5bb 100644
--- a/src/core/lib/transport/static_metadata.h
+++ b/src/core/lib/transport/static_metadata.h
@@ -587,8 +587,6 @@ typedef union {
GRPC_BATCH_CALLOUTS_COUNT) \
: GRPC_BATCH_CALLOUTS_COUNT)
-extern bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT];
-
extern const uint8_t grpc_static_accept_encoding_metadata[8];
#define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \
(GRPC_MAKE_MDELEM( \
diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc
index ad71286e05..c59059f045 100644
--- a/src/cpp/client/channel_cc.cc
+++ b/src/cpp/client/channel_cc.cc
@@ -193,17 +193,19 @@ bool Channel::WaitForStateChangeImpl(grpc_connectivity_state last_observed,
}
namespace {
-class ShutdownCallback : public grpc_core::CQCallbackInterface {
+class ShutdownCallback : public grpc_experimental_completion_queue_functor {
public:
+ ShutdownCallback() { functor_run = &ShutdownCallback::Run; }
// TakeCQ takes ownership of the cq into the shutdown callback
// so that the shutdown callback will be responsible for destroying it
void TakeCQ(CompletionQueue* cq) { cq_ = cq; }
// The Run function will get invoked by the completion queue library
// when the shutdown is actually complete
- void Run(bool) override {
- delete cq_;
- grpc_core::Delete(this);
+ static void Run(grpc_experimental_completion_queue_functor* cb, int) {
+ auto* callback = static_cast<ShutdownCallback*>(cb);
+ delete callback->cq_;
+ grpc_core::Delete(callback);
}
private:
diff --git a/src/cpp/common/alarm.cc b/src/cpp/common/alarm.cc
index 15a373d8a5..5819a4210b 100644
--- a/src/cpp/common/alarm.cc
+++ b/src/cpp/common/alarm.cc
@@ -39,17 +39,6 @@ class AlarmImpl : public CompletionQueueTag {
AlarmImpl() : cq_(nullptr), tag_(nullptr) {
gpr_ref_init(&refs_, 1);
grpc_timer_init_unset(&timer_);
- GRPC_CLOSURE_INIT(&on_alarm_,
- [](void* arg, grpc_error* error) {
- // queue the op on the completion queue
- AlarmImpl* alarm = static_cast<AlarmImpl*>(arg);
- alarm->Ref();
- grpc_cq_end_op(
- alarm->cq_, alarm, error,
- [](void* arg, grpc_cq_completion* completion) {},
- arg, &alarm->completion_);
- },
- this, grpc_schedule_on_exec_ctx);
}
~AlarmImpl() {
grpc_core::ExecCtx exec_ctx;
@@ -68,6 +57,32 @@ class AlarmImpl : public CompletionQueueTag {
cq_ = cq->cq();
tag_ = tag;
GPR_ASSERT(grpc_cq_begin_op(cq_, this));
+ GRPC_CLOSURE_INIT(&on_alarm_,
+ [](void* arg, grpc_error* error) {
+ // queue the op on the completion queue
+ AlarmImpl* alarm = static_cast<AlarmImpl*>(arg);
+ alarm->Ref();
+ grpc_cq_end_op(
+ alarm->cq_, alarm, error,
+ [](void* arg, grpc_cq_completion* completion) {},
+ arg, &alarm->completion_);
+ },
+ this, grpc_schedule_on_exec_ctx);
+ grpc_timer_init(&timer_, grpc_timespec_to_millis_round_up(deadline),
+ &on_alarm_);
+ }
+ void Set(gpr_timespec deadline, std::function<void(bool)> f) {
+ grpc_core::ExecCtx exec_ctx;
+ // Don't use any CQ at all. Instead just use the timer to fire the function
+ callback_ = std::move(f);
+ Ref();
+ GRPC_CLOSURE_INIT(&on_alarm_,
+ [](void* arg, grpc_error* error) {
+ AlarmImpl* alarm = static_cast<AlarmImpl*>(arg);
+ alarm->callback_(error == GRPC_ERROR_NONE);
+ alarm->Unref();
+ },
+ this, grpc_schedule_on_exec_ctx);
grpc_timer_init(&timer_, grpc_timespec_to_millis_round_up(deadline),
&on_alarm_);
}
@@ -95,6 +110,7 @@ class AlarmImpl : public CompletionQueueTag {
// completion queue where events about this alarm will be posted
grpc_completion_queue* cq_;
void* tag_;
+ std::function<void(bool)> callback_;
};
} // namespace internal
@@ -113,6 +129,15 @@ void Alarm::SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag) {
static_cast<internal::AlarmImpl*>(alarm_)->Set(cq, deadline, tag);
}
+void Alarm::SetInternal(gpr_timespec deadline, std::function<void(bool)> f) {
+ // Note that we know that alarm_ is actually an internal::AlarmImpl
+ // but we declared it as the base pointer to avoid a forward declaration
+ // or exposing core data structures in the C++ public headers.
+ // Thus it is safe to use a static_cast to the subclass here, and the
+ // C++ style guide allows us to do so in this case
+ static_cast<internal::AlarmImpl*>(alarm_)->Set(deadline, std::move(f));
+}
+
Alarm::~Alarm() {
if (alarm_ != nullptr) {
static_cast<internal::AlarmImpl*>(alarm_)->Destroy();
diff --git a/src/cpp/common/callback_common.cc b/src/cpp/common/callback_common.cc
deleted file mode 100644
index fa586286d1..0000000000
--- a/src/cpp/common/callback_common.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- *
- * Copyright 2018 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <functional>
-
-#include <grpcpp/impl/codegen/callback_common.h>
-#include <grpcpp/impl/codegen/status.h>
-
-#include "src/core/lib/gprpp/memory.h"
-#include "src/core/lib/surface/completion_queue.h"
-
-namespace grpc {
-namespace internal {
-namespace {
-
-template <class Func, class Arg>
-void CatchingCallback(Func&& func, Arg&& arg) {
-#if GRPC_ALLOW_EXCEPTIONS
- try {
- func(arg);
- } catch (...) {
- // nothing to return or change here, just don't crash the library
- }
-#else // GRPC_ALLOW_EXCEPTIONS
- func(arg);
-#endif // GRPC_ALLOW_EXCEPTIONS
-}
-
-class CallbackWithSuccessImpl : public grpc_core::CQCallbackInterface {
- public:
- static void operator delete(void* ptr, std::size_t size) {
- assert(size == sizeof(CallbackWithSuccessImpl));
- }
-
- // This operator should never be called as the memory should be freed as part
- // of the arena destruction. It only exists to provide a matching operator
- // delete to the operator new so that some compilers will not complain (see
- // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
- // there are no tests catching the compiler warning.
- static void operator delete(void*, void*) { assert(0); }
-
- CallbackWithSuccessImpl(grpc_call* call, CallbackWithSuccessTag* parent,
- std::function<void(bool)> f)
- : call_(call), parent_(parent), func_(std::move(f)) {
- grpc_call_ref(call);
- }
-
- void Run(bool ok) override {
- void* ignored = parent_->ops();
- bool new_ok = ok;
- GPR_ASSERT(parent_->ops()->FinalizeResult(&ignored, &new_ok));
- GPR_ASSERT(ignored == parent_->ops());
-
- // Last use of func_ or ok, so ok to move them out for rvalue call above
- CatchingCallback(std::move(func_), std::move(ok));
-
- func_ = nullptr; // reset to clear this out for sure
- grpc_call_unref(call_);
- }
-
- private:
- grpc_call* call_;
- CallbackWithSuccessTag* parent_;
- std::function<void(bool)> func_;
-};
-
-class CallbackWithStatusImpl : public grpc_core::CQCallbackInterface {
- public:
- static void operator delete(void* ptr, std::size_t size) {
- assert(size == sizeof(CallbackWithStatusImpl));
- }
-
- // This operator should never be called as the memory should be freed as part
- // of the arena destruction. It only exists to provide a matching operator
- // delete to the operator new so that some compilers will not complain (see
- // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
- // there are no tests catching the compiler warning.
- static void operator delete(void*, void*) { assert(0); }
-
- CallbackWithStatusImpl(grpc_call* call, CallbackWithStatusTag* parent,
- std::function<void(Status)> f)
- : call_(call), parent_(parent), func_(std::move(f)), status_() {
- grpc_call_ref(call);
- }
-
- void Run(bool ok) override {
- void* ignored = parent_->ops();
-
- GPR_ASSERT(parent_->ops()->FinalizeResult(&ignored, &ok));
- GPR_ASSERT(ignored == parent_->ops());
-
- // Last use of func_ or status_, so ok to move them out
- CatchingCallback(std::move(func_), std::move(status_));
-
- func_ = nullptr; // reset to clear this out for sure
- grpc_call_unref(call_);
- }
- Status* status_ptr() { return &status_; }
-
- private:
- grpc_call* call_;
- CallbackWithStatusTag* parent_;
- std::function<void(Status)> func_;
- Status status_;
-};
-
-} // namespace
-
-CallbackWithSuccessTag::CallbackWithSuccessTag(grpc_call* call,
- std::function<void(bool)> f,
- CompletionQueueTag* ops)
- : impl_(new (grpc_call_arena_alloc(call, sizeof(CallbackWithSuccessImpl)))
- CallbackWithSuccessImpl(call, this, std::move(f))),
- ops_(ops) {}
-
-void CallbackWithSuccessTag::force_run(bool ok) { impl_->Run(ok); }
-
-CallbackWithStatusTag::CallbackWithStatusTag(grpc_call* call,
- std::function<void(Status)> f,
- CompletionQueueTag* ops)
- : ops_(ops) {
- auto* impl = new (grpc_call_arena_alloc(call, sizeof(CallbackWithStatusImpl)))
- CallbackWithStatusImpl(call, this, std::move(f));
- impl_ = impl;
- status_ = impl->status_ptr();
-}
-
-void CallbackWithStatusTag::force_run(Status s) {
- *status_ = std::move(s);
- impl_->Run(true);
-}
-
-} // namespace internal
-} // namespace grpc
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 0f68e823d7..ceacc83e62 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -223,6 +223,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/transport/chttp2/transport/frame_settings.cc',
'src/core/ext/transport/chttp2/transport/frame_window_update.cc',
'src/core/ext/transport/chttp2/transport/hpack_encoder.cc',
+ 'src/core/ext/transport/chttp2/transport/hpack_mapping.cc',
'src/core/ext/transport/chttp2/transport/hpack_parser.cc',
'src/core/ext/transport/chttp2/transport/hpack_table.cc',
'src/core/ext/transport/chttp2/transport/http2_settings.cc',
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index d00e75c326..8ea5807e4f 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -107,7 +107,7 @@ extern grpc_completion_queue_create_for_next_type grpc_completion_queue_create_f
typedef grpc_completion_queue*(*grpc_completion_queue_create_for_pluck_type)(void* reserved);
extern grpc_completion_queue_create_for_pluck_type grpc_completion_queue_create_for_pluck_import;
#define grpc_completion_queue_create_for_pluck grpc_completion_queue_create_for_pluck_import
-typedef grpc_completion_queue*(*grpc_completion_queue_create_for_callback_type)(void* shutdown_callback, void* reserved);
+typedef grpc_completion_queue*(*grpc_completion_queue_create_for_callback_type)(grpc_experimental_completion_queue_functor* shutdown_callback, void* reserved);
extern grpc_completion_queue_create_for_callback_type grpc_completion_queue_create_for_callback_import;
#define grpc_completion_queue_create_for_callback grpc_completion_queue_create_for_callback_import
typedef grpc_completion_queue*(*grpc_completion_queue_create_type)(const grpc_completion_queue_factory* factory, const grpc_completion_queue_attributes* attributes, void* reserved);
@@ -407,10 +407,10 @@ extern grpc_call_set_credentials_type grpc_call_set_credentials_import;
typedef void(*grpc_server_credentials_set_auth_metadata_processor_type)(grpc_server_credentials* creds, grpc_auth_metadata_processor processor);
extern grpc_server_credentials_set_auth_metadata_processor_type grpc_server_credentials_set_auth_metadata_processor_import;
#define grpc_server_credentials_set_auth_metadata_processor grpc_server_credentials_set_auth_metadata_processor_import
-typedef grpc_alts_credentials_options*(*grpc_alts_credentials_client_options_create_type)();
+typedef grpc_alts_credentials_options*(*grpc_alts_credentials_client_options_create_type)(void);
extern grpc_alts_credentials_client_options_create_type grpc_alts_credentials_client_options_create_import;
#define grpc_alts_credentials_client_options_create grpc_alts_credentials_client_options_create_import
-typedef grpc_alts_credentials_options*(*grpc_alts_credentials_server_options_create_type)();
+typedef grpc_alts_credentials_options*(*grpc_alts_credentials_server_options_create_type)(void);
extern grpc_alts_credentials_server_options_create_type grpc_alts_credentials_server_options_create_import;
#define grpc_alts_credentials_server_options_create grpc_alts_credentials_server_options_create_import
typedef void(*grpc_alts_credentials_client_options_add_target_service_account_type)(grpc_alts_credentials_options* options, const char* service_account);
diff --git a/src/ruby/lib/grpc/generic/rpc_desc.rb b/src/ruby/lib/grpc/generic/rpc_desc.rb
index 5fd1805aab..efb0e4233d 100644
--- a/src/ruby/lib/grpc/generic/rpc_desc.rb
+++ b/src/ruby/lib/grpc/generic/rpc_desc.rb
@@ -32,7 +32,7 @@ module GRPC
# @return [Proc] { |instance| marshalled(instance) }
def marshal_proc
- proc { |o| o.class.method(marshal_method).call(o).to_s }
+ proc { |o| o.class.send(marshal_method, o).to_s }
end
# @param [:input, :output] target determines whether to produce the an
@@ -42,9 +42,9 @@ module GRPC
# @return [Proc] An unmarshal proc { |marshalled(instance)| instance }
def unmarshal_proc(target)
fail ArgumentError unless [:input, :output].include?(target)
- unmarshal_class = method(target).call
+ unmarshal_class = send(target)
unmarshal_class = unmarshal_class.type if unmarshal_class.is_a? Stream
- proc { |o| unmarshal_class.method(unmarshal_method).call(o) }
+ proc { |o| unmarshal_class.send(unmarshal_method, o) }
end
def handle_request_response(active_call, mth, inter_ctx)
diff --git a/src/ruby/spec/client_auth_spec.rb b/src/ruby/spec/client_auth_spec.rb
index c563ed3227..5d2e6d24ec 100644
--- a/src/ruby/spec/client_auth_spec.rb
+++ b/src/ruby/spec/client_auth_spec.rb
@@ -30,7 +30,7 @@ end
def create_server_creds
test_root = File.join(File.dirname(__FILE__), 'testdata')
- p "test root: #{test_root}"
+ GRPC.logger.info("test root: #{test_root}")
files = ['ca.pem', 'server1.key', 'server1.pem']
creds = files.map { |f| File.open(File.join(test_root, f)).read }
GRPC::Core::ServerCredentials.new(
@@ -59,7 +59,7 @@ class SslTestService
def a_client_streaming_rpc(call)
check_peer_cert(call)
- call.each_remote_read.each { |r| p r }
+ call.each_remote_read.each { |r| GRPC.logger.info(r) }
EchoMsg.new
end
@@ -70,7 +70,7 @@ class SslTestService
def a_bidi_rpc(requests, call)
check_peer_cert(call)
- requests.each { |r| p r }
+ requests.each { |r| GRPC.logger.info(r) }
[EchoMsg.new, EchoMsg.new]
end
end
@@ -116,11 +116,11 @@ describe 'client-server auth' do
it 'client-server auth with server streaming RPCs' do
responses = @stub.a_server_streaming_rpc(EchoMsg.new)
- responses.each { |r| p r }
+ responses.each { |r| GRPC.logger.info(r) }
end
it 'client-server auth with bidi RPCs' do
responses = @stub.a_bidi_rpc([EchoMsg.new, EchoMsg.new])
- responses.each { |r| p r }
+ responses.each { |r| GRPC.logger.info(r) }
end
end
diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb
index fc50362ca5..200139d849 100644
--- a/src/ruby/spec/generic/client_stub_spec.rb
+++ b/src/ruby/spec/generic/client_stub_spec.rb
@@ -293,7 +293,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
describe 'without a call operation' do
def get_response(stub, credentials: nil)
- puts credentials.inspect
+ GRPC.logger.info(credentials.inspect)
stub.request_response(@method, @sent_msg, noop, noop,
metadata: @metadata,
credentials: credentials)
@@ -342,13 +342,15 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
it 'sends metadata to the server ok when running start_call first' do
run_op_view_metadata_test(true)
check_op_view_of_finished_client_call(
- @op, @server_initial_md, @server_trailing_md) { |r| p r }
+ @op, @server_initial_md, @server_trailing_md
+ ) { |r| GRPC.logger.info(r) }
end
it 'does not crash when used after the call has been finished' do
run_op_view_metadata_test(false)
check_op_view_of_finished_client_call(
- @op, @server_initial_md, @server_trailing_md) { |r| p r }
+ @op, @server_initial_md, @server_trailing_md
+ ) { |r| GRPC.logger.info(r) }
end
end
end
@@ -435,13 +437,15 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
it 'sends metadata to the server ok when running start_call first' do
run_op_view_metadata_test(true)
check_op_view_of_finished_client_call(
- @op, @server_initial_md, @server_trailing_md) { |r| p r }
+ @op, @server_initial_md, @server_trailing_md
+ ) { |r| GRPC.logger.info(r) }
end
it 'does not crash when used after the call has been finished' do
run_op_view_metadata_test(false)
check_op_view_of_finished_client_call(
- @op, @server_initial_md, @server_trailing_md) { |r| p r }
+ @op, @server_initial_md, @server_trailing_md
+ ) { |r| GRPC.logger.info(r) }
end
end
end
@@ -578,7 +582,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
run_op_view_metadata_test(true)
check_op_view_of_finished_client_call(
@op, @server_initial_md, @server_trailing_md) do |responses|
- responses.each { |r| p r }
+ responses.each { |r| GRPC.logger.info(r) }
end
end
@@ -586,7 +590,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
run_op_view_metadata_test(false)
check_op_view_of_finished_client_call(
@op, @server_initial_md, @server_trailing_md) do |responses|
- responses.each { |r| p r }
+ responses.each { |r| GRPC.logger.info(r) }
end
end
@@ -895,7 +899,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
run_op_view_metadata_test(true)
check_op_view_of_finished_client_call(
@op, @server_initial_md, @server_trailing_md) do |responses|
- responses.each { |r| p r }
+ responses.each { |r| GRPC.logger.info(r) }
end
end
@@ -903,7 +907,7 @@ describe 'ClientStub' do # rubocop:disable Metrics/BlockLength
run_op_view_metadata_test(false)
check_op_view_of_finished_client_call(
@op, @server_initial_md, @server_trailing_md) do |responses|
- responses.each { |r| p r }
+ responses.each { |r| GRPC.logger.info(r) }
end
end
diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb
index e072d0c45f..44a6134086 100644
--- a/src/ruby/spec/generic/rpc_server_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_spec.rb
@@ -125,7 +125,7 @@ class CheckCallAfterFinishedService
fail 'shouldnt reuse service' unless @server_side_call.nil?
@server_side_call = call
# iterate through requests so call can complete
- call.each_remote_read.each { |r| p r }
+ call.each_remote_read.each { |r| GRPC.logger.info(r) }
EchoMsg.new
end
@@ -138,7 +138,7 @@ class CheckCallAfterFinishedService
def a_bidi_rpc(requests, call)
fail 'shouldnt reuse service' unless @server_side_call.nil?
@server_side_call = call
- requests.each { |r| p r }
+ requests.each { |r| GRPC.logger.info(r) }
[EchoMsg.new, EchoMsg.new]
end
end
@@ -560,7 +560,7 @@ describe GRPC::RpcServer do
'connect_k1' => 'connect_v1'
}
wanted_md.each do |key, value|
- puts "key: #{key}"
+ GRPC.logger.info("key: #{key}")
expect(op.metadata[key]).to eq(value)
end
@srv.stop
diff --git a/src/ruby/spec/support/services.rb b/src/ruby/spec/support/services.rb
index 27239cd66c..6e693f1cde 100644
--- a/src/ruby/spec/support/services.rb
+++ b/src/ruby/spec/support/services.rb
@@ -50,7 +50,9 @@ class EchoService
def a_client_streaming_rpc(call)
# iterate through requests so call can complete
call.output_metadata.update(@trailing_metadata)
- call.each_remote_read.each { |r| p r }
+ call.each_remote_read.each do |r|
+ GRPC.logger.info(r)
+ end
EchoMsg.new
end
@@ -61,7 +63,9 @@ class EchoService
def a_bidi_rpc(requests, call)
call.output_metadata.update(@trailing_metadata)
- requests.each { |r| p r }
+ requests.each do |r|
+ GRPC.logger.info(r)
+ end
[EchoMsg.new, EchoMsg.new]
end
end
@@ -71,35 +75,37 @@ EchoStub = EchoService.rpc_stub_class
# For testing server interceptors
class TestServerInterceptor < GRPC::ServerInterceptor
def request_response(request:, call:, method:)
- p "Received request/response call at method #{method}" \
- " with request #{request} for call #{call}"
+ GRPC.logger.info("Received request/response call at method #{method}" \
+ " with request #{request} for call #{call}")
call.output_metadata[:interc] = 'from_request_response'
- p "[GRPC::Ok] (#{method.owner.name}.#{method.name})"
+ GRPC.logger.info("[GRPC::Ok] (#{method.owner.name}.#{method.name})")
yield
end
def client_streamer(call:, method:)
call.output_metadata[:interc] = 'from_client_streamer'
call.each_remote_read.each do |r|
- p "In interceptor: #{r}"
+ GRPC.logger.info("In interceptor: #{r}")
end
- p "Received client streamer call at method #{method} for call #{call}"
+ GRPC.logger.info(
+ "Received client streamer call at method #{method} for call #{call}"
+ )
yield
end
def server_streamer(request:, call:, method:)
- p "Received server streamer call at method #{method} with request" \
- " #{request} for call #{call}"
+ GRPC.logger.info("Received server streamer call at method #{method} with request" \
+ " #{request} for call #{call}")
call.output_metadata[:interc] = 'from_server_streamer'
yield
end
def bidi_streamer(requests:, call:, method:)
requests.each do |r|
- p "Bidi request: #{r}"
+ GRPC.logger.info("Bidi request: #{r}")
end
- p "Received bidi streamer call at method #{method} with requests" \
- " #{requests} for call #{call}"
+ GRPC.logger.info("Received bidi streamer call at method #{method} with requests" \
+ " #{requests} for call #{call}")
call.output_metadata[:interc] = 'from_bidi_streamer'
yield
end
@@ -108,38 +114,38 @@ end
# For testing client interceptors
class TestClientInterceptor < GRPC::ClientInterceptor
def request_response(request:, call:, method:, metadata: {})
- p "Intercepted request/response call at method #{method}" \
+ GRPC.logger.info("Intercepted request/response call at method #{method}" \
" with request #{request} for call #{call}" \
- " and metadata: #{metadata}"
+ " and metadata: #{metadata}")
metadata['foo'] = 'bar_from_request_response'
yield
end
def client_streamer(requests:, call:, method:, metadata: {})
- p "Received client streamer call at method #{method}" \
+ GRPC.logger.info("Received client streamer call at method #{method}" \
" with requests #{requests} for call #{call}" \
- " and metadata: #{metadata}"
+ " and metadata: #{metadata}")
requests.each do |r|
- p "In client interceptor: #{r}"
+ GRPC.logger.info("In client interceptor: #{r}")
end
metadata['foo'] = 'bar_from_client_streamer'
yield
end
def server_streamer(request:, call:, method:, metadata: {})
- p "Received server streamer call at method #{method}" \
+ GRPC.logger.info("Received server streamer call at method #{method}" \
" with request #{request} for call #{call}" \
- " and metadata: #{metadata}"
+ " and metadata: #{metadata}")
metadata['foo'] = 'bar_from_server_streamer'
yield
end
def bidi_streamer(requests:, call:, method:, metadata: {})
- p "Received bidi streamer call at method #{method}" \
+ GRPC.logger.info("Received bidi streamer call at method #{method}" \
"with requests #{requests} for call #{call}" \
- " and metadata: #{metadata}"
+ " and metadata: #{metadata}")
requests.each do |r|
- p "In client interceptor: #{r}"
+ GRPC.logger.info("In client interceptor: #{r}")
end
metadata['foo'] = 'bar_from_bidi_streamer'
yield
diff --git a/test/core/end2end/inproc_callback_test.cc b/test/core/end2end/inproc_callback_test.cc
index 0d6c7c75a8..310030046a 100644
--- a/test/core/end2end/inproc_callback_test.cc
+++ b/test/core/end2end/inproc_callback_test.cc
@@ -37,13 +37,16 @@ typedef struct inproc_fixture_data {
namespace {
template <typename F>
-class CQDeletingCallback : public grpc_core::CQCallbackInterface {
+class CQDeletingCallback : public grpc_experimental_completion_queue_functor {
public:
- explicit CQDeletingCallback(F f) : func_(f) {}
- ~CQDeletingCallback() override {}
- void Run(bool ok) override {
- func_(ok);
- grpc_core::Delete(this);
+ explicit CQDeletingCallback(F f) : func_(f) {
+ functor_run = &CQDeletingCallback::Run;
+ }
+ ~CQDeletingCallback() {}
+ static void Run(grpc_experimental_completion_queue_functor* cb, int ok) {
+ auto* callback = static_cast<CQDeletingCallback*>(cb);
+ callback->func_(static_cast<bool>(ok));
+ grpc_core::Delete(callback);
}
private:
@@ -51,18 +54,24 @@ class CQDeletingCallback : public grpc_core::CQCallbackInterface {
};
template <typename F>
-grpc_core::CQCallbackInterface* NewDeletingCallback(F f) {
+grpc_experimental_completion_queue_functor* NewDeletingCallback(F f) {
return grpc_core::New<CQDeletingCallback<F>>(f);
}
-class ShutdownCallback : public grpc_core::CQCallbackInterface {
+class ShutdownCallback : public grpc_experimental_completion_queue_functor {
public:
ShutdownCallback() : done_(false) {
+ functor_run = &ShutdownCallback::StaticRun;
gpr_mu_init(&mu_);
gpr_cv_init(&cv_);
}
- ~ShutdownCallback() override {}
- void Run(bool ok) override {
+ ~ShutdownCallback() {}
+ static void StaticRun(grpc_experimental_completion_queue_functor* cb,
+ int ok) {
+ auto* callback = static_cast<ShutdownCallback*>(cb);
+ callback->Run(static_cast<bool>(ok));
+ }
+ void Run(bool ok) {
gpr_log(GPR_DEBUG, "CQ shutdown notification invoked");
gpr_mu_lock(&mu_);
done_ = true;
@@ -170,7 +179,7 @@ static void verify_tags(gpr_timespec deadline) {
// This function creates a callback functor that emits the
// desired tag into the global tag set
-static grpc_core::CQCallbackInterface* tag(intptr_t t) {
+static grpc_experimental_completion_queue_functor* tag(intptr_t t) {
auto func = [t](bool ok) {
gpr_mu_lock(&tags_mu);
gpr_log(GPR_DEBUG, "Completing operation %" PRIdPTR, t);
diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc
index b889fd0fc6..f7ce8a7042 100644
--- a/test/core/surface/completion_queue_test.cc
+++ b/test/core/surface/completion_queue_test.cc
@@ -369,11 +369,15 @@ static void test_callback(void) {
LOG_TEST("test_callback");
bool got_shutdown = false;
- class ShutdownCallback : public grpc_core::CQCallbackInterface {
+ class ShutdownCallback : public grpc_experimental_completion_queue_functor {
public:
- ShutdownCallback(bool* done) : done_(done) {}
+ ShutdownCallback(bool* done) : done_(done) {
+ functor_run = &ShutdownCallback::Run;
+ }
~ShutdownCallback() {}
- void Run(bool ok) override { *done_ = ok; }
+ static void Run(grpc_experimental_completion_queue_functor* cb, int ok) {
+ *static_cast<ShutdownCallback*>(cb)->done_ = static_cast<bool>(ok);
+ }
private:
bool* done_;
@@ -391,14 +395,17 @@ static void test_callback(void) {
grpc_completion_queue_factory_lookup(&attr), &attr, nullptr);
int counter = 0;
- class TagCallback : public grpc_core::CQCallbackInterface {
+ class TagCallback : public grpc_experimental_completion_queue_functor {
public:
- TagCallback(int* counter, int tag) : counter_(counter), tag_(tag) {}
+ TagCallback(int* counter, int tag) : counter_(counter), tag_(tag) {
+ functor_run = &TagCallback::Run;
+ }
~TagCallback() {}
- void Run(bool ok) override {
- GPR_ASSERT(ok);
- *counter_ += tag_;
- grpc_core::Delete(this);
+ static void Run(grpc_experimental_completion_queue_functor* cb, int ok) {
+ GPR_ASSERT(static_cast<bool>(ok));
+ auto* callback = static_cast<TagCallback*>(cb);
+ *callback->counter_ += callback->tag_;
+ grpc_core::Delete(callback);
};
private:
diff --git a/test/core/transport/chttp2/hpack_encoder_test.cc b/test/core/transport/chttp2/hpack_encoder_test.cc
index 2a57198ab6..ab819f9092 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.cc
+++ b/test/core/transport/chttp2/hpack_encoder_test.cc
@@ -202,7 +202,7 @@ static void verify_table_size_change_match_elem_size(const char* key,
grpc_mdelem elem = grpc_mdelem_from_slices(
grpc_slice_intern(grpc_slice_from_static_string(key)),
grpc_slice_intern(grpc_slice_from_static_string(value)));
- size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem, use_true_binary);
+ size_t elem_size = grpc_chttp2_get_size_in_hpack_table(elem, use_true_binary);
size_t initial_table_size = g_compressor.table_size;
grpc_linked_mdelem* e =
static_cast<grpc_linked_mdelem*>(gpr_malloc(sizeof(*e)));
diff --git a/test/core/transport/metadata_test.cc b/test/core/transport/metadata_test.cc
index 4be34f72d9..8ab9639dfa 100644
--- a/test/core/transport/metadata_test.cc
+++ b/test/core/transport/metadata_test.cc
@@ -27,6 +27,7 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
+#include "src/core/ext/transport/chttp2/transport/hpack_table.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/slice/slice_internal.h"
@@ -293,7 +294,7 @@ static void verify_ascii_header_size(const char* key, const char* value,
grpc_mdelem elem = grpc_mdelem_from_slices(
maybe_intern(grpc_slice_from_static_string(key), intern_key),
maybe_intern(grpc_slice_from_static_string(value), intern_value));
- size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem, false);
+ size_t elem_size = grpc_chttp2_get_size_in_hpack_table(elem, false);
size_t expected_size = 32 + strlen(key) + strlen(value);
GPR_ASSERT(expected_size == elem_size);
GRPC_MDELEM_UNREF(elem);
@@ -307,7 +308,7 @@ static void verify_binary_header_size(const char* key, const uint8_t* value,
maybe_intern(grpc_slice_from_static_buffer(value, value_len),
intern_value));
GPR_ASSERT(grpc_is_binary_header(GRPC_MDKEY(elem)));
- size_t elem_size = grpc_mdelem_get_size_in_hpack_table(elem, false);
+ size_t elem_size = grpc_chttp2_get_size_in_hpack_table(elem, false);
grpc_slice value_slice = grpc_slice_from_copied_buffer(
reinterpret_cast<const char*>(value), value_len);
grpc_slice base64_encoded = grpc_chttp2_base64_encode(value_slice);
diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden
index 756f6a0224..93e1e68654 100644
--- a/test/cpp/codegen/compiler_test_golden
+++ b/test/cpp/codegen/compiler_test_golden
@@ -26,6 +26,7 @@
#include "src/proto/grpc/testing/compiler_test.pb.h"
+#include <functional>
#include <grpcpp/impl/codegen/async_generic_service.h>
#include <grpcpp/impl/codegen/async_stream.h>
#include <grpcpp/impl/codegen/async_unary_call.h>
@@ -105,6 +106,23 @@ class ServiceA final {
return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::testing::Request, ::grpc::testing::Response>>(PrepareAsyncMethodA4Raw(context, cq));
}
// Method A4 trailing comment 1
+ class experimental_async_interface {
+ public:
+ virtual ~experimental_async_interface() {}
+ // MethodA1 leading comment 1
+ virtual void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function<void(::grpc::Status)>) = 0;
+ // MethodA1 trailing comment 1
+ // MethodA2 detached leading comment 1
+ //
+ // Method A2 leading comment 1
+ // Method A2 leading comment 2
+ // MethodA2 trailing comment 1
+ // Method A3 leading comment 1
+ // Method A3 trailing comment 1
+ // Method A4 leading comment 1
+ // Method A4 trailing comment 1
+ };
+ virtual class experimental_async_interface* experimental_async() { return nullptr; }
private:
virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0;
virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* PrepareAsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0;
@@ -155,9 +173,21 @@ class ServiceA final {
std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>> PrepareAsyncMethodA4(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq) {
return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::testing::Request, ::grpc::testing::Response>>(PrepareAsyncMethodA4Raw(context, cq));
}
+ class experimental_async final :
+ public StubInterface::experimental_async_interface {
+ public:
+ void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function<void(::grpc::Status)>) override;
+ private:
+ friend class Stub;
+ explicit experimental_async(Stub* stub): stub_(stub) { }
+ Stub* stub() { return stub_; }
+ Stub* stub_;
+ };
+ class experimental_async_interface* experimental_async() override { return &async_stub_; }
private:
std::shared_ptr< ::grpc::ChannelInterface> channel_;
+ class experimental_async async_stub_{this};
::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* AsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override;
::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* PrepareAsyncMethodA1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override;
::grpc::ClientWriter< ::grpc::testing::Request>* MethodA2Raw(::grpc::ClientContext* context, ::grpc::testing::Response* response) override;
@@ -488,6 +518,14 @@ class ServiceB final {
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>>(PrepareAsyncMethodB1Raw(context, request, cq));
}
// MethodB1 trailing comment 1
+ class experimental_async_interface {
+ public:
+ virtual ~experimental_async_interface() {}
+ // MethodB1 leading comment 1
+ virtual void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function<void(::grpc::Status)>) = 0;
+ // MethodB1 trailing comment 1
+ };
+ virtual class experimental_async_interface* experimental_async() { return nullptr; }
private:
virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* AsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0;
virtual ::grpc::ClientAsyncResponseReaderInterface< ::grpc::testing::Response>* PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) = 0;
@@ -502,9 +540,21 @@ class ServiceB final {
std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>> PrepareAsyncMethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) {
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>>(PrepareAsyncMethodB1Raw(context, request, cq));
}
+ class experimental_async final :
+ public StubInterface::experimental_async_interface {
+ public:
+ void MethodB1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function<void(::grpc::Status)>) override;
+ private:
+ friend class Stub;
+ explicit experimental_async(Stub* stub): stub_(stub) { }
+ Stub* stub() { return stub_; }
+ Stub* stub_;
+ };
+ class experimental_async_interface* experimental_async() override { return &async_stub_; }
private:
std::shared_ptr< ::grpc::ChannelInterface> channel_;
+ class experimental_async async_stub_{this};
::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* AsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override;
::grpc::ClientAsyncResponseReader< ::grpc::testing::Response>* PrepareAsyncMethodB1Raw(::grpc::ClientContext* context, const ::grpc::testing::Request& request, ::grpc::CompletionQueue* cq) override;
const ::grpc::internal::RpcMethod rpcmethod_MethodB1_;
diff --git a/test/cpp/common/alarm_test.cc b/test/cpp/common/alarm_test.cc
index 57d958349e..e909d03658 100644
--- a/test/cpp/common/alarm_test.cc
+++ b/test/cpp/common/alarm_test.cc
@@ -16,9 +16,13 @@
*
*/
+#include <condition_variable>
+#include <memory>
+#include <mutex>
+#include <thread>
+
#include <grpcpp/alarm.h>
#include <grpcpp/completion_queue.h>
-#include <thread>
#include <gtest/gtest.h>
@@ -43,6 +47,66 @@ TEST(AlarmTest, RegularExpiry) {
EXPECT_EQ(junk, output_tag);
}
+struct Completion {
+ bool completed = false;
+ std::mutex mu;
+ std::condition_variable cv;
+};
+
+TEST(AlarmTest, CallbackRegularExpiry) {
+ Alarm alarm;
+
+ auto c = std::make_shared<Completion>();
+ alarm.experimental().Set(
+ std::chrono::system_clock::now() + std::chrono::seconds(1), [c](bool ok) {
+ EXPECT_TRUE(ok);
+ std::lock_guard<std::mutex> l(c->mu);
+ c->completed = true;
+ c->cv.notify_one();
+ });
+
+ std::unique_lock<std::mutex> l(c->mu);
+ EXPECT_TRUE(c->cv.wait_until(
+ l, std::chrono::system_clock::now() + std::chrono::seconds(10),
+ [c] { return c->completed; }));
+}
+
+TEST(AlarmTest, CallbackZeroExpiry) {
+ Alarm alarm;
+
+ auto c = std::make_shared<Completion>();
+ alarm.experimental().Set(grpc_timeout_seconds_to_deadline(0), [c](bool ok) {
+ EXPECT_TRUE(ok);
+ std::lock_guard<std::mutex> l(c->mu);
+ c->completed = true;
+ c->cv.notify_one();
+ });
+
+ std::unique_lock<std::mutex> l(c->mu);
+ EXPECT_TRUE(c->cv.wait_until(
+ l, std::chrono::system_clock::now() + std::chrono::seconds(10),
+ [c] { return c->completed; }));
+}
+
+TEST(AlarmTest, CallbackNegativeExpiry) {
+ Alarm alarm;
+
+ auto c = std::make_shared<Completion>();
+ alarm.experimental().Set(
+ std::chrono::system_clock::now() + std::chrono::seconds(-1),
+ [c](bool ok) {
+ EXPECT_TRUE(ok);
+ std::lock_guard<std::mutex> l(c->mu);
+ c->completed = true;
+ c->cv.notify_one();
+ });
+
+ std::unique_lock<std::mutex> l(c->mu);
+ EXPECT_TRUE(c->cv.wait_until(
+ l, std::chrono::system_clock::now() + std::chrono::seconds(10),
+ [c] { return c->completed; }));
+}
+
TEST(AlarmTest, MultithreadedRegularExpiry) {
CompletionQueue cq;
void* junk = reinterpret_cast<void*>(1618033);
@@ -182,6 +246,26 @@ TEST(AlarmTest, Cancellation) {
EXPECT_EQ(junk, output_tag);
}
+TEST(AlarmTest, CallbackCancellation) {
+ Alarm alarm;
+
+ auto c = std::make_shared<Completion>();
+ alarm.experimental().Set(
+ std::chrono::system_clock::now() + std::chrono::seconds(10),
+ [c](bool ok) {
+ EXPECT_FALSE(ok);
+ std::lock_guard<std::mutex> l(c->mu);
+ c->completed = true;
+ c->cv.notify_one();
+ });
+ alarm.Cancel();
+
+ std::unique_lock<std::mutex> l(c->mu);
+ EXPECT_TRUE(c->cv.wait_until(
+ l, std::chrono::system_clock::now() + std::chrono::seconds(1),
+ [c] { return c->completed; }));
+}
+
TEST(AlarmTest, SetDestruction) {
CompletionQueue cq;
void* junk = reinterpret_cast<void*>(1618033);
@@ -200,6 +284,26 @@ TEST(AlarmTest, SetDestruction) {
EXPECT_EQ(junk, output_tag);
}
+TEST(AlarmTest, CallbackSetDestruction) {
+ auto c = std::make_shared<Completion>();
+ {
+ Alarm alarm;
+ alarm.experimental().Set(
+ std::chrono::system_clock::now() + std::chrono::seconds(10),
+ [c](bool ok) {
+ EXPECT_FALSE(ok);
+ std::lock_guard<std::mutex> l(c->mu);
+ c->completed = true;
+ c->cv.notify_one();
+ });
+ }
+
+ std::unique_lock<std::mutex> l(c->mu);
+ EXPECT_TRUE(c->cv.wait_until(
+ l, std::chrono::system_clock::now() + std::chrono::seconds(1),
+ [c] { return c->completed; }));
+}
+
TEST(AlarmTest, UnsetDestruction) {
CompletionQueue cq;
Alarm alarm;
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index c9246f0806..d97ea071d1 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -178,7 +178,7 @@ class Verifier {
EXPECT_EQ(it2->second.ok, ok);
}
} else {
- gpr_log(GPR_ERROR, "Unexpected tag: %p", tag);
+ gpr_log(GPR_ERROR, "Unexpected tag: %p", got_tag);
abort();
}
}
diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc
index 3b492090dd..62a85641c7 100644
--- a/test/cpp/end2end/client_callback_end2end_test.cc
+++ b/test/cpp/end2end/client_callback_end2end_test.cc
@@ -18,6 +18,7 @@
#include <functional>
#include <mutex>
+#include <thread>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
@@ -55,7 +56,8 @@ class ClientCallbackEnd2endTest : public ::testing::Test {
void ResetStub() {
ChannelArguments args;
channel_ = server_->InProcessChannel(args);
- stub_.reset(new GenericStub(channel_));
+ stub_ = grpc::testing::EchoTestService::NewStub(channel_);
+ generic_stub_.reset(new GenericStub(channel_));
}
void TearDown() override {
@@ -64,7 +66,45 @@ class ClientCallbackEnd2endTest : public ::testing::Test {
}
}
- void SendRpcs(int num_rpcs, bool maybe_except) {
+ void SendRpcs(int num_rpcs, bool with_binary_metadata) {
+ grpc::string test_string("");
+ for (int i = 0; i < num_rpcs; i++) {
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext cli_ctx;
+
+ test_string += "Hello world. ";
+ request.set_message(test_string);
+
+ if (with_binary_metadata) {
+ char bytes[8] = {'\0', '\1', '\2', '\3',
+ '\4', '\5', '\6', static_cast<char>(i)};
+ cli_ctx.AddMetadata("custom-bin", grpc::string(bytes, 8));
+ }
+
+ cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP);
+
+ std::mutex mu;
+ std::condition_variable cv;
+ bool done = false;
+ stub_->experimental_async()->Echo(
+ &cli_ctx, &request, &response,
+ [&request, &response, &done, &mu, &cv](Status s) {
+ GPR_ASSERT(s.ok());
+
+ EXPECT_EQ(request.message(), response.message());
+ std::lock_guard<std::mutex> l(mu);
+ done = true;
+ cv.notify_one();
+ });
+ std::unique_lock<std::mutex> l(mu);
+ while (!done) {
+ cv.wait(l);
+ }
+ }
+ }
+
+ void SendRpcsGeneric(int num_rpcs, bool maybe_except) {
const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo");
grpc::string test_string("");
for (int i = 0; i < num_rpcs; i++) {
@@ -80,7 +120,7 @@ class ClientCallbackEnd2endTest : public ::testing::Test {
std::mutex mu;
std::condition_variable cv;
bool done = false;
- stub_->experimental().UnaryCall(
+ generic_stub_->experimental().UnaryCall(
&cli_ctx, kMethodName, send_buf.get(), &recv_buf,
[&request, &recv_buf, &done, &mu, &cv, maybe_except](Status s) {
GPR_ASSERT(s.ok());
@@ -95,6 +135,8 @@ class ClientCallbackEnd2endTest : public ::testing::Test {
if (maybe_except) {
throw - 1;
}
+#else
+ GPR_ASSERT(!maybe_except);
#endif
});
std::unique_lock<std::mutex> l(mu);
@@ -103,9 +145,11 @@ class ClientCallbackEnd2endTest : public ::testing::Test {
}
}
}
+
bool is_server_started_;
std::shared_ptr<Channel> channel_;
- std::unique_ptr<grpc::GenericStub> stub_;
+ std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
+ std::unique_ptr<grpc::GenericStub> generic_stub_;
TestServiceImpl service_;
std::unique_ptr<Server> server_;
};
@@ -120,13 +164,72 @@ TEST_F(ClientCallbackEnd2endTest, SequentialRpcs) {
SendRpcs(10, false);
}
+TEST_F(ClientCallbackEnd2endTest, SequentialRpcsWithVariedBinaryMetadataValue) {
+ ResetStub();
+ SendRpcs(10, true);
+}
+
+TEST_F(ClientCallbackEnd2endTest, SequentialGenericRpcs) {
+ ResetStub();
+ SendRpcsGeneric(10, false);
+}
+
#if GRPC_ALLOW_EXCEPTIONS
TEST_F(ClientCallbackEnd2endTest, ExceptingRpc) {
ResetStub();
- SendRpcs(10, true);
+ SendRpcsGeneric(10, true);
}
#endif
+TEST_F(ClientCallbackEnd2endTest, MultipleRpcsWithVariedBinaryMetadataValue) {
+ ResetStub();
+ std::vector<std::thread> threads;
+ threads.reserve(10);
+ for (int i = 0; i < 10; ++i) {
+ threads.emplace_back([this] { SendRpcs(10, true); });
+ }
+ for (int i = 0; i < 10; ++i) {
+ threads[i].join();
+ }
+}
+
+TEST_F(ClientCallbackEnd2endTest, MultipleRpcs) {
+ ResetStub();
+ std::vector<std::thread> threads;
+ threads.reserve(10);
+ for (int i = 0; i < 10; ++i) {
+ threads.emplace_back([this] { SendRpcs(10, false); });
+ }
+ for (int i = 0; i < 10; ++i) {
+ threads[i].join();
+ }
+}
+
+TEST_F(ClientCallbackEnd2endTest, CancelRpcBeforeStart) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+ request.set_message("hello");
+ context.TryCancel();
+
+ std::mutex mu;
+ std::condition_variable cv;
+ bool done = false;
+ stub_->experimental_async()->Echo(
+ &context, &request, &response, [&response, &done, &mu, &cv](Status s) {
+ EXPECT_EQ("", response.message());
+ EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
+ std::lock_guard<std::mutex> l(mu);
+ done = true;
+ cv.notify_one();
+ });
+ std::unique_lock<std::mutex> l(mu);
+ while (!done) {
+ cv.wait(l);
+ }
+}
+
} // namespace
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc
index e5d6132012..a9d68ab058 100644
--- a/test/cpp/end2end/client_lb_end2end_test.cc
+++ b/test/cpp/end2end/client_lb_end2end_test.cc
@@ -119,6 +119,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
}
void SetUp() override {
+ grpc_init();
response_generator_ =
grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>();
}
@@ -127,6 +128,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
for (size_t i = 0; i < servers_.size(); ++i) {
servers_[i]->Shutdown();
}
+ grpc_shutdown();
}
void CreateServers(size_t num_servers,
@@ -560,7 +562,23 @@ TEST_F(ClientLbEnd2endTest, PickFirstUpdateSuperset) {
EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName());
}
-TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) {
+class ClientLbEnd2endWithParamTest
+ : public ClientLbEnd2endTest,
+ public ::testing::WithParamInterface<bool> {
+ protected:
+ void SetUp() override {
+ grpc_subchannel_index_test_only_set_force_creation(GetParam());
+ ClientLbEnd2endTest::SetUp();
+ }
+
+ void TearDown() override {
+ ClientLbEnd2endTest::TearDown();
+ grpc_subchannel_index_test_only_set_force_creation(false);
+ }
+};
+
+TEST_P(ClientLbEnd2endWithParamTest, PickFirstManyUpdates) {
+ gpr_log(GPR_INFO, "subchannel force creation: %d", GetParam());
// Start servers and send one RPC per server.
const int kNumServers = 3;
StartServers(kNumServers);
@@ -570,20 +588,21 @@ TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) {
for (size_t i = 0; i < servers_.size(); ++i) {
ports.emplace_back(servers_[i]->port_);
}
- for (const bool force_creation : {true, false}) {
- grpc_subchannel_index_test_only_set_force_creation(force_creation);
- gpr_log(GPR_INFO, "Force subchannel creation: %d", force_creation);
- for (size_t i = 0; i < 1000; ++i) {
- std::shuffle(ports.begin(), ports.end(),
- std::mt19937(std::random_device()()));
- SetNextResolution(ports);
- if (i % 10 == 0) CheckRpcSendOk(stub, DEBUG_LOCATION);
- }
+ for (size_t i = 0; i < 1000; ++i) {
+ std::shuffle(ports.begin(), ports.end(),
+ std::mt19937(std::random_device()()));
+ SetNextResolution(ports);
+ // We should re-enter core at the end of the loop to give the resolution
+ // setting closure a chance to run.
+ if ((i + 1) % 10 == 0) CheckRpcSendOk(stub, DEBUG_LOCATION);
}
// Check LB policy name for the channel.
EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName());
}
+INSTANTIATE_TEST_CASE_P(SubchannelForceCreation, ClientLbEnd2endWithParamTest,
+ ::testing::Bool());
+
TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) {
// Prepare the ports for up servers and down servers.
const int kNumServers = 3;
@@ -984,8 +1003,6 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) {
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc_test_init(argc, argv);
- grpc_init();
const auto result = RUN_ALL_TESTS();
- grpc_shutdown();
return result;
}
diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
index 6fcf048bf3..ba4b57ad22 100644
--- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
+++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
@@ -27,6 +27,7 @@
#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
#include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
+#include "src/core/ext/transport/chttp2/transport/incoming_metadata.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/transport/static_metadata.h"
@@ -456,8 +457,9 @@ static void BM_HpackParserParseHeader(benchmark::State& state) {
std::vector<grpc_slice> benchmark_slices = Fixture::GetBenchmarkSlices();
grpc_chttp2_hpack_parser p;
grpc_chttp2_hpack_parser_init(&p);
+ const int kArenaSize = 4096 * 4096;
+ p.on_header_user_data = gpr_arena_create(kArenaSize);
p.on_header = OnHeader;
- p.on_header_user_data = nullptr;
for (auto slice : init_slices) {
GPR_ASSERT(GRPC_ERROR_NONE == grpc_chttp2_hpack_parser_parse(&p, slice));
}
@@ -466,7 +468,14 @@ static void BM_HpackParserParseHeader(benchmark::State& state) {
GPR_ASSERT(GRPC_ERROR_NONE == grpc_chttp2_hpack_parser_parse(&p, slice));
}
grpc_core::ExecCtx::Get()->Flush();
+ // Recreate arena every 4k iterations to avoid oom
+ if (0 == (state.iterations() & 0xfff)) {
+ gpr_arena_destroy((gpr_arena*)p.on_header_user_data);
+ p.on_header_user_data = gpr_arena_create(kArenaSize);
+ }
}
+ // Clean up
+ gpr_arena_destroy((gpr_arena*)p.on_header_user_data);
for (auto slice : init_slices) grpc_slice_unref(slice);
for (auto slice : benchmark_slices) grpc_slice_unref(slice);
grpc_chttp2_hpack_parser_destroy(&p);
@@ -766,8 +775,58 @@ class RepresentativeServerTrailingMetadata {
static void free_timeout(void* p) { gpr_free(p); }
-// New implementation.
-static void OnHeaderNew(void* user_data, grpc_mdelem md) {
+// Benchmark the current on_initial_header implementation
+static void OnInitialHeader(void* user_data, grpc_mdelem md) {
+ // Setup for benchmark. This will bloat the absolute values of this benchmark
+ grpc_chttp2_incoming_metadata_buffer buffer;
+ grpc_chttp2_incoming_metadata_buffer_init(&buffer, (gpr_arena*)user_data);
+ bool seen_error = false;
+
+ // Below here is the code we actually care about benchmarking
+ if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_STATUS) &&
+ !grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
+ seen_error = true;
+ }
+ if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) {
+ grpc_millis* cached_timeout =
+ static_cast<grpc_millis*>(grpc_mdelem_get_user_data(md, free_timeout));
+ grpc_millis timeout;
+ if (cached_timeout != nullptr) {
+ timeout = *cached_timeout;
+ } else {
+ if (GPR_UNLIKELY(
+ !grpc_http2_decode_timeout(GRPC_MDVALUE(md), &timeout))) {
+ char* val = grpc_slice_to_c_string(GRPC_MDVALUE(md));
+ gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", val);
+ gpr_free(val);
+ timeout = GRPC_MILLIS_INF_FUTURE;
+ }
+ if (GRPC_MDELEM_IS_INTERNED(md)) {
+ /* not already parsed: parse it now, and store the
+ * result away */
+ cached_timeout =
+ static_cast<grpc_millis*>(gpr_malloc(sizeof(grpc_millis)));
+ *cached_timeout = timeout;
+ grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
+ }
+ }
+ benchmark::DoNotOptimize(timeout);
+ GRPC_MDELEM_UNREF(md);
+ } else {
+ const size_t new_size = buffer.size + GRPC_MDELEM_LENGTH(md);
+ if (!seen_error) {
+ buffer.size = new_size;
+ }
+ grpc_error* error = grpc_chttp2_incoming_metadata_buffer_add(&buffer, md);
+ if (error != GRPC_ERROR_NONE) {
+ GPR_ASSERT(0);
+ }
+ }
+ grpc_chttp2_incoming_metadata_buffer_destroy(&buffer);
+}
+
+// Benchmark timeout handling
+static void OnHeaderTimeout(void* user_data, grpc_mdelem md) {
if (grpc_slice_eq(GRPC_MDKEY(md), GRPC_MDSTR_GRPC_TIMEOUT)) {
grpc_millis* cached_timeout =
static_cast<grpc_millis*>(grpc_mdelem_get_user_data(md, free_timeout));
@@ -853,8 +912,13 @@ BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
RepresentativeServerInitialMetadata, UnrefHeader);
BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
RepresentativeServerTrailingMetadata, UnrefHeader);
-
-BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, SameDeadline, OnHeaderNew);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
+ RepresentativeClientInitialMetadata, OnInitialHeader);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
+ MoreRepresentativeClientInitialMetadata, OnInitialHeader);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
+ RepresentativeServerInitialMetadata, OnInitialHeader);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, SameDeadline, OnHeaderTimeout);
} // namespace hpack_parser_fixtures
diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h
index 9d70277fbc..d390ae08f6 100644
--- a/test/cpp/microbenchmarks/fullstack_fixtures.h
+++ b/test/cpp/microbenchmarks/fullstack_fixtures.h
@@ -48,6 +48,7 @@ namespace testing {
class FixtureConfiguration {
public:
+ virtual ~FixtureConfiguration() {}
virtual void ApplyCommonChannelArguments(ChannelArguments* c) const {
c->SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, INT_MAX);
c->SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, INT_MAX);
diff --git a/test/cpp/microbenchmarks/helpers.h b/test/cpp/microbenchmarks/helpers.h
index 4aabd4094a..25d34b5f87 100644
--- a/test/cpp/microbenchmarks/helpers.h
+++ b/test/cpp/microbenchmarks/helpers.h
@@ -63,6 +63,7 @@ extern gpr_atm gpr_now_call_count;
class TrackCounters {
public:
TrackCounters() { grpc_stats_collect(&stats_begin_); }
+ virtual ~TrackCounters() {}
virtual void Finish(benchmark::State& state);
virtual void AddLabel(const grpc::string& label);
virtual void AddToLabel(std::ostream& out, benchmark::State& state);
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
index 25da3fdd5f..ab2e5a671a 100755
--- a/tools/codegen/core/gen_static_metadata.py
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -23,10 +23,14 @@ import subprocess
import re
import perfection
-# configuration: a list of either strings or 2-tuples of strings
-# a single string represents a static grpc_mdstr
-# a 2-tuple represents a static grpc_mdelem (and appropriate grpc_mdstrs will
-# also be created)
+# Configuration: a list of either strings or 2-tuples of strings or 3-tuples of
+# strings.
+# A single string represents a static grpc_mdstr.
+# A 2-tuple represents a static grpc_mdelem (and appropriate grpc_mdstrs will
+# also be created).
+# A 3-tuple represents a static grpc_mdelem (and appropriate grpc_mdstrs will
+# also be created), with the last value equivalent to the mdelem's static hpack
+# table index as defined by RFC 7541
CONFIG = [
# metadata strings
@@ -72,105 +76,104 @@ CONFIG = [
('grpc-encoding', 'deflate'),
('te', 'trailers'),
('content-type', 'application/grpc'),
- (':method', 'POST'),
- (':status', '200'),
- (':status', '404'),
- (':scheme', 'http'),
- (':scheme', 'https'),
- (':scheme', 'grpc'),
- (':authority', ''),
- (':method', 'GET'),
+ (':method', 'POST', 3),
+ (':status', '200', 8),
+ (':status', '404', 13),
+ (':scheme', 'http', 6),
+ (':scheme', 'https', 7),
+ (':scheme', 'grpc', 0),
+ (':authority', '', 1),
+ (':method', 'GET', 2),
(':method', 'PUT'),
- (':path', '/'),
- (':path', '/index.html'),
- (':status', '204'),
- (':status', '206'),
- (':status', '304'),
- (':status', '400'),
- (':status', '500'),
- ('accept-charset', ''),
+ (':path', '/', 4),
+ (':path', '/index.html', 5),
+ (':status', '204', 9),
+ (':status', '206', 10),
+ (':status', '304', 11),
+ (':status', '400', 12),
+ (':status', '500', 14),
+ ('accept-charset', '', 15),
('accept-encoding', ''),
- ('accept-encoding', 'gzip, deflate'),
- ('accept-language', ''),
- ('accept-ranges', ''),
- ('accept', ''),
- ('access-control-allow-origin', ''),
- ('age', ''),
- ('allow', ''),
- ('authorization', ''),
- ('cache-control', ''),
- ('content-disposition', ''),
+ ('accept-encoding', 'gzip, deflate', 16),
+ ('accept-language', '', 17),
+ ('accept-ranges', '', 18),
+ ('accept', '', 19),
+ ('access-control-allow-origin', '', 20),
+ ('age', '', 21),
+ ('allow', '', 22),
+ ('authorization', '', 23),
+ ('cache-control', '', 24),
+ ('content-disposition', '', 25),
('content-encoding', 'identity'),
('content-encoding', 'gzip'),
- ('content-encoding', ''),
- ('content-language', ''),
- ('content-length', ''),
- ('content-location', ''),
- ('content-range', ''),
- ('content-type', ''),
- ('cookie', ''),
- ('date', ''),
- ('etag', ''),
- ('expect', ''),
- ('expires', ''),
- ('from', ''),
- ('host', ''),
- ('if-match', ''),
- ('if-modified-since', ''),
- ('if-none-match', ''),
- ('if-range', ''),
- ('if-unmodified-since', ''),
- ('last-modified', ''),
+ ('content-encoding', '', 26),
+ ('content-language', '', 27),
+ ('content-length', '', 28),
+ ('content-location', '', 29),
+ ('content-range', '', 30),
+ ('content-type', '', 31),
+ ('cookie', '', 32),
+ ('date', '', 33),
+ ('etag', '', 34),
+ ('expect', '', 35),
+ ('expires', '', 36),
+ ('from', '', 37),
+ ('host', '', 38),
+ ('if-match', '', 39),
+ ('if-modified-since', '', 40),
+ ('if-none-match', '', 41),
+ ('if-range', '', 42),
+ ('if-unmodified-since', '', 43),
+ ('last-modified', '', 44),
('lb-token', ''),
('lb-cost-bin', ''),
- ('link', ''),
- ('location', ''),
- ('max-forwards', ''),
- ('proxy-authenticate', ''),
- ('proxy-authorization', ''),
- ('range', ''),
- ('referer', ''),
- ('refresh', ''),
- ('retry-after', ''),
- ('server', ''),
- ('set-cookie', ''),
- ('strict-transport-security', ''),
- ('transfer-encoding', ''),
- ('user-agent', ''),
- ('vary', ''),
- ('via', ''),
- ('www-authenticate', ''),
+ ('link', '', 45),
+ ('location', '', 46),
+ ('max-forwards', '', 47),
+ ('proxy-authenticate', '', 48),
+ ('proxy-authorization', '', 49),
+ ('range', '', 50),
+ ('referer', '', 51),
+ ('refresh', '', 52),
+ ('retry-after', '', 53),
+ ('server', '', 54),
+ ('set-cookie', '', 55),
+ ('strict-transport-security', '', 56),
+ ('transfer-encoding', '', 57),
+ ('user-agent', '', 58),
+ ('vary', '', 59),
+ ('via', '', 60),
+ ('www-authenticate', '', 61),
]
-# Entries marked with is_default=True are ignored when counting
-# non-default initial metadata that prevents the chttp2 server from
-# sending a Trailers-Only response.
+# All entries here are ignored when counting non-default initial metadata that
+# prevents the chttp2 server from sending a Trailers-Only response.
METADATA_BATCH_CALLOUTS = [
- # (name, is_default)
- (':path', True),
- (':method', True),
- (':status', True),
- (':authority', True),
- (':scheme', True),
- ('te', True),
- ('grpc-message', True),
- ('grpc-status', True),
- ('grpc-payload-bin', True),
- ('grpc-encoding', True),
- ('grpc-accept-encoding', True),
- ('grpc-server-stats-bin', True),
- ('grpc-tags-bin', True),
- ('grpc-trace-bin', True),
- ('content-type', True),
- ('content-encoding', True),
- ('accept-encoding', True),
- ('grpc-internal-encoding-request', True),
- ('grpc-internal-stream-encoding-request', True),
- ('user-agent', True),
- ('host', True),
- ('lb-token', True),
- ('grpc-previous-rpc-attempts', True),
- ('grpc-retry-pushback-ms', True),
+ # (name)
+ (':path'),
+ (':method'),
+ (':status'),
+ (':authority'),
+ (':scheme'),
+ ('te'),
+ ('grpc-message'),
+ ('grpc-status'),
+ ('grpc-payload-bin'),
+ ('grpc-encoding'),
+ ('grpc-accept-encoding'),
+ ('grpc-server-stats-bin'),
+ ('grpc-tags-bin'),
+ ('grpc-trace-bin'),
+ ('content-type'),
+ ('content-encoding'),
+ ('accept-encoding'),
+ ('grpc-internal-encoding-request'),
+ ('grpc-internal-stream-encoding-request'),
+ ('user-agent'),
+ ('host'),
+ ('lb-token'),
+ ('grpc-previous-rpc-attempts'),
+ ('grpc-retry-pushback-ms'),
]
COMPRESSION_ALGORITHMS = [
@@ -252,7 +255,7 @@ all_elems = list()
static_userdata = {}
# put metadata batch callouts first, to make the check of if a static metadata
# string is a callout trivial
-for elem, _ in METADATA_BATCH_CALLOUTS:
+for elem in METADATA_BATCH_CALLOUTS:
if elem not in all_strs:
all_strs.append(elem)
for elem in CONFIG:
@@ -323,6 +326,17 @@ else:
os.path.dirname(sys.argv[0]),
'../../../test/core/end2end/fuzzers/hpack.dictionary'), 'w')
+HPACK_H = open(
+ os.path.join(
+ os.path.dirname(sys.argv[0]),
+ '../../../src/core/ext/transport/chttp2/transport/hpack_mapping.h'),
+ 'w')
+HPACK_C = open(
+ os.path.join(
+ os.path.dirname(sys.argv[0]),
+ '../../../src/core/ext/transport/chttp2/transport/hpack_mapping.cc'),
+ 'w')
+
# copy-paste copyright notice from this file
with open(sys.argv[0]) as my_source:
copyright = []
@@ -337,7 +351,8 @@ with open(sys.argv[0]) as my_source:
if line[0] != '#':
break
copyright.append(line)
- put_banner([H, C], [line[2:].rstrip() for line in copyright])
+ put_banner([H, C, HPACK_H, HPACK_C],
+ [line[2:].rstrip() for line in copyright])
hex_bytes = [ord(c) for c in 'abcdefABCDEF0123456789']
@@ -364,16 +379,44 @@ See metadata.h for an explanation of the interface here, and metadata.cc for
an explanation of what's going on.
""".splitlines())
+put_banner([HPACK_H, HPACK_C], """WARNING: Auto-generated code.
+
+To make changes to this file, change
+tools/codegen/core/gen_static_metadata.py, and then re-run it.
+
+This file contains the mapping from the index of each metadata element in the
+grpc static metadata table to the index of that element in the hpack static
+metadata table. If the element is not contained in the static hpack table, then
+the returned index is 0.
+""".splitlines())
+
print >> H, '#ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H'
print >> H, '#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H'
print >> H
+print >> H, '#include <grpc/support/port_platform.h>'
+print >> H
print >> H, '#include "src/core/lib/transport/metadata.h"'
print >> H
-
+print >> C, '#include <grpc/support/port_platform.h>'
+print >> C
print >> C, '#include "src/core/lib/transport/static_metadata.h"'
print >> C
print >> C, '#include "src/core/lib/slice/slice_internal.h"'
print >> C
+print >> HPACK_H, ('#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_'
+ 'MAPPING_H')
+print >> HPACK_H, ('#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_'
+ 'MAPPING_H')
+print >> HPACK_H
+print >> HPACK_H, '#include <grpc/support/port_platform.h>'
+print >> HPACK_H
+print >> HPACK_H, '#include "src/core/lib/transport/static_metadata.h"'
+print >> HPACK_H
+print >> HPACK_C, '#include <grpc/support/port_platform.h>'
+print >> HPACK_C
+print >> HPACK_C, ('#include '
+ '"src/core/ext/transport/chttp2/transport/hpack_mapping.h"')
+print >> HPACK_C
str_ofs = 0
id2strofs = {}
@@ -388,7 +431,7 @@ def slice_def(i):
# validate configuration
-for elem, _ in METADATA_BATCH_CALLOUTS:
+for elem in METADATA_BATCH_CALLOUTS:
assert elem in all_strs
print >> H, '#define GRPC_STATIC_MDSTR_COUNT %d' % len(all_strs)
@@ -450,10 +493,28 @@ print >> H, ('extern grpc_mdelem_data '
print >> H, ('extern uintptr_t '
'grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];')
for i, elem in enumerate(all_elems):
- print >> H, '/* "%s": "%s" */' % elem
+ print >> H, '/* "%s": "%s" */' % (elem[0], elem[1])
print >> H, ('#define %s (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[%d], '
'GRPC_MDELEM_STORAGE_STATIC))') % (mangle(elem).upper(), i)
print >> H
+
+# Print out the chttp2 mapping between static mdelem index and the hpack static
+# table index
+print >> HPACK_H, ('extern const uint8_t grpc_hpack_static_mdelem_indices['
+ 'GRPC_STATIC_MDELEM_COUNT];')
+print >> HPACK_H
+print >> HPACK_C, ('const uint8_t grpc_hpack_static_mdelem_indices['
+ 'GRPC_STATIC_MDELEM_COUNT] = {')
+indices = ''
+for elem in all_elems:
+ index = 0
+ if len(elem) == 3:
+ index = elem[2]
+ indices += '%d,' % index
+print >> HPACK_C, ' %s' % indices
+print >> HPACK_C, '};'
+print >> HPACK_C
+
print >> C, ('uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] '
'= {')
print >> C, ' %s' % ','.join(
@@ -546,12 +607,13 @@ print >> C, '}'
print >> C
print >> C, 'grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {'
-for a, b in all_elems:
- print >> C, '{%s,%s},' % (slice_def(str_idx(a)), slice_def(str_idx(b)))
+for elem in all_elems:
+ print >> C, '{%s,%s},' % (slice_def(str_idx(elem[0])),
+ slice_def(str_idx(elem[1])))
print >> C, '};'
print >> H, 'typedef enum {'
-for elem, _ in METADATA_BATCH_CALLOUTS:
+for elem in METADATA_BATCH_CALLOUTS:
print >> H, ' %s,' % mangle(elem, 'batch').upper()
print >> H, ' GRPC_BATCH_CALLOUTS_COUNT'
print >> H, '} grpc_metadata_batch_callouts_index;'
@@ -559,7 +621,7 @@ print >> H
print >> H, 'typedef union {'
print >> H, ' struct grpc_linked_mdelem *array[GRPC_BATCH_CALLOUTS_COUNT];'
print >> H, ' struct {'
-for elem, _ in METADATA_BATCH_CALLOUTS:
+for elem in METADATA_BATCH_CALLOUTS:
print >> H, ' struct grpc_linked_mdelem *%s;' % mangle(elem, '').lower()
print >> H, ' } named;'
print >> H, '} grpc_metadata_batch_callouts;'
@@ -567,14 +629,6 @@ print >> H
print >> H, '#define GRPC_BATCH_INDEX_OF(slice) \\'
print >> H, ' (GRPC_IS_STATIC_METADATA_STRING((slice)) ? (grpc_metadata_batch_callouts_index)GPR_CLAMP(GRPC_STATIC_METADATA_INDEX((slice)), 0, GRPC_BATCH_CALLOUTS_COUNT) : GRPC_BATCH_CALLOUTS_COUNT)'
print >> H
-print >> H, ('extern bool grpc_static_callout_is_default['
- 'GRPC_BATCH_CALLOUTS_COUNT];')
-print >> H
-print >> C, 'bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = {'
-for elem, is_default in METADATA_BATCH_CALLOUTS:
- print >> C, ' %s, // %s' % (str(is_default).lower(), elem)
-print >> C, '};'
-print >> C
print >> H, 'extern const uint8_t grpc_static_accept_encoding_metadata[%d];' % (
1 << len(COMPRESSION_ALGORITHMS))
@@ -599,5 +653,8 @@ print >> H, '#define GRPC_MDELEM_ACCEPT_STREAM_ENCODING_FOR_ALGORITHMS(algs) (GR
print >> H, '#endif /* GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H */'
+print >> HPACK_H, ('#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_'
+ 'MAPPING_H */')
+
H.close()
C.close()
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index a72390d9f8..cfc5ef98e7 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -1190,7 +1190,6 @@ src/cpp/client/secure_credentials.h \
src/cpp/codegen/codegen_init.cc \
src/cpp/common/alarm.cc \
src/cpp/common/auth_property_iterator.cc \
-src/cpp/common/callback_common.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/channel_filter.cc \
src/cpp/common/channel_filter.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 7cd1dc7bf3..ed0e17a99e 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1013,6 +1013,8 @@ src/core/ext/transport/chttp2/transport/frame_window_update.cc \
src/core/ext/transport/chttp2/transport/frame_window_update.h \
src/core/ext/transport/chttp2/transport/hpack_encoder.cc \
src/core/ext/transport/chttp2/transport/hpack_encoder.h \
+src/core/ext/transport/chttp2/transport/hpack_mapping.cc \
+src/core/ext/transport/chttp2/transport/hpack_mapping.h \
src/core/ext/transport/chttp2/transport/hpack_parser.cc \
src/core/ext/transport/chttp2/transport/hpack_parser.h \
src/core/ext/transport/chttp2/transport/hpack_table.cc \
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index f3e93a0874..3f7393ae94 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -10697,6 +10697,7 @@
"src/core/ext/transport/chttp2/transport/frame_settings.h",
"src/core/ext/transport/chttp2/transport/frame_window_update.h",
"src/core/ext/transport/chttp2/transport/hpack_encoder.h",
+ "src/core/ext/transport/chttp2/transport/hpack_mapping.h",
"src/core/ext/transport/chttp2/transport/hpack_parser.h",
"src/core/ext/transport/chttp2/transport/hpack_table.h",
"src/core/ext/transport/chttp2/transport/http2_settings.h",
@@ -10734,6 +10735,8 @@
"src/core/ext/transport/chttp2/transport/frame_window_update.h",
"src/core/ext/transport/chttp2/transport/hpack_encoder.cc",
"src/core/ext/transport/chttp2/transport/hpack_encoder.h",
+ "src/core/ext/transport/chttp2/transport/hpack_mapping.cc",
+ "src/core/ext/transport/chttp2/transport/hpack_mapping.h",
"src/core/ext/transport/chttp2/transport/hpack_parser.cc",
"src/core/ext/transport/chttp2/transport/hpack_parser.h",
"src/core/ext/transport/chttp2/transport/hpack_table.cc",
@@ -11470,7 +11473,6 @@
"src/cpp/client/credentials_cc.cc",
"src/cpp/client/generic_stub.cc",
"src/cpp/common/alarm.cc",
- "src/cpp/common/callback_common.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/channel_filter.cc",
"src/cpp/common/channel_filter.h",