aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD35
-rw-r--r--Makefile86
-rw-r--r--build.yaml44
-rw-r--r--examples/cpp/helloworld/greeter_async_server.cc4
-rw-r--r--gRPC.podspec3
-rwxr-xr-xgrpc.gemspec3
-rw-r--r--include/grpc++/channel.h73
-rw-r--r--include/grpc++/client_context.h4
-rw-r--r--include/grpc++/completion_queue.h16
-rw-r--r--include/grpc++/generic/async_generic_service.h5
-rw-r--r--include/grpc++/generic/generic_stub.h7
-rw-r--r--include/grpc++/impl/call.h12
-rw-r--r--include/grpc++/impl/client_unary_call.h5
-rw-r--r--include/grpc++/impl/codegen/call_hook.h51
-rw-r--r--include/grpc++/impl/codegen/channel_interface.h123
-rw-r--r--include/grpc++/impl/codegen/completion_queue_tag.h52
-rw-r--r--include/grpc++/impl/codegen/config.h116
-rw-r--r--include/grpc++/impl/codegen/server_interface.h253
-rw-r--r--include/grpc++/impl/codegen/status.h76
-rw-r--r--include/grpc++/impl/codegen/status_code_enum.h152
-rw-r--r--include/grpc++/impl/codegen/time.h111
-rw-r--r--include/grpc++/impl/method_handler_impl.h203
-rw-r--r--include/grpc++/impl/rpc_method.h6
-rw-r--r--include/grpc++/impl/rpc_service_method.h191
-rw-r--r--include/grpc++/impl/service_type.h118
-rw-r--r--include/grpc++/server.h174
-rw-r--r--include/grpc++/server_builder.h37
-rw-r--r--include/grpc++/server_context.h2
-rw-r--r--include/grpc++/support/async_stream.h8
-rw-r--r--include/grpc++/support/async_unary_call.h6
-rw-r--r--include/grpc++/support/config.h81
-rw-r--r--include/grpc++/support/status.h41
-rw-r--r--include/grpc++/support/status_code_enum.h117
-rw-r--r--include/grpc++/support/sync_stream.h9
-rw-r--r--include/grpc++/support/time.h76
-rw-r--r--include/grpc/grpc.h15
-rw-r--r--include/grpc/impl/codegen/connectivity_state.h59
-rw-r--r--include/grpc/impl/codegen/port_platform.h340
-rw-r--r--include/grpc/impl/codegen/time.h128
-rw-r--r--include/grpc/support/port_platform.h305
-rw-r--r--include/grpc/support/time.h93
-rw-r--r--package.json3
-rw-r--r--src/compiler/cpp_generator.cc320
-rw-r--r--src/compiler/python_generator.cc1
-rw-r--r--src/cpp/client/channel.cc3
-rw-r--r--src/cpp/common/completion_queue.cc3
-rw-r--r--src/cpp/server/server.cc75
-rw-r--r--src/cpp/server/server_builder.cc57
-rw-r--r--test/core/surface/public_headers_must_be_c89.c3
-rw-r--r--test/cpp/common/alarm_test.cc3
-rw-r--r--test/cpp/end2end/async_end2end_test.cc12
-rw-r--r--test/cpp/end2end/end2end_test.cc166
-rw-r--r--test/cpp/end2end/generic_end2end_test.cc23
-rw-r--r--test/cpp/end2end/hybrid_end2end_test.cc556
-rw-r--r--test/cpp/end2end/test_service_impl.cc199
-rw-r--r--test/cpp/end2end/test_service_impl.h85
-rw-r--r--test/cpp/qps/client_async.cc2
-rw-r--r--test/cpp/qps/server_async.cc2
-rw-r--r--test/cpp/util/byte_buffer_proto_helper.cc60
-rw-r--r--test/cpp/util/byte_buffer_proto_helper.h53
-rw-r--r--test/cpp/util/metrics_server.cc3
-rw-r--r--tools/doxygen/Doxyfile.c++11
-rw-r--r--tools/doxygen/Doxyfile.c++.internal9
-rw-r--r--tools/doxygen/Doxyfile.core5
-rw-r--r--tools/doxygen/Doxyfile.core.internal3
-rw-r--r--tools/run_tests/sources_and_headers.json86
-rw-r--r--tools/run_tests/tests.json20
-rw-r--r--vsprojects/vcxproj/gpr/gpr.vcxproj3
-rw-r--r--vsprojects/vcxproj/gpr/gpr.vcxproj.filters15
-rw-r--r--vsprojects/vcxproj/grpc++/grpc++.vcxproj9
-rw-r--r--vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters30
-rw-r--r--vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj6
-rw-r--r--vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters15
-rw-r--r--vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj9
-rw-r--r--vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters30
-rw-r--r--vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj13
-rw-r--r--vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters50
-rw-r--r--vsprojects/vcxproj/test/hybrid_end2end_test/hybrid_end2end_test.vcxproj207
-rw-r--r--vsprojects/vcxproj/test/hybrid_end2end_test/hybrid_end2end_test.vcxproj.filters21
79 files changed, 3783 insertions, 1628 deletions
diff --git a/BUILD b/BUILD
index fa19d3d0e3..3cca41462c 100644
--- a/BUILD
+++ b/BUILD
@@ -125,6 +125,9 @@ cc_library(
"include/grpc/support/tls_msvc.h",
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
+ "include/grpc/impl/codegen/connectivity_state.h",
+ "include/grpc/impl/codegen/port_platform.h",
+ "include/grpc/impl/codegen/time.h",
],
includes = [
"include",
@@ -793,6 +796,7 @@ cc_library(
"include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/grpc_library.h",
+ "include/grpc++/impl/method_handler_impl.h",
"include/grpc++/impl/proto_utils.h",
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
@@ -825,6 +829,14 @@ cc_library(
"include/grpc++/support/stub_options.h",
"include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h",
+ "include/grpc++/impl/codegen/call_hook.h",
+ "include/grpc++/impl/codegen/channel_interface.h",
+ "include/grpc++/impl/codegen/completion_queue_tag.h",
+ "include/grpc++/impl/codegen/config.h",
+ "include/grpc++/impl/codegen/server_interface.h",
+ "include/grpc++/impl/codegen/status.h",
+ "include/grpc++/impl/codegen/status_code_enum.h",
+ "include/grpc++/impl/codegen/time.h",
],
includes = [
"include",
@@ -886,6 +898,7 @@ cc_library(
"include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/grpc_library.h",
+ "include/grpc++/impl/method_handler_impl.h",
"include/grpc++/impl/proto_utils.h",
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
@@ -918,6 +931,14 @@ cc_library(
"include/grpc++/support/stub_options.h",
"include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h",
+ "include/grpc++/impl/codegen/call_hook.h",
+ "include/grpc++/impl/codegen/channel_interface.h",
+ "include/grpc++/impl/codegen/completion_queue_tag.h",
+ "include/grpc++/impl/codegen/config.h",
+ "include/grpc++/impl/codegen/server_interface.h",
+ "include/grpc++/impl/codegen/status.h",
+ "include/grpc++/impl/codegen/status_code_enum.h",
+ "include/grpc++/impl/codegen/time.h",
],
includes = [
"include",
@@ -956,6 +977,17 @@ cc_library(
"src/compiler/ruby_generator.cc",
],
hdrs = [
+ "include/grpc++/impl/codegen/call_hook.h",
+ "include/grpc++/impl/codegen/channel_interface.h",
+ "include/grpc++/impl/codegen/completion_queue_tag.h",
+ "include/grpc++/impl/codegen/config.h",
+ "include/grpc++/impl/codegen/server_interface.h",
+ "include/grpc++/impl/codegen/status.h",
+ "include/grpc++/impl/codegen/status_code_enum.h",
+ "include/grpc++/impl/codegen/time.h",
+ "include/grpc/impl/codegen/connectivity_state.h",
+ "include/grpc/impl/codegen/port_platform.h",
+ "include/grpc/impl/codegen/time.h",
],
includes = [
"include",
@@ -1060,6 +1092,9 @@ objc_library(
"include/grpc/support/tls_msvc.h",
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
+ "include/grpc/impl/codegen/connectivity_state.h",
+ "include/grpc/impl/codegen/port_platform.h",
+ "include/grpc/impl/codegen/time.h",
"src/core/profiling/timers.h",
"src/core/support/block_annotate.h",
"src/core/support/env.h",
diff --git a/Makefile b/Makefile
index d3597c276c..ca846dd6f5 100644
--- a/Makefile
+++ b/Makefile
@@ -944,6 +944,7 @@ grpc_csharp_plugin: $(BINDIR)/$(CONFIG)/grpc_csharp_plugin
grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin
grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin
grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
+hybrid_end2end_test: $(BINDIR)/$(CONFIG)/hybrid_end2end_test
interop_client: $(BINDIR)/$(CONFIG)/interop_client
interop_server: $(BINDIR)/$(CONFIG)/interop_server
interop_test: $(BINDIR)/$(CONFIG)/interop_test
@@ -1286,6 +1287,7 @@ buildtests_cxx: buildtests_zookeeper privatelibs_cxx \
$(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_test \
$(BINDIR)/$(CONFIG)/generic_end2end_test \
$(BINDIR)/$(CONFIG)/grpc_cli \
+ $(BINDIR)/$(CONFIG)/hybrid_end2end_test \
$(BINDIR)/$(CONFIG)/interop_client \
$(BINDIR)/$(CONFIG)/interop_server \
$(BINDIR)/$(CONFIG)/interop_test \
@@ -1589,6 +1591,8 @@ test_cxx: test_zookeeper buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/generic_async_streaming_ping_pong_test || ( echo test generic_async_streaming_ping_pong_test failed ; exit 1 )
$(E) "[RUN] Testing generic_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 )
+ $(E) "[RUN] Testing hybrid_end2end_test"
+ $(Q) $(BINDIR)/$(CONFIG)/hybrid_end2end_test || ( echo test hybrid_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing interop_test"
$(Q) $(BINDIR)/$(CONFIG)/interop_test || ( echo test interop_test failed ; exit 1 )
$(E) "[RUN] Testing mock_test"
@@ -2270,6 +2274,9 @@ PUBLIC_HEADERS_C += \
include/grpc/support/tls_msvc.h \
include/grpc/support/tls_pthread.h \
include/grpc/support/useful.h \
+ include/grpc/impl/codegen/connectivity_state.h \
+ include/grpc/impl/codegen/port_platform.h \
+ include/grpc/impl/codegen/time.h \
LIBGPR_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_SRC))))
@@ -3014,6 +3021,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/call.h \
include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/grpc_library.h \
+ include/grpc++/impl/method_handler_impl.h \
include/grpc++/impl/proto_utils.h \
include/grpc++/impl/rpc_method.h \
include/grpc++/impl/rpc_service_method.h \
@@ -3046,6 +3054,14 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/support/stub_options.h \
include/grpc++/support/sync_stream.h \
include/grpc++/support/time.h \
+ include/grpc++/impl/codegen/call_hook.h \
+ include/grpc++/impl/codegen/channel_interface.h \
+ include/grpc++/impl/codegen/completion_queue_tag.h \
+ include/grpc++/impl/codegen/config.h \
+ include/grpc++/impl/codegen/server_interface.h \
+ include/grpc++/impl/codegen/status.h \
+ include/grpc++/impl/codegen/status_code_enum.h \
+ include/grpc++/impl/codegen/time.h \
LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
@@ -3185,6 +3201,8 @@ LIBGRPC++_TEST_UTIL_SRC = \
$(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \
+ test/cpp/end2end/test_service_impl.cc \
+ test/cpp/util/byte_buffer_proto_helper.cc \
test/cpp/util/cli_call.cc \
test/cpp/util/create_test_channel.cc \
test/cpp/util/string_ref_helper.cc \
@@ -3233,6 +3251,8 @@ ifneq ($(NO_DEPS),true)
-include $(LIBGRPC++_TEST_UTIL_OBJS:.o=.dep)
endif
endif
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
@@ -3279,6 +3299,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/call.h \
include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/grpc_library.h \
+ include/grpc++/impl/method_handler_impl.h \
include/grpc++/impl/proto_utils.h \
include/grpc++/impl/rpc_method.h \
include/grpc++/impl/rpc_service_method.h \
@@ -3311,6 +3332,14 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/support/stub_options.h \
include/grpc++/support/sync_stream.h \
include/grpc++/support/time.h \
+ include/grpc++/impl/codegen/call_hook.h \
+ include/grpc++/impl/codegen/channel_interface.h \
+ include/grpc++/impl/codegen/completion_queue_tag.h \
+ include/grpc++/impl/codegen/config.h \
+ include/grpc++/impl/codegen/server_interface.h \
+ include/grpc++/impl/codegen/status.h \
+ include/grpc++/impl/codegen/status_code_enum.h \
+ include/grpc++/impl/codegen/time.h \
LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC))))
@@ -3387,6 +3416,18 @@ LIBGRPC_PLUGIN_SUPPORT_SRC = \
src/compiler/python_generator.cc \
src/compiler/ruby_generator.cc \
+PUBLIC_HEADERS_CXX += \
+ include/grpc++/impl/codegen/call_hook.h \
+ include/grpc++/impl/codegen/channel_interface.h \
+ include/grpc++/impl/codegen/completion_queue_tag.h \
+ include/grpc++/impl/codegen/config.h \
+ include/grpc++/impl/codegen/server_interface.h \
+ include/grpc++/impl/codegen/status.h \
+ include/grpc++/impl/codegen/status_code_enum.h \
+ include/grpc++/impl/codegen/time.h \
+ include/grpc/impl/codegen/connectivity_state.h \
+ include/grpc/impl/codegen/port_platform.h \
+ include/grpc/impl/codegen/time.h \
LIBGRPC_PLUGIN_SUPPORT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_PLUGIN_SUPPORT_SRC))))
@@ -9716,6 +9757,49 @@ ifneq ($(NO_DEPS),true)
endif
+HYBRID_END2END_TEST_SRC = \
+ test/cpp/end2end/hybrid_end2end_test.cc \
+
+HYBRID_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HYBRID_END2END_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/hybrid_end2end_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/hybrid_end2end_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/hybrid_end2end_test: $(PROTOBUF_DEP) $(HYBRID_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(HYBRID_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/hybrid_end2end_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/hybrid_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_hybrid_end2end_test: $(HYBRID_END2END_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(HYBRID_END2END_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
@@ -12955,6 +13039,7 @@ test/core/end2end/tests/call_creds.c: $(OPENSSL_DEP)
test/core/security/oauth2_utils.c: $(OPENSSL_DEP)
test/core/util/reconnect_server.c: $(OPENSSL_DEP)
test/core/util/test_tcp_server.c: $(OPENSSL_DEP)
+test/cpp/end2end/test_service_impl.cc: $(OPENSSL_DEP)
test/cpp/interop/client.cc: $(OPENSSL_DEP)
test/cpp/interop/client_helper.cc: $(OPENSSL_DEP)
test/cpp/interop/interop_client.cc: $(OPENSSL_DEP)
@@ -12970,6 +13055,7 @@ test/cpp/qps/server_async.cc: $(OPENSSL_DEP)
test/cpp/qps/server_sync.cc: $(OPENSSL_DEP)
test/cpp/qps/timer.cc: $(OPENSSL_DEP)
test/cpp/util/benchmark_config.cc: $(OPENSSL_DEP)
+test/cpp/util/byte_buffer_proto_helper.cc: $(OPENSSL_DEP)
test/cpp/util/cli_call.cc: $(OPENSSL_DEP)
test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP)
test/cpp/util/string_ref_helper.cc: $(OPENSSL_DEP)
diff --git a/build.yaml b/build.yaml
index 500ec855ae..3be674888d 100644
--- a/build.yaml
+++ b/build.yaml
@@ -34,6 +34,7 @@ filegroups:
- include/grpc++/impl/call.h
- include/grpc++/impl/client_unary_call.h
- include/grpc++/impl/grpc_library.h
+ - include/grpc++/impl/method_handler_impl.h
- include/grpc++/impl/proto_utils.h
- include/grpc++/impl/rpc_method.h
- include/grpc++/impl/rpc_service_method.h
@@ -99,6 +100,16 @@ filegroups:
- src/cpp/util/status.cc
- src/cpp/util/string_ref.cc
- src/cpp/util/time.cc
+- name: grpc++_codegen
+ public_headers:
+ - include/grpc++/impl/codegen/call_hook.h
+ - include/grpc++/impl/codegen/channel_interface.h
+ - include/grpc++/impl/codegen/completion_queue_tag.h
+ - include/grpc++/impl/codegen/config.h
+ - include/grpc++/impl/codegen/server_interface.h
+ - include/grpc++/impl/codegen/status.h
+ - include/grpc++/impl/codegen/status_code_enum.h
+ - include/grpc++/impl/codegen/time.h
- name: grpc_base
public_headers:
- include/grpc/byte_buffer.h
@@ -347,6 +358,16 @@ filegroups:
- src/core/transport/static_metadata.c
- src/core/transport/transport.c
- src/core/transport/transport_op_string.c
+- name: grpc_base_codegen
+ public_headers:
+ - include/grpc/impl/codegen/connectivity_state.h
+ - include/grpc/impl/codegen/port_platform.h
+ - include/grpc/impl/codegen/time.h
+- name: grpc_codegen
+ public_headers:
+ - include/grpc/impl/codegen/connectivity_state.h
+ - include/grpc/impl/codegen/port_platform.h
+ - include/grpc/impl/codegen/time.h
- name: grpc_test_util_base
headers:
- test/core/end2end/cq_verifier.h
@@ -451,6 +472,8 @@ libs:
- src/core/support/time_precise.c
- src/core/support/time_win32.c
- src/core/support/tls_pthread.c
+ filegroups:
+ - grpc_codegen
secure: false
vs_project_guid: '{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}'
- name: gpr_test_util
@@ -624,6 +647,7 @@ libs:
dll: true
filegroups:
- grpc++_base
+ - grpc++_codegen
secure: check
vs_project_guid: '{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}'
- name: grpc++_test_config
@@ -637,6 +661,8 @@ libs:
build: private
language: c++
headers:
+ - test/cpp/end2end/test_service_impl.h
+ - test/cpp/util/byte_buffer_proto_helper.h
- test/cpp/util/cli_call.h
- test/cpp/util/create_test_channel.h
- test/cpp/util/string_ref_helper.h
@@ -645,6 +671,8 @@ libs:
- src/proto/grpc/testing/echo_messages.proto
- src/proto/grpc/testing/echo.proto
- src/proto/grpc/testing/duplicate/echo_duplicate.proto
+ - test/cpp/end2end/test_service_impl.cc
+ - test/cpp/util/byte_buffer_proto_helper.cc
- test/cpp/util/cli_call.cc
- test/cpp/util/create_test_channel.cc
- test/cpp/util/string_ref_helper.cc
@@ -664,6 +692,7 @@ libs:
dll: true
filegroups:
- grpc++_base
+ - grpc++_codegen
secure: false
vs_project_guid: '{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}'
- name: grpc_plugin_support
@@ -692,6 +721,9 @@ libs:
- src/compiler/python_generator.cc
- src/compiler/ruby_generator.cc
deps: []
+ filegroups:
+ - grpc++_codegen
+ - grpc_codegen
secure: false
vs_project_guid: '{B6E81D84-2ACB-41B8-8781-493A944C7817}'
- name: interop_client_helper
@@ -2071,6 +2103,18 @@ targets:
secure: false
vs_config_type: Application
vs_project_guid: '{069E9D05-B78B-4751-9252-D21EBAE7DE8E}'
+- name: hybrid_end2end_test
+ build: test
+ language: c++
+ src:
+ - test/cpp/end2end/hybrid_end2end_test.cc
+ deps:
+ - grpc++_test_util
+ - grpc_test_util
+ - grpc++
+ - grpc
+ - gpr_test_util
+ - gpr
- name: interop_client
build: test
run: false
diff --git a/examples/cpp/helloworld/greeter_async_server.cc b/examples/cpp/helloworld/greeter_async_server.cc
index d06e7c7148..c9b1a67e95 100644
--- a/examples/cpp/helloworld/greeter_async_server.cc
+++ b/examples/cpp/helloworld/greeter_async_server.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -67,7 +67,7 @@ class ServerImpl final {
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service_" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *asynchronous* service.
- builder.RegisterAsyncService(&service_);
+ builder.RegisterService(&service_);
// Get hold of the completion queue used for the asynchronous communication
// with the gRPC runtime.
cq_ = builder.AddCompletionQueue();
diff --git a/gRPC.podspec b/gRPC.podspec
index 18c05e2bd4..b20e2e5e36 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -101,6 +101,9 @@ Pod::Spec.new do |s|
'include/grpc/support/tls_msvc.h',
'include/grpc/support/tls_pthread.h',
'include/grpc/support/useful.h',
+ 'include/grpc/impl/codegen/connectivity_state.h',
+ 'include/grpc/impl/codegen/port_platform.h',
+ 'include/grpc/impl/codegen/time.h',
'src/core/profiling/basic_timers.c',
'src/core/profiling/stap_timers.c',
'src/core/support/alloc.c',
diff --git a/grpc.gemspec b/grpc.gemspec
index 47b66ae535..909cb89acc 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -74,6 +74,9 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/support/tls_msvc.h )
s.files += %w( include/grpc/support/tls_pthread.h )
s.files += %w( include/grpc/support/useful.h )
+ s.files += %w( include/grpc/impl/codegen/connectivity_state.h )
+ s.files += %w( include/grpc/impl/codegen/port_platform.h )
+ s.files += %w( include/grpc/impl/codegen/time.h )
s.files += %w( src/core/profiling/timers.h )
s.files += %w( src/core/support/block_annotate.h )
s.files += %w( src/core/support/env.h )
diff --git a/include/grpc++/channel.h b/include/grpc++/channel.h
index 541be1345f..d6f55a8bf6 100644
--- a/include/grpc++/channel.h
+++ b/include/grpc++/channel.h
@@ -38,35 +38,16 @@
#include <grpc/grpc.h>
#include <grpc++/impl/call.h>
+#include <grpc++/impl/codegen/channel_interface.h>
#include <grpc++/impl/grpc_library.h>
#include <grpc++/support/config.h>
struct grpc_channel;
namespace grpc {
-class CallOpSetInterface;
-class ChannelArguments;
-class CompletionQueue;
-class ChannelCredentials;
-class SecureChannelCredentials;
-
-template <class R>
-class ClientReader;
-template <class W>
-class ClientWriter;
-template <class W, class R>
-class ClientReaderWriter;
-template <class R>
-class ClientAsyncReader;
-template <class W>
-class ClientAsyncWriter;
-template <class W, class R>
-class ClientAsyncReaderWriter;
-template <class R>
-class ClientAsyncResponseReader;
-
/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
-class Channel GRPC_FINAL : public GrpcLibrary,
+class Channel GRPC_FINAL : public ChannelInterface,
+ public GrpcLibrary,
public CallHook,
public std::enable_shared_from_this<Channel> {
public:
@@ -74,61 +55,29 @@ class Channel GRPC_FINAL : public GrpcLibrary,
/// Get the current channel state. If the channel is in IDLE and
/// \a try_to_connect is set to true, try to connect.
- grpc_connectivity_state GetState(bool try_to_connect);
-
- /// Return the \a tag on \a cq when the channel state is changed or \a
- /// deadline expires. \a GetState needs to called to get the current state.
- template <typename T>
- void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline,
- CompletionQueue* cq, void* tag) {
- TimePoint<T> deadline_tp(deadline);
- NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag);
- }
-
- /// Blocking wait for channel state change or \a deadline expiration.
- /// \a GetState needs to called to get the current state.
- template <typename T>
- bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) {
- TimePoint<T> deadline_tp(deadline);
- return WaitForStateChangeImpl(last_observed, deadline_tp.raw_time());
- }
+ grpc_connectivity_state GetState(bool try_to_connect) GRPC_OVERRIDE;
private:
- template <class R>
- friend class ::grpc::ClientReader;
- template <class W>
- friend class ::grpc::ClientWriter;
- template <class W, class R>
- friend class ::grpc::ClientReaderWriter;
- template <class R>
- friend class ::grpc::ClientAsyncReader;
- template <class W>
- friend class ::grpc::ClientAsyncWriter;
- template <class W, class R>
- friend class ::grpc::ClientAsyncReaderWriter;
- template <class R>
- friend class ::grpc::ClientAsyncResponseReader;
template <class InputMessage, class OutputMessage>
- friend Status BlockingUnaryCall(Channel* channel, const RpcMethod& method,
+ friend Status BlockingUnaryCall(ChannelInterface* channel,
+ const RpcMethod& method,
ClientContext* context,
const InputMessage& request,
OutputMessage* result);
- friend class ::grpc::RpcMethod;
friend std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel);
-
Channel(const grpc::string& host, grpc_channel* c_channel);
Call CreateCall(const RpcMethod& method, ClientContext* context,
- CompletionQueue* cq);
- void PerformOpsOnCall(CallOpSetInterface* ops, Call* call);
- void* RegisterMethod(const char* method);
+ CompletionQueue* cq) GRPC_OVERRIDE;
+ void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) GRPC_OVERRIDE;
+ void* RegisterMethod(const char* method) GRPC_OVERRIDE;
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline, CompletionQueue* cq,
- void* tag);
+ void* tag) GRPC_OVERRIDE;
bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
- gpr_timespec deadline);
+ gpr_timespec deadline) GRPC_OVERRIDE;
const grpc::string host_;
grpc_channel* const c_channel_; // owned
diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h
index 25eeb3876f..a926ed0505 100644
--- a/include/grpc++/client_context.h
+++ b/include/grpc++/client_context.h
@@ -69,6 +69,7 @@ struct census_context;
namespace grpc {
class Channel;
+class ChannelInterface;
class CompletionQueue;
class CallCredentials;
class RpcMethod;
@@ -315,7 +316,8 @@ class ClientContext {
template <class R>
friend class ::grpc::ClientAsyncResponseReader;
template <class InputMessage, class OutputMessage>
- friend Status BlockingUnaryCall(Channel* channel, const RpcMethod& method,
+ friend Status BlockingUnaryCall(ChannelInterface* channel,
+ const RpcMethod& method,
ClientContext* context,
const InputMessage& request,
OutputMessage* result);
diff --git a/include/grpc++/completion_queue.h b/include/grpc++/completion_queue.h
index 5c2bc202c3..7ed8f59008 100644
--- a/include/grpc++/completion_queue.h
+++ b/include/grpc++/completion_queue.h
@@ -36,7 +36,6 @@
#ifndef GRPCXX_COMPLETION_QUEUE_H
#define GRPCXX_COMPLETION_QUEUE_H
-#include <grpc/support/time.h>
#include <grpc++/impl/grpc_library.h>
#include <grpc++/support/status.h>
#include <grpc++/support/time.h>
@@ -68,6 +67,7 @@ class BidiStreamingHandler;
class UnknownMethodHandler;
class Channel;
+class ChannelInterface;
class ClientContext;
class CompletionQueueTag;
class CompletionQueue;
@@ -171,7 +171,8 @@ class CompletionQueue : public GrpcLibrary {
friend class ::grpc::Server;
friend class ::grpc::ServerContext;
template <class InputMessage, class OutputMessage>
- friend Status BlockingUnaryCall(Channel* channel, const RpcMethod& method,
+ friend Status BlockingUnaryCall(ChannelInterface* channel,
+ const RpcMethod& method,
ClientContext* context,
const InputMessage& request,
OutputMessage* result);
@@ -188,17 +189,6 @@ class CompletionQueue : public GrpcLibrary {
grpc_completion_queue* cq_; // owned
};
-/// An interface allowing implementors to process and filter event tags.
-class CompletionQueueTag {
- public:
- virtual ~CompletionQueueTag() {}
- // Called prior to returning from Next(), return value is the status of the
- // operation (return status is the default thing to do). If this function
- // returns false, the tag is dropped and not returned from the completion
- // queue
- virtual bool FinalizeResult(void** tag, bool* status) = 0;
-};
-
/// A specific type of completion queue used by the processing of notifications
/// by servers. Instantiated by \a ServerBuilder.
class ServerCompletionQueue : public CompletionQueue {
diff --git a/include/grpc++/generic/async_generic_service.h b/include/grpc++/generic/async_generic_service.h
index 57a2696b3b..9ae8391dc4 100644
--- a/include/grpc++/generic/async_generic_service.h
+++ b/include/grpc++/generic/async_generic_service.h
@@ -51,6 +51,7 @@ class GenericServerContext GRPC_FINAL : public ServerContext {
private:
friend class Server;
+ friend class ServerInterface;
grpc::string method_;
grpc::string host_;
@@ -58,11 +59,7 @@ class GenericServerContext GRPC_FINAL : public ServerContext {
class AsyncGenericService GRPC_FINAL {
public:
- // TODO(yangg) Once we can add multiple completion queues to the server
- // in c core, add a CompletionQueue* argument to the ctor here.
- // TODO(yangg) support methods list.
AsyncGenericService() : server_(nullptr) {}
- AsyncGenericService(const grpc::string& methods) : server_(nullptr) {}
void RequestCall(GenericServerContext* ctx,
GenericServerAsyncReaderWriter* reader_writer,
diff --git a/include/grpc++/generic/generic_stub.h b/include/grpc++/generic/generic_stub.h
index 1bb7900b06..5ac0371efb 100644
--- a/include/grpc++/generic/generic_stub.h
+++ b/include/grpc++/generic/generic_stub.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -47,7 +47,8 @@ typedef ClientAsyncReaderWriter<ByteBuffer, ByteBuffer>
// by name.
class GenericStub GRPC_FINAL {
public:
- explicit GenericStub(std::shared_ptr<Channel> channel) : channel_(channel) {}
+ explicit GenericStub(std::shared_ptr<ChannelInterface> channel)
+ : channel_(channel) {}
// begin a call to a named method
std::unique_ptr<GenericClientAsyncReaderWriter> Call(
@@ -55,7 +56,7 @@ class GenericStub GRPC_FINAL {
void* tag);
private:
- std::shared_ptr<Channel> channel_;
+ std::shared_ptr<ChannelInterface> channel_;
};
} // namespace grpc
diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h
index cb7856bfbe..0fc0698e54 100644
--- a/include/grpc++/impl/call.h
+++ b/include/grpc++/impl/call.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,8 @@
#include <grpc/support/alloc.h>
#include <grpc++/client_context.h>
#include <grpc++/completion_queue.h>
+#include <grpc++/impl/codegen/call_hook.h>
+#include <grpc++/impl/codegen/completion_queue_tag.h>
#include <grpc++/impl/serialization_traits.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
@@ -53,6 +55,7 @@ namespace grpc {
class ByteBuffer;
class Call;
+class CallHook;
void FillMetadataMap(
grpc_metadata_array* arr,
@@ -548,13 +551,6 @@ class SneakyCallOpSet : public CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> {
}
};
-// Channel and Server implement this to allow them to hook performing ops
-class CallHook {
- public:
- virtual ~CallHook() {}
- virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
-};
-
// Straightforward wrapping of the C call object
class Call GRPC_FINAL {
public:
diff --git a/include/grpc++/impl/client_unary_call.h b/include/grpc++/impl/client_unary_call.h
index 4cdc800267..6033fb7cc2 100644
--- a/include/grpc++/impl/client_unary_call.h
+++ b/include/grpc++/impl/client_unary_call.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,7 @@
#define GRPCXX_IMPL_CLIENT_UNARY_CALL_H
#include <grpc++/impl/call.h>
+#include <grpc++/impl/codegen/channel_interface.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
@@ -47,7 +48,7 @@ class RpcMethod;
// Wrapper that performs a blocking unary call
template <class InputMessage, class OutputMessage>
-Status BlockingUnaryCall(Channel* channel, const RpcMethod& method,
+Status BlockingUnaryCall(ChannelInterface* channel, const RpcMethod& method,
ClientContext* context, const InputMessage& request,
OutputMessage* result) {
CompletionQueue cq;
diff --git a/include/grpc++/impl/codegen/call_hook.h b/include/grpc++/impl/codegen/call_hook.h
new file mode 100644
index 0000000000..0b6027293a
--- /dev/null
+++ b/include/grpc++/impl/codegen/call_hook.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright 2015-2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_CALL_HOOK_H
+#define GRPCXX_IMPL_CODEGEN_CALL_HOOK_H
+
+namespace grpc {
+
+class CallOpSetInterface;
+class Call;
+
+/// Channel and Server implement this to allow them to hook performing ops
+class CallHook {
+ public:
+ virtual ~CallHook() {}
+ virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
+};
+
+} // namespace grpc
+
+#endif // GRPCXX_IMPL_CODEGEN_CALL_HOOK_H
diff --git a/include/grpc++/impl/codegen/channel_interface.h b/include/grpc++/impl/codegen/channel_interface.h
new file mode 100644
index 0000000000..6fcd5c315c
--- /dev/null
+++ b/include/grpc++/impl/codegen/channel_interface.h
@@ -0,0 +1,123 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_CHANNEL_INTERFACE_H
+#define GRPCXX_IMPL_CODEGEN_CHANNEL_INTERFACE_H
+
+#include <grpc++/impl/codegen/status.h>
+#include <grpc++/impl/codegen/time.h>
+#include <grpc/impl/codegen/connectivity_state.h>
+
+namespace grpc {
+class Call;
+class ClientContext;
+class RpcMethod;
+class CallOpSetInterface;
+class CompletionQueue;
+
+template <class R>
+class ClientReader;
+template <class W>
+class ClientWriter;
+template <class W, class R>
+class ClientReaderWriter;
+template <class R>
+class ClientAsyncReader;
+template <class W>
+class ClientAsyncWriter;
+template <class W, class R>
+class ClientAsyncReaderWriter;
+template <class R>
+class ClientAsyncResponseReader;
+
+/// Codegen interface for \a grpc::Channel.
+class ChannelInterface {
+ public:
+ virtual ~ChannelInterface() {}
+ /// Get the current channel state. If the channel is in IDLE and
+ /// \a try_to_connect is set to true, try to connect.
+ virtual grpc_connectivity_state GetState(bool try_to_connect) = 0;
+
+ /// Return the \a tag on \a cq when the channel state is changed or \a
+ /// deadline expires. \a GetState needs to called to get the current state.
+ template <typename T>
+ void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline,
+ CompletionQueue* cq, void* tag) {
+ TimePoint<T> deadline_tp(deadline);
+ NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag);
+ }
+
+ /// Blocking wait for channel state change or \a deadline expiration.
+ /// \a GetState needs to called to get the current state.
+ template <typename T>
+ bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) {
+ TimePoint<T> deadline_tp(deadline);
+ return WaitForStateChangeImpl(last_observed, deadline_tp.raw_time());
+ }
+
+ private:
+ template <class R>
+ friend class ::grpc::ClientReader;
+ template <class W>
+ friend class ::grpc::ClientWriter;
+ template <class W, class R>
+ friend class ::grpc::ClientReaderWriter;
+ template <class R>
+ friend class ::grpc::ClientAsyncReader;
+ template <class W>
+ friend class ::grpc::ClientAsyncWriter;
+ template <class W, class R>
+ friend class ::grpc::ClientAsyncReaderWriter;
+ template <class R>
+ friend class ::grpc::ClientAsyncResponseReader;
+ template <class InputMessage, class OutputMessage>
+ friend Status BlockingUnaryCall(ChannelInterface* channel,
+ const RpcMethod& method,
+ ClientContext* context,
+ const InputMessage& request,
+ OutputMessage* result);
+ friend class ::grpc::RpcMethod;
+ virtual Call CreateCall(const RpcMethod& method, ClientContext* context,
+ CompletionQueue* cq) = 0;
+ virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
+ virtual void* RegisterMethod(const char* method) = 0;
+ virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
+ gpr_timespec deadline,
+ CompletionQueue* cq, void* tag) = 0;
+ virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
+ gpr_timespec deadline) = 0;
+};
+
+} // namespace grpc
+
+#endif // GRPCXX_IMPL_CODEGEN_CHANNEL_INTERFACE_H
diff --git a/include/grpc++/impl/codegen/completion_queue_tag.h b/include/grpc++/impl/codegen/completion_queue_tag.h
new file mode 100644
index 0000000000..8be2ac36d6
--- /dev/null
+++ b/include/grpc++/impl/codegen/completion_queue_tag.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2015-2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_COMPLETION_QUEUE_TAG_H
+#define GRPCXX_COMPLETION_QUEUE_TAG_H
+
+namespace grpc {
+
+/// An interface allowing implementors to process and filter event tags.
+class CompletionQueueTag {
+ public:
+ virtual ~CompletionQueueTag() {}
+ // Called prior to returning from Next(), return value is the status of the
+ // operation (return status is the default thing to do). If this function
+ // returns false, the tag is dropped and not returned from the completion
+ // queue
+ virtual bool FinalizeResult(void** tag, bool* status) = 0;
+};
+
+} // namespace grpc
+
+#endif // GRPCXX_COMPLETION_QUEUE_TAG_H
diff --git a/include/grpc++/impl/codegen/config.h b/include/grpc++/impl/codegen/config.h
new file mode 100644
index 0000000000..d782d5f571
--- /dev/null
+++ b/include/grpc++/impl/codegen/config.h
@@ -0,0 +1,116 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_CONFIG_H
+#define GRPCXX_IMPL_CODEGEN_CONFIG_H
+
+#if !defined(GRPC_NO_AUTODETECT_PLATFORM)
+
+#ifdef _MSC_VER
+// Visual Studio 2010 is 1600.
+#if _MSC_VER < 1600
+#error "gRPC is only supported with Visual Studio starting at 2010"
+// Visual Studio 2013 is 1800.
+#elif _MSC_VER < 1800
+#define GRPC_CXX0X_NO_FINAL 1
+#define GRPC_CXX0X_NO_OVERRIDE 1
+#define GRPC_CXX0X_NO_CHRONO 1
+#define GRPC_CXX0X_NO_THREAD 1
+#endif
+#endif // Visual Studio
+
+#ifndef __clang__
+#ifdef __GNUC__
+// nullptr was added in gcc 4.6
+#if (__GNUC__ * 100 + __GNUC_MINOR__ < 406)
+#define GRPC_CXX0X_NO_NULLPTR 1
+#endif
+// final and override were added in gcc 4.7
+#if (__GNUC__ * 100 + __GNUC_MINOR__ < 407)
+#define GRPC_CXX0X_NO_FINAL 1
+#define GRPC_CXX0X_NO_OVERRIDE 1
+#endif
+#endif
+#endif
+
+#endif
+
+#ifdef GRPC_CXX0X_NO_FINAL
+#define GRPC_FINAL
+#else
+#define GRPC_FINAL final
+#endif
+
+#ifdef GRPC_CXX0X_NO_OVERRIDE
+#define GRPC_OVERRIDE
+#else
+#define GRPC_OVERRIDE override
+#endif
+
+#ifdef GRPC_CXX0X_NO_NULLPTR
+#include <memory>
+namespace grpc {
+const class {
+ public:
+ template <class T>
+ operator T *() const {
+ return static_cast<T *>(0);
+ }
+ template <class T>
+ operator std::unique_ptr<T>() const {
+ return std::unique_ptr<T>(static_cast<T *>(0));
+ }
+ template <class T>
+ operator std::shared_ptr<T>() const {
+ return std::shared_ptr<T>(static_cast<T *>(0));
+ }
+ operator bool() const { return false; }
+
+ private:
+ void operator&() const = delete;
+} nullptr = {};
+}
+#endif
+
+#ifndef GRPC_CUSTOM_STRING
+#include <string>
+#define GRPC_CUSTOM_STRING std::string
+#endif
+
+namespace grpc {
+
+typedef GRPC_CUSTOM_STRING string;
+
+} // namespace grpc
+
+#endif // GRPCXX_IMPL_CODEGEN_CONFIG_H
diff --git a/include/grpc++/impl/codegen/server_interface.h b/include/grpc++/impl/codegen/server_interface.h
new file mode 100644
index 0000000000..2eadcb3428
--- /dev/null
+++ b/include/grpc++/impl/codegen/server_interface.h
@@ -0,0 +1,253 @@
+/*
+ *
+ * Copyright 2015-2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_SERVER_INTERFACE_H
+#define GRPCXX_IMPL_CODEGEN_SERVER_INTERFACE_H
+
+#include <grpc++/impl/codegen/completion_queue_tag.h>
+#include <grpc++/impl/codegen/call_hook.h>
+
+namespace grpc {
+
+class AsyncGenericService;
+class AsynchronousService;
+class GenericServerContext;
+class RpcService;
+class RpcServiceMethod;
+class ServerAsyncStreamingInterface;
+class ServerContext;
+class ServerCredentials;
+class Service;
+class ThreadPoolInterface;
+
+/// Models a gRPC server.
+///
+/// Servers are configured and started via \a grpc::ServerBuilder.
+class ServerInterface : public CallHook {
+ public:
+ virtual ~ServerInterface() {}
+
+ /// Shutdown the server, blocking until all rpc processing finishes.
+ /// Forcefully terminate pending calls after \a deadline expires.
+ ///
+ /// \param deadline How long to wait until pending rpcs are forcefully
+ /// terminated.
+ template <class T>
+ void Shutdown(const T& deadline) {
+ ShutdownInternal(TimePoint<T>(deadline).raw_time());
+ }
+
+ /// Shutdown the server, waiting for all rpc processing to finish.
+ void Shutdown() { ShutdownInternal(gpr_inf_future(GPR_CLOCK_MONOTONIC)); }
+
+ /// Block waiting for all work to complete.
+ ///
+ /// \warning The server must be either shutting down or some other thread must
+ /// call \a Shutdown for this function to ever return.
+ virtual void Wait() = 0;
+
+ protected:
+ friend class AsynchronousService;
+ friend class Service;
+
+ /// Register a service. This call does not take ownership of the service.
+ /// The service must exist for the lifetime of the Server instance.
+ virtual bool RegisterService(const grpc::string* host, Service* service) = 0;
+
+ /// Register a generic service. This call does not take ownership of the
+ /// service. The service must exist for the lifetime of the Server instance.
+ virtual void RegisterAsyncGenericService(AsyncGenericService* service) = 0;
+
+ /// Tries to bind \a server to the given \a addr.
+ ///
+ /// It can be invoked multiple times.
+ ///
+ /// \param addr The address to try to bind to the server (eg, localhost:1234,
+ /// 192.168.1.1:31416, [::1]:27182, etc.).
+ /// \params creds The credentials associated with the server.
+ ///
+ /// \return bound port number on sucess, 0 on failure.
+ ///
+ /// \warning It's an error to call this method on an already started server.
+ virtual int AddListeningPort(const grpc::string& addr,
+ ServerCredentials* creds) = 0;
+
+ /// Start the server.
+ ///
+ /// \param cqs Completion queues for handling asynchronous services. The
+ /// caller is required to keep all completion queues live until the server is
+ /// destroyed.
+ /// \param num_cqs How many completion queues does \a cqs hold.
+ ///
+ /// \return true on a successful shutdown.
+ virtual bool Start(ServerCompletionQueue** cqs, size_t num_cqs) = 0;
+
+ /// Process one or more incoming calls.
+ virtual void RunRpc() = 0;
+
+ /// Schedule \a RunRpc to run in the threadpool.
+ virtual void ScheduleCallback() = 0;
+
+ virtual void ShutdownInternal(gpr_timespec deadline) = 0;
+
+ virtual int max_message_size() const = 0;
+
+ virtual grpc_server* server() = 0;
+
+ virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
+
+ class BaseAsyncRequest : public CompletionQueueTag {
+ public:
+ BaseAsyncRequest(ServerInterface* server, ServerContext* context,
+ ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq, void* tag,
+ bool delete_on_finalize);
+ virtual ~BaseAsyncRequest() {}
+
+ bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
+
+ protected:
+ ServerInterface* const server_;
+ ServerContext* const context_;
+ ServerAsyncStreamingInterface* const stream_;
+ CompletionQueue* const call_cq_;
+ void* const tag_;
+ const bool delete_on_finalize_;
+ grpc_call* call_;
+ grpc_metadata_array initial_metadata_array_;
+ };
+
+ class RegisteredAsyncRequest : public BaseAsyncRequest {
+ public:
+ RegisteredAsyncRequest(ServerInterface* server, ServerContext* context,
+ ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq, void* tag);
+
+ // uses BaseAsyncRequest::FinalizeResult
+
+ protected:
+ void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
+ ServerCompletionQueue* notification_cq);
+ };
+
+ class NoPayloadAsyncRequest GRPC_FINAL : public RegisteredAsyncRequest {
+ public:
+ NoPayloadAsyncRequest(void* registered_method, ServerInterface* server,
+ ServerContext* context,
+ ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag)
+ : RegisteredAsyncRequest(server, context, stream, call_cq, tag) {
+ IssueRequest(registered_method, nullptr, notification_cq);
+ }
+
+ // uses RegisteredAsyncRequest::FinalizeResult
+ };
+
+ template <class Message>
+ class PayloadAsyncRequest GRPC_FINAL : public RegisteredAsyncRequest {
+ public:
+ PayloadAsyncRequest(void* registered_method, ServerInterface* server,
+ ServerContext* context,
+ ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag,
+ Message* request)
+ : RegisteredAsyncRequest(server, context, stream, call_cq, tag),
+ request_(request) {
+ IssueRequest(registered_method, &payload_, notification_cq);
+ }
+
+ bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
+ bool serialization_status =
+ *status && payload_ &&
+ SerializationTraits<Message>::Deserialize(
+ payload_, request_, server_->max_message_size()).ok();
+ bool ret = RegisteredAsyncRequest::FinalizeResult(tag, status);
+ *status = serialization_status&&* status;
+ return ret;
+ }
+
+ private:
+ grpc_byte_buffer* payload_;
+ Message* const request_;
+ };
+
+ class GenericAsyncRequest : public BaseAsyncRequest {
+ public:
+ GenericAsyncRequest(ServerInterface* server, GenericServerContext* context,
+ ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag,
+ bool delete_on_finalize);
+
+ bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
+
+ private:
+ grpc_call_details call_details_;
+ };
+
+ template <class Message>
+ void RequestAsyncCall(RpcServiceMethod* method, ServerContext* context,
+ ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag,
+ Message* message) {
+ GPR_ASSERT(method);
+ new PayloadAsyncRequest<Message>(method->server_tag(), this, context,
+ stream, call_cq, notification_cq, tag,
+ message);
+ }
+
+ void RequestAsyncCall(RpcServiceMethod* method, ServerContext* context,
+ ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag) {
+ GPR_ASSERT(method);
+ new NoPayloadAsyncRequest(method->server_tag(), this, context, stream,
+ call_cq, notification_cq, tag);
+ }
+
+ void RequestAsyncGenericCall(GenericServerContext* context,
+ ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq,
+ void* tag) {
+ new GenericAsyncRequest(this, context, stream, call_cq, notification_cq,
+ tag, true);
+ }
+};
+
+} // namespace grpc
+
+#endif // GRPCXX_IMPL_CODEGEN_SERVER_INTERFACE_H
diff --git a/include/grpc++/impl/codegen/status.h b/include/grpc++/impl/codegen/status.h
new file mode 100644
index 0000000000..a509d311d4
--- /dev/null
+++ b/include/grpc++/impl/codegen/status.h
@@ -0,0 +1,76 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_STATUS_H
+#define GRPCXX_IMPL_CODEGEN_STATUS_H
+
+#include <grpc++/impl/codegen/config.h>
+#include <grpc++/impl/codegen/status_code_enum.h>
+
+namespace grpc {
+
+/// Did it work? If it didn't, why?
+///
+/// See \a grpc::StatusCode for details on the available code and their meaning.
+class Status {
+ public:
+ /// Construct an OK instance.
+ Status() : code_(StatusCode::OK) {}
+
+ /// Construct an instance with associated \a code and \a details (also
+ // referred to as "error_message").
+ Status(StatusCode code, const grpc::string& details)
+ : code_(code), details_(details) {}
+
+ // Pre-defined special status objects.
+ /// An OK pre-defined instance.
+ static const Status& OK;
+ /// A CANCELLED pre-defined instance.
+ static const Status& CANCELLED;
+
+ /// Return the instance's error code.
+ StatusCode error_code() const { return code_; }
+ /// Return the instance's error message.
+ grpc::string error_message() const { return details_; }
+
+ /// Is the status OK?
+ bool ok() const { return code_ == StatusCode::OK; }
+
+ private:
+ StatusCode code_;
+ grpc::string details_;
+};
+
+} // namespace grpc
+
+#endif // GRPCXX_IMPL_CODEGEN_STATUS_H
diff --git a/include/grpc++/impl/codegen/status_code_enum.h b/include/grpc++/impl/codegen/status_code_enum.h
new file mode 100644
index 0000000000..9a90a18e2a
--- /dev/null
+++ b/include/grpc++/impl/codegen/status_code_enum.h
@@ -0,0 +1,152 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_STATUS_CODE_ENUM_H
+#define GRPCXX_IMPL_CODEGEN_STATUS_CODE_ENUM_H
+
+namespace grpc {
+
+enum StatusCode {
+ /// Not an error; returned on success.
+ OK = 0,
+
+ /// The operation was cancelled (typically by the caller).
+ CANCELLED = 1,
+
+ /// Unknown error. An example of where this error may be returned is if a
+ /// Status value received from another address space belongs to an error-space
+ /// that is not known in this address space. Also errors raised by APIs that
+ /// do not return enough error information may be converted to this error.
+ UNKNOWN = 2,
+
+ /// Client specified an invalid argument. Note that this differs from
+ /// FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are
+ /// problematic regardless of the state of the system (e.g., a malformed file
+ /// name).
+ INVALID_ARGUMENT = 3,
+
+ /// Deadline expired before operation could complete. For operations that
+ /// change the state of the system, this error may be returned even if the
+ /// operation has completed successfully. For example, a successful response
+ /// from a server could have been delayed long enough for the deadline to
+ /// expire.
+ DEADLINE_EXCEEDED = 4,
+
+ /// Some requested entity (e.g., file or directory) was not found.
+ NOT_FOUND = 5,
+
+ /// Some entity that we attempted to create (e.g., file or directory) already
+ /// exists.
+ ALREADY_EXISTS = 6,
+
+ /// The caller does not have permission to execute the specified operation.
+ /// PERMISSION_DENIED must not be used for rejections caused by exhausting
+ /// some resource (use RESOURCE_EXHAUSTED instead for those errors).
+ /// PERMISSION_DENIED must not be used if the caller can not be identified
+ /// (use UNAUTHENTICATED instead for those errors).
+ PERMISSION_DENIED = 7,
+
+ /// The request does not have valid authentication credentials for the
+ /// operation.
+ UNAUTHENTICATED = 16,
+
+ /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the
+ /// entire file system is out of space.
+ RESOURCE_EXHAUSTED = 8,
+
+ /// Operation was rejected because the system is not in a state required for
+ /// the operation's execution. For example, directory to be deleted may be
+ /// non-empty, an rmdir operation is applied to a non-directory, etc.
+ ///
+ /// A litmus test that may help a service implementor in deciding
+ /// between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
+ /// (a) Use UNAVAILABLE if the client can retry just the failing call.
+ /// (b) Use ABORTED if the client should retry at a higher-level
+ /// (e.g., restarting a read-modify-write sequence).
+ /// (c) Use FAILED_PRECONDITION if the client should not retry until
+ /// the system state has been explicitly fixed. E.g., if an "rmdir"
+ /// fails because the directory is non-empty, FAILED_PRECONDITION
+ /// should be returned since the client should not retry unless
+ /// they have first fixed up the directory by deleting files from it.
+ /// (d) Use FAILED_PRECONDITION if the client performs conditional
+ /// REST Get/Update/Delete on a resource and the resource on the
+ /// server does not match the condition. E.g., conflicting
+ /// read-modify-write on the same resource.
+ FAILED_PRECONDITION = 9,
+
+ /// The operation was aborted, typically due to a concurrency issue like
+ /// sequencer check failures, transaction aborts, etc.
+ ///
+ /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
+ /// and UNAVAILABLE.
+ ABORTED = 10,
+
+ /// Operation was attempted past the valid range. E.g., seeking or reading
+ /// past end of file.
+ ///
+ /// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed
+ /// if the system state changes. For example, a 32-bit file system will
+ /// generate INVALID_ARGUMENT if asked to read at an offset that is not in the
+ /// range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from
+ /// an offset past the current file size.
+ ///
+ /// There is a fair bit of overlap between FAILED_PRECONDITION and
+ /// OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error)
+ /// when it applies so that callers who are iterating through a space can
+ /// easily look for an OUT_OF_RANGE error to detect when they are done.
+ OUT_OF_RANGE = 11,
+
+ /// Operation is not implemented or not supported/enabled in this service.
+ UNIMPLEMENTED = 12,
+
+ /// Internal errors. Means some invariants expected by underlying System has
+ /// been broken. If you see one of these errors, Something is very broken.
+ INTERNAL = 13,
+
+ /// The service is currently unavailable. This is a most likely a transient
+ /// condition and may be corrected by retrying with a backoff.
+ ///
+ /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
+ /// and UNAVAILABLE.
+ UNAVAILABLE = 14,
+
+ /// Unrecoverable data loss or corruption.
+ DATA_LOSS = 15,
+
+ /// Force users to include a default branch:
+ DO_NOT_USE = -1
+};
+
+} // namespace grpc
+
+#endif // GRPCXX_IMPL_CODEGEN_STATUS_CODE_ENUM_H
diff --git a/include/grpc++/impl/codegen/time.h b/include/grpc++/impl/codegen/time.h
new file mode 100644
index 0000000000..bed7423341
--- /dev/null
+++ b/include/grpc++/impl/codegen/time.h
@@ -0,0 +1,111 @@
+/*
+ *
+ * Copyright 2015-2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_TIME_H
+#define GRPCXX_IMPL_CODEGEN_TIME_H
+
+#include <grpc++/impl/codegen/config.h>
+#include <grpc/impl/codegen/time.h>
+
+namespace grpc {
+
+/* If you are trying to use CompletionQueue::AsyncNext with a time class that
+ isn't either gpr_timespec or std::chrono::system_clock::time_point, you
+ will most likely be looking at this comment as your compiler will have
+ fired an error below. In order to fix this issue, you have two potential
+ solutions:
+
+ 1. Use gpr_timespec or std::chrono::system_clock::time_point instead
+ 2. Specialize the TimePoint class with whichever time class that you
+ want to use here. See below for two examples of how to do this.
+ */
+
+template <typename T>
+class TimePoint {
+ public:
+ TimePoint(const T& time) { you_need_a_specialization_of_TimePoint(); }
+ gpr_timespec raw_time() {
+ gpr_timespec t;
+ return t;
+ }
+
+ private:
+ void you_need_a_specialization_of_TimePoint();
+};
+
+template <>
+class TimePoint<gpr_timespec> {
+ public:
+ TimePoint(const gpr_timespec& time) : time_(time) {}
+ gpr_timespec raw_time() { return time_; }
+
+ private:
+ gpr_timespec time_;
+};
+
+} // namespace grpc
+
+#ifndef GRPC_CXX0X_NO_CHRONO
+
+#include <chrono>
+
+#include <grpc/impl/codegen/time.h>
+
+namespace grpc {
+
+// from and to should be absolute time.
+void Timepoint2Timespec(const std::chrono::system_clock::time_point& from,
+ gpr_timespec* to);
+void TimepointHR2Timespec(
+ const std::chrono::high_resolution_clock::time_point& from,
+ gpr_timespec* to);
+
+std::chrono::system_clock::time_point Timespec2Timepoint(gpr_timespec t);
+
+template <>
+class TimePoint<std::chrono::system_clock::time_point> {
+ public:
+ TimePoint(const std::chrono::system_clock::time_point& time) {
+ Timepoint2Timespec(time, &time_);
+ }
+ gpr_timespec raw_time() const { return time_; }
+
+ private:
+ gpr_timespec time_;
+};
+
+} // namespace grpc
+
+#endif // !GRPC_CXX0X_NO_CHRONO
+
+#endif // GRPCXX_IMPL_CODEGEN_TIME_H
diff --git a/include/grpc++/impl/method_handler_impl.h b/include/grpc++/impl/method_handler_impl.h
new file mode 100644
index 0000000000..2997cb0e62
--- /dev/null
+++ b/include/grpc++/impl/method_handler_impl.h
@@ -0,0 +1,203 @@
+/*
+ *
+ * Copyright 2015-2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_METHOD_HANDLER_IMPL_H
+#define GRPCXX_IMPL_METHOD_HANDLER_IMPL_H
+
+#include <grpc++/impl/rpc_service_method.h>
+#include <grpc++/support/sync_stream.h>
+
+namespace grpc {
+
+// A wrapper class of an application provided rpc method handler.
+template <class ServiceType, class RequestType, class ResponseType>
+class RpcMethodHandler : public MethodHandler {
+ public:
+ RpcMethodHandler(
+ std::function<Status(ServiceType*, ServerContext*, const RequestType*,
+ ResponseType*)> func,
+ ServiceType* service)
+ : func_(func), service_(service) {}
+
+ void RunHandler(const HandlerParameter& param) GRPC_FINAL {
+ RequestType req;
+ Status status = SerializationTraits<RequestType>::Deserialize(
+ param.request, &req, param.max_message_size);
+ ResponseType rsp;
+ if (status.ok()) {
+ status = func_(service_, param.server_context, &req, &rsp);
+ }
+
+ GPR_ASSERT(!param.server_context->sent_initial_metadata_);
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+ CallOpServerSendStatus> ops;
+ ops.SendInitialMetadata(param.server_context->initial_metadata_);
+ if (status.ok()) {
+ status = ops.SendMessage(rsp);
+ }
+ ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
+ param.call->PerformOps(&ops);
+ param.call->cq()->Pluck(&ops);
+ }
+
+ private:
+ // Application provided rpc handler function.
+ std::function<Status(ServiceType*, ServerContext*, const RequestType*,
+ ResponseType*)> func_;
+ // The class the above handler function lives in.
+ ServiceType* service_;
+};
+
+// A wrapper class of an application provided client streaming handler.
+template <class ServiceType, class RequestType, class ResponseType>
+class ClientStreamingHandler : public MethodHandler {
+ public:
+ ClientStreamingHandler(
+ std::function<Status(ServiceType*, ServerContext*,
+ ServerReader<RequestType>*, ResponseType*)> func,
+ ServiceType* service)
+ : func_(func), service_(service) {}
+
+ void RunHandler(const HandlerParameter& param) GRPC_FINAL {
+ ServerReader<RequestType> reader(param.call, param.server_context);
+ ResponseType rsp;
+ Status status = func_(service_, param.server_context, &reader, &rsp);
+
+ GPR_ASSERT(!param.server_context->sent_initial_metadata_);
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+ CallOpServerSendStatus> ops;
+ ops.SendInitialMetadata(param.server_context->initial_metadata_);
+ if (status.ok()) {
+ status = ops.SendMessage(rsp);
+ }
+ ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
+ param.call->PerformOps(&ops);
+ param.call->cq()->Pluck(&ops);
+ }
+
+ private:
+ std::function<Status(ServiceType*, ServerContext*, ServerReader<RequestType>*,
+ ResponseType*)> func_;
+ ServiceType* service_;
+};
+
+// A wrapper class of an application provided server streaming handler.
+template <class ServiceType, class RequestType, class ResponseType>
+class ServerStreamingHandler : public MethodHandler {
+ public:
+ ServerStreamingHandler(
+ std::function<Status(ServiceType*, ServerContext*, const RequestType*,
+ ServerWriter<ResponseType>*)> func,
+ ServiceType* service)
+ : func_(func), service_(service) {}
+
+ void RunHandler(const HandlerParameter& param) GRPC_FINAL {
+ RequestType req;
+ Status status = SerializationTraits<RequestType>::Deserialize(
+ param.request, &req, param.max_message_size);
+
+ if (status.ok()) {
+ ServerWriter<ResponseType> writer(param.call, param.server_context);
+ status = func_(service_, param.server_context, &req, &writer);
+ }
+
+ CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
+ if (!param.server_context->sent_initial_metadata_) {
+ ops.SendInitialMetadata(param.server_context->initial_metadata_);
+ }
+ ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
+ param.call->PerformOps(&ops);
+ param.call->cq()->Pluck(&ops);
+ }
+
+ private:
+ std::function<Status(ServiceType*, ServerContext*, const RequestType*,
+ ServerWriter<ResponseType>*)> func_;
+ ServiceType* service_;
+};
+
+// A wrapper class of an application provided bidi-streaming handler.
+template <class ServiceType, class RequestType, class ResponseType>
+class BidiStreamingHandler : public MethodHandler {
+ public:
+ BidiStreamingHandler(
+ std::function<Status(ServiceType*, ServerContext*,
+ ServerReaderWriter<ResponseType, RequestType>*)>
+ func,
+ ServiceType* service)
+ : func_(func), service_(service) {}
+
+ void RunHandler(const HandlerParameter& param) GRPC_FINAL {
+ ServerReaderWriter<ResponseType, RequestType> stream(param.call,
+ param.server_context);
+ Status status = func_(service_, param.server_context, &stream);
+
+ CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
+ if (!param.server_context->sent_initial_metadata_) {
+ ops.SendInitialMetadata(param.server_context->initial_metadata_);
+ }
+ ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
+ param.call->PerformOps(&ops);
+ param.call->cq()->Pluck(&ops);
+ }
+
+ private:
+ std::function<Status(ServiceType*, ServerContext*,
+ ServerReaderWriter<ResponseType, RequestType>*)> func_;
+ ServiceType* service_;
+};
+
+// Handle unknown method by returning UNIMPLEMENTED error.
+class UnknownMethodHandler : public MethodHandler {
+ public:
+ template <class T>
+ static void FillOps(ServerContext* context, T* ops) {
+ Status status(StatusCode::UNIMPLEMENTED, "");
+ if (!context->sent_initial_metadata_) {
+ ops->SendInitialMetadata(context->initial_metadata_);
+ context->sent_initial_metadata_ = true;
+ }
+ ops->ServerSendStatus(context->trailing_metadata_, status);
+ }
+
+ void RunHandler(const HandlerParameter& param) GRPC_FINAL {
+ CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
+ FillOps(param.server_context, &ops);
+ param.call->PerformOps(&ops);
+ param.call->cq()->Pluck(&ops);
+ }
+};
+
+} // namespace grpc
+
+#endif // GRPCXX_IMPL_METHOD_HANDLER_IMPL_H \ No newline at end of file
diff --git a/include/grpc++/impl/rpc_method.h b/include/grpc++/impl/rpc_method.h
index 9800268062..387891727d 100644
--- a/include/grpc++/impl/rpc_method.h
+++ b/include/grpc++/impl/rpc_method.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@
#include <memory>
-#include <grpc++/channel.h>
+#include <grpc++/impl/codegen/channel_interface.h>
namespace grpc {
@@ -53,7 +53,7 @@ class RpcMethod {
: name_(name), method_type_(type), channel_tag_(NULL) {}
RpcMethod(const char* name, RpcType type,
- const std::shared_ptr<Channel>& channel)
+ const std::shared_ptr<ChannelInterface>& channel)
: name_(name),
method_type_(type),
channel_tag_(channel->RegisterMethod(name)) {}
diff --git a/include/grpc++/impl/rpc_service_method.h b/include/grpc++/impl/rpc_service_method.h
index b203c8f53a..a0bae80dab 100644
--- a/include/grpc++/impl/rpc_service_method.h
+++ b/include/grpc++/impl/rpc_service_method.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,14 +43,11 @@
#include <grpc++/impl/rpc_method.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
-#include <grpc++/support/sync_stream.h>
namespace grpc {
class ServerContext;
class StreamContextInterface;
-// TODO(rocking): we might need to split this file into multiple ones.
-
// Base class for running an RPC handler.
class MethodHandler {
public:
@@ -71,197 +68,25 @@ class MethodHandler {
virtual void RunHandler(const HandlerParameter& param) = 0;
};
-// A wrapper class of an application provided rpc method handler.
-template <class ServiceType, class RequestType, class ResponseType>
-class RpcMethodHandler : public MethodHandler {
- public:
- RpcMethodHandler(
- std::function<Status(ServiceType*, ServerContext*, const RequestType*,
- ResponseType*)> func,
- ServiceType* service)
- : func_(func), service_(service) {}
-
- void RunHandler(const HandlerParameter& param) GRPC_FINAL {
- RequestType req;
- Status status = SerializationTraits<RequestType>::Deserialize(
- param.request, &req, param.max_message_size);
- ResponseType rsp;
- if (status.ok()) {
- status = func_(service_, param.server_context, &req, &rsp);
- }
-
- GPR_ASSERT(!param.server_context->sent_initial_metadata_);
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpServerSendStatus> ops;
- ops.SendInitialMetadata(param.server_context->initial_metadata_);
- if (status.ok()) {
- status = ops.SendMessage(rsp);
- }
- ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
- param.call->PerformOps(&ops);
- param.call->cq()->Pluck(&ops);
- }
-
- private:
- // Application provided rpc handler function.
- std::function<Status(ServiceType*, ServerContext*, const RequestType*,
- ResponseType*)> func_;
- // The class the above handler function lives in.
- ServiceType* service_;
-};
-
-// A wrapper class of an application provided client streaming handler.
-template <class ServiceType, class RequestType, class ResponseType>
-class ClientStreamingHandler : public MethodHandler {
- public:
- ClientStreamingHandler(
- std::function<Status(ServiceType*, ServerContext*,
- ServerReader<RequestType>*, ResponseType*)> func,
- ServiceType* service)
- : func_(func), service_(service) {}
-
- void RunHandler(const HandlerParameter& param) GRPC_FINAL {
- ServerReader<RequestType> reader(param.call, param.server_context);
- ResponseType rsp;
- Status status = func_(service_, param.server_context, &reader, &rsp);
-
- GPR_ASSERT(!param.server_context->sent_initial_metadata_);
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpServerSendStatus> ops;
- ops.SendInitialMetadata(param.server_context->initial_metadata_);
- if (status.ok()) {
- status = ops.SendMessage(rsp);
- }
- ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
- param.call->PerformOps(&ops);
- param.call->cq()->Pluck(&ops);
- }
-
- private:
- std::function<Status(ServiceType*, ServerContext*, ServerReader<RequestType>*,
- ResponseType*)> func_;
- ServiceType* service_;
-};
-
-// A wrapper class of an application provided server streaming handler.
-template <class ServiceType, class RequestType, class ResponseType>
-class ServerStreamingHandler : public MethodHandler {
- public:
- ServerStreamingHandler(
- std::function<Status(ServiceType*, ServerContext*, const RequestType*,
- ServerWriter<ResponseType>*)> func,
- ServiceType* service)
- : func_(func), service_(service) {}
-
- void RunHandler(const HandlerParameter& param) GRPC_FINAL {
- RequestType req;
- Status status = SerializationTraits<RequestType>::Deserialize(
- param.request, &req, param.max_message_size);
-
- if (status.ok()) {
- ServerWriter<ResponseType> writer(param.call, param.server_context);
- status = func_(service_, param.server_context, &req, &writer);
- }
-
- CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
- if (!param.server_context->sent_initial_metadata_) {
- ops.SendInitialMetadata(param.server_context->initial_metadata_);
- }
- ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
- param.call->PerformOps(&ops);
- param.call->cq()->Pluck(&ops);
- }
-
- private:
- std::function<Status(ServiceType*, ServerContext*, const RequestType*,
- ServerWriter<ResponseType>*)> func_;
- ServiceType* service_;
-};
-
-// A wrapper class of an application provided bidi-streaming handler.
-template <class ServiceType, class RequestType, class ResponseType>
-class BidiStreamingHandler : public MethodHandler {
- public:
- BidiStreamingHandler(
- std::function<Status(ServiceType*, ServerContext*,
- ServerReaderWriter<ResponseType, RequestType>*)>
- func,
- ServiceType* service)
- : func_(func), service_(service) {}
-
- void RunHandler(const HandlerParameter& param) GRPC_FINAL {
- ServerReaderWriter<ResponseType, RequestType> stream(param.call,
- param.server_context);
- Status status = func_(service_, param.server_context, &stream);
-
- CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
- if (!param.server_context->sent_initial_metadata_) {
- ops.SendInitialMetadata(param.server_context->initial_metadata_);
- }
- ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
- param.call->PerformOps(&ops);
- param.call->cq()->Pluck(&ops);
- }
-
- private:
- std::function<Status(ServiceType*, ServerContext*,
- ServerReaderWriter<ResponseType, RequestType>*)> func_;
- ServiceType* service_;
-};
-
-// Handle unknown method by returning UNIMPLEMENTED error.
-class UnknownMethodHandler : public MethodHandler {
- public:
- template <class T>
- static void FillOps(ServerContext* context, T* ops) {
- Status status(StatusCode::UNIMPLEMENTED, "");
- if (!context->sent_initial_metadata_) {
- ops->SendInitialMetadata(context->initial_metadata_);
- context->sent_initial_metadata_ = true;
- }
- ops->ServerSendStatus(context->trailing_metadata_, status);
- }
-
- void RunHandler(const HandlerParameter& param) GRPC_FINAL {
- CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
- FillOps(param.server_context, &ops);
- param.call->PerformOps(&ops);
- param.call->cq()->Pluck(&ops);
- }
-};
-
// Server side rpc method class
class RpcServiceMethod : public RpcMethod {
public:
// Takes ownership of the handler
RpcServiceMethod(const char* name, RpcMethod::RpcType type,
MethodHandler* handler)
- : RpcMethod(name, type), handler_(handler) {}
+ : RpcMethod(name, type), server_tag_(nullptr), handler_(handler) {}
- MethodHandler* handler() { return handler_.get(); }
+ void set_server_tag(void* tag) { server_tag_ = tag; }
+ void* server_tag() const { return server_tag_; }
+ // if MethodHandler is nullptr, then this is an async method
+ MethodHandler* handler() const { return handler_.get(); }
+ void ResetHandler() { handler_.reset(); }
private:
+ void* server_tag_;
std::unique_ptr<MethodHandler> handler_;
};
-// This class contains all the method information for an rpc service. It is
-// used for registering a service on a grpc server.
-class RpcService {
- public:
- // Takes ownership.
- void AddMethod(RpcServiceMethod* method) { methods_.emplace_back(method); }
-
- RpcServiceMethod* GetMethod(int i) { return methods_[i].get(); }
- int GetMethodCount() const {
- // On win x64, int is only 32bit
- GPR_ASSERT(methods_.size() <= INT_MAX);
- return (int)methods_.size();
- }
-
- private:
- std::vector<std::unique_ptr<RpcServiceMethod>> methods_;
-};
-
} // namespace grpc
#endif // GRPCXX_IMPL_RPC_SERVICE_METHOD_H
diff --git a/include/grpc++/impl/service_type.h b/include/grpc++/impl/service_type.h
index 3b6ac1de77..b0c106f9cc 100644
--- a/include/grpc++/impl/service_type.h
+++ b/include/grpc++/impl/service_type.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,8 +34,9 @@
#ifndef GRPCXX_IMPL_SERVICE_TYPE_H
#define GRPCXX_IMPL_SERVICE_TYPE_H
+#include <grpc++/impl/rpc_service_method.h>
#include <grpc++/impl/serialization_traits.h>
-#include <grpc++/server.h>
+#include <grpc++/impl/codegen/server_interface.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
@@ -43,17 +44,11 @@ namespace grpc {
class Call;
class CompletionQueue;
-class RpcService;
class Server;
+class ServerInterface;
class ServerCompletionQueue;
class ServerContext;
-class SynchronousService {
- public:
- virtual ~SynchronousService() {}
- virtual RpcService* service() = 0;
-};
-
class ServerAsyncStreamingInterface {
public:
virtual ~ServerAsyncStreamingInterface() {}
@@ -61,19 +56,41 @@ class ServerAsyncStreamingInterface {
virtual void SendInitialMetadata(void* tag) = 0;
private:
- friend class Server;
+ friend class ServerInterface;
virtual void BindCall(Call* call) = 0;
};
-class AsynchronousService {
+class Service {
public:
- AsynchronousService(const char** method_names, size_t method_count)
- : server_(nullptr),
- method_names_(method_names),
- method_count_(method_count),
- request_args_(nullptr) {}
+ Service() : server_(nullptr) {}
+ virtual ~Service() {}
+
+ bool has_async_methods() const {
+ for (auto it = methods_.begin(); it != methods_.end(); ++it) {
+ if (*it && (*it)->handler() == nullptr) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool has_synchronous_methods() const {
+ for (auto it = methods_.begin(); it != methods_.end(); ++it) {
+ if (*it && (*it)->handler() != nullptr) {
+ return true;
+ }
+ }
+ return false;
+ }
- ~AsynchronousService() { delete[] request_args_; }
+ bool has_generic_methods() const {
+ for (auto it = methods_.begin(); it != methods_.end(); ++it) {
+ if (it->get() == nullptr) {
+ return true;
+ }
+ }
+ return false;
+ }
protected:
template <class Message>
@@ -81,41 +98,62 @@ class AsynchronousService {
ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
- server_->RequestAsyncCall(request_args_[index], context, stream, call_cq,
+ server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag, request);
}
- void RequestClientStreaming(int index, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq,
- void* tag) {
- server_->RequestAsyncCall(request_args_[index], context, stream, call_cq,
+ void RequestAsyncClientStreaming(int index, ServerContext* context,
+ ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq,
+ void* tag) {
+ server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag);
}
template <class Message>
- void RequestServerStreaming(int index, ServerContext* context,
- Message* request,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq,
- void* tag) {
- server_->RequestAsyncCall(request_args_[index], context, stream, call_cq,
+ void RequestAsyncServerStreaming(int index, ServerContext* context,
+ Message* request,
+ ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq,
+ void* tag) {
+ server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag, request);
}
- void RequestBidiStreaming(int index, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag) {
- server_->RequestAsyncCall(request_args_[index], context, stream, call_cq,
+ void RequestAsyncBidiStreaming(int index, ServerContext* context,
+ ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq,
+ void* tag) {
+ server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
notification_cq, tag);
}
+ void AddMethod(RpcServiceMethod* method) { methods_.emplace_back(method); }
+
+ void MarkMethodAsync(int index) {
+ if (methods_[index].get() == nullptr) {
+ gpr_log(GPR_ERROR,
+ "Cannot mark the method as 'async' because it has already been "
+ "marked as 'generic'.");
+ return;
+ }
+ methods_[index]->ResetHandler();
+ }
+
+ void MarkMethodGeneric(int index) {
+ if (methods_[index]->handler() == nullptr) {
+ gpr_log(GPR_ERROR,
+ "Cannot mark the method as 'generic' because it has already been "
+ "marked as 'async'.");
+ }
+ methods_[index].reset();
+ }
+
private:
friend class Server;
- Server* server_;
- const char** const method_names_;
- size_t method_count_;
- void** request_args_;
+ friend class ServerInterface;
+ ServerInterface* server_;
+ std::vector<std::unique_ptr<RpcServiceMethod>> methods_;
};
} // namespace grpc
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 644e66e6e0..c6af748c51 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,9 @@
#include <grpc++/completion_queue.h>
#include <grpc++/impl/call.h>
#include <grpc++/impl/grpc_library.h>
+#include <grpc++/impl/rpc_service_method.h>
#include <grpc++/impl/sync.h>
+#include <grpc++/impl/codegen/server_interface.h>
#include <grpc++/security/server_credentials.h>
#include <grpc++/support/channel_arguments.h>
#include <grpc++/support/config.h>
@@ -51,11 +53,8 @@ struct grpc_server;
namespace grpc {
-class AsynchronousService;
class GenericServerContext;
class AsyncGenericService;
-class RpcService;
-class RpcServiceMethod;
class ServerAsyncStreamingInterface;
class ServerContext;
class ThreadPoolInterface;
@@ -63,28 +62,15 @@ class ThreadPoolInterface;
/// Models a gRPC server.
///
/// Servers are configured and started via \a grpc::ServerBuilder.
-class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
+class Server GRPC_FINAL : public ServerInterface, public GrpcLibrary {
public:
~Server();
- /// Shutdown the server, blocking until all rpc processing finishes.
- /// Forcefully terminate pending calls after \a deadline expires.
- ///
- /// \param deadline How long to wait until pending rpcs are forcefully
- /// terminated.
- template <class T>
- void Shutdown(const T& deadline) {
- ShutdownInternal(TimePoint<T>(deadline).raw_time());
- }
-
- /// Shutdown the server, waiting for all rpc processing to finish.
- void Shutdown() { ShutdownInternal(gpr_inf_future(GPR_CLOCK_MONOTONIC)); }
-
/// Block waiting for all work to complete.
///
/// \warning The server must be either shutting down or some other thread must
/// call \a Shutdown for this function to ever return.
- void Wait();
+ void Wait() GRPC_OVERRIDE;
/// Global Callbacks
///
@@ -105,13 +91,16 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
private:
friend class AsyncGenericService;
- friend class AsynchronousService;
friend class ServerBuilder;
class SyncRequest;
class AsyncRequest;
class ShutdownRequest;
+ class UnimplementedAsyncRequestContext;
+ class UnimplementedAsyncRequest;
+ class UnimplementedAsyncResponse;
+
/// Server constructors. To be used by \a ServerBuilder only.
///
/// \param thread_pool The threadpool instance to use for call processing.
@@ -123,16 +112,12 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
/// Register a service. This call does not take ownership of the service.
/// The service must exist for the lifetime of the Server instance.
- bool RegisterService(const grpc::string* host, RpcService* service);
-
- /// Register an asynchronous service. This call does not take ownership of the
- /// service. The service must exist for the lifetime of the Server instance.
- bool RegisterAsyncService(const grpc::string* host,
- AsynchronousService* service);
+ bool RegisterService(const grpc::string* host,
+ Service* service) GRPC_OVERRIDE;
/// Register a generic service. This call does not take ownership of the
/// service. The service must exist for the lifetime of the Server instance.
- void RegisterAsyncGenericService(AsyncGenericService* service);
+ void RegisterAsyncGenericService(AsyncGenericService* service) GRPC_OVERRIDE;
/// Tries to bind \a server to the given \a addr.
///
@@ -145,7 +130,8 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
/// \return bound port number on sucess, 0 on failure.
///
/// \warning It's an error to call this method on an already started server.
- int AddListeningPort(const grpc::string& addr, ServerCredentials* creds);
+ int AddListeningPort(const grpc::string& addr,
+ ServerCredentials* creds) GRPC_OVERRIDE;
/// Start the server.
///
@@ -155,141 +141,21 @@ class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
/// \param num_cqs How many completion queues does \a cqs hold.
///
/// \return true on a successful shutdown.
- bool Start(ServerCompletionQueue** cqs, size_t num_cqs);
-
- void HandleQueueClosed();
+ bool Start(ServerCompletionQueue** cqs, size_t num_cqs) GRPC_OVERRIDE;
/// Process one or more incoming calls.
- void RunRpc();
+ void RunRpc() GRPC_OVERRIDE;
/// Schedule \a RunRpc to run in the threadpool.
- void ScheduleCallback();
+ void ScheduleCallback() GRPC_OVERRIDE;
void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) GRPC_OVERRIDE;
- void ShutdownInternal(gpr_timespec deadline);
-
- class BaseAsyncRequest : public CompletionQueueTag {
- public:
- BaseAsyncRequest(Server* server, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq, void* tag,
- bool delete_on_finalize);
- virtual ~BaseAsyncRequest();
-
- bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
-
- protected:
- Server* const server_;
- ServerContext* const context_;
- ServerAsyncStreamingInterface* const stream_;
- CompletionQueue* const call_cq_;
- void* const tag_;
- const bool delete_on_finalize_;
- grpc_call* call_;
- grpc_metadata_array initial_metadata_array_;
- };
-
- class RegisteredAsyncRequest : public BaseAsyncRequest {
- public:
- RegisteredAsyncRequest(Server* server, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq, void* tag);
-
- // uses BaseAsyncRequest::FinalizeResult
-
- protected:
- void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
- ServerCompletionQueue* notification_cq);
- };
-
- class NoPayloadAsyncRequest GRPC_FINAL : public RegisteredAsyncRequest {
- public:
- NoPayloadAsyncRequest(void* registered_method, Server* server,
- ServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag)
- : RegisteredAsyncRequest(server, context, stream, call_cq, tag) {
- IssueRequest(registered_method, nullptr, notification_cq);
- }
-
- // uses RegisteredAsyncRequest::FinalizeResult
- };
-
- template <class Message>
- class PayloadAsyncRequest GRPC_FINAL : public RegisteredAsyncRequest {
- public:
- PayloadAsyncRequest(void* registered_method, Server* server,
- ServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag,
- Message* request)
- : RegisteredAsyncRequest(server, context, stream, call_cq, tag),
- request_(request) {
- IssueRequest(registered_method, &payload_, notification_cq);
- }
-
- bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
- bool serialization_status =
- *status && payload_ &&
- SerializationTraits<Message>::Deserialize(
- payload_, request_, server_->max_message_size_).ok();
- bool ret = RegisteredAsyncRequest::FinalizeResult(tag, status);
- *status = serialization_status&&* status;
- return ret;
- }
-
- private:
- grpc_byte_buffer* payload_;
- Message* const request_;
- };
-
- class GenericAsyncRequest : public BaseAsyncRequest {
- public:
- GenericAsyncRequest(Server* server, GenericServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag,
- bool delete_on_finalize);
-
- bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
-
- private:
- grpc_call_details call_details_;
- };
-
- class UnimplementedAsyncRequestContext;
- class UnimplementedAsyncRequest;
- class UnimplementedAsyncResponse;
-
- template <class Message>
- void RequestAsyncCall(void* registered_method, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag,
- Message* message) {
- new PayloadAsyncRequest<Message>(registered_method, this, context, stream,
- call_cq, notification_cq, tag, message);
- }
+ void ShutdownInternal(gpr_timespec deadline) GRPC_OVERRIDE;
- void RequestAsyncCall(void* registered_method, ServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag) {
- new NoPayloadAsyncRequest(registered_method, this, context, stream, call_cq,
- notification_cq, tag);
- }
+ int max_message_size() const GRPC_OVERRIDE { return max_message_size_; };
- void RequestAsyncGenericCall(GenericServerContext* context,
- ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq,
- void* tag) {
- new GenericAsyncRequest(this, context, stream, call_cq, notification_cq,
- tag, true);
- }
+ grpc_server* server() GRPC_OVERRIDE { return server_; };
const int max_message_size_;
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index b324deb9e0..73bcfb6038 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -44,14 +44,12 @@
namespace grpc {
class AsyncGenericService;
-class AsynchronousService;
class CompletionQueue;
class RpcService;
class Server;
class ServerCompletionQueue;
class ServerCredentials;
-class SynchronousService;
-class ThreadPoolInterface;
+class Service;
/// A builder class for the creation and startup of \a grpc::Server instances.
class ServerBuilder {
@@ -62,14 +60,7 @@ class ServerBuilder {
/// The service must exist for the lifetime of the \a Server instance returned
/// by \a BuildAndStart().
/// Matches requests with any :authority
- void RegisterService(SynchronousService* service);
-
- /// Register an asynchronous service.
- /// This call does not take ownership of the service or completion queue.
- /// The service and completion queuemust exist for the lifetime of the \a
- /// Server instance returned by \a BuildAndStart().
- /// Matches requests with any :authority
- void RegisterAsyncService(AsynchronousService* service);
+ void RegisterService(Service* service);
/// Register a generic service.
/// Matches requests with any :authority
@@ -79,15 +70,7 @@ class ServerBuilder {
/// The service must exist for the lifetime of the \a Server instance returned
/// by BuildAndStart().
/// Only matches requests with :authority \a host
- void RegisterService(const grpc::string& host, SynchronousService* service);
-
- /// Register an asynchronous service.
- /// This call does not take ownership of the service or completion queue.
- /// The service and completion queuemust exist for the lifetime of the \a
- /// Server instance returned by \a BuildAndStart().
- /// Only matches requests with :authority equal to \a host
- void RegisterAsyncService(const grpc::string& host,
- AsynchronousService* service);
+ void RegisterService(const grpc::string& host, Service* service);
/// Set max message size in bytes.
void SetMaxMessageSize(int max_message_size) {
@@ -132,26 +115,22 @@ class ServerBuilder {
};
typedef std::unique_ptr<grpc::string> HostString;
- template <class T>
struct NamedService {
- explicit NamedService(T* s) : service(s) {}
- NamedService(const grpc::string& h, T* s)
+ explicit NamedService(Service* s) : service(s) {}
+ NamedService(const grpc::string& h, Service* s)
: host(new grpc::string(h)), service(s) {}
HostString host;
- T* service;
+ Service* service;
};
int max_message_size_;
grpc_compression_options compression_options_;
std::vector<std::unique_ptr<ServerBuilderOption>> options_;
- std::vector<std::unique_ptr<NamedService<RpcService>>> services_;
- std::vector<std::unique_ptr<NamedService<AsynchronousService>>>
- async_services_;
+ std::vector<std::unique_ptr<NamedService>> services_;
std::vector<Port> ports_;
std::vector<ServerCompletionQueue*> cqs_;
std::shared_ptr<ServerCredentials> creds_;
AsyncGenericService* generic_service_;
- ThreadPoolInterface* thread_pool_;
};
} // namespace grpc
diff --git a/include/grpc++/server_context.h b/include/grpc++/server_context.h
index 8ba73486dc..1c3f39e238 100644
--- a/include/grpc++/server_context.h
+++ b/include/grpc++/server_context.h
@@ -80,6 +80,7 @@ class Call;
class CallOpBuffer;
class CompletionQueue;
class Server;
+class ServerInterface;
namespace testing {
class InteropServerContextInspector;
@@ -138,6 +139,7 @@ class ServerContext {
private:
friend class ::grpc::testing::InteropServerContextInspector;
+ friend class ::grpc::ServerInterface;
friend class ::grpc::Server;
template <class W, class R>
friend class ::grpc::ServerAsyncReader;
diff --git a/include/grpc++/support/async_stream.h b/include/grpc++/support/async_stream.h
index 0c96352ccd..87c38a7ec8 100644
--- a/include/grpc++/support/async_stream.h
+++ b/include/grpc++/support/async_stream.h
@@ -35,7 +35,7 @@
#define GRPCXX_SUPPORT_ASYNC_STREAM_H
#include <grpc/support/log.h>
-#include <grpc++/channel.h>
+#include <grpc++/impl/codegen/channel_interface.h>
#include <grpc++/client_context.h>
#include <grpc++/completion_queue.h>
#include <grpc++/impl/call.h>
@@ -103,7 +103,7 @@ class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface<R> {
public:
/// Create a stream and write the first request out.
template <class W>
- ClientAsyncReader(Channel* channel, CompletionQueue* cq,
+ ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
const W& request, void* tag)
: context_(context), call_(channel->CreateCall(method, context, cq)) {
@@ -166,7 +166,7 @@ template <class W>
class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface<W> {
public:
template <class R>
- ClientAsyncWriter(Channel* channel, CompletionQueue* cq,
+ ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
R* response, void* tag)
: context_(context), call_(channel->CreateCall(method, context, cq)) {
@@ -234,7 +234,7 @@ template <class W, class R>
class ClientAsyncReaderWriter GRPC_FINAL
: public ClientAsyncReaderWriterInterface<W, R> {
public:
- ClientAsyncReaderWriter(Channel* channel, CompletionQueue* cq,
+ ClientAsyncReaderWriter(ChannelInterface* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
void* tag)
: context_(context), call_(channel->CreateCall(method, context, cq)) {
diff --git a/include/grpc++/support/async_unary_call.h b/include/grpc++/support/async_unary_call.h
index 0f4ad2656f..55ca56b6a6 100644
--- a/include/grpc++/support/async_unary_call.h
+++ b/include/grpc++/support/async_unary_call.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@
#define GRPCXX_SUPPORT_ASYNC_UNARY_CALL_H
#include <grpc/support/log.h>
-#include <grpc++/channel.h>
+#include <grpc++/impl/codegen/channel_interface.h>
#include <grpc++/client_context.h>
#include <grpc++/completion_queue.h>
#include <grpc++/server_context.h>
@@ -58,7 +58,7 @@ class ClientAsyncResponseReader GRPC_FINAL
: public ClientAsyncResponseReaderInterface<R> {
public:
template <class W>
- ClientAsyncResponseReader(Channel* channel, CompletionQueue* cq,
+ ClientAsyncResponseReader(ChannelInterface* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
const W& request)
: context_(context), call_(channel->CreateCall(method, context, cq)) {
diff --git a/include/grpc++/support/config.h b/include/grpc++/support/config.h
index 836bd47283..be8c89c462 100644
--- a/include/grpc++/support/config.h
+++ b/include/grpc++/support/config.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,83 +34,6 @@
#ifndef GRPCXX_SUPPORT_CONFIG_H
#define GRPCXX_SUPPORT_CONFIG_H
-#if !defined(GRPC_NO_AUTODETECT_PLATFORM)
-
-#ifdef _MSC_VER
-// Visual Studio 2010 is 1600.
-#if _MSC_VER < 1600
-#error "gRPC is only supported with Visual Studio starting at 2010"
-// Visual Studio 2013 is 1800.
-#elif _MSC_VER < 1800
-#define GRPC_CXX0X_NO_FINAL 1
-#define GRPC_CXX0X_NO_OVERRIDE 1
-#define GRPC_CXX0X_NO_CHRONO 1
-#define GRPC_CXX0X_NO_THREAD 1
-#endif
-#endif // Visual Studio
-
-#ifndef __clang__
-#ifdef __GNUC__
-// nullptr was added in gcc 4.6
-#if (__GNUC__ * 100 + __GNUC_MINOR__ < 406)
-#define GRPC_CXX0X_NO_NULLPTR 1
-#endif
-// final and override were added in gcc 4.7
-#if (__GNUC__ * 100 + __GNUC_MINOR__ < 407)
-#define GRPC_CXX0X_NO_FINAL 1
-#define GRPC_CXX0X_NO_OVERRIDE 1
-#endif
-#endif
-#endif
-
-#endif
-
-#ifdef GRPC_CXX0X_NO_FINAL
-#define GRPC_FINAL
-#else
-#define GRPC_FINAL final
-#endif
-
-#ifdef GRPC_CXX0X_NO_OVERRIDE
-#define GRPC_OVERRIDE
-#else
-#define GRPC_OVERRIDE override
-#endif
-
-#ifdef GRPC_CXX0X_NO_NULLPTR
-#include <memory>
-namespace grpc {
-const class {
- public:
- template <class T>
- operator T *() const {
- return static_cast<T *>(0);
- }
- template <class T>
- operator std::unique_ptr<T>() const {
- return std::unique_ptr<T>(static_cast<T *>(0));
- }
- template <class T>
- operator std::shared_ptr<T>() const {
- return std::shared_ptr<T>(static_cast<T *>(0));
- }
- operator bool() const { return false; }
-
- private:
- void operator&() const = delete;
-} nullptr = {};
-}
-#endif
-
-#ifndef GRPC_CUSTOM_STRING
-#include <string>
-#define GRPC_CUSTOM_STRING std::string
-#endif
-
-namespace grpc {
-
-typedef GRPC_CUSTOM_STRING string;
-
-} // namespace grpc
+#include <grpc++/impl/codegen/config.h>
#endif // GRPCXX_SUPPORT_CONFIG_H
diff --git a/include/grpc++/support/status.h b/include/grpc++/support/status.h
index e59bac92d1..a33fbedf12 100644
--- a/include/grpc++/support/status.h
+++ b/include/grpc++/support/status.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,43 +34,6 @@
#ifndef GRPCXX_SUPPORT_STATUS_H
#define GRPCXX_SUPPORT_STATUS_H
-#include <grpc++/support/config.h>
-#include <grpc++/support/status_code_enum.h>
-
-namespace grpc {
-
-/// Did it work? If it didn't, why?
-///
-/// See \a grpc::StatusCode for details on the available code and their meaning.
-class Status {
- public:
- /// Construct an OK instance.
- Status() : code_(StatusCode::OK) {}
-
- /// Construct an instance with associated \a code and \a details (also
- // referred to as "error_message").
- Status(StatusCode code, const grpc::string& details)
- : code_(code), details_(details) {}
-
- // Pre-defined special status objects.
- /// An OK pre-defined instance.
- static const Status& OK;
- /// A CANCELLED pre-defined instance.
- static const Status& CANCELLED;
-
- /// Return the instance's error code.
- StatusCode error_code() const { return code_; }
- /// Return the instance's error message.
- grpc::string error_message() const { return details_; }
-
- /// Is the status OK?
- bool ok() const { return code_ == StatusCode::OK; }
-
- private:
- StatusCode code_;
- grpc::string details_;
-};
-
-} // namespace grpc
+#include <grpc++/impl/codegen/status.h>
#endif // GRPCXX_SUPPORT_STATUS_H
diff --git a/include/grpc++/support/status_code_enum.h b/include/grpc++/support/status_code_enum.h
index ee05b40b51..21b9c40d7e 100644
--- a/include/grpc++/support/status_code_enum.h
+++ b/include/grpc++/support/status_code_enum.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,119 +34,6 @@
#ifndef GRPCXX_SUPPORT_STATUS_CODE_ENUM_H
#define GRPCXX_SUPPORT_STATUS_CODE_ENUM_H
-namespace grpc {
-
-enum StatusCode {
- /// Not an error; returned on success.
- OK = 0,
-
- /// The operation was cancelled (typically by the caller).
- CANCELLED = 1,
-
- /// Unknown error. An example of where this error may be returned is if a
- /// Status value received from another address space belongs to an error-space
- /// that is not known in this address space. Also errors raised by APIs that
- /// do not return enough error information may be converted to this error.
- UNKNOWN = 2,
-
- /// Client specified an invalid argument. Note that this differs from
- /// FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are
- /// problematic regardless of the state of the system (e.g., a malformed file
- /// name).
- INVALID_ARGUMENT = 3,
-
- /// Deadline expired before operation could complete. For operations that
- /// change the state of the system, this error may be returned even if the
- /// operation has completed successfully. For example, a successful response
- /// from a server could have been delayed long enough for the deadline to
- /// expire.
- DEADLINE_EXCEEDED = 4,
-
- /// Some requested entity (e.g., file or directory) was not found.
- NOT_FOUND = 5,
-
- /// Some entity that we attempted to create (e.g., file or directory) already
- /// exists.
- ALREADY_EXISTS = 6,
-
- /// The caller does not have permission to execute the specified operation.
- /// PERMISSION_DENIED must not be used for rejections caused by exhausting
- /// some resource (use RESOURCE_EXHAUSTED instead for those errors).
- /// PERMISSION_DENIED must not be used if the caller can not be identified
- /// (use UNAUTHENTICATED instead for those errors).
- PERMISSION_DENIED = 7,
-
- /// The request does not have valid authentication credentials for the
- /// operation.
- UNAUTHENTICATED = 16,
-
- /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the
- /// entire file system is out of space.
- RESOURCE_EXHAUSTED = 8,
-
- /// Operation was rejected because the system is not in a state required for
- /// the operation's execution. For example, directory to be deleted may be
- /// non-empty, an rmdir operation is applied to a non-directory, etc.
- ///
- /// A litmus test that may help a service implementor in deciding
- /// between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
- /// (a) Use UNAVAILABLE if the client can retry just the failing call.
- /// (b) Use ABORTED if the client should retry at a higher-level
- /// (e.g., restarting a read-modify-write sequence).
- /// (c) Use FAILED_PRECONDITION if the client should not retry until
- /// the system state has been explicitly fixed. E.g., if an "rmdir"
- /// fails because the directory is non-empty, FAILED_PRECONDITION
- /// should be returned since the client should not retry unless
- /// they have first fixed up the directory by deleting files from it.
- /// (d) Use FAILED_PRECONDITION if the client performs conditional
- /// REST Get/Update/Delete on a resource and the resource on the
- /// server does not match the condition. E.g., conflicting
- /// read-modify-write on the same resource.
- FAILED_PRECONDITION = 9,
-
- /// The operation was aborted, typically due to a concurrency issue like
- /// sequencer check failures, transaction aborts, etc.
- ///
- /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
- /// and UNAVAILABLE.
- ABORTED = 10,
-
- /// Operation was attempted past the valid range. E.g., seeking or reading
- /// past end of file.
- ///
- /// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed
- /// if the system state changes. For example, a 32-bit file system will
- /// generate INVALID_ARGUMENT if asked to read at an offset that is not in the
- /// range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from
- /// an offset past the current file size.
- ///
- /// There is a fair bit of overlap between FAILED_PRECONDITION and
- /// OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error)
- /// when it applies so that callers who are iterating through a space can
- /// easily look for an OUT_OF_RANGE error to detect when they are done.
- OUT_OF_RANGE = 11,
-
- /// Operation is not implemented or not supported/enabled in this service.
- UNIMPLEMENTED = 12,
-
- /// Internal errors. Means some invariants expected by underlying System has
- /// been broken. If you see one of these errors, Something is very broken.
- INTERNAL = 13,
-
- /// The service is currently unavailable. This is a most likely a transient
- /// condition and may be corrected by retrying with a backoff.
- ///
- /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
- /// and UNAVAILABLE.
- UNAVAILABLE = 14,
-
- /// Unrecoverable data loss or corruption.
- DATA_LOSS = 15,
-
- /// Force users to include a default branch:
- DO_NOT_USE = -1
-};
-
-} // namespace grpc
+#include <grpc++/impl/codegen/status_code_enum.h>
#endif // GRPCXX_SUPPORT_STATUS_CODE_ENUM_H
diff --git a/include/grpc++/support/sync_stream.h b/include/grpc++/support/sync_stream.h
index daf4e367ae..3f3acc5308 100644
--- a/include/grpc++/support/sync_stream.h
+++ b/include/grpc++/support/sync_stream.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,7 @@
#include <grpc/support/log.h>
#include <grpc++/channel.h>
+#include <grpc++/impl/codegen/channel_interface.h>
#include <grpc++/client_context.h>
#include <grpc++/completion_queue.h>
#include <grpc++/impl/call.h>
@@ -118,7 +119,7 @@ class ClientReader GRPC_FINAL : public ClientReaderInterface<R> {
public:
/// Blocking create a stream and write the first request out.
template <class W>
- ClientReader(Channel* channel, const RpcMethod& method,
+ ClientReader(ChannelInterface* channel, const RpcMethod& method,
ClientContext* context, const W& request)
: context_(context), call_(channel->CreateCall(method, context, &cq_)) {
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
@@ -182,7 +183,7 @@ class ClientWriter : public ClientWriterInterface<W> {
public:
/// Blocking create a stream.
template <class R>
- ClientWriter(Channel* channel, const RpcMethod& method,
+ ClientWriter(ChannelInterface* channel, const RpcMethod& method,
ClientContext* context, R* response)
: context_(context), call_(channel->CreateCall(method, context, &cq_)) {
finish_ops_.RecvMessage(response);
@@ -248,7 +249,7 @@ template <class W, class R>
class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> {
public:
/// Blocking create a stream.
- ClientReaderWriter(Channel* channel, const RpcMethod& method,
+ ClientReaderWriter(ChannelInterface* channel, const RpcMethod& method,
ClientContext* context)
: context_(context), call_(channel->CreateCall(method, context, &cq_)) {
CallOpSet<CallOpSendInitialMetadata> ops;
diff --git a/include/grpc++/support/time.h b/include/grpc++/support/time.h
index e00e0d8e91..f0b758f254 100644
--- a/include/grpc++/support/time.h
+++ b/include/grpc++/support/time.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,78 +34,6 @@
#ifndef GRPCXX_SUPPORT_TIME_H
#define GRPCXX_SUPPORT_TIME_H
-#include <grpc++/support/config.h>
-#include <grpc/support/time.h>
-
-namespace grpc {
-
-/* If you are trying to use CompletionQueue::AsyncNext with a time class that
- isn't either gpr_timespec or std::chrono::system_clock::time_point, you
- will most likely be looking at this comment as your compiler will have
- fired an error below. In order to fix this issue, you have two potential
- solutions:
-
- 1. Use gpr_timespec or std::chrono::system_clock::time_point instead
- 2. Specialize the TimePoint class with whichever time class that you
- want to use here. See below for two examples of how to do this.
- */
-
-template <typename T>
-class TimePoint {
- public:
- TimePoint(const T& time) { you_need_a_specialization_of_TimePoint(); }
- gpr_timespec raw_time() {
- gpr_timespec t;
- return t;
- }
-
- private:
- void you_need_a_specialization_of_TimePoint();
-};
-
-template <>
-class TimePoint<gpr_timespec> {
- public:
- TimePoint(const gpr_timespec& time) : time_(time) {}
- gpr_timespec raw_time() { return time_; }
-
- private:
- gpr_timespec time_;
-};
-
-} // namespace grpc
-
-#ifndef GRPC_CXX0X_NO_CHRONO
-
-#include <chrono>
-
-#include <grpc/support/time.h>
-
-namespace grpc {
-
-// from and to should be absolute time.
-void Timepoint2Timespec(const std::chrono::system_clock::time_point& from,
- gpr_timespec* to);
-void TimepointHR2Timespec(
- const std::chrono::high_resolution_clock::time_point& from,
- gpr_timespec* to);
-
-std::chrono::system_clock::time_point Timespec2Timepoint(gpr_timespec t);
-
-template <>
-class TimePoint<std::chrono::system_clock::time_point> {
- public:
- TimePoint(const std::chrono::system_clock::time_point& time) {
- Timepoint2Timespec(time, &time_);
- }
- gpr_timespec raw_time() const { return time_; }
-
- private:
- gpr_timespec time_;
-};
-
-} // namespace grpc
-
-#endif // !GRPC_CXX0X_NO_CHRONO
+#include <grpc++/impl/codegen/time.h>
#endif // GRPCXX_SUPPORT_TIME_H
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 952e86ea49..2d012adc00 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -40,6 +40,7 @@
#include <grpc/byte_buffer.h>
#include <grpc/support/slice.h>
#include <grpc/support/time.h>
+#include <grpc/impl/codegen/connectivity_state.h>
#ifdef __cplusplus
extern "C" {
@@ -155,20 +156,6 @@ typedef struct {
channel, it will just be ignored. */
#define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override"
-/** Connectivity state of a channel. */
-typedef enum {
- /** channel is idle */
- GRPC_CHANNEL_IDLE,
- /** channel is connecting */
- GRPC_CHANNEL_CONNECTING,
- /** channel is ready for work */
- GRPC_CHANNEL_READY,
- /** channel has seen a failure but expects to recover */
- GRPC_CHANNEL_TRANSIENT_FAILURE,
- /** channel has seen a failure that it cannot recover from */
- GRPC_CHANNEL_FATAL_FAILURE
-} grpc_connectivity_state;
-
/** Result of a grpc call. If the caller satisfies the prerequisites of a
particular operation, the grpc_call_error returned will be GRPC_CALL_OK.
Receiving any other value listed here is an indication of a bug in the
diff --git a/include/grpc/impl/codegen/connectivity_state.h b/include/grpc/impl/codegen/connectivity_state.h
new file mode 100644
index 0000000000..5bb9eb8f4e
--- /dev/null
+++ b/include/grpc/impl/codegen/connectivity_state.h
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_CONNECTIVITY_STATE_H
+#define GRPC_IMPL_CODEGEN_CONNECTIVITY_STATE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Connectivity state of a channel. */
+typedef enum {
+ /** channel is idle */
+ GRPC_CHANNEL_IDLE,
+ /** channel is connecting */
+ GRPC_CHANNEL_CONNECTING,
+ /** channel is ready for work */
+ GRPC_CHANNEL_READY,
+ /** channel has seen a failure but expects to recover */
+ GRPC_CHANNEL_TRANSIENT_FAILURE,
+ /** channel has seen a failure that it cannot recover from */
+ GRPC_CHANNEL_FATAL_FAILURE
+} grpc_connectivity_state;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_CONNECTIVITY_STATE_H */
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
new file mode 100644
index 0000000000..b5a708e7f2
--- /dev/null
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -0,0 +1,340 @@
+/*
+ *
+ * Copyright 2015-2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_PORT_PLATFORM_H
+#define GRPC_IMPL_CODEGEN_PORT_PLATFORM_H
+
+/* Get windows.h included everywhere (we need it) */
+#if defined(_WIN64) || defined(WIN64) || defined(_WIN32) || defined(WIN32)
+#ifndef WIN32_LEAN_AND_MEAN
+#define GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED
+#define WIN32_LEAN_AND_MEAN
+#endif /* WIN32_LEAN_AND_MEAN */
+
+#ifndef NOMINMAX
+#define GRPC_NOMINMX_WAS_NOT_DEFINED
+#define NOMINMAX
+#endif /* NOMINMAX */
+
+#ifndef _WIN32_WINNT
+#error \
+ "Please compile grpc with _WIN32_WINNT of at least 0x600 (aka Windows Vista)"
+#else /* !defined(_WIN32_WINNT) */
+#if (_WIN32_WINNT < 0x0600)
+#error \
+ "Please compile grpc with _WIN32_WINNT of at least 0x600 (aka Windows Vista)"
+#endif /* _WIN32_WINNT < 0x0600 */
+#endif /* defined(_WIN32_WINNT) */
+
+#include <windows.h>
+
+#ifdef GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED
+#undef GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED
+#undef WIN32_LEAN_AND_MEAN
+#endif /* GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED */
+
+#ifdef GRPC_NOMINMAX_WAS_NOT_DEFINED
+#undef GRPC_NOMINMAX_WAS_NOT_DEFINED
+#undef NOMINMAX
+#endif /* GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED */
+#endif /* defined(_WIN64) || defined(WIN64) || defined(_WIN32) || \
+ defined(WIN32) */
+
+/* Override this file with one for your platform if you need to redefine
+ things. */
+
+#if !defined(GPR_NO_AUTODETECT_PLATFORM)
+#if defined(_WIN64) || defined(WIN64)
+#define GPR_PLATFORM_STRING "windows"
+#define GPR_WIN32 1
+#define GPR_ARCH_64 1
+#define GPR_GETPID_IN_PROCESS_H 1
+#define GPR_WINSOCK_SOCKET 1
+#ifdef __GNUC__
+#define GPR_GCC_ATOMIC 1
+#define GPR_GCC_TLS 1
+#else
+#define GPR_WIN32_ATOMIC 1
+#define GPR_MSVC_TLS 1
+#endif
+#define GPR_WINDOWS_CRASH_HANDLER 1
+#elif defined(_WIN32) || defined(WIN32)
+#define GPR_PLATFORM_STRING "windows"
+#define GPR_ARCH_32 1
+#define GPR_WIN32 1
+#define GPR_GETPID_IN_PROCESS_H 1
+#define GPR_WINSOCK_SOCKET 1
+#ifdef __GNUC__
+#define GPR_GCC_ATOMIC 1
+#define GPR_GCC_TLS 1
+#else
+#define GPR_WIN32_ATOMIC 1
+#define GPR_MSVC_TLS 1
+#endif
+#define GPR_WINDOWS_CRASH_HANDLER 1
+#elif defined(ANDROID) || defined(__ANDROID__)
+#define GPR_PLATFORM_STRING "android"
+#define GPR_ANDROID 1
+#define GPR_ARCH_32 1
+#define GPR_CPU_LINUX 1
+#define GPR_GCC_SYNC 1
+#define GPR_GCC_TLS 1
+#define GPR_POSIX_MULTIPOLL_WITH_POLL 1
+#define GPR_POSIX_WAKEUP_FD 1
+#define GPR_LINUX_EVENTFD 1
+#define GPR_POSIX_SOCKET 1
+#define GPR_POSIX_SOCKETADDR 1
+#define GPR_POSIX_SOCKETUTILS 1
+#define GPR_POSIX_ENV 1
+#define GPR_POSIX_FILE 1
+#define GPR_POSIX_STRING 1
+#define GPR_POSIX_SUBPROCESS 1
+#define GPR_POSIX_SYNC 1
+#define GPR_POSIX_TIME 1
+#define GPR_GETPID_IN_UNISTD_H 1
+#define GPR_HAVE_MSG_NOSIGNAL 1
+#elif defined(__linux__)
+#define GPR_POSIX_CRASH_HANDLER 1
+#define GPR_PLATFORM_STRING "linux"
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE
+#endif
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <features.h>
+#define GPR_CPU_LINUX 1
+#define GPR_GCC_ATOMIC 1
+#define GPR_GCC_TLS 1
+#define GPR_LINUX 1
+#define GPR_LINUX_MULTIPOLL_WITH_EPOLL 1
+#define GPR_POSIX_WAKEUP_FD 1
+#define GPR_POSIX_SOCKET 1
+#define GPR_POSIX_SOCKETADDR 1
+#ifdef __GLIBC_PREREQ
+#if __GLIBC_PREREQ(2, 9)
+#define GPR_LINUX_EVENTFD 1
+#endif
+#if __GLIBC_PREREQ(2, 10)
+#define GPR_LINUX_SOCKETUTILS 1
+#endif
+#if __GLIBC_PREREQ(2, 17)
+#define GPR_LINUX_ENV 1
+#endif
+#endif
+#ifndef GPR_LINUX_EVENTFD
+#define GPR_POSIX_NO_SPECIAL_WAKEUP_FD 1
+#endif
+#ifndef GPR_LINUX_SOCKETUTILS
+#define GPR_POSIX_SOCKETUTILS
+#endif
+#ifndef GPR_LINUX_ENV
+#define GPR_POSIX_ENV 1
+#endif
+#define GPR_POSIX_FILE 1
+#define GPR_POSIX_STRING 1
+#define GPR_POSIX_SUBPROCESS 1
+#define GPR_POSIX_SYNC 1
+#define GPR_POSIX_TIME 1
+#define GPR_GETPID_IN_UNISTD_H 1
+#define GPR_HAVE_MSG_NOSIGNAL 1
+#ifdef _LP64
+#define GPR_ARCH_64 1
+#else /* _LP64 */
+#define GPR_ARCH_32 1
+#endif /* _LP64 */
+#elif defined(__APPLE__)
+#include <TargetConditionals.h>
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#define GPR_MSG_IOVLEN_TYPE int
+#if TARGET_OS_IPHONE
+#define GPR_FORBID_UNREACHABLE_CODE 1
+#define GPR_PLATFORM_STRING "ios"
+#define GPR_CPU_IPHONE 1
+#define GPR_PTHREAD_TLS 1
+#else /* TARGET_OS_IPHONE */
+#define GPR_PLATFORM_STRING "osx"
+#define GPR_CPU_POSIX 1
+#define GPR_GCC_TLS 1
+#define GPR_POSIX_CRASH_HANDLER 1
+#endif
+#define GPR_GCC_ATOMIC 1
+#define GPR_POSIX_LOG 1
+#define GPR_POSIX_MULTIPOLL_WITH_POLL 1
+#define GPR_POSIX_WAKEUP_FD 1
+#define GPR_POSIX_NO_SPECIAL_WAKEUP_FD 1
+#define GPR_POSIX_SOCKET 1
+#define GPR_POSIX_SOCKETADDR 1
+#define GPR_POSIX_SOCKETUTILS 1
+#define GPR_POSIX_ENV 1
+#define GPR_POSIX_FILE 1
+#define GPR_POSIX_STRING 1
+#define GPR_POSIX_SUBPROCESS 1
+#define GPR_POSIX_SYNC 1
+#define GPR_POSIX_TIME 1
+#define GPR_GETPID_IN_UNISTD_H 1
+#define GPR_HAVE_SO_NOSIGPIPE 1
+#ifdef _LP64
+#define GPR_ARCH_64 1
+#else /* _LP64 */
+#define GPR_ARCH_32 1
+#endif /* _LP64 */
+#elif defined(__FreeBSD__)
+#define GPR_PLATFORM_STRING "freebsd"
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#define GPR_CPU_POSIX 1
+#define GPR_GCC_ATOMIC 1
+#define GPR_GCC_TLS 1
+#define GPR_POSIX_LOG 1
+#define GPR_POSIX_MULTIPOLL_WITH_POLL 1
+#define GPR_POSIX_WAKEUP_FD 1
+#define GPR_POSIX_NO_SPECIAL_WAKEUP_FD 1
+#define GPR_POSIX_SOCKET 1
+#define GPR_POSIX_SOCKETADDR 1
+#define GPR_POSIX_SOCKETUTILS 1
+#define GPR_POSIX_ENV 1
+#define GPR_POSIX_FILE 1
+#define GPR_POSIX_STRING 1
+#define GPR_POSIX_SUBPROCESS 1
+#define GPR_POSIX_SYNC 1
+#define GPR_POSIX_TIME 1
+#define GPR_GETPID_IN_UNISTD_H 1
+#define GPR_HAVE_SO_NOSIGPIPE 1
+#ifdef _LP64
+#define GPR_ARCH_64 1
+#else /* _LP64 */
+#define GPR_ARCH_32 1
+#endif /* _LP64 */
+#else
+#error Could not auto-detect platform
+#endif
+#endif /* GPR_NO_AUTODETECT_PLATFORM */
+
+#ifndef GPR_PLATFORM_STRING
+#warning "GPR_PLATFORM_STRING not auto-detected"
+#define GPR_PLATFORM_STRING "unknown"
+#endif
+
+#ifdef GPR_GCOV
+#undef GPR_FORBID_UNREACHABLE_CODE
+#define GPR_FORBID_UNREACHABLE_CODE 1
+#endif
+
+/* For a common case, assume that the platform has a C99-like stdint.h */
+
+#include <stdint.h>
+
+/* Cache line alignment */
+#ifndef GPR_CACHELINE_SIZE_LOG
+#if defined(__i386__) || defined(__x86_64__)
+#define GPR_CACHELINE_SIZE_LOG 6
+#endif
+#ifndef GPR_CACHELINE_SIZE_LOG
+/* A reasonable default guess. Note that overestimates tend to waste more
+ space, while underestimates tend to waste more time. */
+#define GPR_CACHELINE_SIZE_LOG 6
+#endif /* GPR_CACHELINE_SIZE_LOG */
+#endif /* GPR_CACHELINE_SIZE_LOG */
+
+#define GPR_CACHELINE_SIZE (1 << GPR_CACHELINE_SIZE_LOG)
+
+/* scrub GCC_ATOMIC if it's not available on this compiler */
+#if defined(GPR_GCC_ATOMIC) && !defined(__ATOMIC_RELAXED)
+#undef GPR_GCC_ATOMIC
+#define GPR_GCC_SYNC 1
+#endif
+
+/* Validate platform combinations */
+#if defined(GPR_GCC_ATOMIC) + defined(GPR_GCC_SYNC) + \
+ defined(GPR_WIN32_ATOMIC) != \
+ 1
+#error Must define exactly one of GPR_GCC_ATOMIC, GPR_GCC_SYNC, GPR_WIN32_ATOMIC
+#endif
+
+#if defined(GPR_ARCH_32) + defined(GPR_ARCH_64) != 1
+#error Must define exactly one of GPR_ARCH_32, GPR_ARCH_64
+#endif
+
+#if defined(GPR_CPU_LINUX) + defined(GPR_CPU_POSIX) + defined(GPR_WIN32) + \
+ defined(GPR_CPU_IPHONE) + defined(GPR_CPU_CUSTOM) != \
+ 1
+#error Must define exactly one of GPR_CPU_LINUX, GPR_CPU_POSIX, GPR_WIN32, GPR_CPU_IPHONE, GPR_CPU_CUSTOM
+#endif
+
+#if defined(GPR_POSIX_MULTIPOLL_WITH_POLL) && !defined(GPR_POSIX_SOCKET)
+#error Must define GPR_POSIX_SOCKET to use GPR_POSIX_MULTIPOLL_WITH_POLL
+#endif
+
+#if defined(GPR_POSIX_SOCKET) + defined(GPR_WINSOCK_SOCKET) + \
+ defined(GPR_CUSTOM_SOCKET) != \
+ 1
+#error Must define exactly one of GPR_POSIX_SOCKET, GPR_WINSOCK_SOCKET, GPR_CUSTOM_SOCKET
+#endif
+
+#if defined(GPR_MSVC_TLS) + defined(GPR_GCC_TLS) + defined(GPR_PTHREAD_TLS) + \
+ defined(GPR_CUSTOM_TLS) != \
+ 1
+#error Must define exactly one of GPR_MSVC_TLS, GPR_GCC_TLS, GPR_PTHREAD_TLS, GPR_CUSTOM_TLS
+#endif
+
+/* maximum alignment needed for any type on this platform, rounded up to a
+ power of two */
+#define GPR_MAX_ALIGNMENT 16
+
+#ifndef GRPC_MUST_USE_RESULT
+#ifdef __GNUC__
+#define GRPC_MUST_USE_RESULT __attribute__((warn_unused_result))
+#else
+#define GRPC_MUST_USE_RESULT
+#endif
+#endif
+
+#if GPR_FORBID_UNREACHABLE_CODE
+#define GPR_UNREACHABLE_CODE(STATEMENT)
+#else
+#define GPR_UNREACHABLE_CODE(STATEMENT) \
+ do { \
+ gpr_log(GPR_ERROR, "Should never reach here."); \
+ abort(); \
+ STATEMENT; \
+ } while (0)
+#endif /* GPR_FORBID_UNREACHABLE_CODE */
+
+#endif /* GRPC_IMPL_CODEGEN_PORT_PLATFORM_H */
diff --git a/include/grpc/impl/codegen/time.h b/include/grpc/impl/codegen/time.h
new file mode 100644
index 0000000000..2248391f52
--- /dev/null
+++ b/include/grpc/impl/codegen/time.h
@@ -0,0 +1,128 @@
+/*
+ *
+ * Copyright 2015-2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_IMPL_CODEGEN_TIME_H
+#define GRPC_IMPL_CODEGEN_TIME_H
+/* Time support.
+ We use gpr_timespec, which is analogous to struct timespec. On some
+ machines, absolute times may be in local time. */
+
+#include <grpc/impl/codegen/port_platform.h>
+#include <stddef.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The clocks we support. */
+typedef enum {
+ /* Monotonic clock. Epoch undefined. Always moves forwards. */
+ GPR_CLOCK_MONOTONIC = 0,
+ /* Realtime clock. May jump forwards or backwards. Settable by
+ the system administrator. Has its epoch at 0:00:00 UTC 1 Jan 1970. */
+ GPR_CLOCK_REALTIME,
+ /* CPU cycle time obtained by rdtsc instruction on x86 platforms. Epoch
+ undefined. Degrades to GPR_CLOCK_REALTIME on other platforms. */
+ GPR_CLOCK_PRECISE,
+ /* Unmeasurable clock type: no base, created by taking the difference
+ between two times */
+ GPR_TIMESPAN
+} gpr_clock_type;
+
+typedef struct gpr_timespec {
+ int64_t tv_sec;
+ int32_t tv_nsec;
+ /** Against which clock was this time measured? (or GPR_TIMESPAN if
+ this is a relative time meaure) */
+ gpr_clock_type clock_type;
+} gpr_timespec;
+
+/* Time constants. */
+gpr_timespec gpr_time_0(gpr_clock_type type); /* The zero time interval. */
+gpr_timespec gpr_inf_future(gpr_clock_type type); /* The far future */
+gpr_timespec gpr_inf_past(gpr_clock_type type); /* The far past. */
+
+#define GPR_MS_PER_SEC 1000
+#define GPR_US_PER_SEC 1000000
+#define GPR_NS_PER_SEC 1000000000
+#define GPR_NS_PER_MS 1000000
+#define GPR_NS_PER_US 1000
+#define GPR_US_PER_MS 1000
+
+/* initialize time subsystem */
+void gpr_time_init(void);
+
+/* Return the current time measured from the given clocks epoch. */
+gpr_timespec gpr_now(gpr_clock_type clock);
+
+/* Convert a timespec from one clock to another */
+gpr_timespec gpr_convert_clock_type(gpr_timespec t,
+ gpr_clock_type target_clock);
+
+/* Return -ve, 0, or +ve according to whether a < b, a == b, or a > b
+ respectively. */
+int gpr_time_cmp(gpr_timespec a, gpr_timespec b);
+
+gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b);
+gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b);
+
+/* Add and subtract times. Calculations saturate at infinities. */
+gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b);
+gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b);
+
+/* Return a timespec representing a given number of time units. LONG_MIN is
+ interpreted as gpr_inf_past, and LONG_MAX as gpr_inf_future. */
+gpr_timespec gpr_time_from_micros(long x, gpr_clock_type clock_type);
+gpr_timespec gpr_time_from_nanos(long x, gpr_clock_type clock_type);
+gpr_timespec gpr_time_from_millis(long x, gpr_clock_type clock_type);
+gpr_timespec gpr_time_from_seconds(long x, gpr_clock_type clock_type);
+gpr_timespec gpr_time_from_minutes(long x, gpr_clock_type clock_type);
+gpr_timespec gpr_time_from_hours(long x, gpr_clock_type clock_type);
+
+int32_t gpr_time_to_millis(gpr_timespec timespec);
+
+/* Return 1 if two times are equal or within threshold of each other,
+ 0 otherwise */
+int gpr_time_similar(gpr_timespec a, gpr_timespec b, gpr_timespec threshold);
+
+/* Sleep until at least 'until' - an absolute timeout */
+void gpr_sleep_until(gpr_timespec until);
+
+double gpr_timespec_to_micros(gpr_timespec t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_TIME_H */
diff --git a/include/grpc/support/port_platform.h b/include/grpc/support/port_platform.h
index 8a30f1da41..6b14f8b0b0 100644
--- a/include/grpc/support/port_platform.h
+++ b/include/grpc/support/port_platform.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,307 +34,6 @@
#ifndef GRPC_SUPPORT_PORT_PLATFORM_H
#define GRPC_SUPPORT_PORT_PLATFORM_H
-/* Get windows.h included everywhere (we need it) */
-#if defined(_WIN64) || defined(WIN64) || defined(_WIN32) || defined(WIN32)
-#ifndef WIN32_LEAN_AND_MEAN
-#define GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED
-#define WIN32_LEAN_AND_MEAN
-#endif /* WIN32_LEAN_AND_MEAN */
-
-#ifndef NOMINMAX
-#define GRPC_NOMINMX_WAS_NOT_DEFINED
-#define NOMINMAX
-#endif /* NOMINMAX */
-
-#ifndef _WIN32_WINNT
-#error \
- "Please compile grpc with _WIN32_WINNT of at least 0x600 (aka Windows Vista)"
-#else /* !defined(_WIN32_WINNT) */
-#if (_WIN32_WINNT < 0x0600)
-#error \
- "Please compile grpc with _WIN32_WINNT of at least 0x600 (aka Windows Vista)"
-#endif /* _WIN32_WINNT < 0x0600 */
-#endif /* defined(_WIN32_WINNT) */
-
-#include <windows.h>
-
-#ifdef GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED
-#undef GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED
-#undef WIN32_LEAN_AND_MEAN
-#endif /* GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED */
-
-#ifdef GRPC_NOMINMAX_WAS_NOT_DEFINED
-#undef GRPC_NOMINMAX_WAS_NOT_DEFINED
-#undef NOMINMAX
-#endif /* GRPC_WIN32_LEAN_AND_MEAN_WAS_NOT_DEFINED */
-#endif /* defined(_WIN64) || defined(WIN64) || defined(_WIN32) || \
- defined(WIN32) */
-
-/* Override this file with one for your platform if you need to redefine
- things. */
-
-#if !defined(GPR_NO_AUTODETECT_PLATFORM)
-#if defined(_WIN64) || defined(WIN64)
-#define GPR_PLATFORM_STRING "windows"
-#define GPR_WIN32 1
-#define GPR_ARCH_64 1
-#define GPR_GETPID_IN_PROCESS_H 1
-#define GPR_WINSOCK_SOCKET 1
-#ifdef __GNUC__
-#define GPR_GCC_ATOMIC 1
-#define GPR_GCC_TLS 1
-#else
-#define GPR_WIN32_ATOMIC 1
-#define GPR_MSVC_TLS 1
-#endif
-#define GPR_WINDOWS_CRASH_HANDLER 1
-#elif defined(_WIN32) || defined(WIN32)
-#define GPR_PLATFORM_STRING "windows"
-#define GPR_ARCH_32 1
-#define GPR_WIN32 1
-#define GPR_GETPID_IN_PROCESS_H 1
-#define GPR_WINSOCK_SOCKET 1
-#ifdef __GNUC__
-#define GPR_GCC_ATOMIC 1
-#define GPR_GCC_TLS 1
-#else
-#define GPR_WIN32_ATOMIC 1
-#define GPR_MSVC_TLS 1
-#endif
-#define GPR_WINDOWS_CRASH_HANDLER 1
-#elif defined(ANDROID) || defined(__ANDROID__)
-#define GPR_PLATFORM_STRING "android"
-#define GPR_ANDROID 1
-#define GPR_ARCH_32 1
-#define GPR_CPU_LINUX 1
-#define GPR_GCC_SYNC 1
-#define GPR_GCC_TLS 1
-#define GPR_POSIX_MULTIPOLL_WITH_POLL 1
-#define GPR_POSIX_WAKEUP_FD 1
-#define GPR_LINUX_EVENTFD 1
-#define GPR_POSIX_SOCKET 1
-#define GPR_POSIX_SOCKETADDR 1
-#define GPR_POSIX_SOCKETUTILS 1
-#define GPR_POSIX_ENV 1
-#define GPR_POSIX_FILE 1
-#define GPR_POSIX_STRING 1
-#define GPR_POSIX_SUBPROCESS 1
-#define GPR_POSIX_SYNC 1
-#define GPR_POSIX_TIME 1
-#define GPR_GETPID_IN_UNISTD_H 1
-#define GPR_HAVE_MSG_NOSIGNAL 1
-#elif defined(__linux__)
-#define GPR_POSIX_CRASH_HANDLER 1
-#define GPR_PLATFORM_STRING "linux"
-#ifndef _BSD_SOURCE
-#define _BSD_SOURCE
-#endif
-#ifndef _DEFAULT_SOURCE
-#define _DEFAULT_SOURCE
-#endif
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <features.h>
-#define GPR_CPU_LINUX 1
-#define GPR_GCC_ATOMIC 1
-#define GPR_GCC_TLS 1
-#define GPR_LINUX 1
-#define GPR_LINUX_MULTIPOLL_WITH_EPOLL 1
-#define GPR_POSIX_WAKEUP_FD 1
-#define GPR_POSIX_SOCKET 1
-#define GPR_POSIX_SOCKETADDR 1
-#ifdef __GLIBC_PREREQ
-#if __GLIBC_PREREQ(2, 9)
-#define GPR_LINUX_EVENTFD 1
-#endif
-#if __GLIBC_PREREQ(2, 10)
-#define GPR_LINUX_SOCKETUTILS 1
-#endif
-#if __GLIBC_PREREQ(2, 17)
-#define GPR_LINUX_ENV 1
-#endif
-#endif
-#ifndef GPR_LINUX_EVENTFD
-#define GPR_POSIX_NO_SPECIAL_WAKEUP_FD 1
-#endif
-#ifndef GPR_LINUX_SOCKETUTILS
-#define GPR_POSIX_SOCKETUTILS
-#endif
-#ifndef GPR_LINUX_ENV
-#define GPR_POSIX_ENV 1
-#endif
-#define GPR_POSIX_FILE 1
-#define GPR_POSIX_STRING 1
-#define GPR_POSIX_SUBPROCESS 1
-#define GPR_POSIX_SYNC 1
-#define GPR_POSIX_TIME 1
-#define GPR_GETPID_IN_UNISTD_H 1
-#define GPR_HAVE_MSG_NOSIGNAL 1
-#ifdef _LP64
-#define GPR_ARCH_64 1
-#else /* _LP64 */
-#define GPR_ARCH_32 1
-#endif /* _LP64 */
-#elif defined(__APPLE__)
-#include <TargetConditionals.h>
-#ifndef _BSD_SOURCE
-#define _BSD_SOURCE
-#endif
-#define GPR_MSG_IOVLEN_TYPE int
-#if TARGET_OS_IPHONE
-#define GPR_FORBID_UNREACHABLE_CODE 1
-#define GPR_PLATFORM_STRING "ios"
-#define GPR_CPU_IPHONE 1
-#define GPR_PTHREAD_TLS 1
-#else /* TARGET_OS_IPHONE */
-#define GPR_PLATFORM_STRING "osx"
-#define GPR_CPU_POSIX 1
-#define GPR_GCC_TLS 1
-#define GPR_POSIX_CRASH_HANDLER 1
-#endif
-#define GPR_GCC_ATOMIC 1
-#define GPR_POSIX_LOG 1
-#define GPR_POSIX_MULTIPOLL_WITH_POLL 1
-#define GPR_POSIX_WAKEUP_FD 1
-#define GPR_POSIX_NO_SPECIAL_WAKEUP_FD 1
-#define GPR_POSIX_SOCKET 1
-#define GPR_POSIX_SOCKETADDR 1
-#define GPR_POSIX_SOCKETUTILS 1
-#define GPR_POSIX_ENV 1
-#define GPR_POSIX_FILE 1
-#define GPR_POSIX_STRING 1
-#define GPR_POSIX_SUBPROCESS 1
-#define GPR_POSIX_SYNC 1
-#define GPR_POSIX_TIME 1
-#define GPR_GETPID_IN_UNISTD_H 1
-#define GPR_HAVE_SO_NOSIGPIPE 1
-#ifdef _LP64
-#define GPR_ARCH_64 1
-#else /* _LP64 */
-#define GPR_ARCH_32 1
-#endif /* _LP64 */
-#elif defined(__FreeBSD__)
-#define GPR_PLATFORM_STRING "freebsd"
-#ifndef _BSD_SOURCE
-#define _BSD_SOURCE
-#endif
-#define GPR_CPU_POSIX 1
-#define GPR_GCC_ATOMIC 1
-#define GPR_GCC_TLS 1
-#define GPR_POSIX_LOG 1
-#define GPR_POSIX_MULTIPOLL_WITH_POLL 1
-#define GPR_POSIX_WAKEUP_FD 1
-#define GPR_POSIX_NO_SPECIAL_WAKEUP_FD 1
-#define GPR_POSIX_SOCKET 1
-#define GPR_POSIX_SOCKETADDR 1
-#define GPR_POSIX_SOCKETUTILS 1
-#define GPR_POSIX_ENV 1
-#define GPR_POSIX_FILE 1
-#define GPR_POSIX_STRING 1
-#define GPR_POSIX_SUBPROCESS 1
-#define GPR_POSIX_SYNC 1
-#define GPR_POSIX_TIME 1
-#define GPR_GETPID_IN_UNISTD_H 1
-#define GPR_HAVE_SO_NOSIGPIPE 1
-#ifdef _LP64
-#define GPR_ARCH_64 1
-#else /* _LP64 */
-#define GPR_ARCH_32 1
-#endif /* _LP64 */
-#else
-#error Could not auto-detect platform
-#endif
-#endif /* GPR_NO_AUTODETECT_PLATFORM */
-
-#ifndef GPR_PLATFORM_STRING
-#warning "GPR_PLATFORM_STRING not auto-detected"
-#define GPR_PLATFORM_STRING "unknown"
-#endif
-
-#ifdef GPR_GCOV
-#undef GPR_FORBID_UNREACHABLE_CODE
-#define GPR_FORBID_UNREACHABLE_CODE 1
-#endif
-
-/* For a common case, assume that the platform has a C99-like stdint.h */
-
-#include <stdint.h>
-
-/* Cache line alignment */
-#ifndef GPR_CACHELINE_SIZE_LOG
-#if defined(__i386__) || defined(__x86_64__)
-#define GPR_CACHELINE_SIZE_LOG 6
-#endif
-#ifndef GPR_CACHELINE_SIZE_LOG
-/* A reasonable default guess. Note that overestimates tend to waste more
- space, while underestimates tend to waste more time. */
-#define GPR_CACHELINE_SIZE_LOG 6
-#endif /* GPR_CACHELINE_SIZE_LOG */
-#endif /* GPR_CACHELINE_SIZE_LOG */
-
-#define GPR_CACHELINE_SIZE (1 << GPR_CACHELINE_SIZE_LOG)
-
-/* scrub GCC_ATOMIC if it's not available on this compiler */
-#if defined(GPR_GCC_ATOMIC) && !defined(__ATOMIC_RELAXED)
-#undef GPR_GCC_ATOMIC
-#define GPR_GCC_SYNC 1
-#endif
-
-/* Validate platform combinations */
-#if defined(GPR_GCC_ATOMIC) + defined(GPR_GCC_SYNC) + \
- defined(GPR_WIN32_ATOMIC) != \
- 1
-#error Must define exactly one of GPR_GCC_ATOMIC, GPR_GCC_SYNC, GPR_WIN32_ATOMIC
-#endif
-
-#if defined(GPR_ARCH_32) + defined(GPR_ARCH_64) != 1
-#error Must define exactly one of GPR_ARCH_32, GPR_ARCH_64
-#endif
-
-#if defined(GPR_CPU_LINUX) + defined(GPR_CPU_POSIX) + defined(GPR_WIN32) + \
- defined(GPR_CPU_IPHONE) + defined(GPR_CPU_CUSTOM) != \
- 1
-#error Must define exactly one of GPR_CPU_LINUX, GPR_CPU_POSIX, GPR_WIN32, GPR_CPU_IPHONE, GPR_CPU_CUSTOM
-#endif
-
-#if defined(GPR_POSIX_MULTIPOLL_WITH_POLL) && !defined(GPR_POSIX_SOCKET)
-#error Must define GPR_POSIX_SOCKET to use GPR_POSIX_MULTIPOLL_WITH_POLL
-#endif
-
-#if defined(GPR_POSIX_SOCKET) + defined(GPR_WINSOCK_SOCKET) + \
- defined(GPR_CUSTOM_SOCKET) != \
- 1
-#error Must define exactly one of GPR_POSIX_SOCKET, GPR_WINSOCK_SOCKET, GPR_CUSTOM_SOCKET
-#endif
-
-#if defined(GPR_MSVC_TLS) + defined(GPR_GCC_TLS) + defined(GPR_PTHREAD_TLS) + \
- defined(GPR_CUSTOM_TLS) != \
- 1
-#error Must define exactly one of GPR_MSVC_TLS, GPR_GCC_TLS, GPR_PTHREAD_TLS, GPR_CUSTOM_TLS
-#endif
-
-/* maximum alignment needed for any type on this platform, rounded up to a
- power of two */
-#define GPR_MAX_ALIGNMENT 16
-
-#ifndef GRPC_MUST_USE_RESULT
-#ifdef __GNUC__
-#define GRPC_MUST_USE_RESULT __attribute__((warn_unused_result))
-#else
-#define GRPC_MUST_USE_RESULT
-#endif
-#endif
-
-#if GPR_FORBID_UNREACHABLE_CODE
-#define GPR_UNREACHABLE_CODE(STATEMENT)
-#else
-#define GPR_UNREACHABLE_CODE(STATEMENT) \
- do { \
- gpr_log(GPR_ERROR, "Should never reach here."); \
- abort(); \
- STATEMENT; \
- } while (0)
-#endif /* GPR_FORBID_UNREACHABLE_CODE */
+#include <grpc/impl/codegen/port_platform.h>
#endif /* GRPC_SUPPORT_PORT_PLATFORM_H */
diff --git a/include/grpc/support/time.h b/include/grpc/support/time.h
index d2607f3e95..2c7f8533a2 100644
--- a/include/grpc/support/time.h
+++ b/include/grpc/support/time.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,96 +33,7 @@
#ifndef GRPC_SUPPORT_TIME_H
#define GRPC_SUPPORT_TIME_H
-/* Time support.
- We use gpr_timespec, which is analogous to struct timespec. On some
- machines, absolute times may be in local time. */
-#include <grpc/support/port_platform.h>
-#include <stddef.h>
-#include <time.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The clocks we support. */
-typedef enum {
- /* Monotonic clock. Epoch undefined. Always moves forwards. */
- GPR_CLOCK_MONOTONIC = 0,
- /* Realtime clock. May jump forwards or backwards. Settable by
- the system administrator. Has its epoch at 0:00:00 UTC 1 Jan 1970. */
- GPR_CLOCK_REALTIME,
- /* CPU cycle time obtained by rdtsc instruction on x86 platforms. Epoch
- undefined. Degrades to GPR_CLOCK_REALTIME on other platforms. */
- GPR_CLOCK_PRECISE,
- /* Unmeasurable clock type: no base, created by taking the difference
- between two times */
- GPR_TIMESPAN
-} gpr_clock_type;
-
-typedef struct gpr_timespec {
- int64_t tv_sec;
- int32_t tv_nsec;
- /** Against which clock was this time measured? (or GPR_TIMESPAN if
- this is a relative time meaure) */
- gpr_clock_type clock_type;
-} gpr_timespec;
-
-/* Time constants. */
-gpr_timespec gpr_time_0(gpr_clock_type type); /* The zero time interval. */
-gpr_timespec gpr_inf_future(gpr_clock_type type); /* The far future */
-gpr_timespec gpr_inf_past(gpr_clock_type type); /* The far past. */
-
-#define GPR_MS_PER_SEC 1000
-#define GPR_US_PER_SEC 1000000
-#define GPR_NS_PER_SEC 1000000000
-#define GPR_NS_PER_MS 1000000
-#define GPR_NS_PER_US 1000
-#define GPR_US_PER_MS 1000
-
-/* initialize time subsystem */
-void gpr_time_init(void);
-
-/* Return the current time measured from the given clocks epoch. */
-gpr_timespec gpr_now(gpr_clock_type clock);
-
-/* Convert a timespec from one clock to another */
-gpr_timespec gpr_convert_clock_type(gpr_timespec t,
- gpr_clock_type target_clock);
-
-/* Return -ve, 0, or +ve according to whether a < b, a == b, or a > b
- respectively. */
-int gpr_time_cmp(gpr_timespec a, gpr_timespec b);
-
-gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b);
-gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b);
-
-/* Add and subtract times. Calculations saturate at infinities. */
-gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b);
-gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b);
-
-/* Return a timespec representing a given number of time units. LONG_MIN is
- interpreted as gpr_inf_past, and LONG_MAX as gpr_inf_future. */
-gpr_timespec gpr_time_from_micros(long x, gpr_clock_type clock_type);
-gpr_timespec gpr_time_from_nanos(long x, gpr_clock_type clock_type);
-gpr_timespec gpr_time_from_millis(long x, gpr_clock_type clock_type);
-gpr_timespec gpr_time_from_seconds(long x, gpr_clock_type clock_type);
-gpr_timespec gpr_time_from_minutes(long x, gpr_clock_type clock_type);
-gpr_timespec gpr_time_from_hours(long x, gpr_clock_type clock_type);
-
-int32_t gpr_time_to_millis(gpr_timespec timespec);
-
-/* Return 1 if two times are equal or within threshold of each other,
- 0 otherwise */
-int gpr_time_similar(gpr_timespec a, gpr_timespec b, gpr_timespec threshold);
-
-/* Sleep until at least 'until' - an absolute timeout */
-void gpr_sleep_until(gpr_timespec until);
-
-double gpr_timespec_to_micros(gpr_timespec t);
-
-#ifdef __cplusplus
-}
-#endif
+#include <grpc/impl/codegen/time.h>
#endif /* GRPC_SUPPORT_TIME_H */
diff --git a/package.json b/package.json
index 0b87f6a59d..a683ec33e4 100644
--- a/package.json
+++ b/package.json
@@ -393,6 +393,9 @@
"include/grpc/support/tls_msvc.h",
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
+ "include/grpc/impl/codegen/connectivity_state.h",
+ "include/grpc/impl/codegen/port_platform.h",
+ "include/grpc/impl/codegen/time.h",
"src/core/profiling/timers.h",
"src/core/support/block_annotate.h",
"src/core/support/env.h",
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index 3c8ca8ab45..c491eb88c8 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -123,7 +123,6 @@ grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
"\n"
"namespace grpc {\n"
"class CompletionQueue;\n"
- "class Channel;\n"
"class RpcService;\n"
"class ServerCompletionQueue;\n"
"class ServerContext;\n"
@@ -491,39 +490,186 @@ void PrintHeaderServerMethodAsync(
grpc_cpp_generator::ClassName(method->input_type(), true);
(*vars)["Response"] =
grpc_cpp_generator::ClassName(method->output_type(), true);
+ printer->Print(*vars, "template <class BaseClass>\n");
+ printer->Print(*vars,
+ "class WithAsyncMethod_$Method$ : public BaseClass {\n");
+ printer->Print(
+ " private:\n"
+ " void BaseClassMustBeDerivedFromService(Service *service) {}\n");
+ printer->Print(" public:\n");
+ printer->Indent();
+ printer->Print(*vars,
+ "WithAsyncMethod_$Method$() {\n"
+ " ::grpc::Service::MarkMethodAsync($Idx$);\n"
+ "}\n");
+ printer->Print(*vars,
+ "~WithAsyncMethod_$Method$() GRPC_OVERRIDE {\n"
+ " BaseClassMustBeDerivedFromService(this);\n"
+ "}\n");
if (NoStreaming(method)) {
printer->Print(
*vars,
+ "// disable synchronous version of this method\n"
+ "::grpc::Status $Method$("
+ "::grpc::ServerContext* context, const $Request$* request, "
+ "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n"
+ " abort();\n"
+ " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+ "}\n");
+ printer->Print(
+ *vars,
"void Request$Method$("
"::grpc::ServerContext* context, $Request$* request, "
"::grpc::ServerAsyncResponseWriter< $Response$>* response, "
"::grpc::CompletionQueue* new_call_cq, "
- "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
+ "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
+ printer->Print(*vars,
+ " ::grpc::Service::RequestAsyncUnary($Idx$, context, "
+ "request, response, new_call_cq, notification_cq, tag);\n");
+ printer->Print("}\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(
*vars,
+ "// disable synchronous version of this method\n"
+ "::grpc::Status $Method$("
+ "::grpc::ServerContext* context, "
+ "::grpc::ServerReader< $Request$>* reader, "
+ "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n"
+ " abort();\n"
+ " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+ "}\n");
+ printer->Print(
+ *vars,
"void Request$Method$("
"::grpc::ServerContext* context, "
"::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
"::grpc::CompletionQueue* new_call_cq, "
- "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
+ "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
+ printer->Print(*vars,
+ " ::grpc::Service::RequestAsyncClientStreaming($Idx$, "
+ "context, reader, new_call_cq, notification_cq, tag);\n");
+ printer->Print("}\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
+ "// disable synchronous version of this method\n"
+ "::grpc::Status $Method$("
+ "::grpc::ServerContext* context, const $Request$* request, "
+ "::grpc::ServerWriter< $Response$>* writer) GRPC_FINAL GRPC_OVERRIDE "
+ "{\n"
+ " abort();\n"
+ " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+ "}\n");
+ printer->Print(
+ *vars,
"void Request$Method$("
"::grpc::ServerContext* context, $Request$* request, "
"::grpc::ServerAsyncWriter< $Response$>* writer, "
"::grpc::CompletionQueue* new_call_cq, "
- "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
+ "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
+ printer->Print(
+ *vars,
+ " ::grpc::Service::RequestAsyncServerStreaming($Idx$, "
+ "context, request, writer, new_call_cq, notification_cq, tag);\n");
+ printer->Print("}\n");
} else if (BidiStreaming(method)) {
printer->Print(
*vars,
+ "// disable synchronous version of this method\n"
+ "::grpc::Status $Method$("
+ "::grpc::ServerContext* context, "
+ "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
+ "GRPC_FINAL GRPC_OVERRIDE {\n"
+ " abort();\n"
+ " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+ "}\n");
+ printer->Print(
+ *vars,
"void Request$Method$("
"::grpc::ServerContext* context, "
"::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
"::grpc::CompletionQueue* new_call_cq, "
- "::grpc::ServerCompletionQueue* notification_cq, void *tag);\n");
+ "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
+ printer->Print(*vars,
+ " ::grpc::Service::RequestAsyncBidiStreaming($Idx$, "
+ "context, stream, new_call_cq, notification_cq, tag);\n");
+ printer->Print("}\n");
}
+ printer->Outdent();
+ printer->Print(*vars, "};\n");
+}
+
+void PrintHeaderServerMethodGeneric(
+ grpc::protobuf::io::Printer *printer,
+ const grpc::protobuf::MethodDescriptor *method,
+ std::map<grpc::string, grpc::string> *vars) {
+ (*vars)["Method"] = method->name();
+ (*vars)["Request"] =
+ grpc_cpp_generator::ClassName(method->input_type(), true);
+ (*vars)["Response"] =
+ grpc_cpp_generator::ClassName(method->output_type(), true);
+ printer->Print(*vars, "template <class BaseClass>\n");
+ printer->Print(*vars,
+ "class WithGenericMethod_$Method$ : public BaseClass {\n");
+ printer->Print(
+ " private:\n"
+ " void BaseClassMustBeDerivedFromService(Service *service) {}\n");
+ printer->Print(" public:\n");
+ printer->Indent();
+ printer->Print(*vars,
+ "WithGenericMethod_$Method$() {\n"
+ " ::grpc::Service::MarkMethodGeneric($Idx$);\n"
+ "}\n");
+ printer->Print(*vars,
+ "~WithGenericMethod_$Method$() GRPC_OVERRIDE {\n"
+ " BaseClassMustBeDerivedFromService(this);\n"
+ "}\n");
+ if (NoStreaming(method)) {
+ printer->Print(
+ *vars,
+ "// disable synchronous version of this method\n"
+ "::grpc::Status $Method$("
+ "::grpc::ServerContext* context, const $Request$* request, "
+ "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n"
+ " abort();\n"
+ " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+ "}\n");
+ } else if (ClientOnlyStreaming(method)) {
+ printer->Print(
+ *vars,
+ "// disable synchronous version of this method\n"
+ "::grpc::Status $Method$("
+ "::grpc::ServerContext* context, "
+ "::grpc::ServerReader< $Request$>* reader, "
+ "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n"
+ " abort();\n"
+ " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+ "}\n");
+ } else if (ServerOnlyStreaming(method)) {
+ printer->Print(
+ *vars,
+ "// disable synchronous version of this method\n"
+ "::grpc::Status $Method$("
+ "::grpc::ServerContext* context, const $Request$* request, "
+ "::grpc::ServerWriter< $Response$>* writer) GRPC_FINAL GRPC_OVERRIDE "
+ "{\n"
+ " abort();\n"
+ " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+ "}\n");
+ } else if (BidiStreaming(method)) {
+ printer->Print(
+ *vars,
+ "// disable synchronous version of this method\n"
+ "::grpc::Status $Method$("
+ "::grpc::ServerContext* context, "
+ "::grpc::ServerReaderWriter< $Response$, $Request$>* stream) "
+ "GRPC_FINAL GRPC_OVERRIDE {\n"
+ " abort();\n"
+ " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+ "}\n");
+ }
+ printer->Outdent();
+ printer->Print(*vars, "};\n");
}
void PrintHeaderService(grpc::protobuf::io::Printer *printer,
@@ -557,14 +703,14 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer,
"class Stub GRPC_FINAL : public StubInterface"
" {\n public:\n");
printer->Indent();
- printer->Print("Stub(const std::shared_ptr< ::grpc::Channel>& channel);\n");
+ printer->Print("Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);\n");
for (int i = 0; i < service->method_count(); ++i) {
PrintHeaderClientMethod(printer, service->method(i), vars, true);
}
printer->Outdent();
printer->Print("\n private:\n");
printer->Indent();
- printer->Print("std::shared_ptr< ::grpc::Channel> channel_;\n");
+ printer->Print("std::shared_ptr< ::grpc::ChannelInterface> channel_;\n");
for (int i = 0; i < service->method_count(); ++i) {
PrintHeaderClientMethod(printer, service->method(i), vars, false);
}
@@ -575,14 +721,14 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer,
printer->Print("};\n");
printer->Print(
"static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
- "::grpc::Channel>& channel, "
+ "::grpc::ChannelInterface>& channel, "
"const ::grpc::StubOptions& options = ::grpc::StubOptions());\n");
printer->Print("\n");
- // Server side - Synchronous
+ // Server side - base
printer->Print(
- "class Service : public ::grpc::SynchronousService {\n"
+ "class Service : public ::grpc::Service {\n"
" public:\n");
printer->Indent();
printer->Print("Service();\n");
@@ -590,26 +736,32 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer,
for (int i = 0; i < service->method_count(); ++i) {
PrintHeaderServerMethodSync(printer, service->method(i), vars);
}
- printer->Print("::grpc::RpcService* service() GRPC_OVERRIDE GRPC_FINAL;\n");
printer->Outdent();
- printer->Print(
- " private:\n"
- " std::unique_ptr< ::grpc::RpcService> service_;\n");
printer->Print("};\n");
// Server side - Asynchronous
- printer->Print(
- "class AsyncService GRPC_FINAL : public ::grpc::AsynchronousService {\n"
- " public:\n");
- printer->Indent();
- (*vars)["MethodCount"] = as_string(service->method_count());
- printer->Print("explicit AsyncService();\n");
- printer->Print("~AsyncService() {};\n");
for (int i = 0; i < service->method_count(); ++i) {
+ (*vars)["Idx"] = as_string(i);
PrintHeaderServerMethodAsync(printer, service->method(i), vars);
}
- printer->Outdent();
- printer->Print("};\n");
+
+ printer->Print("typedef ");
+
+ for (int i = 0; i < service->method_count(); ++i) {
+ (*vars)["method_name"] = service->method(i)->name();
+ printer->Print(*vars, "WithAsyncMethod_$method_name$<");
+ }
+ printer->Print("Service");
+ for (int i = 0; i < service->method_count(); ++i) {
+ printer->Print(" >");
+ }
+ printer->Print(" AsyncService;\n");
+
+ // Server side - Generic
+ for (int i = 0; i < service->method_count(); ++i) {
+ (*vars)["Idx"] = as_string(i);
+ PrintHeaderServerMethodGeneric(printer, service->method(i), vars);
+ }
printer->Outdent();
printer->Print("};\n");
@@ -623,6 +775,12 @@ grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
grpc::protobuf::io::StringOutputStream output_stream(&output);
grpc::protobuf::io::Printer printer(&output_stream, '$');
std::map<grpc::string, grpc::string> vars;
+ // Package string is empty or ends with a dot. It is used to fully qualify
+ // method names.
+ vars["Package"] = file->package();
+ if (!file->package().empty()) {
+ vars["Package"].append(".");
+ }
if (!params.services_namespace.empty()) {
vars["services_namespace"] = params.services_namespace;
@@ -702,10 +860,11 @@ grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
grpc::protobuf::io::Printer printer(&output_stream, '$');
std::map<grpc::string, grpc::string> vars;
- printer.Print(vars, "#include <grpc++/channel.h>\n");
printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/method_handler_impl.h>\n");
printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/codegen/channel_interface.h>\n");
printer.Print(vars, "#include <grpc++/support/async_unary_call.h>\n");
printer.Print(vars, "#include <grpc++/support/async_stream.h>\n");
printer.Print(vars, "#include <grpc++/support/sync_stream.h>\n");
@@ -889,69 +1048,6 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer,
}
}
-void PrintSourceServerAsyncMethod(
- grpc::protobuf::io::Printer *printer,
- const grpc::protobuf::MethodDescriptor *method,
- std::map<grpc::string, grpc::string> *vars) {
- (*vars)["Method"] = method->name();
- (*vars)["Request"] =
- grpc_cpp_generator::ClassName(method->input_type(), true);
- (*vars)["Response"] =
- grpc_cpp_generator::ClassName(method->output_type(), true);
- if (NoStreaming(method)) {
- printer->Print(
- *vars,
- "void $ns$$Service$::AsyncService::Request$Method$("
- "::grpc::ServerContext* context, "
- "$Request$* request, "
- "::grpc::ServerAsyncResponseWriter< $Response$>* response, "
- "::grpc::CompletionQueue* new_call_cq, "
- "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
- printer->Print(*vars,
- " AsynchronousService::RequestAsyncUnary($Idx$, context, "
- "request, response, new_call_cq, notification_cq, tag);\n");
- printer->Print("}\n\n");
- } else if (ClientOnlyStreaming(method)) {
- printer->Print(
- *vars,
- "void $ns$$Service$::AsyncService::Request$Method$("
- "::grpc::ServerContext* context, "
- "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, "
- "::grpc::CompletionQueue* new_call_cq, "
- "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
- printer->Print(*vars,
- " AsynchronousService::RequestClientStreaming($Idx$, "
- "context, reader, new_call_cq, notification_cq, tag);\n");
- printer->Print("}\n\n");
- } else if (ServerOnlyStreaming(method)) {
- printer->Print(
- *vars,
- "void $ns$$Service$::AsyncService::Request$Method$("
- "::grpc::ServerContext* context, "
- "$Request$* request, "
- "::grpc::ServerAsyncWriter< $Response$>* writer, "
- "::grpc::CompletionQueue* new_call_cq, "
- "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
- printer->Print(
- *vars,
- " AsynchronousService::RequestServerStreaming($Idx$, "
- "context, request, writer, new_call_cq, notification_cq, tag);\n");
- printer->Print("}\n\n");
- } else if (BidiStreaming(method)) {
- printer->Print(
- *vars,
- "void $ns$$Service$::AsyncService::Request$Method$("
- "::grpc::ServerContext* context, "
- "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, "
- "::grpc::CompletionQueue* new_call_cq, "
- "::grpc::ServerCompletionQueue* notification_cq, void *tag) {\n");
- printer->Print(*vars,
- " AsynchronousService::RequestBidiStreaming($Idx$, "
- "context, stream, new_call_cq, notification_cq, tag);\n");
- printer->Print("}\n\n");
- }
-}
-
void PrintSourceService(grpc::protobuf::io::Printer *printer,
const grpc::protobuf::ServiceDescriptor *service,
std::map<grpc::string, grpc::string> *vars) {
@@ -967,7 +1063,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
printer->Print(*vars,
"std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub("
- "const std::shared_ptr< ::grpc::Channel>& channel, "
+ "const std::shared_ptr< ::grpc::ChannelInterface>& channel, "
"const ::grpc::StubOptions& options) {\n"
" std::unique_ptr< $ns$$Service$::Stub> stub(new "
"$ns$$Service$::Stub(channel));\n"
@@ -975,7 +1071,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
"}\n\n");
printer->Print(*vars,
"$ns$$Service$::Stub::Stub(const std::shared_ptr< "
- "::grpc::Channel>& channel)\n");
+ "::grpc::ChannelInterface>& channel)\n");
printer->Indent();
printer->Print(": channel_(channel)");
for (int i = 0; i < service->method_count(); ++i) {
@@ -1006,32 +1102,8 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
PrintSourceClientMethod(printer, service->method(i), vars);
}
- (*vars)["MethodCount"] = as_string(service->method_count());
- printer->Print(*vars,
- "$ns$$Service$::AsyncService::AsyncService() : "
- "::grpc::AsynchronousService("
- "$prefix$$Service$_method_names, $MethodCount$) "
- "{}\n\n");
-
- printer->Print(*vars,
- "$ns$$Service$::Service::Service() {\n"
- "}\n\n");
- printer->Print(*vars,
- "$ns$$Service$::Service::~Service() {\n"
- "}\n\n");
- for (int i = 0; i < service->method_count(); ++i) {
- (*vars)["Idx"] = as_string(i);
- PrintSourceServerMethod(printer, service->method(i), vars);
- PrintSourceServerAsyncMethod(printer, service->method(i), vars);
- }
- printer->Print(*vars,
- "::grpc::RpcService* $ns$$Service$::Service::service() {\n");
+ printer->Print(*vars, "$ns$$Service$::Service::Service() {\n");
printer->Indent();
- printer->Print(
- "if (service_) {\n"
- " return service_.get();\n"
- "}\n");
- printer->Print("service_ = std::unique_ptr< ::grpc::RpcService>(new ::grpc::RpcService());\n");
for (int i = 0; i < service->method_count(); ++i) {
const grpc::protobuf::MethodDescriptor *method = service->method(i);
(*vars)["Idx"] = as_string(i);
@@ -1043,7 +1115,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
if (NoStreaming(method)) {
printer->Print(
*vars,
- "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
+ "AddMethod(new ::grpc::RpcServiceMethod(\n"
" $prefix$$Service$_method_names[$Idx$],\n"
" ::grpc::RpcMethod::NORMAL_RPC,\n"
" new ::grpc::RpcMethodHandler< $ns$$Service$::Service, "
@@ -1053,7 +1125,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
} else if (ClientOnlyStreaming(method)) {
printer->Print(
*vars,
- "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
+ "AddMethod(new ::grpc::RpcServiceMethod(\n"
" $prefix$$Service$_method_names[$Idx$],\n"
" ::grpc::RpcMethod::CLIENT_STREAMING,\n"
" new ::grpc::ClientStreamingHandler< "
@@ -1062,7 +1134,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
- "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
+ "AddMethod(new ::grpc::RpcServiceMethod(\n"
" $prefix$$Service$_method_names[$Idx$],\n"
" ::grpc::RpcMethod::SERVER_STREAMING,\n"
" new ::grpc::ServerStreamingHandler< "
@@ -1071,7 +1143,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
} else if (BidiStreaming(method)) {
printer->Print(
*vars,
- "service_->AddMethod(new ::grpc::RpcServiceMethod(\n"
+ "AddMethod(new ::grpc::RpcServiceMethod(\n"
" $prefix$$Service$_method_names[$Idx$],\n"
" ::grpc::RpcMethod::BIDI_STREAMING,\n"
" new ::grpc::BidiStreamingHandler< "
@@ -1079,9 +1151,15 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
}
}
- printer->Print("return service_.get();\n");
printer->Outdent();
- printer->Print("}\n\n");
+ printer->Print(*vars, "}\n\n");
+ printer->Print(*vars,
+ "$ns$$Service$::Service::~Service() {\n"
+ "}\n\n");
+ for (int i = 0; i < service->method_count(); ++i) {
+ (*vars)["Idx"] = as_string(i);
+ PrintSourceServerMethod(printer, service->method(i), vars);
+ }
}
grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index c754ae299b..4fd5dfbecb 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -42,7 +42,6 @@
#include <tuple>
#include <vector>
-#include <grpc++/support/config.h>
#include "src/compiler/config.h"
#include "src/compiler/generator_helpers.h"
#include "src/compiler/python_generator.h"
diff --git a/src/cpp/client/channel.cc b/src/cpp/client/channel.cc
index c7974d655b..f9bedbd0b5 100644
--- a/src/cpp/client/channel.cc
+++ b/src/cpp/client/channel.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,6 +43,7 @@
#include <grpc++/security/credentials.h>
#include <grpc++/impl/call.h>
#include <grpc++/impl/rpc_method.h>
+#include <grpc++/impl/codegen/completion_queue_tag.h>
#include <grpc++/support/channel_arguments.h>
#include <grpc++/support/config.h>
#include <grpc++/support/status.h>
diff --git a/src/cpp/common/completion_queue.cc b/src/cpp/common/completion_queue.cc
index a175beb452..6ef77fcfff 100644
--- a/src/cpp/common/completion_queue.cc
+++ b/src/cpp/common/completion_queue.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,7 @@
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include <grpc++/support/time.h>
+#include <grpc++/impl/codegen/completion_queue_tag.h>
namespace grpc {
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index 878775bbee..1a041133bd 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,8 +40,10 @@
#include <grpc/support/log.h>
#include <grpc++/completion_queue.h>
#include <grpc++/generic/async_generic_service.h>
+#include <grpc++/impl/method_handler_impl.h>
#include <grpc++/impl/rpc_service_method.h>
#include <grpc++/impl/service_type.h>
+#include <grpc++/impl/codegen/completion_queue_tag.h>
#include <grpc++/server_context.h>
#include <grpc++/security/server_credentials.h>
#include <grpc++/support/time.h>
@@ -296,6 +298,8 @@ Server::~Server() {
if (started_ && !shutdown_) {
lock.unlock();
Shutdown();
+ } else if (!started_) {
+ cq_.Shutdown();
}
}
void* got_tag;
@@ -314,36 +318,31 @@ void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) {
g_callbacks = callbacks;
}
-bool Server::RegisterService(const grpc::string* host, RpcService* service) {
- for (int i = 0; i < service->GetMethodCount(); ++i) {
- RpcServiceMethod* method = service->GetMethod(i);
+bool Server::RegisterService(const grpc::string* host, Service* service) {
+ bool has_async_methods = service->has_async_methods();
+ if (has_async_methods) {
+ GPR_ASSERT(service->server_ == nullptr &&
+ "Can only register an asynchronous service against one server.");
+ service->server_ = this;
+ }
+ for (auto it = service->methods_.begin(); it != service->methods_.end();
+ ++it) {
+ if (it->get() == nullptr) { // Handled by generic service if any.
+ continue;
+ }
+ RpcServiceMethod* method = it->get();
void* tag = grpc_server_register_method(server_, method->name(),
host ? host->c_str() : nullptr);
- if (!tag) {
+ if (tag == nullptr) {
gpr_log(GPR_DEBUG, "Attempt to register %s multiple times",
method->name());
return false;
}
- sync_methods_->emplace_back(method, tag);
- }
- return true;
-}
-
-bool Server::RegisterAsyncService(const grpc::string* host,
- AsynchronousService* service) {
- GPR_ASSERT(service->server_ == nullptr &&
- "Can only register an asynchronous service against one server.");
- service->server_ = this;
- service->request_args_ = new void* [service->method_count_];
- for (size_t i = 0; i < service->method_count_; ++i) {
- void* tag = grpc_server_register_method(server_, service->method_names_[i],
- host ? host->c_str() : nullptr);
- if (!tag) {
- gpr_log(GPR_DEBUG, "Attempt to register %s multiple times",
- service->method_names_[i]);
- return false;
+ if (method->handler() == nullptr) {
+ method->set_server_tag(tag);
+ } else {
+ sync_methods_->emplace_back(method, tag);
}
- service->request_args_[i] = tag;
}
return true;
}
@@ -439,8 +438,8 @@ void Server::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) {
GPR_ASSERT(GRPC_CALL_OK == result);
}
-Server::BaseAsyncRequest::BaseAsyncRequest(
- Server* server, ServerContext* context,
+ServerInterface::BaseAsyncRequest::BaseAsyncRequest(
+ ServerInterface* server, ServerContext* context,
ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, void* tag,
bool delete_on_finalize)
: server_(server),
@@ -453,9 +452,8 @@ Server::BaseAsyncRequest::BaseAsyncRequest(
memset(&initial_metadata_array_, 0, sizeof(initial_metadata_array_));
}
-Server::BaseAsyncRequest::~BaseAsyncRequest() {}
-
-bool Server::BaseAsyncRequest::FinalizeResult(void** tag, bool* status) {
+bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag,
+ bool* status) {
if (*status) {
for (size_t i = 0; i < initial_metadata_array_.count; i++) {
context_->client_metadata_.insert(
@@ -469,7 +467,7 @@ bool Server::BaseAsyncRequest::FinalizeResult(void** tag, bool* status) {
grpc_metadata_array_destroy(&initial_metadata_array_);
context_->set_call(call_);
context_->cq_ = call_cq_;
- Call call(call_, server_, call_cq_, server_->max_message_size_);
+ Call call(call_, server_, call_cq_, server_->max_message_size());
if (*status && call_) {
context_->BeginCompletionOp(&call);
}
@@ -482,22 +480,22 @@ bool Server::BaseAsyncRequest::FinalizeResult(void** tag, bool* status) {
return true;
}
-Server::RegisteredAsyncRequest::RegisteredAsyncRequest(
- Server* server, ServerContext* context,
+ServerInterface::RegisteredAsyncRequest::RegisteredAsyncRequest(
+ ServerInterface* server, ServerContext* context,
ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, void* tag)
: BaseAsyncRequest(server, context, stream, call_cq, tag, true) {}
-void Server::RegisteredAsyncRequest::IssueRequest(
+void ServerInterface::RegisteredAsyncRequest::IssueRequest(
void* registered_method, grpc_byte_buffer** payload,
ServerCompletionQueue* notification_cq) {
grpc_server_request_registered_call(
- server_->server_, registered_method, &call_, &context_->deadline_,
+ server_->server(), registered_method, &call_, &context_->deadline_,
&initial_metadata_array_, payload, call_cq_->cq(), notification_cq->cq(),
this);
}
-Server::GenericAsyncRequest::GenericAsyncRequest(
- Server* server, GenericServerContext* context,
+ServerInterface::GenericAsyncRequest::GenericAsyncRequest(
+ ServerInterface* server, GenericServerContext* context,
ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize)
: BaseAsyncRequest(server, context, stream, call_cq, tag,
@@ -505,12 +503,13 @@ Server::GenericAsyncRequest::GenericAsyncRequest(
grpc_call_details_init(&call_details_);
GPR_ASSERT(notification_cq);
GPR_ASSERT(call_cq);
- grpc_server_request_call(server->server_, &call_, &call_details_,
+ grpc_server_request_call(server->server(), &call_, &call_details_,
&initial_metadata_array_, call_cq->cq(),
notification_cq->cq(), this);
}
-bool Server::GenericAsyncRequest::FinalizeResult(void** tag, bool* status) {
+bool ServerInterface::GenericAsyncRequest::FinalizeResult(void** tag,
+ bool* status) {
// TODO(yangg) remove the copy here.
if (*status) {
static_cast<GenericServerContext*>(context_)->method_ =
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index 26c0724a30..a8c188e5a5 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,7 +43,7 @@
namespace grpc {
ServerBuilder::ServerBuilder()
- : max_message_size_(-1), generic_service_(nullptr), thread_pool_(nullptr) {
+ : max_message_size_(-1), generic_service_(nullptr) {
grpc_compression_options_init(&compression_options_);
}
@@ -53,24 +53,13 @@ std::unique_ptr<ServerCompletionQueue> ServerBuilder::AddCompletionQueue() {
return std::unique_ptr<ServerCompletionQueue>(cq);
}
-void ServerBuilder::RegisterService(SynchronousService* service) {
- services_.emplace_back(new NamedService<RpcService>(service->service()));
-}
-
-void ServerBuilder::RegisterAsyncService(AsynchronousService* service) {
- async_services_.emplace_back(new NamedService<AsynchronousService>(service));
+void ServerBuilder::RegisterService(Service* service) {
+ services_.emplace_back(new NamedService(service));
}
void ServerBuilder::RegisterService(const grpc::string& addr,
- SynchronousService* service) {
- services_.emplace_back(
- new NamedService<RpcService>(addr, service->service()));
-}
-
-void ServerBuilder::RegisterAsyncService(const grpc::string& addr,
- AsynchronousService* service) {
- async_services_.emplace_back(
- new NamedService<AsynchronousService>(addr, service));
+ Service* service) {
+ services_.emplace_back(new NamedService(addr, service));
}
void ServerBuilder::RegisterAsyncGenericService(AsyncGenericService* service) {
@@ -96,14 +85,14 @@ void ServerBuilder::AddListeningPort(const grpc::string& addr,
}
std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
- bool thread_pool_owned = false;
- if (!async_services_.empty() && !services_.empty()) {
- gpr_log(GPR_ERROR, "Mixing async and sync services is unsupported for now");
- return nullptr;
- }
- if (!thread_pool_ && !services_.empty()) {
- thread_pool_ = CreateDefaultThreadPool();
- thread_pool_owned = true;
+ std::unique_ptr<ThreadPoolInterface> thread_pool;
+ for (auto it = services_.begin(); it != services_.end(); ++it) {
+ if ((*it)->service->has_synchronous_methods()) {
+ if (thread_pool == nullptr) {
+ thread_pool.reset(CreateDefaultThreadPool());
+ break;
+ }
+ }
}
ChannelArguments args;
for (auto option = options_.begin(); option != options_.end(); ++option) {
@@ -115,7 +104,7 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
args.SetInt(GRPC_COMPRESSION_ALGORITHM_STATE_ARG,
compression_options_.enabled_algorithms_bitset);
std::unique_ptr<Server> server(
- new Server(thread_pool_, thread_pool_owned, max_message_size_, args));
+ new Server(thread_pool.release(), true, max_message_size_, args));
for (auto cq = cqs_.begin(); cq != cqs_.end(); ++cq) {
grpc_server_register_completion_queue(server->server_, (*cq)->cq(),
nullptr);
@@ -126,15 +115,17 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
return nullptr;
}
}
- for (auto service = async_services_.begin(); service != async_services_.end();
- service++) {
- if (!server->RegisterAsyncService((*service)->host.get(),
- (*service)->service)) {
- return nullptr;
- }
- }
if (generic_service_) {
server->RegisterAsyncGenericService(generic_service_);
+ } else {
+ for (auto it = services_.begin(); it != services_.end(); ++it) {
+ if ((*it)->service->has_generic_methods()) {
+ gpr_log(GPR_ERROR,
+ "Some methods were marked generic but there is no "
+ "generic service registered.");
+ return nullptr;
+ }
+ }
}
for (auto port = ports_.begin(); port != ports_.end(); port++) {
int r = server->AddListeningPort(port->addr, port->creds.get());
diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index 1e1524d098..1e14ac3410 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -37,6 +37,9 @@
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
+#include <grpc/impl/codegen/connectivity_state.h>
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpc/impl/codegen/time.h>
#include <grpc/status.h>
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
diff --git a/test/cpp/common/alarm_test.cc b/test/cpp/common/alarm_test.cc
index d41a25a63c..09df6852a5 100644
--- a/test/cpp/common/alarm_test.cc
+++ b/test/cpp/common/alarm_test.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,7 @@
#include <grpc++/completion_queue.h>
#include <gtest/gtest.h>
+#include <grpc++/completion_queue.h>
#include "test/core/util/test_config.h"
namespace grpc {
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index cfda571326..0616cc07ee 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -180,21 +180,11 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<bool> {
int port = grpc_pick_unused_port_or_die();
server_address_ << "localhost:" << port;
- // It is currently unsupported to mix sync and async services
- // in the same server, so first test that (for coverage)
- ServerBuilder build_bad;
- build_bad.AddListeningPort(server_address_.str(),
- grpc::InsecureServerCredentials());
- build_bad.RegisterAsyncService(&service_);
- grpc::testing::EchoTestService::Service sync_service;
- build_bad.RegisterService(&sync_service);
- GPR_ASSERT(build_bad.BuildAndStart() == nullptr);
-
// Setup server
ServerBuilder builder;
builder.AddListeningPort(server_address_.str(),
grpc::InsecureServerCredentials());
- builder.RegisterAsyncService(&service_);
+ builder.RegisterService(&service_);
cq_ = builder.AddCompletionQueue();
server_ = builder.BuildAndStart();
}
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index f8027bcf0b..58b20e61c9 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -54,6 +54,7 @@
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
+#include "test/cpp/end2end/test_service_impl.h"
#include "test/cpp/util/string_ref_helper.h"
using grpc::testing::EchoRequest;
@@ -64,40 +65,6 @@ namespace grpc {
namespace testing {
namespace {
-const char* kServerCancelAfterReads = "cancel_after_reads";
-
-// When echo_deadline is requested, deadline seen in the ServerContext is set in
-// the response in seconds.
-void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
- EchoResponse* response) {
- if (request->has_param() && request->param().echo_deadline()) {
- gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
- if (context->deadline() != system_clock::time_point::max()) {
- Timepoint2Timespec(context->deadline(), &deadline);
- }
- response->mutable_param()->set_request_deadline(deadline.tv_sec);
- }
-}
-
-void CheckServerAuthContext(const ServerContext* context,
- const grpc::string& expected_client_identity) {
- std::shared_ptr<const AuthContext> auth_ctx = context->auth_context();
- std::vector<grpc::string_ref> ssl =
- auth_ctx->FindPropertyValues("transport_security_type");
- EXPECT_EQ(1u, ssl.size());
- EXPECT_EQ("ssl", ToString(ssl[0]));
- if (expected_client_identity.length() == 0) {
- EXPECT_TRUE(auth_ctx->GetPeerIdentityPropertyName().empty());
- EXPECT_TRUE(auth_ctx->GetPeerIdentity().empty());
- EXPECT_FALSE(auth_ctx->IsPeerAuthenticated());
- } else {
- auto identity = auth_ctx->GetPeerIdentity();
- EXPECT_TRUE(auth_ctx->IsPeerAuthenticated());
- EXPECT_EQ(1u, identity.size());
- EXPECT_EQ(expected_client_identity, identity[0]);
- }
-}
-
bool CheckIsLocalhost(const grpc::string& addr) {
const grpc::string kIpv6("ipv6:[::1]:");
const grpc::string kIpv4MappedIpv6("ipv6:[::ffff:127.0.0.1]:");
@@ -212,137 +179,6 @@ class Proxy : public ::grpc::testing::EchoTestService::Service {
std::unique_ptr< ::grpc::testing::EchoTestService::Stub> stub_;
};
-class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
- public:
- TestServiceImpl() : signal_client_(false), host_() {}
- explicit TestServiceImpl(const grpc::string& host)
- : signal_client_(false), host_(new grpc::string(host)) {}
-
- Status Echo(ServerContext* context, const EchoRequest* request,
- EchoResponse* response) GRPC_OVERRIDE {
- response->set_message(request->message());
- MaybeEchoDeadline(context, request, response);
- if (host_) {
- response->mutable_param()->set_host(*host_);
- }
- if (request->has_param() && request->param().client_cancel_after_us()) {
- {
- std::unique_lock<std::mutex> lock(mu_);
- signal_client_ = true;
- }
- while (!context->IsCancelled()) {
- gpr_sleep_until(gpr_time_add(
- gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_micros(request->param().client_cancel_after_us(),
- GPR_TIMESPAN)));
- }
- return Status::CANCELLED;
- } else if (request->has_param() &&
- request->param().server_cancel_after_us()) {
- gpr_sleep_until(gpr_time_add(
- gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_micros(request->param().server_cancel_after_us(),
- GPR_TIMESPAN)));
- return Status::CANCELLED;
- } else {
- EXPECT_FALSE(context->IsCancelled());
- }
-
- if (request->has_param() && request->param().echo_metadata()) {
- const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata =
- context->client_metadata();
- for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
- iter = client_metadata.begin();
- iter != client_metadata.end(); ++iter) {
- context->AddTrailingMetadata(ToString(iter->first),
- ToString(iter->second));
- }
- }
- if (request->has_param() &&
- (request->param().expected_client_identity().length() > 0 ||
- request->param().check_auth_context())) {
- CheckServerAuthContext(context,
- request->param().expected_client_identity());
- }
- if (request->has_param() &&
- request->param().response_message_length() > 0) {
- response->set_message(
- grpc::string(request->param().response_message_length(), '\0'));
- }
- if (request->has_param() && request->param().echo_peer()) {
- response->mutable_param()->set_peer(context->peer());
- }
- return Status::OK;
- }
-
- // Unimplemented is left unimplemented to test the returned error.
-
- Status RequestStream(ServerContext* context,
- ServerReader<EchoRequest>* reader,
- EchoResponse* response) GRPC_OVERRIDE {
- EchoRequest request;
- response->set_message("");
- int cancel_after_reads = 0;
- const std::multimap<grpc::string_ref, grpc::string_ref>&
- client_initial_metadata = context->client_metadata();
- if (client_initial_metadata.find(kServerCancelAfterReads) !=
- client_initial_metadata.end()) {
- std::istringstream iss(ToString(
- client_initial_metadata.find(kServerCancelAfterReads)->second));
- iss >> cancel_after_reads;
- gpr_log(GPR_INFO, "cancel_after_reads %d", cancel_after_reads);
- }
- while (reader->Read(&request)) {
- if (cancel_after_reads == 1) {
- gpr_log(GPR_INFO, "return cancel status");
- return Status::CANCELLED;
- } else if (cancel_after_reads > 0) {
- cancel_after_reads--;
- }
- response->mutable_message()->append(request.message());
- }
- return Status::OK;
- }
-
- // Return 3 messages.
- // TODO(yangg) make it generic by adding a parameter into EchoRequest
- Status ResponseStream(ServerContext* context, const EchoRequest* request,
- ServerWriter<EchoResponse>* writer) GRPC_OVERRIDE {
- EchoResponse response;
- response.set_message(request->message() + "0");
- writer->Write(response);
- response.set_message(request->message() + "1");
- writer->Write(response);
- response.set_message(request->message() + "2");
- writer->Write(response);
-
- return Status::OK;
- }
-
- Status BidiStream(ServerContext* context,
- ServerReaderWriter<EchoResponse, EchoRequest>* stream)
- GRPC_OVERRIDE {
- EchoRequest request;
- EchoResponse response;
- while (stream->Read(&request)) {
- gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
- response.set_message(request.message());
- stream->Write(response);
- }
- return Status::OK;
- }
-
- bool signal_client() {
- std::unique_lock<std::mutex> lock(mu_);
- return signal_client_;
- }
-
- private:
- bool signal_client_;
- std::mutex mu_;
- std::unique_ptr<grpc::string> host_;
-};
-
class TestServiceImplDupPkg
: public ::grpc::testing::duplicate::EchoTestService::Service {
public:
diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc
index c5d9de3f29..4e6d50ea80 100644
--- a/test/cpp/end2end/generic_end2end_test.cc
+++ b/test/cpp/end2end/generic_end2end_test.cc
@@ -51,6 +51,7 @@
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
+#include "test/cpp/util/byte_buffer_proto_helper.h"
using grpc::testing::EchoRequest;
using grpc::testing::EchoResponse;
@@ -70,29 +71,9 @@ void verify_ok(CompletionQueue* cq, int i, bool expect_ok) {
EXPECT_EQ(tag(i), got_tag);
}
-bool ParseFromByteBuffer(ByteBuffer* buffer, grpc::protobuf::Message* message) {
- std::vector<Slice> slices;
- buffer->Dump(&slices);
- grpc::string buf;
- buf.reserve(buffer->Length());
- for (auto s = slices.begin(); s != slices.end(); s++) {
- buf.append(reinterpret_cast<const char*>(s->begin()), s->size());
- }
- return message->ParseFromString(buf);
-}
-
-std::unique_ptr<ByteBuffer> SerializeToByteBuffer(
- grpc::protobuf::Message* message) {
- grpc::string buf;
- message->SerializeToString(&buf);
- gpr_slice s = gpr_slice_from_copied_string(buf.c_str());
- Slice slice(s, Slice::STEAL_REF);
- return std::unique_ptr<ByteBuffer>(new ByteBuffer(&slice, 1));
-}
-
class GenericEnd2endTest : public ::testing::Test {
protected:
- GenericEnd2endTest() : generic_service_("*"), server_host_("localhost") {}
+ GenericEnd2endTest() : server_host_("localhost") {}
void SetUp() GRPC_OVERRIDE {
int port = grpc_pick_unused_port_or_die();
diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc
new file mode 100644
index 0000000000..f8405627f9
--- /dev/null
+++ b/test/cpp/end2end/hybrid_end2end_test.cc
@@ -0,0 +1,556 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <memory>
+#include <thread>
+
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/generic/async_generic_service.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc/grpc.h>
+#include <gtest/gtest.h>
+
+#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+#include "test/cpp/end2end/test_service_impl.h"
+#include "test/cpp/util/byte_buffer_proto_helper.h"
+
+namespace grpc {
+namespace testing {
+
+namespace {
+
+void* tag(int i) { return (void*)(intptr_t)i; }
+
+bool VerifyReturnSuccess(CompletionQueue* cq, int i) {
+ void* got_tag;
+ bool ok;
+ EXPECT_TRUE(cq->Next(&got_tag, &ok));
+ EXPECT_EQ(tag(i), got_tag);
+ return ok;
+}
+
+void Verify(CompletionQueue* cq, int i, bool expect_ok) {
+ EXPECT_EQ(expect_ok, VerifyReturnSuccess(cq, i));
+}
+
+// Handlers to handle async request at a server. To be run in a separate thread.
+template <class Service>
+void HandleEcho(Service* service, ServerCompletionQueue* cq, bool dup_service) {
+ ServerContext srv_ctx;
+ grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
+ EchoRequest recv_request;
+ EchoResponse send_response;
+ service->RequestEcho(&srv_ctx, &recv_request, &response_writer, cq, cq,
+ tag(1));
+ Verify(cq, 1, true);
+ send_response.set_message(recv_request.message());
+ if (dup_service) {
+ send_response.mutable_message()->append("_dup");
+ }
+ response_writer.Finish(send_response, Status::OK, tag(2));
+ Verify(cq, 2, true);
+}
+
+template <class Service>
+void HandleClientStreaming(Service* service, ServerCompletionQueue* cq) {
+ ServerContext srv_ctx;
+ EchoRequest recv_request;
+ EchoResponse send_response;
+ ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
+ service->RequestRequestStream(&srv_ctx, &srv_stream, cq, cq, tag(1));
+ Verify(cq, 1, true);
+ int i = 1;
+ do {
+ i++;
+ send_response.mutable_message()->append(recv_request.message());
+ srv_stream.Read(&recv_request, tag(i));
+ } while (VerifyReturnSuccess(cq, i));
+ srv_stream.Finish(send_response, Status::OK, tag(100));
+ Verify(cq, 100, true);
+}
+
+template <class Service>
+void HandleServerStreaming(Service* service, ServerCompletionQueue* cq) {
+ ServerContext srv_ctx;
+ EchoRequest recv_request;
+ EchoResponse send_response;
+ ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx);
+ service->RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, cq, cq,
+ tag(1));
+ Verify(cq, 1, true);
+ send_response.set_message(recv_request.message() + "0");
+ srv_stream.Write(send_response, tag(2));
+ Verify(cq, 2, true);
+ send_response.set_message(recv_request.message() + "1");
+ srv_stream.Write(send_response, tag(3));
+ Verify(cq, 3, true);
+ send_response.set_message(recv_request.message() + "2");
+ srv_stream.Write(send_response, tag(4));
+ Verify(cq, 4, true);
+ srv_stream.Finish(Status::OK, tag(5));
+ Verify(cq, 5, true);
+}
+
+void HandleGenericEcho(GenericServerAsyncReaderWriter* stream,
+ CompletionQueue* cq) {
+ ByteBuffer recv_buffer;
+ stream->Read(&recv_buffer, tag(2));
+ Verify(cq, 2, true);
+ EchoRequest recv_request;
+ EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request));
+ EchoResponse send_response;
+ send_response.set_message(recv_request.message());
+ auto send_buffer = SerializeToByteBuffer(&send_response);
+ stream->Write(*send_buffer, tag(3));
+ Verify(cq, 3, true);
+ stream->Finish(Status::OK, tag(4));
+ Verify(cq, 4, true);
+}
+
+void HandleGenericRequestStream(GenericServerAsyncReaderWriter* stream,
+ CompletionQueue* cq) {
+ ByteBuffer recv_buffer;
+ EchoRequest recv_request;
+ EchoResponse send_response;
+ int i = 1;
+ while (true) {
+ i++;
+ stream->Read(&recv_buffer, tag(i));
+ if (!VerifyReturnSuccess(cq, i)) {
+ break;
+ }
+ EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request));
+ send_response.mutable_message()->append(recv_request.message());
+ }
+ auto send_buffer = SerializeToByteBuffer(&send_response);
+ stream->Write(*send_buffer, tag(99));
+ Verify(cq, 99, true);
+ stream->Finish(Status::OK, tag(100));
+ Verify(cq, 100, true);
+}
+
+// Request and handle one generic call.
+void HandleGenericCall(AsyncGenericService* service,
+ ServerCompletionQueue* cq) {
+ GenericServerContext srv_ctx;
+ GenericServerAsyncReaderWriter stream(&srv_ctx);
+ service->RequestCall(&srv_ctx, &stream, cq, cq, tag(1));
+ Verify(cq, 1, true);
+ if (srv_ctx.method() == "/grpc.testing.EchoTestService/Echo") {
+ HandleGenericEcho(&stream, cq);
+ } else if (srv_ctx.method() ==
+ "/grpc.testing.EchoTestService/RequestStream") {
+ HandleGenericRequestStream(&stream, cq);
+ } else { // other methods not handled yet.
+ gpr_log(GPR_ERROR, "method: %s", srv_ctx.method().c_str());
+ GPR_ASSERT(0);
+ }
+}
+
+class TestServiceImplDupPkg
+ : public ::grpc::testing::duplicate::EchoTestService::Service {
+ public:
+ Status Echo(ServerContext* context, const EchoRequest* request,
+ EchoResponse* response) GRPC_OVERRIDE {
+ response->set_message(request->message() + "_dup");
+ return Status::OK;
+ }
+};
+
+class HybridEnd2endTest : public ::testing::Test {
+ protected:
+ HybridEnd2endTest() {}
+
+ void SetUpServer(::grpc::Service* service1, ::grpc::Service* service2,
+ AsyncGenericService* generic_service) {
+ int port = grpc_pick_unused_port_or_die();
+ server_address_ << "localhost:" << port;
+
+ // Setup server
+ ServerBuilder builder;
+ builder.AddListeningPort(server_address_.str(),
+ grpc::InsecureServerCredentials());
+ builder.RegisterService(service1);
+ if (service2) {
+ builder.RegisterService(service2);
+ }
+ if (generic_service) {
+ builder.RegisterAsyncGenericService(generic_service);
+ }
+ // Create a separate cq for each potential handler.
+ for (int i = 0; i < 5; i++) {
+ cqs_.push_back(std::move(builder.AddCompletionQueue()));
+ }
+ server_ = builder.BuildAndStart();
+ }
+
+ void TearDown() GRPC_OVERRIDE {
+ if (server_) {
+ server_->Shutdown();
+ }
+ void* ignored_tag;
+ bool ignored_ok;
+ for (auto it = cqs_.begin(); it != cqs_.end(); ++it) {
+ (*it)->Shutdown();
+ while ((*it)->Next(&ignored_tag, &ignored_ok))
+ ;
+ }
+ }
+
+ void ResetStub() {
+ std::shared_ptr<Channel> channel =
+ CreateChannel(server_address_.str(), InsecureChannelCredentials());
+ stub_ = grpc::testing::EchoTestService::NewStub(channel);
+ }
+
+ // Test all rpc methods.
+ void TestAllMethods() {
+ SendEcho();
+ SendSimpleClientStreaming();
+ SendSimpleServerStreaming();
+ SendBidiStreaming();
+ }
+
+ void SendEcho() {
+ EchoRequest send_request;
+ EchoResponse recv_response;
+ ClientContext cli_ctx;
+ send_request.set_message("Hello");
+ Status recv_status = stub_->Echo(&cli_ctx, send_request, &recv_response);
+ EXPECT_EQ(send_request.message(), recv_response.message());
+ EXPECT_TRUE(recv_status.ok());
+ }
+
+ void SendEchoToDupService() {
+ std::shared_ptr<Channel> channel =
+ CreateChannel(server_address_.str(), InsecureChannelCredentials());
+ auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel);
+ EchoRequest send_request;
+ EchoResponse recv_response;
+ ClientContext cli_ctx;
+ send_request.set_message("Hello");
+ Status recv_status = stub->Echo(&cli_ctx, send_request, &recv_response);
+ EXPECT_EQ(send_request.message() + "_dup", recv_response.message());
+ EXPECT_TRUE(recv_status.ok());
+ }
+
+ void SendSimpleClientStreaming() {
+ EchoRequest send_request;
+ EchoResponse recv_response;
+ grpc::string expected_message;
+ ClientContext cli_ctx;
+ send_request.set_message("Hello");
+ auto stream = stub_->RequestStream(&cli_ctx, &recv_response);
+ for (int i = 0; i < 5; i++) {
+ EXPECT_TRUE(stream->Write(send_request));
+ expected_message.append(send_request.message());
+ }
+ stream->WritesDone();
+ Status recv_status = stream->Finish();
+ EXPECT_EQ(expected_message, recv_response.message());
+ EXPECT_TRUE(recv_status.ok());
+ }
+
+ void SendSimpleServerStreaming() {
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+ request.set_message("hello");
+
+ auto stream = stub_->ResponseStream(&context, request);
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message() + "0");
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message() + "1");
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message() + "2");
+ EXPECT_FALSE(stream->Read(&response));
+
+ Status s = stream->Finish();
+ EXPECT_TRUE(s.ok());
+ }
+
+ void SendBidiStreaming() {
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+ grpc::string msg("hello");
+
+ auto stream = stub_->BidiStream(&context);
+
+ request.set_message(msg + "0");
+ EXPECT_TRUE(stream->Write(request));
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message());
+
+ request.set_message(msg + "1");
+ EXPECT_TRUE(stream->Write(request));
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message());
+
+ request.set_message(msg + "2");
+ EXPECT_TRUE(stream->Write(request));
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message());
+
+ stream->WritesDone();
+ EXPECT_FALSE(stream->Read(&response));
+ EXPECT_FALSE(stream->Read(&response));
+
+ Status s = stream->Finish();
+ EXPECT_TRUE(s.ok());
+ }
+
+ std::vector<std::unique_ptr<ServerCompletionQueue> > cqs_;
+ std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
+ std::unique_ptr<Server> server_;
+ std::ostringstream server_address_;
+};
+
+TEST_F(HybridEnd2endTest, AsyncEcho) {
+ EchoTestService::WithAsyncMethod_Echo<TestServiceImpl> service;
+ SetUpServer(&service, nullptr, nullptr);
+ ResetStub();
+ std::thread echo_handler_thread(
+ [this, &service] { HandleEcho(&service, cqs_[0].get(), false); });
+ TestAllMethods();
+ echo_handler_thread.join();
+}
+
+TEST_F(HybridEnd2endTest, AsyncEchoRequestStream) {
+ EchoTestService::WithAsyncMethod_RequestStream<
+ EchoTestService::WithAsyncMethod_Echo<TestServiceImpl> > service;
+ SetUpServer(&service, nullptr, nullptr);
+ ResetStub();
+ std::thread echo_handler_thread(
+ [this, &service] { HandleEcho(&service, cqs_[0].get(), false); });
+ std::thread request_stream_handler_thread(
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); });
+ TestAllMethods();
+ echo_handler_thread.join();
+ request_stream_handler_thread.join();
+}
+
+TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream) {
+ EchoTestService::WithAsyncMethod_RequestStream<
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl> >
+ service;
+ SetUpServer(&service, nullptr, nullptr);
+ ResetStub();
+ std::thread response_stream_handler_thread(
+ [this, &service] { HandleServerStreaming(&service, cqs_[0].get()); });
+ std::thread request_stream_handler_thread(
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); });
+ TestAllMethods();
+ response_stream_handler_thread.join();
+ request_stream_handler_thread.join();
+}
+
+// Add a second service with one sync method.
+TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_SyncDupService) {
+ EchoTestService::WithAsyncMethod_RequestStream<
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl> >
+ service;
+ TestServiceImplDupPkg dup_service;
+ SetUpServer(&service, &dup_service, nullptr);
+ ResetStub();
+ std::thread response_stream_handler_thread(
+ [this, &service] { HandleServerStreaming(&service, cqs_[0].get()); });
+ std::thread request_stream_handler_thread(
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); });
+ TestAllMethods();
+ SendEchoToDupService();
+ response_stream_handler_thread.join();
+ request_stream_handler_thread.join();
+}
+
+// Add a second service with one async method.
+TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_AsyncDupService) {
+ EchoTestService::WithAsyncMethod_RequestStream<
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl> >
+ service;
+ duplicate::EchoTestService::AsyncService dup_service;
+ SetUpServer(&service, &dup_service, nullptr);
+ ResetStub();
+ std::thread response_stream_handler_thread(
+ [this, &service] { HandleServerStreaming(&service, cqs_[0].get()); });
+ std::thread request_stream_handler_thread(
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); });
+ std::thread echo_handler_thread(
+ [this, &dup_service] { HandleEcho(&dup_service, cqs_[2].get(), true); });
+ TestAllMethods();
+ SendEchoToDupService();
+ response_stream_handler_thread.join();
+ request_stream_handler_thread.join();
+ echo_handler_thread.join();
+}
+
+TEST_F(HybridEnd2endTest, GenericEcho) {
+ EchoTestService::WithGenericMethod_Echo<TestServiceImpl> service;
+ AsyncGenericService generic_service;
+ SetUpServer(&service, nullptr, &generic_service);
+ ResetStub();
+ std::thread generic_handler_thread([this, &generic_service] {
+ HandleGenericCall(&generic_service, cqs_[0].get());
+ });
+ TestAllMethods();
+ generic_handler_thread.join();
+}
+
+TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream) {
+ EchoTestService::WithAsyncMethod_RequestStream<
+ EchoTestService::WithGenericMethod_Echo<TestServiceImpl> > service;
+ AsyncGenericService generic_service;
+ SetUpServer(&service, nullptr, &generic_service);
+ ResetStub();
+ std::thread generic_handler_thread([this, &generic_service] {
+ HandleGenericCall(&generic_service, cqs_[0].get());
+ });
+ std::thread request_stream_handler_thread(
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); });
+ TestAllMethods();
+ generic_handler_thread.join();
+ request_stream_handler_thread.join();
+}
+
+// Add a second service with one sync method.
+TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_SyncDupService) {
+ EchoTestService::WithAsyncMethod_RequestStream<
+ EchoTestService::WithGenericMethod_Echo<TestServiceImpl> > service;
+ AsyncGenericService generic_service;
+ TestServiceImplDupPkg dup_service;
+ SetUpServer(&service, &dup_service, &generic_service);
+ ResetStub();
+ std::thread generic_handler_thread([this, &generic_service] {
+ HandleGenericCall(&generic_service, cqs_[0].get());
+ });
+ std::thread request_stream_handler_thread(
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); });
+ TestAllMethods();
+ SendEchoToDupService();
+ generic_handler_thread.join();
+ request_stream_handler_thread.join();
+}
+
+// Add a second service with one async method.
+TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStream_AsyncDupService) {
+ EchoTestService::WithAsyncMethod_RequestStream<
+ EchoTestService::WithGenericMethod_Echo<TestServiceImpl> > service;
+ AsyncGenericService generic_service;
+ duplicate::EchoTestService::AsyncService dup_service;
+ SetUpServer(&service, &dup_service, &generic_service);
+ ResetStub();
+ std::thread generic_handler_thread([this, &generic_service] {
+ HandleGenericCall(&generic_service, cqs_[0].get());
+ });
+ std::thread request_stream_handler_thread(
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); });
+ std::thread echo_handler_thread(
+ [this, &dup_service] { HandleEcho(&dup_service, cqs_[2].get(), true); });
+ TestAllMethods();
+ SendEchoToDupService();
+ generic_handler_thread.join();
+ request_stream_handler_thread.join();
+ echo_handler_thread.join();
+}
+
+TEST_F(HybridEnd2endTest, GenericEchoAsyncRequestStreamResponseStream) {
+ EchoTestService::WithAsyncMethod_RequestStream<
+ EchoTestService::WithGenericMethod_Echo<
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl> > >
+ service;
+ AsyncGenericService generic_service;
+ SetUpServer(&service, nullptr, &generic_service);
+ ResetStub();
+ std::thread generic_handler_thread([this, &generic_service] {
+ HandleGenericCall(&generic_service, cqs_[0].get());
+ });
+ std::thread request_stream_handler_thread(
+ [this, &service] { HandleClientStreaming(&service, cqs_[1].get()); });
+ std::thread response_stream_handler_thread(
+ [this, &service] { HandleServerStreaming(&service, cqs_[2].get()); });
+ TestAllMethods();
+ generic_handler_thread.join();
+ request_stream_handler_thread.join();
+ response_stream_handler_thread.join();
+}
+
+TEST_F(HybridEnd2endTest, GenericEchoRequestStreamAsyncResponseStream) {
+ EchoTestService::WithGenericMethod_RequestStream<
+ EchoTestService::WithGenericMethod_Echo<
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl> > >
+ service;
+ AsyncGenericService generic_service;
+ SetUpServer(&service, nullptr, &generic_service);
+ ResetStub();
+ std::thread generic_handler_thread([this, &generic_service] {
+ HandleGenericCall(&generic_service, cqs_[0].get());
+ });
+ std::thread generic_handler_thread2([this, &generic_service] {
+ HandleGenericCall(&generic_service, cqs_[1].get());
+ });
+ std::thread response_stream_handler_thread(
+ [this, &service] { HandleServerStreaming(&service, cqs_[2].get()); });
+ TestAllMethods();
+ generic_handler_thread.join();
+ generic_handler_thread2.join();
+ response_stream_handler_thread.join();
+}
+
+// If WithGenericMethod is called and no generic service is registered, the
+// server will fail to build.
+TEST_F(HybridEnd2endTest, GenericMethodWithoutGenericService) {
+ EchoTestService::WithGenericMethod_RequestStream<
+ EchoTestService::WithGenericMethod_Echo<
+ EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl> > >
+ service;
+ SetUpServer(&service, nullptr, nullptr);
+ EXPECT_EQ(nullptr, server_.get());
+}
+
+} // namespace
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc
new file mode 100644
index 0000000000..c9a32ecf5a
--- /dev/null
+++ b/test/cpp/end2end/test_service_impl.cc
@@ -0,0 +1,199 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/cpp/end2end/test_service_impl.h"
+
+#include <grpc++/security/credentials.h>
+#include <grpc++/server_context.h>
+#include <grpc/grpc.h>
+#include <gtest/gtest.h>
+
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/cpp/util/string_ref_helper.h"
+
+using std::chrono::system_clock;
+
+namespace grpc {
+namespace testing {
+namespace {
+
+// When echo_deadline is requested, deadline seen in the ServerContext is set in
+// the response in seconds.
+void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
+ EchoResponse* response) {
+ if (request->has_param() && request->param().echo_deadline()) {
+ gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
+ if (context->deadline() != system_clock::time_point::max()) {
+ Timepoint2Timespec(context->deadline(), &deadline);
+ }
+ response->mutable_param()->set_request_deadline(deadline.tv_sec);
+ }
+}
+
+void CheckServerAuthContext(const ServerContext* context,
+ const grpc::string& expected_client_identity) {
+ std::shared_ptr<const AuthContext> auth_ctx = context->auth_context();
+ std::vector<grpc::string_ref> ssl =
+ auth_ctx->FindPropertyValues("transport_security_type");
+ EXPECT_EQ(1u, ssl.size());
+ EXPECT_EQ("ssl", ToString(ssl[0]));
+ if (expected_client_identity.length() == 0) {
+ EXPECT_TRUE(auth_ctx->GetPeerIdentityPropertyName().empty());
+ EXPECT_TRUE(auth_ctx->GetPeerIdentity().empty());
+ EXPECT_FALSE(auth_ctx->IsPeerAuthenticated());
+ } else {
+ auto identity = auth_ctx->GetPeerIdentity();
+ EXPECT_TRUE(auth_ctx->IsPeerAuthenticated());
+ EXPECT_EQ(1u, identity.size());
+ EXPECT_EQ(expected_client_identity, identity[0]);
+ }
+}
+} // namespace
+
+Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request,
+ EchoResponse* response) {
+ response->set_message(request->message());
+ MaybeEchoDeadline(context, request, response);
+ if (host_) {
+ response->mutable_param()->set_host(*host_);
+ }
+ if (request->has_param() && request->param().client_cancel_after_us()) {
+ {
+ std::unique_lock<std::mutex> lock(mu_);
+ signal_client_ = true;
+ }
+ while (!context->IsCancelled()) {
+ gpr_sleep_until(gpr_time_add(
+ gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_micros(request->param().client_cancel_after_us(),
+ GPR_TIMESPAN)));
+ }
+ return Status::CANCELLED;
+ } else if (request->has_param() &&
+ request->param().server_cancel_after_us()) {
+ gpr_sleep_until(gpr_time_add(
+ gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_micros(request->param().server_cancel_after_us(),
+ GPR_TIMESPAN)));
+ return Status::CANCELLED;
+ } else {
+ EXPECT_FALSE(context->IsCancelled());
+ }
+
+ if (request->has_param() && request->param().echo_metadata()) {
+ const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata =
+ context->client_metadata();
+ for (
+ std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator iter =
+ client_metadata.begin();
+ iter != client_metadata.end(); ++iter) {
+ context->AddTrailingMetadata(ToString(iter->first),
+ ToString(iter->second));
+ }
+ }
+ if (request->has_param() &&
+ (request->param().expected_client_identity().length() > 0 ||
+ request->param().check_auth_context())) {
+ CheckServerAuthContext(context,
+ request->param().expected_client_identity());
+ }
+ if (request->has_param() && request->param().response_message_length() > 0) {
+ response->set_message(
+ grpc::string(request->param().response_message_length(), '\0'));
+ }
+ if (request->has_param() && request->param().echo_peer()) {
+ response->mutable_param()->set_peer(context->peer());
+ }
+ return Status::OK;
+}
+
+// Unimplemented is left unimplemented to test the returned error.
+
+Status TestServiceImpl::RequestStream(ServerContext* context,
+ ServerReader<EchoRequest>* reader,
+ EchoResponse* response) {
+ EchoRequest request;
+ response->set_message("");
+ int cancel_after_reads = 0;
+ const std::multimap<grpc::string_ref, grpc::string_ref>&
+ client_initial_metadata = context->client_metadata();
+ if (client_initial_metadata.find(kServerCancelAfterReads) !=
+ client_initial_metadata.end()) {
+ std::istringstream iss(ToString(
+ client_initial_metadata.find(kServerCancelAfterReads)->second));
+ iss >> cancel_after_reads;
+ gpr_log(GPR_INFO, "cancel_after_reads %d", cancel_after_reads);
+ }
+ while (reader->Read(&request)) {
+ if (cancel_after_reads == 1) {
+ gpr_log(GPR_INFO, "return cancel status");
+ return Status::CANCELLED;
+ } else if (cancel_after_reads > 0) {
+ cancel_after_reads--;
+ }
+ response->mutable_message()->append(request.message());
+ }
+ return Status::OK;
+}
+
+// Return 3 messages.
+// TODO(yangg) make it generic by adding a parameter into EchoRequest
+Status TestServiceImpl::ResponseStream(ServerContext* context,
+ const EchoRequest* request,
+ ServerWriter<EchoResponse>* writer) {
+ EchoResponse response;
+ response.set_message(request->message() + "0");
+ writer->Write(response);
+ response.set_message(request->message() + "1");
+ writer->Write(response);
+ response.set_message(request->message() + "2");
+ writer->Write(response);
+
+ return Status::OK;
+}
+
+Status TestServiceImpl::BidiStream(
+ ServerContext* context,
+ ServerReaderWriter<EchoResponse, EchoRequest>* stream) {
+ EchoRequest request;
+ EchoResponse response;
+ while (stream->Read(&request)) {
+ gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
+ response.set_message(request.message());
+ stream->Write(response);
+ }
+ return Status::OK;
+}
+
+} // namespace testing
+} // namespace grpc
diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h
new file mode 100644
index 0000000000..2c35b5614c
--- /dev/null
+++ b/test/cpp/end2end/test_service_impl.h
@@ -0,0 +1,85 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef GRPC_TEST_CPP_END2END_TEST_SERVICE_IMPL_H
+#define GRPC_TEST_CPP_END2END_TEST_SERVICE_IMPL_H
+
+#include <memory>
+#include <mutex>
+
+#include <grpc++/server_context.h>
+#include <grpc/grpc.h>
+
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+
+namespace grpc {
+namespace testing {
+
+const char* const kServerCancelAfterReads = "cancel_after_reads";
+
+class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
+ public:
+ TestServiceImpl() : signal_client_(false), host_() {}
+ explicit TestServiceImpl(const grpc::string& host)
+ : signal_client_(false), host_(new grpc::string(host)) {}
+
+ Status Echo(ServerContext* context, const EchoRequest* request,
+ EchoResponse* response) GRPC_OVERRIDE;
+
+ // Unimplemented is left unimplemented to test the returned error.
+
+ Status RequestStream(ServerContext* context,
+ ServerReader<EchoRequest>* reader,
+ EchoResponse* response) GRPC_OVERRIDE;
+
+ Status ResponseStream(ServerContext* context, const EchoRequest* request,
+ ServerWriter<EchoResponse>* writer) GRPC_OVERRIDE;
+
+ Status BidiStream(ServerContext* context,
+ ServerReaderWriter<EchoResponse, EchoRequest>* stream)
+ GRPC_OVERRIDE;
+
+ bool signal_client() {
+ std::unique_lock<std::mutex> lock(mu_);
+ return signal_client_;
+ }
+
+ private:
+ bool signal_client_;
+ std::mutex mu_;
+ std::unique_ptr<grpc::string> host_;
+};
+
+} // namespace testing
+} // namespace grpc
+
+#endif // GRPC_TEST_CPP_END2END_TEST_SERVICE_IMPL_H
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index f270cd0987..d02769d8e6 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -49,10 +49,10 @@
#include <grpc/support/histogram.h>
#include <grpc/support/log.h>
+#include "src/proto/grpc/testing/services.grpc.pb.h"
#include "test/cpp/qps/client.h"
#include "test/cpp/qps/timer.h"
#include "test/cpp/util/create_test_channel.h"
-#include "src/proto/grpc/testing/services.grpc.pb.h"
namespace grpc {
namespace testing {
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index d530dac86b..32a8fc48e6 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -350,7 +350,7 @@ class AsyncQpsServerTest : public Server {
static void RegisterBenchmarkService(ServerBuilder *builder,
BenchmarkService::AsyncService *service) {
- builder->RegisterAsyncService(service);
+ builder->RegisterService(service);
}
static void RegisterGenericService(ServerBuilder *builder,
grpc::AsyncGenericService *service) {
diff --git a/test/cpp/util/byte_buffer_proto_helper.cc b/test/cpp/util/byte_buffer_proto_helper.cc
new file mode 100644
index 0000000000..2512c9bdf8
--- /dev/null
+++ b/test/cpp/util/byte_buffer_proto_helper.cc
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/cpp/util/byte_buffer_proto_helper.h"
+
+namespace grpc {
+namespace testing {
+
+bool ParseFromByteBuffer(ByteBuffer* buffer, grpc::protobuf::Message* message) {
+ std::vector<Slice> slices;
+ buffer->Dump(&slices);
+ grpc::string buf;
+ buf.reserve(buffer->Length());
+ for (auto s = slices.begin(); s != slices.end(); s++) {
+ buf.append(reinterpret_cast<const char*>(s->begin()), s->size());
+ }
+ return message->ParseFromString(buf);
+}
+
+std::unique_ptr<ByteBuffer> SerializeToByteBuffer(
+ grpc::protobuf::Message* message) {
+ grpc::string buf;
+ message->SerializeToString(&buf);
+ gpr_slice s = gpr_slice_from_copied_string(buf.c_str());
+ Slice slice(s, Slice::STEAL_REF);
+ return std::unique_ptr<ByteBuffer>(new ByteBuffer(&slice, 1));
+}
+
+} // namespace testing
+} // namespace grpc
diff --git a/test/cpp/util/byte_buffer_proto_helper.h b/test/cpp/util/byte_buffer_proto_helper.h
new file mode 100644
index 0000000000..42cea59e33
--- /dev/null
+++ b/test/cpp/util/byte_buffer_proto_helper.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_TEST_CPP_UTIL_BYTE_BUFFER_PROTO_HELPER_H
+#define GRPC_TEST_CPP_UTIL_BYTE_BUFFER_PROTO_HELPER_H
+
+#include <memory>
+
+#include <grpc++/support/byte_buffer.h>
+#include <grpc++/support/config_protobuf.h>
+
+namespace grpc {
+namespace testing {
+
+bool ParseFromByteBuffer(ByteBuffer* buffer, grpc::protobuf::Message* message);
+
+std::unique_ptr<ByteBuffer> SerializeToByteBuffer(
+ grpc::protobuf::Message* message);
+
+} // namespace testing
+} // namespace grpc
+
+#endif // GRPC_TEST_CPP_UTIL_BYTE_BUFFER_PROTO_HELPER_H
diff --git a/test/cpp/util/metrics_server.cc b/test/cpp/util/metrics_server.cc
index 40028d3957..07978d0bdb 100644
--- a/test/cpp/util/metrics_server.cc
+++ b/test/cpp/util/metrics_server.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,7 @@
#include "test/cpp/util/metrics_server.h"
+#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include "src/proto/grpc/testing/metrics.grpc.pb.h"
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 500d110ad0..6706b3dbd5 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -770,6 +770,7 @@ include/grpc++/grpc++.h \
include/grpc++/impl/call.h \
include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/grpc_library.h \
+include/grpc++/impl/method_handler_impl.h \
include/grpc++/impl/proto_utils.h \
include/grpc++/impl/rpc_method.h \
include/grpc++/impl/rpc_service_method.h \
@@ -801,7 +802,15 @@ include/grpc++/support/status_code_enum.h \
include/grpc++/support/string_ref.h \
include/grpc++/support/stub_options.h \
include/grpc++/support/sync_stream.h \
-include/grpc++/support/time.h
+include/grpc++/support/time.h \
+include/grpc++/impl/codegen/call_hook.h \
+include/grpc++/impl/codegen/channel_interface.h \
+include/grpc++/impl/codegen/completion_queue_tag.h \
+include/grpc++/impl/codegen/config.h \
+include/grpc++/impl/codegen/server_interface.h \
+include/grpc++/impl/codegen/status.h \
+include/grpc++/impl/codegen/status_code_enum.h \
+include/grpc++/impl/codegen/time.h
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index ba1dec0d38..fa46adc5e4 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -770,6 +770,7 @@ include/grpc++/grpc++.h \
include/grpc++/impl/call.h \
include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/grpc_library.h \
+include/grpc++/impl/method_handler_impl.h \
include/grpc++/impl/proto_utils.h \
include/grpc++/impl/rpc_method.h \
include/grpc++/impl/rpc_service_method.h \
@@ -802,6 +803,14 @@ include/grpc++/support/string_ref.h \
include/grpc++/support/stub_options.h \
include/grpc++/support/sync_stream.h \
include/grpc++/support/time.h \
+include/grpc++/impl/codegen/call_hook.h \
+include/grpc++/impl/codegen/channel_interface.h \
+include/grpc++/impl/codegen/completion_queue_tag.h \
+include/grpc++/impl/codegen/config.h \
+include/grpc++/impl/codegen/server_interface.h \
+include/grpc++/impl/codegen/status.h \
+include/grpc++/impl/codegen/status_code_enum.h \
+include/grpc++/impl/codegen/time.h \
src/cpp/client/secure_credentials.h \
src/cpp/common/secure_auth_context.h \
src/cpp/server/secure_server_credentials.h \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 3a1d097fb9..c3a2e66aea 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -794,7 +794,10 @@ include/grpc/support/tls.h \
include/grpc/support/tls_gcc.h \
include/grpc/support/tls_msvc.h \
include/grpc/support/tls_pthread.h \
-include/grpc/support/useful.h
+include/grpc/support/useful.h \
+include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/port_platform.h \
+include/grpc/impl/codegen/time.h
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index f6b6e59dfd..ee87fbd592 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1077,6 +1077,9 @@ include/grpc/support/tls_gcc.h \
include/grpc/support/tls_msvc.h \
include/grpc/support/tls_pthread.h \
include/grpc/support/useful.h \
+include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/port_platform.h \
+include/grpc/impl/codegen/time.h \
src/core/profiling/timers.h \
src/core/support/block_annotate.h \
src/core/support/env.h \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index a311a04af3..fc57ef098c 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -1622,6 +1622,22 @@
"gpr_test_util",
"grpc",
"grpc++",
+ "grpc++_test_util",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "language": "c++",
+ "name": "hybrid_end2end_test",
+ "src": [
+ "test/cpp/end2end/hybrid_end2end_test.cc"
+ ]
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc++",
"grpc++_test_config",
"grpc++_test_util",
"grpc_test_util",
@@ -2738,6 +2754,9 @@
{
"deps": [],
"headers": [
+ "include/grpc/impl/codegen/connectivity_state.h",
+ "include/grpc/impl/codegen/port_platform.h",
+ "include/grpc/impl/codegen/time.h",
"include/grpc/support/alloc.h",
"include/grpc/support/atm.h",
"include/grpc/support/atm_gcc_atomic.h",
@@ -2780,6 +2799,9 @@
"language": "c",
"name": "gpr",
"src": [
+ "include/grpc/impl/codegen/connectivity_state.h",
+ "include/grpc/impl/codegen/port_platform.h",
+ "include/grpc/impl/codegen/time.h",
"include/grpc/support/alloc.h",
"include/grpc/support/atm.h",
"include/grpc/support/atm_gcc_atomic.h",
@@ -3844,7 +3866,16 @@
"include/grpc++/grpc++.h",
"include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h",
+ "include/grpc++/impl/codegen/call_hook.h",
+ "include/grpc++/impl/codegen/channel_interface.h",
+ "include/grpc++/impl/codegen/completion_queue_tag.h",
+ "include/grpc++/impl/codegen/config.h",
+ "include/grpc++/impl/codegen/server_interface.h",
+ "include/grpc++/impl/codegen/status.h",
+ "include/grpc++/impl/codegen/status_code_enum.h",
+ "include/grpc++/impl/codegen/time.h",
"include/grpc++/impl/grpc_library.h",
+ "include/grpc++/impl/method_handler_impl.h",
"include/grpc++/impl/proto_utils.h",
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
@@ -3898,7 +3929,16 @@
"include/grpc++/grpc++.h",
"include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h",
+ "include/grpc++/impl/codegen/call_hook.h",
+ "include/grpc++/impl/codegen/channel_interface.h",
+ "include/grpc++/impl/codegen/completion_queue_tag.h",
+ "include/grpc++/impl/codegen/config.h",
+ "include/grpc++/impl/codegen/server_interface.h",
+ "include/grpc++/impl/codegen/status.h",
+ "include/grpc++/impl/codegen/status_code_enum.h",
+ "include/grpc++/impl/codegen/time.h",
"include/grpc++/impl/grpc_library.h",
+ "include/grpc++/impl/method_handler_impl.h",
"include/grpc++/impl/proto_utils.h",
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
@@ -3997,6 +4037,8 @@
"src/proto/grpc/testing/echo.pb.h",
"src/proto/grpc/testing/echo_messages.grpc.pb.h",
"src/proto/grpc/testing/echo_messages.pb.h",
+ "test/cpp/end2end/test_service_impl.h",
+ "test/cpp/util/byte_buffer_proto_helper.h",
"test/cpp/util/cli_call.h",
"test/cpp/util/create_test_channel.h",
"test/cpp/util/string_ref_helper.h",
@@ -4005,6 +4047,10 @@
"language": "c++",
"name": "grpc++_test_util",
"src": [
+ "test/cpp/end2end/test_service_impl.cc",
+ "test/cpp/end2end/test_service_impl.h",
+ "test/cpp/util/byte_buffer_proto_helper.cc",
+ "test/cpp/util/byte_buffer_proto_helper.h",
"test/cpp/util/cli_call.cc",
"test/cpp/util/cli_call.h",
"test/cpp/util/create_test_channel.cc",
@@ -4030,7 +4076,16 @@
"include/grpc++/grpc++.h",
"include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h",
+ "include/grpc++/impl/codegen/call_hook.h",
+ "include/grpc++/impl/codegen/channel_interface.h",
+ "include/grpc++/impl/codegen/completion_queue_tag.h",
+ "include/grpc++/impl/codegen/config.h",
+ "include/grpc++/impl/codegen/server_interface.h",
+ "include/grpc++/impl/codegen/status.h",
+ "include/grpc++/impl/codegen/status_code_enum.h",
+ "include/grpc++/impl/codegen/time.h",
"include/grpc++/impl/grpc_library.h",
+ "include/grpc++/impl/method_handler_impl.h",
"include/grpc++/impl/proto_utils.h",
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
@@ -4081,7 +4136,16 @@
"include/grpc++/grpc++.h",
"include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h",
+ "include/grpc++/impl/codegen/call_hook.h",
+ "include/grpc++/impl/codegen/channel_interface.h",
+ "include/grpc++/impl/codegen/completion_queue_tag.h",
+ "include/grpc++/impl/codegen/config.h",
+ "include/grpc++/impl/codegen/server_interface.h",
+ "include/grpc++/impl/codegen/status.h",
+ "include/grpc++/impl/codegen/status_code_enum.h",
+ "include/grpc++/impl/codegen/time.h",
"include/grpc++/impl/grpc_library.h",
+ "include/grpc++/impl/method_handler_impl.h",
"include/grpc++/impl/proto_utils.h",
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
@@ -4151,8 +4215,19 @@
{
"deps": [],
"headers": [
+ "include/grpc++/impl/codegen/call_hook.h",
+ "include/grpc++/impl/codegen/channel_interface.h",
+ "include/grpc++/impl/codegen/completion_queue_tag.h",
+ "include/grpc++/impl/codegen/config.h",
+ "include/grpc++/impl/codegen/server_interface.h",
+ "include/grpc++/impl/codegen/status.h",
+ "include/grpc++/impl/codegen/status_code_enum.h",
+ "include/grpc++/impl/codegen/time.h",
"include/grpc++/support/config.h",
"include/grpc++/support/config_protobuf.h",
+ "include/grpc/impl/codegen/connectivity_state.h",
+ "include/grpc/impl/codegen/port_platform.h",
+ "include/grpc/impl/codegen/time.h",
"src/compiler/config.h",
"src/compiler/cpp_generator.h",
"src/compiler/cpp_generator_helpers.h",
@@ -4170,8 +4245,19 @@
"language": "c++",
"name": "grpc_plugin_support",
"src": [
+ "include/grpc++/impl/codegen/call_hook.h",
+ "include/grpc++/impl/codegen/channel_interface.h",
+ "include/grpc++/impl/codegen/completion_queue_tag.h",
+ "include/grpc++/impl/codegen/config.h",
+ "include/grpc++/impl/codegen/server_interface.h",
+ "include/grpc++/impl/codegen/status.h",
+ "include/grpc++/impl/codegen/status_code_enum.h",
+ "include/grpc++/impl/codegen/time.h",
"include/grpc++/support/config.h",
"include/grpc++/support/config_protobuf.h",
+ "include/grpc/impl/codegen/connectivity_state.h",
+ "include/grpc/impl/codegen/port_platform.h",
+ "include/grpc/impl/codegen/time.h",
"src/compiler/config.h",
"src/compiler/cpp_generator.cc",
"src/compiler/cpp_generator.h",
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 8c76b3f134..d59efacdf1 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -1984,6 +1984,26 @@
"ci_platforms": [
"linux",
"mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "flaky": false,
+ "language": "c++",
+ "name": "hybrid_end2end_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ]
+ },
+ {
+ "args": [],
+ "ci_platforms": [
+ "linux",
+ "mac",
"posix"
],
"cpu_cost": 0.1,
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj
index 270fc89749..4079e316c9 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj
@@ -175,6 +175,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\support\tls_msvc.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\support\tls_pthread.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\support\useful.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(SolutionDir)\..\src\core\profiling\timers.h" />
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
index c92a92fb9b..b8551c2440 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
@@ -210,6 +210,15 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\support\useful.h">
<Filter>include\grpc\support</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(SolutionDir)\..\src\core\profiling\timers.h">
@@ -251,6 +260,12 @@
<Filter Include="include\grpc">
<UniqueIdentifier>{e6957ec1-85ba-6515-03c0-e12878045b1f}</UniqueIdentifier>
</Filter>
+ <Filter Include="include\grpc\impl">
+ <UniqueIdentifier>{4c72091a-872d-10da-2694-ce5a7b069a1f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="include\grpc\impl\codegen">
+ <UniqueIdentifier>{e52e0384-d0d3-1475-0d4e-11719aac8f2a}</UniqueIdentifier>
+ </Filter>
<Filter Include="include\grpc\support">
<UniqueIdentifier>{31c42000-3ed7-95e1-d076-df814b72cdee}</UniqueIdentifier>
</Filter>
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 886d415631..b70d0c080d 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -268,6 +268,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\method_handler_impl.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\proto_utils.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_method.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_service_method.h" />
@@ -300,6 +301,14 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\support\stub_options.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\support\sync_stream.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\support\time.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.h" />
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index abd39c7aa1..abe44a1577 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -129,6 +129,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\method_handler_impl.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\proto_utils.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
@@ -225,6 +228,30 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\support\time.h">
<Filter>include\grpc++\support</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.h">
@@ -266,6 +293,9 @@
<Filter Include="include\grpc++\impl">
<UniqueIdentifier>{0da8cd95-314f-da1b-5ce7-7791a5be1f1a}</UniqueIdentifier>
</Filter>
+ <Filter Include="include\grpc++\impl\codegen">
+ <UniqueIdentifier>{a3e7f28b-a7c7-7364-d402-edb1bfa414a4}</UniqueIdentifier>
+ </Filter>
<Filter Include="include\grpc++\security">
<UniqueIdentifier>{a80eb32b-1be9-1187-5f40-30d92accecc8}</UniqueIdentifier>
</Filter>
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
index 299fdaf773..3d353716a9 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
@@ -147,6 +147,8 @@
</ItemDefinitionGroup>
<ItemGroup>
+ <ClInclude Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.h" />
+ <ClInclude Include="$(SolutionDir)\..\test\cpp\util\byte_buffer_proto_helper.h" />
<ClInclude Include="$(SolutionDir)\..\test\cpp\util\cli_call.h" />
<ClInclude Include="$(SolutionDir)\..\test\cpp\util\create_test_channel.h" />
<ClInclude Include="$(SolutionDir)\..\test\cpp\util\string_ref_helper.h" />
@@ -177,6 +179,10 @@
</ClCompile>
<ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\duplicate\echo_duplicate.grpc.pb.h">
</ClInclude>
+ <ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.cc">
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\test\cpp\util\byte_buffer_proto_helper.cc">
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\cpp\util\cli_call.cc">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\cpp\util\create_test_channel.cc">
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
index 70addd61b1..27ac6751b9 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
@@ -10,6 +10,12 @@
<ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\duplicate\echo_duplicate.proto">
<Filter>src\proto\grpc\testing\duplicate</Filter>
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.cc">
+ <Filter>test\cpp\end2end</Filter>
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\test\cpp\util\byte_buffer_proto_helper.cc">
+ <Filter>test\cpp\util</Filter>
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\cpp\util\cli_call.cc">
<Filter>test\cpp\util</Filter>
</ClCompile>
@@ -24,6 +30,12 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.h">
+ <Filter>test\cpp\end2end</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\test\cpp\util\byte_buffer_proto_helper.h">
+ <Filter>test\cpp\util</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\test\cpp\util\cli_call.h">
<Filter>test\cpp\util</Filter>
</ClInclude>
@@ -60,6 +72,9 @@
<Filter Include="test\cpp">
<UniqueIdentifier>{793efaa7-370f-c34a-d347-31fc4e0630e2}</UniqueIdentifier>
</Filter>
+ <Filter Include="test\cpp\end2end">
+ <UniqueIdentifier>{1e6760f2-4cf7-1ecb-88a5-5faeec3c2150}</UniqueIdentifier>
+ </Filter>
<Filter Include="test\cpp\util">
<UniqueIdentifier>{bbe1e5b7-f4f9-8e32-ce7c-8c21afcf39d8}</UniqueIdentifier>
</Filter>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index 2193321913..0557b7f665 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -268,6 +268,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\method_handler_impl.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\proto_utils.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_method.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_service_method.h" />
@@ -300,6 +301,14 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\support\stub_options.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\support\sync_stream.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\support\time.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 073b181225..28e72277c6 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -114,6 +114,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\method_handler_impl.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\proto_utils.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
@@ -210,6 +213,30 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\support\time.h">
<Filter>include\grpc++\support</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h">
@@ -242,6 +269,9 @@
<Filter Include="include\grpc++\impl">
<UniqueIdentifier>{dadc0002-f2ac-451b-a9b8-33b8de10b5fc}</UniqueIdentifier>
</Filter>
+ <Filter Include="include\grpc++\impl\codegen">
+ <UniqueIdentifier>{ccc364e2-3f28-8bfc-c26e-800dd6f9a9af}</UniqueIdentifier>
+ </Filter>
<Filter Include="include\grpc++\security">
<UniqueIdentifier>{64bf60ff-9192-bb59-dcc8-8a0021e1d016}</UniqueIdentifier>
</Filter>
diff --git a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
index 6a70001e0e..f45d01667a 100644
--- a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
+++ b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
@@ -147,6 +147,19 @@
</ItemDefinitionGroup>
<ItemGroup>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
+ </ItemGroup>
+ <ItemGroup>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config_protobuf.h" />
<ClInclude Include="$(SolutionDir)\..\src\compiler\config.h" />
diff --git a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters
index 133e1e33d9..e24a2bfae7 100644
--- a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters
@@ -18,6 +18,41 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h">
+ <Filter>include\grpc++\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config.h">
<Filter>include\grpc++\support</Filter>
</ClInclude>
@@ -69,12 +104,27 @@
<Filter Include="include">
<UniqueIdentifier>{93ed419d-4540-7fa4-814d-3392745b77ff}</UniqueIdentifier>
</Filter>
+ <Filter Include="include\grpc">
+ <UniqueIdentifier>{ae5560ea-77fe-ab95-c7a3-4538c66591a8}</UniqueIdentifier>
+ </Filter>
<Filter Include="include\grpc++">
<UniqueIdentifier>{893c09ee-e315-e763-9d9d-37522ba2f51c}</UniqueIdentifier>
</Filter>
+ <Filter Include="include\grpc++\impl">
+ <UniqueIdentifier>{3e8c71a4-8a06-a577-2799-2224a1ad1f1b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="include\grpc++\impl\codegen">
+ <UniqueIdentifier>{ec2a6e26-915b-ba1b-4f59-f361dc01105c}</UniqueIdentifier>
+ </Filter>
<Filter Include="include\grpc++\support">
<UniqueIdentifier>{1c34d005-1ffb-8a31-881a-c6bb431cda69}</UniqueIdentifier>
</Filter>
+ <Filter Include="include\grpc\impl">
+ <UniqueIdentifier>{3c047248-00c2-4c59-fffd-9e313353e390}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="include\grpc\impl\codegen">
+ <UniqueIdentifier>{749ae941-63f0-c623-8b4b-a3114ec81bb7}</UniqueIdentifier>
+ </Filter>
<Filter Include="src">
<UniqueIdentifier>{94c9769a-a6cd-49fd-2b30-e52d2d02ed91}</UniqueIdentifier>
</Filter>
diff --git a/vsprojects/vcxproj/test/hybrid_end2end_test/hybrid_end2end_test.vcxproj b/vsprojects/vcxproj/test/hybrid_end2end_test/hybrid_end2end_test.vcxproj
new file mode 100644
index 0000000000..7bdc6c6674
--- /dev/null
+++ b/vsprojects/vcxproj/test/hybrid_end2end_test/hybrid_end2end_test.vcxproj
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{2DBA9954-A78A-6F68-5669-0370C6D6080C}</ProjectGuid>
+ <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+ <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+ <PlatformToolset>v100</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(SolutionDir)\..\vsprojects\cpptest.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\protobuf.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+ <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+ <TargetName>hybrid_end2end_test</TargetName>
+ <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+ <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+ <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+ <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)'=='Release'">
+ <TargetName>hybrid_end2end_test</TargetName>
+ <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+ <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+ <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+ <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+ <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+ <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+
+ <ItemGroup>
+ <ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\hybrid_end2end_test.cc">
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
+ <Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+ <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+ <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+ <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+ <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+ </ProjectReference>
+ <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+ <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+ <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+ </ImportGroup>
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+ <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+ </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/hybrid_end2end_test/hybrid_end2end_test.vcxproj.filters b/vsprojects/vcxproj/test/hybrid_end2end_test/hybrid_end2end_test.vcxproj.filters
new file mode 100644
index 0000000000..ebb9753af1
--- /dev/null
+++ b/vsprojects/vcxproj/test/hybrid_end2end_test/hybrid_end2end_test.vcxproj.filters
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\hybrid_end2end_test.cc">
+ <Filter>test\cpp\end2end</Filter>
+ </ClCompile>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Filter Include="test">
+ <UniqueIdentifier>{034a7201-59db-54c2-0af5-fd686ce948b6}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="test\cpp">
+ <UniqueIdentifier>{2bb7ef60-02e9-bb7c-6a37-4d8e2d8870ec}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="test\cpp\end2end">
+ <UniqueIdentifier>{d1b13ade-4b26-87da-a8a8-4c9766121e60}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project>
+