Merge branch 'cronetfix' into status

pull/16418/head
Yash Tibrewal 6 years ago
commit 4b859a61c7
  1. 4
      .clang-tidy
  2. 2
      .pylintrc-tests
  3. 18
      BUILD
  4. 3
      BUILDING.md
  5. 78
      CMakeLists.txt
  6. 88
      Makefile
  7. 329
      bazel/grpc_build_system.bzl
  8. 8
      bazel/grpc_deps.bzl
  9. 41
      build.yaml
  10. 9
      cmake/ssl.cmake
  11. 2
      config.m4
  12. 2
      config.w32
  13. 8
      doc/core/grpc-error.md
  14. 3
      doc/cpp/pending_api_cleanups.md
  15. 3
      doc/g_stands_for.md
  16. 64
      doc/naming.md
  17. 4
      doc/ssl-performance.md
  18. 10
      examples/csharp/Helloworld/Greeter/Greeter.csproj
  19. 38
      examples/csharp/Helloworld/Greeter/Helloworld.cs
  20. 23
      examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs
  21. 2
      examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj
  22. 2
      examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj
  23. 8
      examples/csharp/Helloworld/README.md
  24. 5
      examples/csharp/Helloworld/generate_protos.bat
  25. 19
      examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj
  26. 38
      examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs
  27. 23
      examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs
  28. 8
      examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config
  29. 19
      examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj
  30. 6
      examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config
  31. 19
      examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj
  32. 6
      examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config
  33. 2
      examples/csharp/HelloworldLegacyCsproj/generate_protos.bat
  34. 94
      examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs
  35. 10
      examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj
  36. 47
      examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs
  37. 2
      examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj
  38. 2
      examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj
  39. 6
      examples/csharp/RouteGuide/generate_protos.bat
  40. 9
      gRPC-C++.podspec
  41. 13
      gRPC-Core.podspec
  42. 2
      gRPC-ProtoRPC.podspec
  43. 2
      gRPC-RxLibrary.podspec
  44. 2
      gRPC.podspec
  45. 1
      grpc.def
  46. 5
      grpc.gemspec
  47. 8
      grpc.gyp
  48. 6
      include/grpc/grpc.h
  49. 43
      include/grpc/grpc_security_constants.h
  50. 11
      include/grpcpp/impl/codegen/call.h
  51. 4
      include/grpcpp/impl/codegen/client_context.h
  52. 50
      include/grpcpp/impl/codegen/metadata_map.h
  53. 2
      include/grpcpp/impl/codegen/server_context.h
  54. 37
      include/grpcpp/impl/codegen/service_type.h
  55. 9
      package.xml
  56. 18
      src/core/ext/filters/client_channel/README.md
  57. 3
      src/core/ext/filters/client_channel/client_channel.cc
  58. 2
      src/core/ext/filters/client_channel/http_connect_handshaker.cc
  59. 33
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  60. 5
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  61. 9
      src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
  62. 13
      src/core/ext/filters/client_channel/resolver.h
  63. 12
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  64. 12
      src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
  65. 18
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
  66. 3
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
  67. 7
      src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
  68. 2
      src/core/ext/filters/http/client_authority_filter.cc
  69. 7
      src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
  70. 3
      src/core/ext/filters/max_age/max_age_filter.cc
  71. 2
      src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
  72. 2
      src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
  73. 3
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  74. 2
      src/core/ext/transport/cronet/transport/cronet_transport.cc
  75. 77
      src/core/lib/gpr/arena.cc
  76. 74
      src/core/lib/gprpp/fork.cc
  77. 17
      src/core/lib/gprpp/fork.h
  78. 2
      src/core/lib/http/httpcli.cc
  79. 134
      src/core/lib/iomgr/buffer_list.cc
  80. 96
      src/core/lib/iomgr/buffer_list.h
  81. 4
      src/core/lib/iomgr/endpoint.cc
  82. 8
      src/core/lib/iomgr/endpoint.h
  83. 2
      src/core/lib/iomgr/endpoint_cfstream.cc
  84. 4
      src/core/lib/iomgr/endpoint_pair_posix.cc
  85. 72
      src/core/lib/iomgr/ev_epoll1_linux.cc
  86. 114
      src/core/lib/iomgr/ev_poll_posix.cc
  87. 9
      src/core/lib/iomgr/ev_posix.cc
  88. 6
      src/core/lib/iomgr/exec_ctx.cc
  89. 2
      src/core/lib/iomgr/exec_ctx.h
  90. 13
      src/core/lib/iomgr/fork_posix.cc
  91. 36
      src/core/lib/iomgr/internal_errqueue.cc
  92. 83
      src/core/lib/iomgr/internal_errqueue.h
  93. 5
      src/core/lib/iomgr/port.h
  94. 2
      src/core/lib/iomgr/socket_mutator.cc
  95. 2
      src/core/lib/iomgr/socket_mutator.h
  96. 2
      src/core/lib/iomgr/tcp_client_posix.cc
  97. 2
      src/core/lib/iomgr/tcp_custom.cc
  98. 312
      src/core/lib/iomgr/tcp_posix.cc
  99. 3
      src/core/lib/iomgr/tcp_posix.h
  100. 4
      src/core/lib/iomgr/tcp_server_posix.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,6 +1,6 @@
---
Checks: 'modernize-use-nullptr,google-build-namespaces,google-build-explicit-make-pair,readability-function-size,performance-*'
WarningsAsErrors: 'modernize-use-nullptr,google-build-namespaces,google-build-explicit-make-pair,readability-function-size,performance-*'
Checks: 'modernize-use-nullptr,google-build-namespaces,google-build-explicit-make-pair,readability-function-size,performance-*,bugprone-*'
WarningsAsErrors: 'modernize-use-nullptr,google-build-namespaces,google-build-explicit-make-pair,readability-function-size,performance-*,bugprone-*'
CheckOptions:
- key: readability-function-size.StatementThreshold
value: '450'

@ -20,6 +20,8 @@ notes=FIXME,XXX
[MESSAGES CONTROL]
extension-pkg-whitelist=grpc._cython.cygrpc
disable=
# These suppressions are specific to tests:
#

18
BUILD

@ -64,11 +64,11 @@ config_setting(
)
# This should be updated along with build.yaml
g_stands_for = "glider"
g_stands_for = "gao"
core_version = "6.0.0-dev"
version = "1.15.0-dev"
version = "1.16.0-dev"
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",
@ -696,6 +696,7 @@ grpc_cc_library(
"src/core/lib/http/format_request.cc",
"src/core/lib/http/httpcli.cc",
"src/core/lib/http/parser.cc",
"src/core/lib/iomgr/buffer_list.cc",
"src/core/lib/iomgr/call_combiner.cc",
"src/core/lib/iomgr/combiner.cc",
"src/core/lib/iomgr/endpoint.cc",
@ -716,6 +717,7 @@ grpc_cc_library(
"src/core/lib/iomgr/gethostname_fallback.cc",
"src/core/lib/iomgr/gethostname_host_name_max.cc",
"src/core/lib/iomgr/gethostname_sysconf.cc",
"src/core/lib/iomgr/internal_errqueue.cc",
"src/core/lib/iomgr/iocp_windows.cc",
"src/core/lib/iomgr/iomgr.cc",
"src/core/lib/iomgr/iomgr_custom.cc",
@ -845,6 +847,7 @@ grpc_cc_library(
"src/core/lib/http/format_request.h",
"src/core/lib/http/httpcli.h",
"src/core/lib/http/parser.h",
"src/core/lib/iomgr/buffer_list.h",
"src/core/lib/iomgr/block_annotate.h",
"src/core/lib/iomgr/call_combiner.h",
"src/core/lib/iomgr/closure.h",
@ -862,6 +865,7 @@ grpc_cc_library(
"src/core/lib/iomgr/executor.h",
"src/core/lib/iomgr/gethostname.h",
"src/core/lib/iomgr/gevent_util.h",
"src/core/lib/iomgr/internal_errqueue.h",
"src/core/lib/iomgr/iocp_windows.h",
"src/core/lib/iomgr/iomgr.h",
"src/core/lib/iomgr/iomgr_custom.h",
@ -1549,6 +1553,7 @@ grpc_cc_library(
"grpc_base",
"grpc_transport_chttp2_alpn",
"tsi",
"grpc_shadow_boringssl",
],
)
@ -1809,6 +1814,7 @@ grpc_cc_library(
"gpr",
"grpc_base",
"tsi_interface",
"grpc_shadow_boringssl",
],
)
@ -1905,6 +1911,7 @@ grpc_cc_library(
"grpc_base",
"grpc_transport_chttp2_client_insecure",
"tsi_interface",
"grpc_shadow_boringssl",
],
)
@ -2160,4 +2167,11 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "grpc_shadow_boringssl",
hdrs = [
"src/core/tsi/grpc_shadow_boringssl.h",
],
)
grpc_generate_one_off_targets()

@ -103,6 +103,9 @@ repository at the latest stable version.
In the C++ world, there's no "standard" build system that would work for in all supported use cases and on all supported platforms.
Therefore, gRPC supports several major build systems, which should satisfy most users.
Note that this section only covers the build of gRPC itself, not the installation. See the [How to use](https://github.com/grpc/grpc/tree/master/src/cpp#to-start-using-grpc-c) instructions
for guidance on how to add gRPC as a dependency to a C++ application (there are several ways and system wide installation is often not the best choice).
## make (on UNIX systems)
From the grpc repository root

@ -24,7 +24,7 @@
cmake_minimum_required(VERSION 2.8)
set(PACKAGE_NAME "grpc")
set(PACKAGE_VERSION "1.15.0-dev")
set(PACKAGE_VERSION "1.16.0-dev")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@ -230,6 +230,9 @@ add_dependencies(buildtests_c avl_test)
add_dependencies(buildtests_c bad_server_response_test)
add_dependencies(buildtests_c bin_decoder_test)
add_dependencies(buildtests_c bin_encoder_test)
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c buffer_list_test)
endif()
add_dependencies(buildtests_c channel_create_test)
add_dependencies(buildtests_c chttp2_hpack_encoder_test)
add_dependencies(buildtests_c chttp2_stream_map_test)
@ -331,6 +334,7 @@ if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c httpscli_test)
endif()
add_dependencies(buildtests_c init_test)
add_dependencies(buildtests_c inproc_callback_test)
add_dependencies(buildtests_c invalid_call_argument_test)
add_dependencies(buildtests_c json_rewrite)
add_dependencies(buildtests_c json_rewrite_test)
@ -958,6 +962,7 @@ add_library(grpc
src/core/lib/http/format_request.cc
src/core/lib/http/httpcli.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/buffer_list.cc
src/core/lib/iomgr/call_combiner.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.cc
@ -978,6 +983,7 @@ add_library(grpc
src/core/lib/iomgr/gethostname_fallback.cc
src/core/lib/iomgr/gethostname_host_name_max.cc
src/core/lib/iomgr/gethostname_sysconf.cc
src/core/lib/iomgr/internal_errqueue.cc
src/core/lib/iomgr/iocp_windows.cc
src/core/lib/iomgr/iomgr.cc
src/core/lib/iomgr/iomgr_custom.cc
@ -1364,6 +1370,7 @@ add_library(grpc_cronet
src/core/lib/http/format_request.cc
src/core/lib/http/httpcli.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/buffer_list.cc
src/core/lib/iomgr/call_combiner.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.cc
@ -1384,6 +1391,7 @@ add_library(grpc_cronet
src/core/lib/iomgr/gethostname_fallback.cc
src/core/lib/iomgr/gethostname_host_name_max.cc
src/core/lib/iomgr/gethostname_sysconf.cc
src/core/lib/iomgr/internal_errqueue.cc
src/core/lib/iomgr/iocp_windows.cc
src/core/lib/iomgr/iomgr.cc
src/core/lib/iomgr/iomgr_custom.cc
@ -1756,6 +1764,7 @@ add_library(grpc_test_util
src/core/lib/http/format_request.cc
src/core/lib/http/httpcli.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/buffer_list.cc
src/core/lib/iomgr/call_combiner.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.cc
@ -1776,6 +1785,7 @@ add_library(grpc_test_util
src/core/lib/iomgr/gethostname_fallback.cc
src/core/lib/iomgr/gethostname_host_name_max.cc
src/core/lib/iomgr/gethostname_sysconf.cc
src/core/lib/iomgr/internal_errqueue.cc
src/core/lib/iomgr/iocp_windows.cc
src/core/lib/iomgr/iomgr.cc
src/core/lib/iomgr/iomgr_custom.cc
@ -2064,6 +2074,7 @@ add_library(grpc_test_util_unsecure
src/core/lib/http/format_request.cc
src/core/lib/http/httpcli.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/buffer_list.cc
src/core/lib/iomgr/call_combiner.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.cc
@ -2084,6 +2095,7 @@ add_library(grpc_test_util_unsecure
src/core/lib/iomgr/gethostname_fallback.cc
src/core/lib/iomgr/gethostname_host_name_max.cc
src/core/lib/iomgr/gethostname_sysconf.cc
src/core/lib/iomgr/internal_errqueue.cc
src/core/lib/iomgr/iocp_windows.cc
src/core/lib/iomgr/iomgr.cc
src/core/lib/iomgr/iomgr_custom.cc
@ -2351,6 +2363,7 @@ add_library(grpc_unsecure
src/core/lib/http/format_request.cc
src/core/lib/http/httpcli.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/buffer_list.cc
src/core/lib/iomgr/call_combiner.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.cc
@ -2371,6 +2384,7 @@ add_library(grpc_unsecure
src/core/lib/iomgr/gethostname_fallback.cc
src/core/lib/iomgr/gethostname_host_name_max.cc
src/core/lib/iomgr/gethostname_sysconf.cc
src/core/lib/iomgr/internal_errqueue.cc
src/core/lib/iomgr/iocp_windows.cc
src/core/lib/iomgr/iomgr.cc
src/core/lib/iomgr/iomgr_custom.cc
@ -3191,6 +3205,7 @@ add_library(grpc++_cronet
src/core/lib/http/format_request.cc
src/core/lib/http/httpcli.cc
src/core/lib/http/parser.cc
src/core/lib/iomgr/buffer_list.cc
src/core/lib/iomgr/call_combiner.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/endpoint.cc
@ -3211,6 +3226,7 @@ add_library(grpc++_cronet
src/core/lib/iomgr/gethostname_fallback.cc
src/core/lib/iomgr/gethostname_host_name_max.cc
src/core/lib/iomgr/gethostname_sysconf.cc
src/core/lib/iomgr/internal_errqueue.cc
src/core/lib/iomgr/iocp_windows.cc
src/core/lib/iomgr/iomgr.cc
src/core/lib/iomgr/iomgr_custom.cc
@ -5834,6 +5850,37 @@ target_link_libraries(bin_encoder_test
grpc
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX)
add_executable(buffer_list_test
test/core/iomgr/buffer_list_test.cc
)
target_include_directories(buffer_list_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(buffer_list_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr_test_util
gpr
)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
@ -7893,6 +7940,35 @@ target_link_libraries(init_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(inproc_callback_test
test/core/end2end/inproc_callback_test.cc
)
target_include_directories(inproc_callback_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(inproc_callback_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr_test_util
gpr
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(invalid_call_argument_test
test/core/end2end/invalid_call_argument_test.cc
)

@ -437,8 +437,8 @@ Q = @
endif
CORE_VERSION = 6.0.0-dev
CPP_VERSION = 1.15.0-dev
CSHARP_VERSION = 1.15.0-dev
CPP_VERSION = 1.16.0-dev
CSHARP_VERSION = 1.16.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@ -978,6 +978,7 @@ avl_test: $(BINDIR)/$(CONFIG)/avl_test
bad_server_response_test: $(BINDIR)/$(CONFIG)/bad_server_response_test
bin_decoder_test: $(BINDIR)/$(CONFIG)/bin_decoder_test
bin_encoder_test: $(BINDIR)/$(CONFIG)/bin_encoder_test
buffer_list_test: $(BINDIR)/$(CONFIG)/buffer_list_test
channel_create_test: $(BINDIR)/$(CONFIG)/channel_create_test
check_epollexclusive: $(BINDIR)/$(CONFIG)/check_epollexclusive
chttp2_hpack_encoder_test: $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test
@ -1053,6 +1054,7 @@ httpcli_format_request_test: $(BINDIR)/$(CONFIG)/httpcli_format_request_test
httpcli_test: $(BINDIR)/$(CONFIG)/httpcli_test
httpscli_test: $(BINDIR)/$(CONFIG)/httpscli_test
init_test: $(BINDIR)/$(CONFIG)/init_test
inproc_callback_test: $(BINDIR)/$(CONFIG)/inproc_callback_test
invalid_call_argument_test: $(BINDIR)/$(CONFIG)/invalid_call_argument_test
json_fuzzer_test: $(BINDIR)/$(CONFIG)/json_fuzzer_test
json_rewrite: $(BINDIR)/$(CONFIG)/json_rewrite
@ -1433,6 +1435,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/bad_server_response_test \
$(BINDIR)/$(CONFIG)/bin_decoder_test \
$(BINDIR)/$(CONFIG)/bin_encoder_test \
$(BINDIR)/$(CONFIG)/buffer_list_test \
$(BINDIR)/$(CONFIG)/channel_create_test \
$(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test \
$(BINDIR)/$(CONFIG)/chttp2_stream_map_test \
@ -1500,6 +1503,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/httpcli_test \
$(BINDIR)/$(CONFIG)/httpscli_test \
$(BINDIR)/$(CONFIG)/init_test \
$(BINDIR)/$(CONFIG)/inproc_callback_test \
$(BINDIR)/$(CONFIG)/invalid_call_argument_test \
$(BINDIR)/$(CONFIG)/json_rewrite \
$(BINDIR)/$(CONFIG)/json_rewrite_test \
@ -1948,6 +1952,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/bin_decoder_test || ( echo test bin_decoder_test failed ; exit 1 )
$(E) "[RUN] Testing bin_encoder_test"
$(Q) $(BINDIR)/$(CONFIG)/bin_encoder_test || ( echo test bin_encoder_test failed ; exit 1 )
$(E) "[RUN] Testing buffer_list_test"
$(Q) $(BINDIR)/$(CONFIG)/buffer_list_test || ( echo test buffer_list_test failed ; exit 1 )
$(E) "[RUN] Testing channel_create_test"
$(Q) $(BINDIR)/$(CONFIG)/channel_create_test || ( echo test channel_create_test failed ; exit 1 )
$(E) "[RUN] Testing chttp2_hpack_encoder_test"
@ -2076,6 +2082,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/httpscli_test || ( echo test httpscli_test failed ; exit 1 )
$(E) "[RUN] Testing init_test"
$(Q) $(BINDIR)/$(CONFIG)/init_test || ( echo test init_test failed ; exit 1 )
$(E) "[RUN] Testing inproc_callback_test"
$(Q) $(BINDIR)/$(CONFIG)/inproc_callback_test || ( echo test inproc_callback_test failed ; exit 1 )
$(E) "[RUN] Testing invalid_call_argument_test"
$(Q) $(BINDIR)/$(CONFIG)/invalid_call_argument_test || ( echo test invalid_call_argument_test failed ; exit 1 )
$(E) "[RUN] Testing json_rewrite_test"
@ -3456,6 +3464,7 @@ LIBGRPC_SRC = \
src/core/lib/http/format_request.cc \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/buffer_list.cc \
src/core/lib/iomgr/call_combiner.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
@ -3476,6 +3485,7 @@ LIBGRPC_SRC = \
src/core/lib/iomgr/gethostname_fallback.cc \
src/core/lib/iomgr/gethostname_host_name_max.cc \
src/core/lib/iomgr/gethostname_sysconf.cc \
src/core/lib/iomgr/internal_errqueue.cc \
src/core/lib/iomgr/iocp_windows.cc \
src/core/lib/iomgr/iomgr.cc \
src/core/lib/iomgr/iomgr_custom.cc \
@ -3861,6 +3871,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/http/format_request.cc \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/buffer_list.cc \
src/core/lib/iomgr/call_combiner.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
@ -3881,6 +3892,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/iomgr/gethostname_fallback.cc \
src/core/lib/iomgr/gethostname_host_name_max.cc \
src/core/lib/iomgr/gethostname_sysconf.cc \
src/core/lib/iomgr/internal_errqueue.cc \
src/core/lib/iomgr/iocp_windows.cc \
src/core/lib/iomgr/iomgr.cc \
src/core/lib/iomgr/iomgr_custom.cc \
@ -4251,6 +4263,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/http/format_request.cc \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/buffer_list.cc \
src/core/lib/iomgr/call_combiner.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
@ -4271,6 +4284,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/iomgr/gethostname_fallback.cc \
src/core/lib/iomgr/gethostname_host_name_max.cc \
src/core/lib/iomgr/gethostname_sysconf.cc \
src/core/lib/iomgr/internal_errqueue.cc \
src/core/lib/iomgr/iocp_windows.cc \
src/core/lib/iomgr/iomgr.cc \
src/core/lib/iomgr/iomgr_custom.cc \
@ -4550,6 +4564,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/lib/http/format_request.cc \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/buffer_list.cc \
src/core/lib/iomgr/call_combiner.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
@ -4570,6 +4585,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/lib/iomgr/gethostname_fallback.cc \
src/core/lib/iomgr/gethostname_host_name_max.cc \
src/core/lib/iomgr/gethostname_sysconf.cc \
src/core/lib/iomgr/internal_errqueue.cc \
src/core/lib/iomgr/iocp_windows.cc \
src/core/lib/iomgr/iomgr.cc \
src/core/lib/iomgr/iomgr_custom.cc \
@ -4815,6 +4831,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/http/format_request.cc \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/buffer_list.cc \
src/core/lib/iomgr/call_combiner.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
@ -4835,6 +4852,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/iomgr/gethostname_fallback.cc \
src/core/lib/iomgr/gethostname_host_name_max.cc \
src/core/lib/iomgr/gethostname_sysconf.cc \
src/core/lib/iomgr/internal_errqueue.cc \
src/core/lib/iomgr/iocp_windows.cc \
src/core/lib/iomgr/iomgr.cc \
src/core/lib/iomgr/iomgr_custom.cc \
@ -5643,6 +5661,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/http/format_request.cc \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/buffer_list.cc \
src/core/lib/iomgr/call_combiner.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
@ -5663,6 +5682,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/iomgr/gethostname_fallback.cc \
src/core/lib/iomgr/gethostname_host_name_max.cc \
src/core/lib/iomgr/gethostname_sysconf.cc \
src/core/lib/iomgr/internal_errqueue.cc \
src/core/lib/iomgr/iocp_windows.cc \
src/core/lib/iomgr/iomgr.cc \
src/core/lib/iomgr/iomgr_custom.cc \
@ -10697,6 +10717,38 @@ endif
endif
BUFFER_LIST_TEST_SRC = \
test/core/iomgr/buffer_list_test.cc \
BUFFER_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BUFFER_LIST_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/buffer_list_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/buffer_list_test: $(BUFFER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(BUFFER_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/buffer_list_test
endif
$(OBJDIR)/$(CONFIG)/test/core/iomgr/buffer_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_buffer_list_test: $(BUFFER_LIST_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(BUFFER_LIST_TEST_OBJS:.o=.dep)
endif
endif
CHANNEL_CREATE_TEST_SRC = \
test/core/surface/channel_create_test.cc \
@ -13115,6 +13167,38 @@ endif
endif
INPROC_CALLBACK_TEST_SRC = \
test/core/end2end/inproc_callback_test.cc \
INPROC_CALLBACK_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INPROC_CALLBACK_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/inproc_callback_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/inproc_callback_test: $(INPROC_CALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(INPROC_CALLBACK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/inproc_callback_test
endif
$(OBJDIR)/$(CONFIG)/test/core/end2end/inproc_callback_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_inproc_callback_test: $(INPROC_CALLBACK_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(INPROC_CALLBACK_TEST_OBJS:.o=.dep)
endif
endif
INVALID_CALL_ARGUMENT_TEST_SRC = \
test/core/end2end/invalid_call_argument_test.cc \

@ -24,178 +24,203 @@
#
# The set of pollers to test against if a test exercises polling
POLLERS = ['epollex', 'epollsig', 'epoll1', 'poll', 'poll-cv']
POLLERS = ["epollex", "epollsig", "epoll1", "poll", "poll-cv"]
def if_not_windows(a):
return select({
"//:windows": [],
"//:windows_msvc": [],
"//conditions:default": a,
})
return select({
"//:windows": [],
"//:windows_msvc": [],
"//conditions:default": a,
})
def _get_external_deps(external_deps):
ret = []
for dep in external_deps:
if dep == "address_sorting":
ret += ["//third_party/address_sorting"]
elif dep == "cares":
ret += select({"//:grpc_no_ares": [],
"//conditions:default": ["//external:cares"],})
else:
ret += ["//external:" + dep]
return ret
ret = []
for dep in external_deps:
if dep == "address_sorting":
ret += ["//third_party/address_sorting"]
elif dep == "cares":
ret += select({
"//:grpc_no_ares": [],
"//conditions:default": ["//external:cares"],
})
else:
ret += ["//external:" + dep]
return ret
def _maybe_update_cc_library_hdrs(hdrs):
ret = []
hdrs_to_update = {
"third_party/objective_c/Cronet/bidirectional_stream_c.h": "//third_party:objective_c/Cronet/bidirectional_stream_c.h",
}
for h in hdrs:
if h in hdrs_to_update.keys():
ret.append(hdrs_to_update[h])
else:
ret.append(h)
return ret
def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [],
external_deps = [], deps = [], standalone = False,
language = "C++", testonly = False, visibility = None,
alwayslink = 0, data = []):
copts = []
if language.upper() == "C":
copts = if_not_windows(["-std=c99"])
native.cc_library(
name = name,
srcs = srcs,
defines = select({"//:grpc_no_ares": ["GRPC_ARES=0"],
"//conditions:default": [],}) +
select({"//:remote_execution": ["GRPC_PORT_ISOLATED_RUNTIME=1"],
"//conditions:default": [],}) +
select({"//:grpc_allow_exceptions": ["GRPC_ALLOW_EXCEPTIONS=1"],
"//:grpc_disallow_exceptions":
["GRPC_ALLOW_EXCEPTIONS=0"],
"//conditions:default": [],}),
hdrs = _maybe_update_cc_library_hdrs(hdrs + public_hdrs),
deps = deps + _get_external_deps(external_deps),
copts = copts,
visibility = visibility,
testonly = testonly,
linkopts = if_not_windows(["-pthread"]),
includes = [
"include"
],
alwayslink = alwayslink,
data = data,
)
ret = []
hdrs_to_update = {
"third_party/objective_c/Cronet/bidirectional_stream_c.h": "//third_party:objective_c/Cronet/bidirectional_stream_c.h",
}
for h in hdrs:
if h in hdrs_to_update.keys():
ret.append(hdrs_to_update[h])
else:
ret.append(h)
return ret
def grpc_cc_library(
name,
srcs = [],
public_hdrs = [],
hdrs = [],
external_deps = [],
deps = [],
standalone = False,
language = "C++",
testonly = False,
visibility = None,
alwayslink = 0,
data = []):
copts = []
if language.upper() == "C":
copts = if_not_windows(["-std=c99"])
native.cc_library(
name = name,
srcs = srcs,
defines = select({
"//:grpc_no_ares": ["GRPC_ARES=0"],
"//conditions:default": [],
}) +
select({
"//:remote_execution": ["GRPC_PORT_ISOLATED_RUNTIME=1"],
"//conditions:default": [],
}) +
select({
"//:grpc_allow_exceptions": ["GRPC_ALLOW_EXCEPTIONS=1"],
"//:grpc_disallow_exceptions": ["GRPC_ALLOW_EXCEPTIONS=0"],
"//conditions:default": [],
}),
hdrs = _maybe_update_cc_library_hdrs(hdrs + public_hdrs),
deps = deps + _get_external_deps(external_deps),
copts = copts,
visibility = visibility,
testonly = testonly,
linkopts = if_not_windows(["-pthread"]),
includes = [
"include",
],
alwayslink = alwayslink,
data = data,
)
def grpc_proto_plugin(name, srcs = [], deps = []):
native.cc_binary(
name = name,
srcs = srcs,
deps = deps,
)
native.cc_binary(
name = name,
srcs = srcs,
deps = deps,
)
load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library")
def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = False,
has_services = True, use_external = False, generate_mocks = False):
cc_grpc_library(
name = name,
srcs = srcs,
deps = deps,
well_known_protos = well_known_protos,
proto_only = not has_services,
use_external = use_external,
generate_mocks = generate_mocks,
)
def grpc_proto_library(
name,
srcs = [],
deps = [],
well_known_protos = False,
has_services = True,
use_external = False,
generate_mocks = False):
cc_grpc_library(
name = name,
srcs = srcs,
deps = deps,
well_known_protos = well_known_protos,
proto_only = not has_services,
use_external = use_external,
generate_mocks = generate_mocks,
)
def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = "moderate", tags = []):
copts = []
if language.upper() == "C":
copts = if_not_windows(["-std=c99"])
args = {
'name': name,
'srcs': srcs,
'args': args,
'data': data,
'deps': deps + _get_external_deps(external_deps),
'copts': copts,
'linkopts': if_not_windows(["-pthread"]),
'size': size,
'timeout': timeout,
}
if uses_polling:
native.cc_test(testonly=True, tags=['manual'], **args)
for poller in POLLERS:
native.sh_test(
name = name + '@poller=' + poller,
data = [name],
srcs = [
'//test/core/util:run_with_poller_sh',
],
size = size,
timeout = timeout,
args = [
poller,
'$(location %s)' % name,
] + args['args'],
tags = tags,
)
else:
native.cc_test(**args)
copts = []
if language.upper() == "C":
copts = if_not_windows(["-std=c99"])
args = {
"name": name,
"srcs": srcs,
"args": args,
"data": data,
"deps": deps + _get_external_deps(external_deps),
"copts": copts,
"linkopts": if_not_windows(["-pthread"]),
"size": size,
"timeout": timeout,
}
if uses_polling:
native.cc_test(testonly = True, tags = ["manual"], **args)
for poller in POLLERS:
native.sh_test(
name = name + "@poller=" + poller,
data = [name] + data,
srcs = [
"//test/core/util:run_with_poller_sh",
],
size = size,
timeout = timeout,
args = [
poller,
"$(location %s)" % name,
] + args["args"],
tags = tags,
)
else:
native.cc_test(**args)
def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], data = [], language = "C++", testonly = False, linkshared = False, linkopts = []):
copts = []
if language.upper() == "C":
copts = ["-std=c99"]
native.cc_binary(
name = name,
srcs = srcs,
args = args,
data = data,
testonly = testonly,
linkshared = linkshared,
deps = deps + _get_external_deps(external_deps),
copts = copts,
linkopts = if_not_windows(["-pthread"]) + linkopts,
)
def grpc_generate_one_off_targets(): pass
copts = []
if language.upper() == "C":
copts = ["-std=c99"]
native.cc_binary(
name = name,
srcs = srcs,
args = args,
data = data,
testonly = testonly,
linkshared = linkshared,
deps = deps + _get_external_deps(external_deps),
copts = copts,
linkopts = if_not_windows(["-pthread"]) + linkopts,
)
def grpc_generate_one_off_targets():
pass
def grpc_sh_test(name, srcs, args = [], data = []):
native.sh_test(
name = name,
srcs = srcs,
args = args,
data = data)
native.sh_test(
name = name,
srcs = srcs,
args = args,
data = data,
)
def grpc_sh_binary(name, srcs, data = []):
native.sh_binary(
name = name,
srcs = srcs,
data = data)
native.sh_binary(
name = name,
srcs = srcs,
data = data,
)
def grpc_py_binary(name, srcs, data = [], deps = [], external_deps = [], testonly = False):
native.py_binary(
name = name,
srcs = srcs,
testonly = testonly,
data = data,
deps = deps + _get_external_deps(external_deps)
)
native.py_binary(
name = name,
srcs = srcs,
testonly = testonly,
data = data,
deps = deps + _get_external_deps(external_deps),
)
def grpc_package(name, visibility = "private", features = []):
if visibility == "tests":
visibility = ["//test:__subpackages__"]
elif visibility == "public":
visibility = ["//visibility:public"]
elif visibility == "private":
visibility = []
else:
fail("Unknown visibility " + visibility)
if len(visibility) != 0:
native.package(
default_visibility = visibility,
features = features
)
if visibility == "tests":
visibility = ["//test:__subpackages__"]
elif visibility == "public":
visibility = ["//visibility:public"]
elif visibility == "private":
visibility = []
else:
fail("Unknown visibility " + visibility)
if len(visibility) != 0:
native.package(
default_visibility = visibility,
features = features,
)

@ -169,12 +169,12 @@ def grpc_deps():
if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules():
native.http_archive(
name = "com_github_bazelbuild_bazeltoolchains",
strip_prefix = "bazel-toolchains-4653c01284d8a4a536f8f9bb47b7d10f94c549e7",
strip_prefix = "bazel-toolchains-cdea5b8675914d0a354d89f108de5d28e54e0edc",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/4653c01284d8a4a536f8f9bb47b7d10f94c549e7.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/archive/4653c01284d8a4a536f8f9bb47b7d10f94c549e7.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/cdea5b8675914d0a354d89f108de5d28e54e0edc.tar.gz",
"https://github.com/bazelbuild/bazel-toolchains/archive/cdea5b8675914d0a354d89f108de5d28e54e0edc.tar.gz",
],
sha256 = "1c4a532b396c698e6467a1548554571cb85fa091e472b05e398ebc836c315d77",
sha256 = "cefb6ccf86ca592baaa029bcef04148593c0efe8f734542f10293ea58f170715",
)
if "io_opencensus_cpp" not in native.existing_rules():

@ -13,8 +13,8 @@ settings:
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 6.0.0-dev
g_stands_for: glider
version: 1.15.0-dev
g_stands_for: gao
version: 1.16.0-dev
filegroups:
- name: alts_proto
headers:
@ -69,6 +69,7 @@ filegroups:
- grpc_transport_chttp2_client_insecure
- tsi_interface
- tsi
- grpc_shadow_boringssl
- name: alts_util
public_headers:
- include/grpc/grpc_security.h
@ -255,6 +256,7 @@ filegroups:
- src/core/lib/http/format_request.cc
- src/core/lib/http/httpcli.cc
- src/core/lib/http/parser.cc
- src/core/lib/iomgr/buffer_list.cc
- src/core/lib/iomgr/call_combiner.cc
- src/core/lib/iomgr/combiner.cc
- src/core/lib/iomgr/endpoint.cc
@ -275,6 +277,7 @@ filegroups:
- src/core/lib/iomgr/gethostname_fallback.cc
- src/core/lib/iomgr/gethostname_host_name_max.cc
- src/core/lib/iomgr/gethostname_sysconf.cc
- src/core/lib/iomgr/internal_errqueue.cc
- src/core/lib/iomgr/iocp_windows.cc
- src/core/lib/iomgr/iomgr.cc
- src/core/lib/iomgr/iomgr_custom.cc
@ -433,6 +436,7 @@ filegroups:
- src/core/lib/http/httpcli.h
- src/core/lib/http/parser.h
- src/core/lib/iomgr/block_annotate.h
- src/core/lib/iomgr/buffer_list.h
- src/core/lib/iomgr/call_combiner.h
- src/core/lib/iomgr/closure.h
- src/core/lib/iomgr/combiner.h
@ -448,6 +452,7 @@ filegroups:
- src/core/lib/iomgr/exec_ctx.h
- src/core/lib/iomgr/executor.h
- src/core/lib/iomgr/gethostname.h
- src/core/lib/iomgr/internal_errqueue.h
- src/core/lib/iomgr/iocp_windows.h
- src/core/lib/iomgr/iomgr.h
- src/core/lib/iomgr/iomgr_custom.h
@ -841,6 +846,7 @@ filegroups:
- grpc_base
- grpc_transport_chttp2_alpn
- tsi
- grpc_shadow_boringssl
- name: grpc_server_backward_compatibility
headers:
- src/core/ext/filters/workarounds/workaround_utils.h
@ -848,6 +854,9 @@ filegroups:
- src/core/ext/filters/workarounds/workaround_utils.cc
uses:
- grpc_base
- name: grpc_shadow_boringssl
headers:
- src/core/tsi/grpc_shadow_boringssl.h
- name: grpc_test_util_base
build: test
headers:
@ -1109,6 +1118,7 @@ filegroups:
- tsi_interface
- grpc_base
- grpc_trace
- grpc_shadow_boringssl
- name: tsi_interface
headers:
- src/core/tsi/transport_security.h
@ -2133,6 +2143,20 @@ targets:
- grpc_test_util
- grpc
uses_polling: false
- name: buffer_list_test
build: test
language: c
src:
- test/core/iomgr/buffer_list_test.cc
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
exclude_iomgrs:
- uv
platforms:
- linux
- name: channel_create_test
build: test
language: c
@ -3016,6 +3040,19 @@ targets:
- gpr_test_util
- gpr
uses_polling: false
- name: inproc_callback_test
build: test
language: c
headers:
- test/core/end2end/end2end_tests.h
src:
- test/core/end2end/inproc_callback_test.cc
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
uses_polling: false
- name: invalid_call_argument_test
cpu_cost: 0.1
build: test

@ -17,7 +17,14 @@ if("${gRPC_SSL_PROVIDER}" STREQUAL "module")
set(BORINGSSL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/boringssl)
endif()
if(EXISTS "${BORINGSSL_ROOT_DIR}/CMakeLists.txt")
set(OPENSSL_NO_ASM ON) # make boringssl buildable with Visual Studio
if (MSVC AND NOT CMAKE_GENERATOR STREQUAL "Ninja")
# Visual Studio build with assembly optimizations is broken,
# but it works with Ninja generator.
# This will get eventually fixed in cmake, but until then
# we need to disable assembly optimizations.
# See https://github.com/grpc/grpc/issues/16376
set(OPENSSL_NO_ASM ON)
endif()
add_subdirectory(${BORINGSSL_ROOT_DIR} third_party/boringssl)
if(TARGET ssl)
set(_gRPC_SSL_LIBRARIES ssl)

@ -108,6 +108,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/http/format_request.cc \
src/core/lib/http/httpcli.cc \
src/core/lib/http/parser.cc \
src/core/lib/iomgr/buffer_list.cc \
src/core/lib/iomgr/call_combiner.cc \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/endpoint.cc \
@ -128,6 +129,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/iomgr/gethostname_fallback.cc \
src/core/lib/iomgr/gethostname_host_name_max.cc \
src/core/lib/iomgr/gethostname_sysconf.cc \
src/core/lib/iomgr/internal_errqueue.cc \
src/core/lib/iomgr/iocp_windows.cc \
src/core/lib/iomgr/iomgr.cc \
src/core/lib/iomgr/iomgr_custom.cc \

@ -83,6 +83,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\http\\format_request.cc " +
"src\\core\\lib\\http\\httpcli.cc " +
"src\\core\\lib\\http\\parser.cc " +
"src\\core\\lib\\iomgr\\buffer_list.cc " +
"src\\core\\lib\\iomgr\\call_combiner.cc " +
"src\\core\\lib\\iomgr\\combiner.cc " +
"src\\core\\lib\\iomgr\\endpoint.cc " +
@ -103,6 +104,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\iomgr\\gethostname_fallback.cc " +
"src\\core\\lib\\iomgr\\gethostname_host_name_max.cc " +
"src\\core\\lib\\iomgr\\gethostname_sysconf.cc " +
"src\\core\\lib\\iomgr\\internal_errqueue.cc " +
"src\\core\\lib\\iomgr\\iocp_windows.cc " +
"src\\core\\lib\\iomgr\\iomgr.cc " +
"src\\core\\lib\\iomgr\\iomgr_custom.cc " +

@ -56,7 +56,7 @@ For example, in the following code block, error1 and error2 are owned by the
current function.
```C
grpc_error* error1 = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
grpc_error* error1 = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occurred");
grpc_error* error2 = some_operation_that_might_fail(...);
```
@ -87,7 +87,7 @@ callbacks with `GRPC_CLOSURE_RUN` and `GRPC_CLOSURE_SCHED`. These functions are
not callbacks, so they will take ownership of the error passed to them.
```C
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occurred");
GRPC_CLOSURE_RUN(exec_ctx, cb, error);
// current function no longer has ownership of the error
```
@ -96,7 +96,7 @@ If you schedule or run a closure, but still need ownership of the error, then
you must explicitly take a reference.
```C
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occurred");
GRPC_CLOSURE_RUN(exec_ctx, cb, GRPC_ERROR_REF(error));
// do some other things with the error
GRPC_ERROR_UNREF(error);
@ -128,7 +128,7 @@ void on_some_action(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
Take the following example:
```C
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occured");
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Some error occurred");
// do some things
some_function(error);
// can't use error anymore! might be gone.

@ -17,3 +17,6 @@ number:
`include/grpc++/impl/codegen/client_context.h` (commit `9477724`)
- remove directory `include/grpc++` and all headers in it
(commit `eb06572`)
- make all `Request` and `Mark` methods in `grpc::Service` take a
`size_t` argument for `index` rather than `int` (since that is only
used as a vector index)

@ -14,4 +14,5 @@
- 1.12 'g' stands for ['glorious'](https://github.com/grpc/grpc/tree/v1.12.x)
- 1.13 'g' stands for ['gloriosa'](https://github.com/grpc/grpc/tree/v1.13.x)
- 1.14 'g' stands for ['gladiolus'](https://github.com/grpc/grpc/tree/v1.14.x)
- 1.15 'g' stands for ['glider'](https://github.com/grpc/grpc/tree/master)
- 1.15 'g' stands for ['glider'](https://github.com/grpc/grpc/tree/v1.15.x)
- 1.16 'g' stands for ['gao'](https://github.com/grpc/grpc/tree/master)

@ -14,34 +14,48 @@ be plugged in.
### Name Syntax
A fully qualified, self contained name used for gRPC channel construction
uses the syntax:
```
scheme://authority/endpoint_name
```
Here, `scheme` indicates the name-system to be used. Currently, we
support the following schemes:
- `dns`
- `ipv4` (IPv4 address)
- `ipv6` (IPv6 address)
- `unix` (path to unix domain socket -- unix systems only)
uses URI syntax as defined in [RFC 3986](https://tools.ietf.org/html/rfc3986).
The URI scheme indicates what resolver plugin to use. If no scheme
prefix is specified or the scheme is unknown, the `dns` scheme is used
by default.
The URI path indicates the name to be resolved.
Most gRPC implementations support the following URI schemes:
- `dns:[//authority/]host[:port]` -- DNS (default)
- `host` is the host to resolve via DNS.
- `port` is the port to return for each address. If not specified,
443 is used (but some implementations default to 80 for insecure
channels).
- `authority` indicates the DNS server to use, although this is only
supported by some implementations. (In C-core, the default DNS
resolver does not support this, but the c-ares based resolver
supports specifying this in the form "IP:port".)
- `unix:path` or `unix://absolute_path` -- Unix domain sockets (Unix systems only)
- `path` indicates the location of the desired socket.
- In the first form, the path may be relative or absolute; in the
second form, the path must be absolute (i.e., there will actually be
three slashes, two prior to the path and another to begin the
absolute path).
The following schemes are supported by the gRPC C-core implementation,
but may not be supported in other languages:
- `ipv4:address[:port][,address[:port],...]` -- IPv4 addresses
- Can specify multiple comma-delimited addresses of the form `address[:port]`:
- `address` is the IPv4 address to use.
- `port` is the port to use. If not specified, 443 is used.
- `ipv6:address[:port][,address[:port],...]` -- IPv6 addresses
- Can specify multiple comma-delimited addresses of the form `address[:port]`:
- `address` is the IPv6 address to use.
- `port` is the port to use. If not specified, 443 is used.
In the future, additional schemes such as `etcd` could be added.
The `authority` indicates some scheme-specific bootstrap information, e.g.,
for DNS, the authority may include the IP[:port] of the DNS server to
use. Often, a DNS name may be used as the authority, since the ability to
resolve DNS names is already built into all gRPC client libraries.
Finally, the `endpoint_name` indicates a concrete name to be looked up
in a given name-system identified by the scheme and the authority. The
syntax of the endpoint name is dictated by the scheme in use.
### Resolver Plugins
The gRPC client library will use the specified scheme to pick the right

@ -14,7 +14,9 @@ Makefile | all other cases | all | :x:
Bazel | | Linux | :heavy_check_mark:
Bazel | | MacOS | :heavy_check_mark:
Bazel | | Windows | :x:
CMake | boringssl from submodule (default) | all | :x:
CMake | boringssl from submodule (default) | Linux or MacOS | :heavy_check_mark:
CMake | boringssl from submodule (default), generator=Ninja | Windows | :heavy_check_mark:
CMake | boringssl from submodule (default), generator=Visual Studio | Windows | :x:
CMake | pre-installed OpenSSL 1.0.2+ (`gRPC_SSL_PROVIDER=package`) | all | :heavy_check_mark:
## Other Languages: Binary/Source Packages

@ -2,17 +2,17 @@
<PropertyGroup>
<AssemblyTitle>Greeter</AssemblyTitle>
<TargetFrameworks>netcoreapp1.0</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<DebugType>portable</DebugType>
<AssemblyName>Greeter</AssemblyName>
<PackageId>Greeter</PackageId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.5.0" />
<PackageReference Include="Google.Protobuf.Tools" Version="3.5.0" />
<PackageReference Include="Grpc" Version="1.13.1" />
<PackageReference Include="Grpc.Tools" Version="1.13.1" />
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
<PackageReference Include="Google.Protobuf.Tools" Version="3.6.1" />
<PackageReference Include="Grpc" Version="1.14.1" />
<PackageReference Include="Grpc.Tools" Version="1.14.1" />
</ItemGroup>
</Project>

@ -1,5 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: helloworld.proto
// <auto-generated>
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: helloworld.proto
// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@ -44,6 +46,7 @@ namespace Helloworld {
/// </summary>
public sealed partial class HelloRequest : pb::IMessage<HelloRequest> {
private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
@ -67,6 +70,7 @@ namespace Helloworld {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public HelloRequest(HelloRequest other) : this() {
name_ = other.name_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -99,13 +103,16 @@ namespace Helloworld {
return true;
}
if (Name != other.Name) return false;
return true;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
@ -120,6 +127,9 @@ namespace Helloworld {
output.WriteRawTag(10);
output.WriteString(Name);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -128,6 +138,9 @@ namespace Helloworld {
if (Name.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
@ -139,6 +152,7 @@ namespace Helloworld {
if (other.Name.Length != 0) {
Name = other.Name;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -147,7 +161,7 @@ namespace Helloworld {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Name = input.ReadString();
@ -164,6 +178,7 @@ namespace Helloworld {
/// </summary>
public sealed partial class HelloReply : pb::IMessage<HelloReply> {
private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
@ -187,6 +202,7 @@ namespace Helloworld {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public HelloReply(HelloReply other) : this() {
message_ = other.message_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -219,13 +235,16 @@ namespace Helloworld {
return true;
}
if (Message != other.Message) return false;
return true;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Message.Length != 0) hash ^= Message.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
@ -240,6 +259,9 @@ namespace Helloworld {
output.WriteRawTag(10);
output.WriteString(Message);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -248,6 +270,9 @@ namespace Helloworld {
if (Message.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
@ -259,6 +284,7 @@ namespace Helloworld {
if (other.Message.Length != 0) {
Message = other.Message;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -267,7 +293,7 @@ namespace Helloworld {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Message = input.ReadString();

@ -1,5 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: helloworld.proto
// <auto-generated>
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: helloworld.proto
// </auto-generated>
// Original file comments:
// Copyright 2015 gRPC authors.
//
@ -15,12 +17,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#pragma warning disable 1591
#pragma warning disable 0414, 1591
#region Designer generated code
using System;
using System.Threading;
using System.Threading.Tasks;
using grpc = global::Grpc.Core;
namespace Helloworld {
@ -31,15 +30,15 @@ namespace Helloworld {
{
static readonly string __ServiceName = "helloworld.Greeter";
static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_helloworld_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
static readonly grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
grpc::MethodType.Unary,
__ServiceName,
"SayHello",
__Marshaller_HelloRequest,
__Marshaller_HelloReply);
__Marshaller_helloworld_HelloRequest,
__Marshaller_helloworld_HelloReply);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
@ -94,7 +93,7 @@ namespace Helloworld {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@ -116,7 +115,7 @@ namespace Helloworld {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}

@ -2,7 +2,7 @@
<PropertyGroup>
<AssemblyTitle>GreeterClient</AssemblyTitle>
<TargetFrameworks>netcoreapp1.0</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<DebugType>portable</DebugType>
<AssemblyName>GreeterClient</AssemblyName>
<OutputType>Exe</OutputType>

@ -2,7 +2,7 @@
<PropertyGroup>
<AssemblyTitle>GreeterServer</AssemblyTitle>
<TargetFrameworks>netcoreapp1.0</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<DebugType>portable</DebugType>
<AssemblyName>GreeterServer</AssemblyName>
<OutputType>Exe</OutputType>

@ -12,7 +12,7 @@ which have been already added to the project for you.
PREREQUISITES
-------------
- The [.NET Core SDK](https://www.microsoft.com/net/core) (version 2+ is recommended)
- The [.NET Core SDK 2.1+](https://www.microsoft.com/net/core)
You can also build the example directly using Visual Studio 2017, but it's not a requirement.
@ -23,8 +23,6 @@ From the `examples/csharp/Helloworld` directory:
- `dotnet build Greeter.sln`
(if you're using dotnet SDK 1.x you need to run `dotnet restore Greeter.sln` first)
Try it!
-------
@ -32,14 +30,14 @@ Try it!
```
> cd GreeterServer
> dotnet run -f netcoreapp1.0
> dotnet run -f netcoreapp2.1
```
- Run the client
```
> cd GreeterClient
> dotnet run -f netcoreapp1.0
> dotnet run -f netcoreapp2.1
```
Tutorial

@ -19,8 +19,9 @@ setlocal
@rem enter this directory
cd /d %~dp0
set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.5.0\tools\windows_x64\protoc.exe
set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.8.0\tools\windows_x64\grpc_csharp_plugin.exe
@rem packages will be available in nuget cache directory once the project is built or after "dotnet restore"
set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.6.1\tools\windows_x64\protoc.exe
set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.14.1\tools\windows_x64\grpc_csharp_plugin.exe
%PROTOC% -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%PLUGIN%

@ -32,18 +32,17 @@
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.5.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\packages\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll</HintPath>
<Private>True</Private>
<Reference Include="Google.Protobuf, Version=3.6.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<HintPath>..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Grpc.Core">
<HintPath>..\packages\Grpc.Core.1.13.1\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
@ -62,5 +61,11 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="..\packages\Grpc.Core.1.13.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.13.1\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use 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('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets'))" />
</Target>
</Project>

@ -1,5 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: helloworld.proto
// <auto-generated>
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: helloworld.proto
// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@ -44,6 +46,7 @@ namespace Helloworld {
/// </summary>
public sealed partial class HelloRequest : pb::IMessage<HelloRequest> {
private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
@ -67,6 +70,7 @@ namespace Helloworld {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public HelloRequest(HelloRequest other) : this() {
name_ = other.name_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -99,13 +103,16 @@ namespace Helloworld {
return true;
}
if (Name != other.Name) return false;
return true;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
@ -120,6 +127,9 @@ namespace Helloworld {
output.WriteRawTag(10);
output.WriteString(Name);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -128,6 +138,9 @@ namespace Helloworld {
if (Name.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
@ -139,6 +152,7 @@ namespace Helloworld {
if (other.Name.Length != 0) {
Name = other.Name;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -147,7 +161,7 @@ namespace Helloworld {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Name = input.ReadString();
@ -164,6 +178,7 @@ namespace Helloworld {
/// </summary>
public sealed partial class HelloReply : pb::IMessage<HelloReply> {
private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
@ -187,6 +202,7 @@ namespace Helloworld {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public HelloReply(HelloReply other) : this() {
message_ = other.message_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -219,13 +235,16 @@ namespace Helloworld {
return true;
}
if (Message != other.Message) return false;
return true;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
if (Message.Length != 0) hash ^= Message.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
@ -240,6 +259,9 @@ namespace Helloworld {
output.WriteRawTag(10);
output.WriteString(Message);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -248,6 +270,9 @@ namespace Helloworld {
if (Message.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
@ -259,6 +284,7 @@ namespace Helloworld {
if (other.Message.Length != 0) {
Message = other.Message;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -267,7 +293,7 @@ namespace Helloworld {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Message = input.ReadString();

@ -1,5 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: helloworld.proto
// <auto-generated>
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: helloworld.proto
// </auto-generated>
// Original file comments:
// Copyright 2015 gRPC authors.
//
@ -15,12 +17,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#pragma warning disable 1591
#pragma warning disable 0414, 1591
#region Designer generated code
using System;
using System.Threading;
using System.Threading.Tasks;
using grpc = global::Grpc.Core;
namespace Helloworld {
@ -31,15 +30,15 @@ namespace Helloworld {
{
static readonly string __ServiceName = "helloworld.Greeter";
static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_helloworld_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
static readonly grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
grpc::MethodType.Unary,
__ServiceName,
"SayHello",
__Marshaller_HelloRequest,
__Marshaller_HelloReply);
__Marshaller_helloworld_HelloRequest,
__Marshaller_helloworld_HelloReply);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
@ -94,7 +93,7 @@ namespace Helloworld {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@ -116,7 +115,7 @@ namespace Helloworld {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.5.0" targetFramework="net45" />
<package id="Grpc" version="1.13.1" targetFramework="net45" />
<package id="Grpc.Core" version="1.13.1" targetFramework="net45" />
<package id="Grpc.Tools" version="1.13.1" targetFramework="net45" />
<package id="Google.Protobuf" version="3.6.1" targetFramework="net45" />
<package id="Grpc" version="1.14.1" targetFramework="net45" />
<package id="Grpc.Core" version="1.14.1" targetFramework="net45" />
<package id="Grpc.Tools" version="1.14.1" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
</packages>

@ -32,18 +32,17 @@
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.5.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\packages\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll</HintPath>
<Private>True</Private>
<Reference Include="Google.Protobuf, Version=3.6.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<HintPath>..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Grpc.Core">
<HintPath>..\packages\Grpc.Core.1.13.1\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
@ -60,5 +59,11 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="..\packages\Grpc.Core.1.13.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.13.1\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use 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('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets'))" />
</Target>
</Project>

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.5.0" targetFramework="net45" />
<package id="Grpc" version="1.13.1" targetFramework="net45" />
<package id="Grpc.Core" version="1.13.1" targetFramework="net45" />
<package id="Google.Protobuf" version="3.6.1" targetFramework="net45" />
<package id="Grpc" version="1.14.1" targetFramework="net45" />
<package id="Grpc.Core" version="1.14.1" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
</packages>

@ -32,18 +32,17 @@
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.5.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\packages\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll</HintPath>
<Private>True</Private>
<Reference Include="Google.Protobuf, Version=3.6.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<HintPath>..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Grpc.Core">
<HintPath>..\packages\Grpc.Core.1.13.1\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
@ -60,5 +59,11 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="..\packages\Grpc.Core.1.13.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.13.1\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use 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('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets'))" />
</Target>
</Project>

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.5.0" targetFramework="net45" />
<package id="Grpc" version="1.13.1" targetFramework="net45" />
<package id="Grpc.Core" version="1.13.1" targetFramework="net45" />
<package id="Google.Protobuf" version="3.6.1" targetFramework="net45" />
<package id="Grpc" version="1.14.1" targetFramework="net45" />
<package id="Grpc.Core" version="1.14.1" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
</packages>

@ -19,7 +19,7 @@ setlocal
@rem enter this directory
cd /d %~dp0
set TOOLS_PATH=packages\Grpc.Tools.1.8.0\tools\windows_x86
set TOOLS_PATH=packages\Grpc.Tools.1.14.1\tools\windows_x86
%TOOLS_PATH%\protoc.exe -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe

@ -1,5 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: route_guide.proto
// <auto-generated>
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: route_guide.proto
// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
@ -60,6 +62,7 @@ namespace Routeguide {
/// </summary>
public sealed partial class Point : pb::IMessage<Point> {
private static readonly pb::MessageParser<Point> _parser = new pb::MessageParser<Point>(() => new Point());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Point> Parser { get { return _parser; } }
@ -84,6 +87,7 @@ namespace Routeguide {
public Point(Point other) : this() {
latitude_ = other.latitude_;
longitude_ = other.longitude_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -128,7 +132,7 @@ namespace Routeguide {
}
if (Latitude != other.Latitude) return false;
if (Longitude != other.Longitude) return false;
return true;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -136,6 +140,9 @@ namespace Routeguide {
int hash = 1;
if (Latitude != 0) hash ^= Latitude.GetHashCode();
if (Longitude != 0) hash ^= Longitude.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
@ -154,6 +161,9 @@ namespace Routeguide {
output.WriteRawTag(16);
output.WriteInt32(Longitude);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -165,6 +175,9 @@ namespace Routeguide {
if (Longitude != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Longitude);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
@ -179,6 +192,7 @@ namespace Routeguide {
if (other.Longitude != 0) {
Longitude = other.Longitude;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -187,7 +201,7 @@ namespace Routeguide {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
Latitude = input.ReadInt32();
@ -209,6 +223,7 @@ namespace Routeguide {
/// </summary>
public sealed partial class Rectangle : pb::IMessage<Rectangle> {
private static readonly pb::MessageParser<Rectangle> _parser = new pb::MessageParser<Rectangle>(() => new Rectangle());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Rectangle> Parser { get { return _parser; } }
@ -231,8 +246,9 @@ namespace Routeguide {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Rectangle(Rectangle other) : this() {
Lo = other.lo_ != null ? other.Lo.Clone() : null;
Hi = other.hi_ != null ? other.Hi.Clone() : null;
lo_ = other.lo_ != null ? other.lo_.Clone() : null;
hi_ = other.hi_ != null ? other.hi_.Clone() : null;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -283,7 +299,7 @@ namespace Routeguide {
}
if (!object.Equals(Lo, other.Lo)) return false;
if (!object.Equals(Hi, other.Hi)) return false;
return true;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -291,6 +307,9 @@ namespace Routeguide {
int hash = 1;
if (lo_ != null) hash ^= Lo.GetHashCode();
if (hi_ != null) hash ^= Hi.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
@ -309,6 +328,9 @@ namespace Routeguide {
output.WriteRawTag(18);
output.WriteMessage(Hi);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -320,6 +342,9 @@ namespace Routeguide {
if (hi_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Hi);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
@ -340,6 +365,7 @@ namespace Routeguide {
}
Hi.MergeFrom(other.Hi);
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -348,7 +374,7 @@ namespace Routeguide {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
if (lo_ == null) {
@ -377,6 +403,7 @@ namespace Routeguide {
/// </summary>
public sealed partial class Feature : pb::IMessage<Feature> {
private static readonly pb::MessageParser<Feature> _parser = new pb::MessageParser<Feature>(() => new Feature());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<Feature> Parser { get { return _parser; } }
@ -400,7 +427,8 @@ namespace Routeguide {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public Feature(Feature other) : this() {
name_ = other.name_;
Location = other.location_ != null ? other.Location.Clone() : null;
location_ = other.location_ != null ? other.location_.Clone() : null;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -451,7 +479,7 @@ namespace Routeguide {
}
if (Name != other.Name) return false;
if (!object.Equals(Location, other.Location)) return false;
return true;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -459,6 +487,9 @@ namespace Routeguide {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
if (location_ != null) hash ^= Location.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
@ -477,6 +508,9 @@ namespace Routeguide {
output.WriteRawTag(18);
output.WriteMessage(Location);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -488,6 +522,9 @@ namespace Routeguide {
if (location_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Location);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
@ -505,6 +542,7 @@ namespace Routeguide {
}
Location.MergeFrom(other.Location);
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -513,7 +551,7 @@ namespace Routeguide {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
Name = input.ReadString();
@ -537,6 +575,7 @@ namespace Routeguide {
/// </summary>
public sealed partial class RouteNote : pb::IMessage<RouteNote> {
private static readonly pb::MessageParser<RouteNote> _parser = new pb::MessageParser<RouteNote>(() => new RouteNote());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<RouteNote> Parser { get { return _parser; } }
@ -559,8 +598,9 @@ namespace Routeguide {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public RouteNote(RouteNote other) : this() {
Location = other.location_ != null ? other.Location.Clone() : null;
location_ = other.location_ != null ? other.location_.Clone() : null;
message_ = other.message_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -611,7 +651,7 @@ namespace Routeguide {
}
if (!object.Equals(Location, other.Location)) return false;
if (Message != other.Message) return false;
return true;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -619,6 +659,9 @@ namespace Routeguide {
int hash = 1;
if (location_ != null) hash ^= Location.GetHashCode();
if (Message.Length != 0) hash ^= Message.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
@ -637,6 +680,9 @@ namespace Routeguide {
output.WriteRawTag(18);
output.WriteString(Message);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -648,6 +694,9 @@ namespace Routeguide {
if (Message.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
@ -665,6 +714,7 @@ namespace Routeguide {
if (other.Message.Length != 0) {
Message = other.Message;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -673,7 +723,7 @@ namespace Routeguide {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
if (location_ == null) {
@ -701,6 +751,7 @@ namespace Routeguide {
/// </summary>
public sealed partial class RouteSummary : pb::IMessage<RouteSummary> {
private static readonly pb::MessageParser<RouteSummary> _parser = new pb::MessageParser<RouteSummary>(() => new RouteSummary());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<RouteSummary> Parser { get { return _parser; } }
@ -727,6 +778,7 @@ namespace Routeguide {
featureCount_ = other.featureCount_;
distance_ = other.distance_;
elapsedTime_ = other.elapsedTime_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -807,7 +859,7 @@ namespace Routeguide {
if (FeatureCount != other.FeatureCount) return false;
if (Distance != other.Distance) return false;
if (ElapsedTime != other.ElapsedTime) return false;
return true;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -817,6 +869,9 @@ namespace Routeguide {
if (FeatureCount != 0) hash ^= FeatureCount.GetHashCode();
if (Distance != 0) hash ^= Distance.GetHashCode();
if (ElapsedTime != 0) hash ^= ElapsedTime.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
@ -843,6 +898,9 @@ namespace Routeguide {
output.WriteRawTag(32);
output.WriteInt32(ElapsedTime);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -860,6 +918,9 @@ namespace Routeguide {
if (ElapsedTime != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(ElapsedTime);
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
@ -880,6 +941,7 @@ namespace Routeguide {
if (other.ElapsedTime != 0) {
ElapsedTime = other.ElapsedTime;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@ -888,7 +950,7 @@ namespace Routeguide {
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
PointCount = input.ReadInt32();

@ -2,17 +2,17 @@
<PropertyGroup>
<AssemblyTitle>RouteGuide</AssemblyTitle>
<TargetFrameworks>netcoreapp1.0</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<DebugType>portable</DebugType>
<AssemblyName>RouteGuide</AssemblyName>
<PackageId>RouteGuide</PackageId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.5.0" />
<PackageReference Include="Google.Protobuf.Tools" Version="3.5.0" />
<PackageReference Include="Grpc" Version="1.13.1" />
<PackageReference Include="Grpc.Tools" Version="1.13.1" />
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
<PackageReference Include="Google.Protobuf.Tools" Version="3.6.1" />
<PackageReference Include="Grpc" Version="1.14.1" />
<PackageReference Include="Grpc.Tools" Version="1.14.1" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>

@ -1,5 +1,7 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: route_guide.proto
// <auto-generated>
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: route_guide.proto
// </auto-generated>
// Original file comments:
// Copyright 2015 gRPC authors.
//
@ -15,12 +17,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#pragma warning disable 1591
#pragma warning disable 0414, 1591
#region Designer generated code
using System;
using System.Threading;
using System.Threading.Tasks;
using grpc = global::Grpc.Core;
namespace Routeguide {
@ -31,39 +30,39 @@ namespace Routeguide {
{
static readonly string __ServiceName = "routeguide.RouteGuide";
static readonly grpc::Marshaller<global::Routeguide.Point> __Marshaller_Point = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Point.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Routeguide.Feature> __Marshaller_Feature = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Feature.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Routeguide.Rectangle> __Marshaller_Rectangle = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Rectangle.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Routeguide.RouteSummary> __Marshaller_RouteSummary = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteSummary.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Routeguide.RouteNote> __Marshaller_RouteNote = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteNote.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Routeguide.Point> __Marshaller_routeguide_Point = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Point.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Routeguide.Feature> __Marshaller_routeguide_Feature = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Feature.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Routeguide.Rectangle> __Marshaller_routeguide_Rectangle = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Rectangle.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Routeguide.RouteSummary> __Marshaller_routeguide_RouteSummary = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteSummary.Parser.ParseFrom);
static readonly grpc::Marshaller<global::Routeguide.RouteNote> __Marshaller_routeguide_RouteNote = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteNote.Parser.ParseFrom);
static readonly grpc::Method<global::Routeguide.Point, global::Routeguide.Feature> __Method_GetFeature = new grpc::Method<global::Routeguide.Point, global::Routeguide.Feature>(
grpc::MethodType.Unary,
__ServiceName,
"GetFeature",
__Marshaller_Point,
__Marshaller_Feature);
__Marshaller_routeguide_Point,
__Marshaller_routeguide_Feature);
static readonly grpc::Method<global::Routeguide.Rectangle, global::Routeguide.Feature> __Method_ListFeatures = new grpc::Method<global::Routeguide.Rectangle, global::Routeguide.Feature>(
grpc::MethodType.ServerStreaming,
__ServiceName,
"ListFeatures",
__Marshaller_Rectangle,
__Marshaller_Feature);
__Marshaller_routeguide_Rectangle,
__Marshaller_routeguide_Feature);
static readonly grpc::Method<global::Routeguide.Point, global::Routeguide.RouteSummary> __Method_RecordRoute = new grpc::Method<global::Routeguide.Point, global::Routeguide.RouteSummary>(
grpc::MethodType.ClientStreaming,
__ServiceName,
"RecordRoute",
__Marshaller_Point,
__Marshaller_RouteSummary);
__Marshaller_routeguide_Point,
__Marshaller_routeguide_RouteSummary);
static readonly grpc::Method<global::Routeguide.RouteNote, global::Routeguide.RouteNote> __Method_RouteChat = new grpc::Method<global::Routeguide.RouteNote, global::Routeguide.RouteNote>(
grpc::MethodType.DuplexStreaming,
__ServiceName,
"RouteChat",
__Marshaller_RouteNote,
__Marshaller_RouteNote);
__Marshaller_routeguide_RouteNote,
__Marshaller_routeguide_RouteNote);
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
@ -174,7 +173,7 @@ namespace Routeguide {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return GetFeature(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@ -206,7 +205,7 @@ namespace Routeguide {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
public virtual grpc::AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
public virtual grpc::AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return GetFeatureAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@ -238,7 +237,7 @@ namespace Routeguide {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
public virtual grpc::AsyncServerStreamingCall<global::Routeguide.Feature> ListFeatures(global::Routeguide.Rectangle request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
public virtual grpc::AsyncServerStreamingCall<global::Routeguide.Feature> ListFeatures(global::Routeguide.Rectangle request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return ListFeatures(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@ -267,7 +266,7 @@ namespace Routeguide {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
public virtual grpc::AsyncClientStreamingCall<global::Routeguide.Point, global::Routeguide.RouteSummary> RecordRoute(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
public virtual grpc::AsyncClientStreamingCall<global::Routeguide.Point, global::Routeguide.RouteSummary> RecordRoute(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return RecordRoute(new grpc::CallOptions(headers, deadline, cancellationToken));
}
@ -293,7 +292,7 @@ namespace Routeguide {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
public virtual grpc::AsyncDuplexStreamingCall<global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
public virtual grpc::AsyncDuplexStreamingCall<global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return RouteChat(new grpc::CallOptions(headers, deadline, cancellationToken));
}

@ -2,7 +2,7 @@
<PropertyGroup>
<AssemblyTitle>RouteGuideClient</AssemblyTitle>
<TargetFrameworks>netcoreapp1.0</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<DebugType>portable</DebugType>
<AssemblyName>RouteGuideClient</AssemblyName>
<OutputType>Exe</OutputType>

@ -2,7 +2,7 @@
<PropertyGroup>
<AssemblyTitle>RouteGuideServer</AssemblyTitle>
<TargetFrameworks>netcoreapp1.0</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<DebugType>portable</DebugType>
<AssemblyName>RouteGuideServer</AssemblyName>
<OutputType>Exe</OutputType>

@ -19,8 +19,10 @@ setlocal
@rem enter this directory
cd /d %~dp0
set TOOLS_PATH=packages\Grpc.Tools.1.8.0\tools\windows_x86
@rem packages will be available in nuget cache directory once the project is built or after "dotnet restore"
set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.6.1\tools\windows_x64\protoc.exe
set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.14.1\tools\windows_x64\grpc_csharp_plugin.exe
%TOOLS_PATH%\protoc.exe -I../../protos --csharp_out RouteGuide ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe
%PROTOC% -I../../protos --csharp_out RouteGuide ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%PLUGIN%
endlocal

@ -23,7 +23,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
# version = '1.15.0-dev'
# version = '1.16.0-dev'
version = '0.0.3'
s.version = version
s.summary = 'gRPC C++ library'
@ -31,7 +31,7 @@ Pod::Spec.new do |s|
s.license = 'Apache License, Version 2.0'
s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' }
grpc_version = '1.15.0-dev'
grpc_version = '1.16.0-dev'
s.source = {
:git => 'https://github.com/grpc/grpc.git',
@ -348,6 +348,7 @@ Pod::Spec.new do |s|
'src/core/tsi/ssl_transport_security.h',
'src/core/tsi/ssl_types.h',
'src/core/tsi/transport_security_grpc.h',
'src/core/tsi/grpc_shadow_boringssl.h',
'src/core/ext/transport/chttp2/server/chttp2_server.h',
'src/core/ext/transport/inproc/inproc_transport.h',
'src/core/lib/avl/avl.h',
@ -381,6 +382,7 @@ Pod::Spec.new do |s|
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
'src/core/lib/iomgr/block_annotate.h',
'src/core/lib/iomgr/buffer_list.h',
'src/core/lib/iomgr/call_combiner.h',
'src/core/lib/iomgr/closure.h',
'src/core/lib/iomgr/combiner.h',
@ -396,6 +398,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/exec_ctx.h',
'src/core/lib/iomgr/executor.h',
'src/core/lib/iomgr/gethostname.h',
'src/core/lib/iomgr/internal_errqueue.h',
'src/core/lib/iomgr/iocp_windows.h',
'src/core/lib/iomgr/iomgr.h',
'src/core/lib/iomgr/iomgr_custom.h',
@ -569,6 +572,7 @@ Pod::Spec.new do |s|
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
'src/core/lib/iomgr/block_annotate.h',
'src/core/lib/iomgr/buffer_list.h',
'src/core/lib/iomgr/call_combiner.h',
'src/core/lib/iomgr/closure.h',
'src/core/lib/iomgr/combiner.h',
@ -584,6 +588,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/exec_ctx.h',
'src/core/lib/iomgr/executor.h',
'src/core/lib/iomgr/gethostname.h',
'src/core/lib/iomgr/internal_errqueue.h',
'src/core/lib/iomgr/iocp_windows.h',
'src/core/lib/iomgr/iomgr.h',
'src/core/lib/iomgr/iomgr_custom.h',

@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
version = '1.15.0-dev'
version = '1.16.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'
@ -181,8 +181,9 @@ Pod::Spec.new do |s|
ss.header_mappings_dir = '.'
ss.libraries = 'z'
ss.dependency "#{s.name}/Interface", version
ss.dependency 'BoringSSL', '~> 10.0'
ss.dependency 'BoringSSL-GRPC', '0.0.1'
ss.dependency 'nanopb', '~> 0.3'
ss.compiler_flags = '-DGRPC_SHADOW_BORINGSSL_SYMBOLS'
# To save you from scrolling, this is the last part of the podspec.
ss.source_files = 'src/core/lib/gpr/alloc.h',
@ -359,6 +360,7 @@ Pod::Spec.new do |s|
'src/core/tsi/ssl_transport_security.h',
'src/core/tsi/ssl_types.h',
'src/core/tsi/transport_security_grpc.h',
'src/core/tsi/grpc_shadow_boringssl.h',
'src/core/ext/transport/chttp2/server/chttp2_server.h',
'src/core/ext/transport/inproc/inproc_transport.h',
'src/core/lib/avl/avl.h',
@ -392,6 +394,7 @@ Pod::Spec.new do |s|
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
'src/core/lib/iomgr/block_annotate.h',
'src/core/lib/iomgr/buffer_list.h',
'src/core/lib/iomgr/call_combiner.h',
'src/core/lib/iomgr/closure.h',
'src/core/lib/iomgr/combiner.h',
@ -407,6 +410,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/exec_ctx.h',
'src/core/lib/iomgr/executor.h',
'src/core/lib/iomgr/gethostname.h',
'src/core/lib/iomgr/internal_errqueue.h',
'src/core/lib/iomgr/iocp_windows.h',
'src/core/lib/iomgr/iomgr.h',
'src/core/lib/iomgr/iomgr_custom.h',
@ -536,6 +540,7 @@ Pod::Spec.new do |s|
'src/core/lib/http/format_request.cc',
'src/core/lib/http/httpcli.cc',
'src/core/lib/http/parser.cc',
'src/core/lib/iomgr/buffer_list.cc',
'src/core/lib/iomgr/call_combiner.cc',
'src/core/lib/iomgr/combiner.cc',
'src/core/lib/iomgr/endpoint.cc',
@ -556,6 +561,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/gethostname_fallback.cc',
'src/core/lib/iomgr/gethostname_host_name_max.cc',
'src/core/lib/iomgr/gethostname_sysconf.cc',
'src/core/lib/iomgr/internal_errqueue.cc',
'src/core/lib/iomgr/iocp_windows.cc',
'src/core/lib/iomgr/iomgr.cc',
'src/core/lib/iomgr/iomgr_custom.cc',
@ -957,6 +963,7 @@ Pod::Spec.new do |s|
'src/core/tsi/ssl_transport_security.h',
'src/core/tsi/ssl_types.h',
'src/core/tsi/transport_security_grpc.h',
'src/core/tsi/grpc_shadow_boringssl.h',
'src/core/ext/transport/chttp2/server/chttp2_server.h',
'src/core/ext/transport/inproc/inproc_transport.h',
'src/core/lib/avl/avl.h',
@ -990,6 +997,7 @@ Pod::Spec.new do |s|
'src/core/lib/http/httpcli.h',
'src/core/lib/http/parser.h',
'src/core/lib/iomgr/block_annotate.h',
'src/core/lib/iomgr/buffer_list.h',
'src/core/lib/iomgr/call_combiner.h',
'src/core/lib/iomgr/closure.h',
'src/core/lib/iomgr/combiner.h',
@ -1005,6 +1013,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/exec_ctx.h',
'src/core/lib/iomgr/executor.h',
'src/core/lib/iomgr/gethostname.h',
'src/core/lib/iomgr/internal_errqueue.h',
'src/core/lib/iomgr/iocp_windows.h',
'src/core/lib/iomgr/iomgr.h',
'src/core/lib/iomgr/iomgr_custom.h',

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
version = '1.15.0-dev'
version = '1.16.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'

@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
version = '1.15.0-dev'
version = '1.16.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'https://grpc.io'

@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
version = '1.15.0-dev'
version = '1.16.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'

@ -15,6 +15,7 @@ EXPORTS
grpc_register_plugin
grpc_init
grpc_shutdown
grpc_is_initialized
grpc_version_string
grpc_g_stands_for
grpc_completion_queue_factory_lookup

@ -296,6 +296,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/tsi/ssl_transport_security.h )
s.files += %w( src/core/tsi/ssl_types.h )
s.files += %w( src/core/tsi/transport_security_grpc.h )
s.files += %w( src/core/tsi/grpc_shadow_boringssl.h )
s.files += %w( src/core/ext/transport/chttp2/server/chttp2_server.h )
s.files += %w( src/core/ext/transport/inproc/inproc_transport.h )
s.files += %w( src/core/lib/avl/avl.h )
@ -329,6 +330,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/http/httpcli.h )
s.files += %w( src/core/lib/http/parser.h )
s.files += %w( src/core/lib/iomgr/block_annotate.h )
s.files += %w( src/core/lib/iomgr/buffer_list.h )
s.files += %w( src/core/lib/iomgr/call_combiner.h )
s.files += %w( src/core/lib/iomgr/closure.h )
s.files += %w( src/core/lib/iomgr/combiner.h )
@ -344,6 +346,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/exec_ctx.h )
s.files += %w( src/core/lib/iomgr/executor.h )
s.files += %w( src/core/lib/iomgr/gethostname.h )
s.files += %w( src/core/lib/iomgr/internal_errqueue.h )
s.files += %w( src/core/lib/iomgr/iocp_windows.h )
s.files += %w( src/core/lib/iomgr/iomgr.h )
s.files += %w( src/core/lib/iomgr/iomgr_custom.h )
@ -473,6 +476,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/http/format_request.cc )
s.files += %w( src/core/lib/http/httpcli.cc )
s.files += %w( src/core/lib/http/parser.cc )
s.files += %w( src/core/lib/iomgr/buffer_list.cc )
s.files += %w( src/core/lib/iomgr/call_combiner.cc )
s.files += %w( src/core/lib/iomgr/combiner.cc )
s.files += %w( src/core/lib/iomgr/endpoint.cc )
@ -493,6 +497,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/gethostname_fallback.cc )
s.files += %w( src/core/lib/iomgr/gethostname_host_name_max.cc )
s.files += %w( src/core/lib/iomgr/gethostname_sysconf.cc )
s.files += %w( src/core/lib/iomgr/internal_errqueue.cc )
s.files += %w( src/core/lib/iomgr/iocp_windows.cc )
s.files += %w( src/core/lib/iomgr/iomgr.cc )
s.files += %w( src/core/lib/iomgr/iomgr_custom.cc )

@ -300,6 +300,7 @@
'src/core/lib/http/format_request.cc',
'src/core/lib/http/httpcli.cc',
'src/core/lib/http/parser.cc',
'src/core/lib/iomgr/buffer_list.cc',
'src/core/lib/iomgr/call_combiner.cc',
'src/core/lib/iomgr/combiner.cc',
'src/core/lib/iomgr/endpoint.cc',
@ -320,6 +321,7 @@
'src/core/lib/iomgr/gethostname_fallback.cc',
'src/core/lib/iomgr/gethostname_host_name_max.cc',
'src/core/lib/iomgr/gethostname_sysconf.cc',
'src/core/lib/iomgr/internal_errqueue.cc',
'src/core/lib/iomgr/iocp_windows.cc',
'src/core/lib/iomgr/iomgr.cc',
'src/core/lib/iomgr/iomgr_custom.cc',
@ -660,6 +662,7 @@
'src/core/lib/http/format_request.cc',
'src/core/lib/http/httpcli.cc',
'src/core/lib/http/parser.cc',
'src/core/lib/iomgr/buffer_list.cc',
'src/core/lib/iomgr/call_combiner.cc',
'src/core/lib/iomgr/combiner.cc',
'src/core/lib/iomgr/endpoint.cc',
@ -680,6 +683,7 @@
'src/core/lib/iomgr/gethostname_fallback.cc',
'src/core/lib/iomgr/gethostname_host_name_max.cc',
'src/core/lib/iomgr/gethostname_sysconf.cc',
'src/core/lib/iomgr/internal_errqueue.cc',
'src/core/lib/iomgr/iocp_windows.cc',
'src/core/lib/iomgr/iomgr.cc',
'src/core/lib/iomgr/iomgr_custom.cc',
@ -893,6 +897,7 @@
'src/core/lib/http/format_request.cc',
'src/core/lib/http/httpcli.cc',
'src/core/lib/http/parser.cc',
'src/core/lib/iomgr/buffer_list.cc',
'src/core/lib/iomgr/call_combiner.cc',
'src/core/lib/iomgr/combiner.cc',
'src/core/lib/iomgr/endpoint.cc',
@ -913,6 +918,7 @@
'src/core/lib/iomgr/gethostname_fallback.cc',
'src/core/lib/iomgr/gethostname_host_name_max.cc',
'src/core/lib/iomgr/gethostname_sysconf.cc',
'src/core/lib/iomgr/internal_errqueue.cc',
'src/core/lib/iomgr/iocp_windows.cc',
'src/core/lib/iomgr/iomgr.cc',
'src/core/lib/iomgr/iomgr_custom.cc',
@ -1104,6 +1110,7 @@
'src/core/lib/http/format_request.cc',
'src/core/lib/http/httpcli.cc',
'src/core/lib/http/parser.cc',
'src/core/lib/iomgr/buffer_list.cc',
'src/core/lib/iomgr/call_combiner.cc',
'src/core/lib/iomgr/combiner.cc',
'src/core/lib/iomgr/endpoint.cc',
@ -1124,6 +1131,7 @@
'src/core/lib/iomgr/gethostname_fallback.cc',
'src/core/lib/iomgr/gethostname_host_name_max.cc',
'src/core/lib/iomgr/gethostname_sysconf.cc',
'src/core/lib/iomgr/internal_errqueue.cc',
'src/core/lib/iomgr/iocp_windows.cc',
'src/core/lib/iomgr/iomgr.cc',
'src/core/lib/iomgr/iomgr_custom.cc',

@ -79,6 +79,12 @@ GRPCAPI void grpc_init(void);
destroyed. */
GRPCAPI void grpc_shutdown(void);
/** EXPERIMENTAL. Returns 1 if the grpc library has been initialized.
TODO(ericgribkoff) Decide if this should be promoted to non-experimental as
part of stabilizing the fork support API, as tracked in
https://github.com/grpc/grpc/issues/15334 */
GRPCAPI int grpc_is_initialized(void);
/** Return a string representing the current version of grpc */
GRPCAPI const char* grpc_version_string(void);

@ -57,46 +57,51 @@ typedef enum {
} grpc_ssl_certificate_config_reload_status;
typedef enum {
/** Server does not request client certificate. A client can present a self
signed or signed certificates if it wishes to do so and they would be
accepted. */
/** Server does not request client certificate.
The certificate presented by the client is not checked by the server at
all. (A client may present a self signed or signed certificate or not
present a certificate at all and any of those option would be accepted) */
GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE,
/** Server requests client certificate but does not enforce that the client
presents a certificate.
If the client presents a certificate, the client authentication is left to
the application based on the metadata like certificate etc.
the application (the necessary metadata will be available to the
application via authentication context properties, see grpc_auth_context).
The key cert pair should still be valid for the SSL connection to be
established. */
The client's key certificate pair must be valid for the SSL connection to
be established. */
GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY,
/** Server requests client certificate but does not enforce that the client
presents a certificate.
If the client presents a certificate, the client authentication is done by
grpc framework (The client needs to either present a signed cert or skip no
certificate for a successful connection).
the gRPC framework. (For a successful connection the client needs to either
present a certificate that can be verified against the root certificate
configured by the server or not present a certificate at all)
The key cert pair should still be valid for the SSL connection to be
established. */
The client's key certificate pair must be valid for the SSL connection to
be established. */
GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY,
/** Server requests client certificate but enforces that the client presents a
/** Server requests client certificate and enforces that the client presents a
certificate.
If the client presents a certificate, the client authentication is left to
the application based on the metadata like certificate etc.
the application (the necessary metadata will be available to the
application via authentication context properties, see grpc_auth_context).
The key cert pair should still be valid for the SSL connection to be
established. */
The client's key certificate pair must be valid for the SSL connection to
be established. */
GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY,
/** Server requests client certificate but enforces that the client presents a
/** Server requests client certificate and enforces that the client presents a
certificate.
The cerificate presented by the client is verified by grpc framework (The
client needs to present signed certs for a successful connection).
The cerificate presented by the client is verified by the gRPC framework.
(For a successful connection the client needs to present a certificate that
can be verified against the root certificate configured by the server)
The key cert pair should still be valid for the SSL connection to be
established. */
The client's key certificate pair must be valid for the SSL connection to
be established. */
GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
} grpc_ssl_client_certificate_request_type;

@ -50,8 +50,6 @@ namespace internal {
class Call;
class CallHook;
const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin";
// TODO(yangg) if the map is changed before we send, the pointers will be a
// mess. Make sure it does not happen.
inline grpc_metadata* FillMetadataArray(
@ -531,7 +529,6 @@ class CallOpRecvInitialMetadata {
void FinishOp(bool* status) {
if (metadata_map_ == nullptr) return;
metadata_map_->FillMap();
metadata_map_ = nullptr;
}
@ -566,13 +563,7 @@ class CallOpClientRecvStatus {
void FinishOp(bool* status) {
if (recv_status_ == nullptr) return;
metadata_map_->FillMap();
grpc::string binary_error_details;
auto iter = metadata_map_->map()->find(kBinaryErrorDetailsKey);
if (iter != metadata_map_->map()->end()) {
binary_error_details =
grpc::string(iter->second.begin(), iter->second.length());
}
grpc::string binary_error_details = metadata_map_->GetBinaryErrorDetails();
*recv_status_ =
Status(static_cast<StatusCode>(status_code_),
GRPC_SLICE_IS_EMPTY(error_message_)

@ -425,8 +425,8 @@ class ClientContext {
mutable std::shared_ptr<const AuthContext> auth_context_;
struct census_context* census_context_;
std::multimap<grpc::string, grpc::string> send_initial_metadata_;
internal::MetadataMap recv_initial_metadata_;
internal::MetadataMap trailing_metadata_;
mutable internal::MetadataMap recv_initial_metadata_;
mutable internal::MetadataMap trailing_metadata_;
grpc_call* propagate_from_call_;
PropagationOptions propagation_options_;

@ -19,11 +19,15 @@
#ifndef GRPCPP_IMPL_CODEGEN_METADATA_MAP_H
#define GRPCPP_IMPL_CODEGEN_METADATA_MAP_H
#include <grpc/impl/codegen/log.h>
#include <grpcpp/impl/codegen/slice.h>
namespace grpc {
namespace internal {
const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin";
class MetadataMap {
public:
MetadataMap() { memset(&arr_, 0, sizeof(arr_)); }
@ -32,24 +36,54 @@ class MetadataMap {
g_core_codegen_interface->grpc_metadata_array_destroy(&arr_);
}
void FillMap() {
for (size_t i = 0; i < arr_.count; i++) {
// TODO(yangg) handle duplicates?
map_.insert(std::pair<grpc::string_ref, grpc::string_ref>(
StringRefFromSlice(&arr_.metadata[i].key),
StringRefFromSlice(&arr_.metadata[i].value)));
grpc::string GetBinaryErrorDetails() {
// if filled_, extract from the multimap for O(log(n))
if (filled_) {
auto iter = map_.find(kBinaryErrorDetailsKey);
if (iter != map_.end()) {
return grpc::string(iter->second.begin(), iter->second.length());
}
}
// if not yet filled, take the O(n) lookup to avoid allocating the
// multimap until it is requested.
// TODO(ncteisen): plumb this through core as a first class object, just
// like code and message.
else {
for (size_t i = 0; i < arr_.count; i++) {
if (strncmp(reinterpret_cast<const char*>(
GRPC_SLICE_START_PTR(arr_.metadata[i].key)),
kBinaryErrorDetailsKey,
GRPC_SLICE_LENGTH(arr_.metadata[i].key)) == 0) {
return grpc::string(reinterpret_cast<const char*>(
GRPC_SLICE_START_PTR(arr_.metadata[i].value)),
GRPC_SLICE_LENGTH(arr_.metadata[i].value));
}
}
}
return grpc::string();
}
std::multimap<grpc::string_ref, grpc::string_ref>* map() { return &map_; }
const std::multimap<grpc::string_ref, grpc::string_ref>* map() const {
std::multimap<grpc::string_ref, grpc::string_ref>* map() {
FillMap();
return &map_;
}
grpc_metadata_array* arr() { return &arr_; }
private:
bool filled_ = false;
grpc_metadata_array arr_;
std::multimap<grpc::string_ref, grpc::string_ref> map_;
void FillMap() {
if (filled_) return;
filled_ = true;
for (size_t i = 0; i < arr_.count; i++) {
// TODO(yangg) handle duplicates?
map_.insert(std::pair<grpc::string_ref, grpc::string_ref>(
StringRefFromSlice(&arr_.metadata[i].key),
StringRefFromSlice(&arr_.metadata[i].value)));
}
}
};
} // namespace internal

@ -294,7 +294,7 @@ class ServerContext {
CompletionQueue* cq_;
bool sent_initial_metadata_;
mutable std::shared_ptr<const AuthContext> auth_context_;
internal::MetadataMap client_metadata_;
mutable internal::MetadataMap client_metadata_;
std::multimap<grpc::string, grpc::string> initial_metadata_;
std::multimap<grpc::string, grpc::string> trailing_metadata_;

@ -93,14 +93,19 @@ class Service {
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
// Typecast the index to size_t for indexing into a vector
// while preserving the API that existed before a compiler
// warning was first seen (grpc/grpc#11664)
size_t idx = static_cast<size_t>(index);
server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
notification_cq, tag, request);
}
void RequestAsyncClientStreaming(
int index, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
size_t idx = static_cast<size_t>(index);
server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
notification_cq, tag);
}
template <class Message>
@ -108,14 +113,16 @@ class Service {
int index, ServerContext* context, Message* request,
internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
size_t idx = static_cast<size_t>(index);
server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
notification_cq, tag, request);
}
void RequestAsyncBidiStreaming(
int index, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
size_t idx = static_cast<size_t>(index);
server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
notification_cq, tag);
}
@ -126,46 +133,50 @@ class Service {
void MarkMethodAsync(int index) {
// This does not have to be a hard error, however no one has approached us
// with a use case yet. Please file an issue if you believe you have one.
size_t idx = static_cast<size_t>(index);
GPR_CODEGEN_ASSERT(
methods_[index].get() != nullptr &&
methods_[idx].get() != nullptr &&
"Cannot mark the method as 'async' because it has already been "
"marked as 'generic'.");
methods_[index]->SetServerAsyncType(
methods_[idx]->SetServerAsyncType(
internal::RpcServiceMethod::AsyncType::ASYNC);
}
void MarkMethodRaw(int index) {
// This does not have to be a hard error, however no one has approached us
// with a use case yet. Please file an issue if you believe you have one.
GPR_CODEGEN_ASSERT(methods_[index].get() != nullptr &&
size_t idx = static_cast<size_t>(index);
GPR_CODEGEN_ASSERT(methods_[idx].get() != nullptr &&
"Cannot mark the method as 'raw' because it has already "
"been marked as 'generic'.");
methods_[index]->SetServerAsyncType(
methods_[idx]->SetServerAsyncType(
internal::RpcServiceMethod::AsyncType::RAW);
}
void MarkMethodGeneric(int index) {
// This does not have to be a hard error, however no one has approached us
// with a use case yet. Please file an issue if you believe you have one.
size_t idx = static_cast<size_t>(index);
GPR_CODEGEN_ASSERT(
methods_[index]->handler() != nullptr &&
methods_[idx]->handler() != nullptr &&
"Cannot mark the method as 'generic' because it has already been "
"marked as 'async' or 'raw'.");
methods_[index].reset();
methods_[idx].reset();
}
void MarkMethodStreamed(int index, internal::MethodHandler* streamed_method) {
// This does not have to be a hard error, however no one has approached us
// with a use case yet. Please file an issue if you believe you have one.
GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() &&
size_t idx = static_cast<size_t>(index);
GPR_CODEGEN_ASSERT(methods_[idx] && methods_[idx]->handler() &&
"Cannot mark an async or generic method Streamed");
methods_[index]->SetHandler(streamed_method);
methods_[idx]->SetHandler(streamed_method);
// From the server's point of view, streamed unary is a special
// case of BIDI_STREAMING that has 1 read and 1 write, in that order,
// and split server-side streaming is BIDI_STREAMING with 1 read and
// any number of writes, in that order.
methods_[index]->SetMethodType(internal::RpcMethod::BIDI_STREAMING);
methods_[idx]->SetMethodType(internal::RpcMethod::BIDI_STREAMING);
}
private:

@ -13,8 +13,8 @@
<date>2018-01-19</date>
<time>16:06:07</time>
<version>
<release>1.15.0dev</release>
<api>1.15.0dev</api>
<release>1.16.0dev</release>
<api>1.16.0dev</api>
</version>
<stability>
<release>beta</release>
@ -301,6 +301,7 @@
<file baseinstalldir="/" name="src/core/tsi/ssl_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/ssl_types.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/transport_security_grpc.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/grpc_shadow_boringssl.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/chttp2_server.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/inproc/inproc_transport.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/avl/avl.h" role="src" />
@ -334,6 +335,7 @@
<file baseinstalldir="/" name="src/core/lib/http/httpcli.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/parser.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/block_annotate.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/buffer_list.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/call_combiner.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/closure.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/combiner.h" role="src" />
@ -349,6 +351,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/exec_ctx.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/executor.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/gethostname.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/internal_errqueue.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iocp_windows.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_custom.h" role="src" />
@ -478,6 +481,7 @@
<file baseinstalldir="/" name="src/core/lib/http/format_request.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/httpcli.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/http/parser.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/buffer_list.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/call_combiner.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/combiner.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint.cc" role="src" />
@ -498,6 +502,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/gethostname_fallback.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/gethostname_host_name_max.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/gethostname_sysconf.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/internal_errqueue.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iocp_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_custom.cc" role="src" />

@ -46,20 +46,4 @@ construction arguments for concrete grpc_subchannel instances.
Naming for GRPC
===============
Names in GRPC are represented by a URI (as defined in
[RFC 3986](https://tools.ietf.org/html/rfc3986)).
The following schemes are currently supported:
dns:///host:port - dns schemes are currently supported so long as authority is
empty (authority based dns resolution is expected in a future
release)
unix:path - the unix scheme is used to create and connect to unix domain
sockets - the authority must be empty, and the path
represents the absolute or relative path to the desired
socket
ipv4:host:port - a pre-resolved ipv4 dotted decimal address/port combination
ipv6:[host]:port - a pre-resolved ipv6 address/port combination
See [/doc/naming.md](gRPC name resolution).

@ -457,7 +457,6 @@ get_service_config_from_resolver_result_locked(channel_data* chand) {
grpc_uri* uri = grpc_uri_parse(server_uri, true);
GPR_ASSERT(uri->path[0] != '\0');
service_config_parsing_state parsing_state;
memset(&parsing_state, 0, sizeof(parsing_state));
parsing_state.server_name =
uri->path[0] == '/' ? uri->path + 1 : uri->path;
service_config->ParseGlobalParams(parse_retry_throttle_params,
@ -3101,7 +3100,7 @@ static void cc_start_transport_stream_op_batch(
// For all other batches, release the call combiner.
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_INFO,
"chand=%p calld=%p: saved batch, yeilding call combiner", chand,
"chand=%p calld=%p: saved batch, yielding call combiner", chand,
calld);
}
GRPC_CALL_COMBINER_STOP(calld->call_combiner,

@ -320,7 +320,7 @@ static void http_connect_handshaker_do_handshake(
// Take a new ref to be held by the write callback.
gpr_ref(&handshaker->refcount);
grpc_endpoint_write(args->endpoint, &handshaker->write_buffer,
&handshaker->request_done_closure);
&handshaker->request_done_closure, nullptr);
gpr_mu_unlock(&handshaker->mu);
}

@ -126,7 +126,6 @@ class PickFirst : public LoadBalancingPolicy {
void ShutdownLocked() override;
void StartPickingLocked();
void DestroyUnselectedSubchannelsLocked();
void UpdateChildRefsLocked();
// All our subchannels.
@ -250,14 +249,9 @@ void PickFirst::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
void PickFirst::StartPickingLocked() {
started_picking_ = true;
if (subchannel_list_ != nullptr) {
for (size_t i = 0; i < subchannel_list_->num_subchannels(); ++i) {
if (subchannel_list_->subchannel(i)->subchannel() != nullptr) {
subchannel_list_->subchannel(i)
->CheckConnectivityStateAndStartWatchingLocked();
break;
}
}
if (subchannel_list_ != nullptr && subchannel_list_->num_subchannels() > 0) {
subchannel_list_->subchannel(0)
->CheckConnectivityStateAndStartWatchingLocked();
}
}
@ -294,15 +288,6 @@ bool PickFirst::PickLocked(PickState* pick, grpc_error** error) {
return false;
}
void PickFirst::DestroyUnselectedSubchannelsLocked() {
for (size_t i = 0; i < subchannel_list_->num_subchannels(); ++i) {
PickFirstSubchannelData* sd = subchannel_list_->subchannel(i);
if (selected_ != sd) {
sd->UnrefSubchannelLocked("selected_different_subchannel");
}
}
}
grpc_connectivity_state PickFirst::CheckConnectivityLocked(grpc_error** error) {
return grpc_connectivity_state_get(&state_tracker_, error);
}
@ -419,7 +404,6 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
if (sd->CheckConnectivityStateLocked(&error) == GRPC_CHANNEL_READY) {
selected_ = sd;
subchannel_list_ = std::move(subchannel_list);
DestroyUnselectedSubchannelsLocked();
sd->StartConnectivityWatchLocked();
// If there was a previously pending update (which may or may
// not have contained the currently selected subchannel), drop
@ -504,7 +488,6 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE);
// In transient failure. Rely on re-resolution to recover.
p->selected_ = nullptr;
UnrefSubchannelLocked("pf_selected_shutdown");
StopConnectivityWatchLocked();
} else {
grpc_connectivity_state_set(&p->state_tracker_, connectivity_state,
@ -535,11 +518,9 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
case GRPC_CHANNEL_TRANSIENT_FAILURE: {
StopConnectivityWatchLocked();
PickFirstSubchannelData* sd = this;
do {
size_t next_index =
(sd->Index() + 1) % subchannel_list()->num_subchannels();
sd = subchannel_list()->subchannel(next_index);
} while (sd->subchannel() == nullptr);
size_t next_index =
(sd->Index() + 1) % subchannel_list()->num_subchannels();
sd = subchannel_list()->subchannel(next_index);
// Case 1: Only set state to TRANSIENT_FAILURE if we've tried
// all subchannels.
if (sd->Index() == 0 && subchannel_list() == p->subchannel_list_.get()) {
@ -600,8 +581,6 @@ void PickFirst::PickFirstSubchannelData::ProcessUnselectedReadyLocked() {
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p, subchannel());
}
// Drop all other subchannels, since we are now connected.
p->DestroyUnselectedSubchannelsLocked();
// Update any calls that were waiting for a pick.
PickState* pick;
while ((pick = p->pending_picks_)) {

@ -139,7 +139,8 @@ class RoundRobin : public LoadBalancingPolicy {
grpc_client_channel_factory* client_channel_factory,
const grpc_channel_args& args)
: SubchannelList(policy, tracer, addresses, combiner,
client_channel_factory, args) {
client_channel_factory, args),
last_ready_index_(num_subchannels() - 1) {
// Need to maintain a ref to the LB policy as long as we maintain
// any references to subchannels, since the subchannels'
// pollset_sets will include the LB policy's pollset_set.
@ -180,7 +181,7 @@ class RoundRobin : public LoadBalancingPolicy {
size_t num_connecting_ = 0;
size_t num_transient_failure_ = 0;
grpc_error* last_transient_failure_error_ = GRPC_ERROR_NONE;
size_t last_ready_index_ = -1; // Index into list of last pick.
size_t last_ready_index_; // Index into list of last pick.
};
// Helper class to ensure that any function that modifies the child refs

@ -102,11 +102,6 @@ class SubchannelData {
return pending_connectivity_state_unsafe_;
}
// Unrefs the subchannel. May be used if an individual subchannel is
// no longer needed even though the subchannel list as a whole is not
// being unreffed.
virtual void UnrefSubchannelLocked(const char* reason);
// Resets the connection backoff.
// TODO(roth): This method should go away when we move the backoff
// code out of the subchannel and into the LB policies.
@ -154,6 +149,10 @@ class SubchannelData {
grpc_connectivity_state connectivity_state,
grpc_error* error) GRPC_ABSTRACT;
// Unrefs the subchannel. May be overridden by subclasses that need
// to perform extra cleanup when unreffing the subchannel.
virtual void UnrefSubchannelLocked(const char* reason);
private:
// Updates connected_subchannel_ based on pending_connectivity_state_unsafe_.
// Returns true if the connectivity state should be reported.

@ -81,18 +81,7 @@ class Resolver : public InternallyRefCountedWithTracing<Resolver> {
///
/// If this causes new data to become available, then the currently
/// pending call to \a NextLocked() will return the new result.
///
/// Note: Currently, all resolvers are required to return a new result
/// shortly after this method is called. For pull-based mechanisms, if
/// the implementation decides to delay querying the name service, it
/// should immediately return a new copy of the previously returned
/// result (and it can then return the updated data later, when it
/// actually does query the name service). For push-based mechanisms,
/// the implementation should immediately return a new copy of the
/// last-seen result.
/// TODO(roth): Remove this requirement once we fix pick_first to not
/// throw away unselected subchannels.
virtual void RequestReresolutionLocked() GRPC_ABSTRACT;
virtual void RequestReresolutionLocked() {}
/// Resets the re-resolution backoff, if any.
/// This needs to be implemented only by pull-based implementations;

@ -373,13 +373,7 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
void AresDnsResolver::MaybeStartResolvingLocked() {
// If there is an existing timer, the time it fires is the earliest time we
// can start the next resolution.
if (have_next_resolution_timer_) {
// TODO(dgq): remove the following two lines once Pick First stops
// discarding subchannels after selecting.
++resolved_version_;
MaybeFinishNextLocked();
return;
}
if (have_next_resolution_timer_) return;
if (last_resolution_timestamp_ >= 0) {
const grpc_millis earliest_next_resolution =
last_resolution_timestamp_ + min_time_between_resolutions_;
@ -401,10 +395,6 @@ void AresDnsResolver::MaybeStartResolvingLocked() {
self.release();
grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution,
&on_next_resolution_);
// TODO(dgq): remove the following two lines once Pick First stops
// discarding subchannels after selecting.
++resolved_version_;
MaybeFinishNextLocked();
return;
}
}

@ -247,13 +247,7 @@ void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
void NativeDnsResolver::MaybeStartResolvingLocked() {
// If there is an existing timer, the time it fires is the earliest time we
// can start the next resolution.
if (have_next_resolution_timer_) {
// TODO(dgq): remove the following two lines once Pick First stops
// discarding subchannels after selecting.
++resolved_version_;
MaybeFinishNextLocked();
return;
}
if (have_next_resolution_timer_) return;
if (last_resolution_timestamp_ >= 0) {
const grpc_millis earliest_next_resolution =
last_resolution_timestamp_ + min_time_between_resolutions_;
@ -275,10 +269,6 @@ void NativeDnsResolver::MaybeStartResolvingLocked() {
self.release();
grpc_timer_init(&next_resolution_timer_, ms_until_next_resolution,
&on_next_resolution_);
// TODO(dgq): remove the following two lines once Pick First stops
// discarding subchannels after selecting.
++resolved_version_;
MaybeFinishNextLocked();
return;
}
}

@ -73,11 +73,6 @@ class FakeResolver : public Resolver {
// Results to use for the pretended re-resolution in
// RequestReresolutionLocked().
grpc_channel_args* reresolution_results_ = nullptr;
// TODO(juanlishen): This can go away once pick_first is changed to not throw
// away its subchannels, since that will eliminate its dependence on
// channel_saw_error_locked() causing an immediate resolver return.
// A copy of the most-recently used resolution results.
grpc_channel_args* last_used_results_ = nullptr;
// pending next completion, or NULL
grpc_closure* next_completion_ = nullptr;
// target result address for next completion
@ -96,7 +91,6 @@ FakeResolver::FakeResolver(const ResolverArgs& args) : Resolver(args.combiner) {
FakeResolver::~FakeResolver() {
grpc_channel_args_destroy(next_results_);
grpc_channel_args_destroy(reresolution_results_);
grpc_channel_args_destroy(last_used_results_);
grpc_channel_args_destroy(channel_args_);
}
@ -109,17 +103,11 @@ void FakeResolver::NextLocked(grpc_channel_args** target_result,
}
void FakeResolver::RequestReresolutionLocked() {
// A resolution must have been returned before an error is seen.
GPR_ASSERT(last_used_results_ != nullptr);
grpc_channel_args_destroy(next_results_);
if (reresolution_results_ != nullptr) {
grpc_channel_args_destroy(next_results_);
next_results_ = grpc_channel_args_copy(reresolution_results_);
} else {
// If reresolution_results is unavailable, re-resolve with the most-recently
// used results to avoid a no-op re-resolution.
next_results_ = grpc_channel_args_copy(last_used_results_);
MaybeFinishNextLocked();
}
MaybeFinishNextLocked();
}
void FakeResolver::MaybeFinishNextLocked() {
@ -161,8 +149,6 @@ void FakeResolverResponseGenerator::SetResponseLocked(void* arg,
FakeResolver* resolver = closure_arg->generator->resolver_;
grpc_channel_args_destroy(resolver->next_results_);
resolver->next_results_ = closure_arg->response;
grpc_channel_args_destroy(resolver->last_used_results_);
resolver->last_used_results_ = grpc_channel_args_copy(closure_arg->response);
resolver->MaybeFinishNextLocked();
Delete(closure_arg);
}

@ -53,7 +53,8 @@ class FakeResolverResponseGenerator
// The new re-resolution response replaces any previous re-resolution
// response that may have been set by a previous call.
// If the re-resolution response is set to NULL, then the fake
// resolver will return the last value set via \a SetResponse().
// resolver will not return anything when \a RequestReresolutionLocked()
// is called.
void SetReresolutionResponse(grpc_channel_args* response);
// Tells the resolver to return a transient failure (signalled by

@ -50,8 +50,6 @@ class SockaddrResolver : public Resolver {
void NextLocked(grpc_channel_args** result,
grpc_closure* on_complete) override;
void RequestReresolutionLocked() override;
void ShutdownLocked() override;
private:
@ -90,11 +88,6 @@ void SockaddrResolver::NextLocked(grpc_channel_args** target_result,
MaybeFinishNextLocked();
}
void SockaddrResolver::RequestReresolutionLocked() {
published_ = false;
MaybeFinishNextLocked();
}
void SockaddrResolver::ShutdownLocked() {
if (next_completion_ != nullptr) {
*target_result_ = nullptr;

@ -94,7 +94,7 @@ grpc_error* init_channel_elem(grpc_channel_element* elem,
if (default_authority_arg == nullptr) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"GRPC_ARG_DEFAULT_AUTHORITY channel arg. not found. Note that direct "
"channels must explicity specify a value for this argument.");
"channels must explicitly specify a value for this argument.");
}
const char* default_authority_str =
grpc_channel_arg_get_string(default_authority_arg);

@ -162,9 +162,10 @@ void ServerLoadReportingCallData::GetCensusSafeClientIpString(
} else if (addr->sa_family == GRPC_AF_INET6) {
grpc_sockaddr_in6* addr6 = reinterpret_cast<grpc_sockaddr_in6*>(addr);
*client_ip_string = static_cast<char*>(gpr_malloc(32 + 1));
for (size_t i = 0; i < 16; ++i) {
snprintf(*client_ip_string + i * 2, 2 + 1, "%02x",
addr6->sin6_addr.__in6_u.__u6_addr8[i]);
uint32_t* addr6_next_long = reinterpret_cast<uint32_t*>(&addr6->sin6_addr);
for (size_t i = 0; i < 4; ++i) {
snprintf(*client_ip_string + 8 * i, 8 + 1, "%08x",
grpc_ntohl(*addr6_next_long++));
}
*size = 32;
} else {

@ -429,8 +429,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem,
? GRPC_MILLIS_INF_FUTURE
: DEFAULT_MAX_CONNECTION_IDLE_MS;
chand->idle_state = MAX_IDLE_STATE_INIT;
gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis,
GRPC_MILLIS_INF_PAST);
gpr_atm_no_barrier_store(&chand->last_enter_idle_time_millis, GPR_ATM_MIN);
for (size_t i = 0; i < args->channel_args->num_args; ++i) {
if (0 == strcmp(args->channel_args->args[i].key,
GRPC_ARG_MAX_CONNECTION_AGE_MS)) {

@ -50,7 +50,7 @@ grpc_channel* grpc_insecure_channel_create_from_fd(
GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0);
grpc_endpoint* client = grpc_tcp_client_create_from_fd(
grpc_fd_create(fd, "client", false), args, "fd-client");
grpc_fd_create(fd, "client", true), args, "fd-client");
grpc_transport* transport =
grpc_create_chttp2_transport(final_args, client, true);

@ -44,7 +44,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server,
gpr_asprintf(&name, "fd:%d", fd);
grpc_endpoint* server_endpoint =
grpc_tcp_create(grpc_fd_create(fd, name, false),
grpc_tcp_create(grpc_fd_create(fd, name, true),
grpc_server_get_channel_args(server), name);
gpr_free(name);

@ -1029,7 +1029,8 @@ static void write_action(void* gt, grpc_error* error) {
grpc_endpoint_write(
t->ep, &t->outbuf,
GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t,
grpc_combiner_scheduler(t->combiner)));
grpc_combiner_scheduler(t->combiner)),
nullptr);
}
/* Callback from the grpc_endpoint after bytes have been written by calling

@ -1287,7 +1287,7 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) {
grpc_error* error = GRPC_ERROR_NONE;
if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
error = GRPC_ERROR_REF(stream_state->cancel_error);
} else if (stream_state->state_op_done[OP_FAILED]) {
} else if (stream_state->state_callback_received[OP_FAILED]) {
error = make_error_with_desc(GRPC_STATUS_UNAVAILABLE, "Unavailable.");
} else if (oas->s->state.rs.trailing_metadata_valid) {
grpc_chttp2_incoming_metadata_buffer_publish(

@ -77,16 +77,16 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
// would allow us to use the alignment actually needed by the caller.
typedef struct zone {
size_t size_begin; // All the space we have set aside for allocations up
// until this zone.
size_t size_end; // size_end = size_begin plus all the space we set aside for
// allocations in zone z itself.
zone* next;
} zone;
struct gpr_arena {
gpr_atm size_so_far;
// Keep track of the total used size. We use this in our call sizing
// historesis.
gpr_atm total_used;
size_t initial_zone_size;
zone initial_zone;
zone* last_zone;
gpr_mu arena_growth_mutex;
};
@ -100,14 +100,15 @@ gpr_arena* gpr_arena_create(size_t initial_size) {
initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
gpr_arena* a = static_cast<gpr_arena*>(zalloc_aligned(
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size));
a->initial_zone.size_end = initial_size;
a->initial_zone_size = initial_size;
a->last_zone = &a->initial_zone;
gpr_mu_init(&a->arena_growth_mutex);
return a;
}
size_t gpr_arena_destroy(gpr_arena* arena) {
gpr_mu_destroy(&arena->arena_growth_mutex);
gpr_atm size = gpr_atm_no_barrier_load(&arena->size_so_far);
gpr_atm size = gpr_atm_no_barrier_load(&arena->total_used);
zone* z = arena->initial_zone.next;
gpr_free_aligned(arena);
while (z) {
@ -120,55 +121,25 @@ size_t gpr_arena_destroy(gpr_arena* arena) {
void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size);
size_t previous_size_of_arena_allocations = static_cast<size_t>(
gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size));
size_t updated_size_of_arena_allocations =
previous_size_of_arena_allocations + size;
zone* z = &arena->initial_zone;
// Check to see if the allocation isn't able to end in the initial zone.
// This statement is true only in the uncommon case because of our arena
// sizing historesis (that is, most calls should have a large enough initial
// zone and will not need to grow the arena).
if (updated_size_of_arena_allocations > z->size_end) {
// Find a zone to fit this allocation
size_t begin = gpr_atm_no_barrier_fetch_add(&arena->total_used, size);
if (begin + size <= arena->initial_zone_size) {
return reinterpret_cast<char*>(arena) +
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + begin;
} else {
// If the allocation isn't able to end in the initial zone, create a new
// zone for this allocation, and any unused space in the initial zone is
// wasted. This overflowing and wasting is uncommon because of our arena
// sizing historesis (that is, most calls should have a large enough initial
// zone and will not need to grow the arena).
gpr_mu_lock(&arena->arena_growth_mutex);
while (updated_size_of_arena_allocations > z->size_end) {
if (z->next == nullptr) {
// Note that we do an extra increment of size_so_far to prevent multiple
// simultaneous callers from stepping on each other. However, this extra
// increment means some space in the arena is wasted.
// So whenever we need to allocate x bytes and there are x - n (where
// n > 0) remaining in the current zone, we will waste x bytes (x - n
// in the current zone and n in the new zone).
previous_size_of_arena_allocations = static_cast<size_t>(
gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size));
updated_size_of_arena_allocations =
previous_size_of_arena_allocations + size;
size_t next_z_size = updated_size_of_arena_allocations;
z->next = static_cast<zone*>(zalloc_aligned(
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + next_z_size));
z->next->size_begin = z->size_end;
z->next->size_end = z->size_end + next_z_size;
}
z = z->next;
}
zone* z = static_cast<zone*>(
zalloc_aligned(GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + size));
arena->last_zone->next = z;
arena->last_zone = z;
gpr_mu_unlock(&arena->arena_growth_mutex);
return reinterpret_cast<char*>(z) +
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
}
GPR_ASSERT(previous_size_of_arena_allocations >= z->size_begin);
GPR_ASSERT(updated_size_of_arena_allocations <= z->size_end);
// Skip the first part of the zone, which just contains tracking information.
// For the initial zone, this is the gpr_arena struct and for any other zone,
// it's the zone struct.
char* start_of_allocation_space =
(z == &arena->initial_zone)
? reinterpret_cast<char*>(arena) +
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena))
: reinterpret_cast<char*>(z) +
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
// previous_size_of_arena_allocations - size_begin is how many bytes have been
// allocated into the current zone
return start_of_allocation_space + previous_size_of_arena_allocations -
z->size_begin;
}
#endif // SIMPLE_ARENA_FOR_DEBUGGING

@ -157,11 +157,11 @@ class ThreadState {
} // namespace
void Fork::GlobalInit() {
if (!overrideEnabled_) {
if (!override_enabled_) {
#ifdef GRPC_ENABLE_FORK_SUPPORT
supportEnabled_ = true;
support_enabled_ = true;
#else
supportEnabled_ = false;
support_enabled_ = false;
#endif
bool env_var_set = false;
char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT");
@ -172,7 +172,7 @@ void Fork::GlobalInit() {
"False", "FALSE", "0"};
for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) {
if (0 == strcmp(env, truthy[i])) {
supportEnabled_ = true;
support_enabled_ = true;
env_var_set = true;
break;
}
@ -180,7 +180,7 @@ void Fork::GlobalInit() {
if (!env_var_set) {
for (size_t i = 0; i < GPR_ARRAY_SIZE(falsey); i++) {
if (0 == strcmp(env, falsey[i])) {
supportEnabled_ = false;
support_enabled_ = false;
env_var_set = true;
break;
}
@ -189,72 +189,80 @@ void Fork::GlobalInit() {
gpr_free(env);
}
}
if (supportEnabled_) {
execCtxState_ = grpc_core::New<internal::ExecCtxState>();
threadState_ = grpc_core::New<internal::ThreadState>();
if (support_enabled_) {
exec_ctx_state_ = grpc_core::New<internal::ExecCtxState>();
thread_state_ = grpc_core::New<internal::ThreadState>();
}
}
void Fork::GlobalShutdown() {
if (supportEnabled_) {
grpc_core::Delete(execCtxState_);
grpc_core::Delete(threadState_);
if (support_enabled_) {
grpc_core::Delete(exec_ctx_state_);
grpc_core::Delete(thread_state_);
}
}
bool Fork::Enabled() { return supportEnabled_; }
bool Fork::Enabled() { return support_enabled_; }
// Testing Only
void Fork::Enable(bool enable) {
overrideEnabled_ = true;
supportEnabled_ = enable;
override_enabled_ = true;
support_enabled_ = enable;
}
void Fork::IncExecCtxCount() {
if (supportEnabled_) {
execCtxState_->IncExecCtxCount();
if (support_enabled_) {
exec_ctx_state_->IncExecCtxCount();
}
}
void Fork::DecExecCtxCount() {
if (supportEnabled_) {
execCtxState_->DecExecCtxCount();
if (support_enabled_) {
exec_ctx_state_->DecExecCtxCount();
}
}
void Fork::SetResetChildPollingEngineFunc(
Fork::child_postfork_func reset_child_polling_engine) {
reset_child_polling_engine_ = reset_child_polling_engine;
}
Fork::child_postfork_func Fork::GetResetChildPollingEngineFunc() {
return reset_child_polling_engine_;
}
bool Fork::BlockExecCtx() {
if (supportEnabled_) {
return execCtxState_->BlockExecCtx();
if (support_enabled_) {
return exec_ctx_state_->BlockExecCtx();
}
return false;
}
void Fork::AllowExecCtx() {
if (supportEnabled_) {
execCtxState_->AllowExecCtx();
if (support_enabled_) {
exec_ctx_state_->AllowExecCtx();
}
}
void Fork::IncThreadCount() {
if (supportEnabled_) {
threadState_->IncThreadCount();
if (support_enabled_) {
thread_state_->IncThreadCount();
}
}
void Fork::DecThreadCount() {
if (supportEnabled_) {
threadState_->DecThreadCount();
if (support_enabled_) {
thread_state_->DecThreadCount();
}
}
void Fork::AwaitThreads() {
if (supportEnabled_) {
threadState_->AwaitThreads();
if (support_enabled_) {
thread_state_->AwaitThreads();
}
}
internal::ExecCtxState* Fork::execCtxState_ = nullptr;
internal::ThreadState* Fork::threadState_ = nullptr;
bool Fork::supportEnabled_ = false;
bool Fork::overrideEnabled_ = false;
internal::ExecCtxState* Fork::exec_ctx_state_ = nullptr;
internal::ThreadState* Fork::thread_state_ = nullptr;
bool Fork::support_enabled_ = false;
bool Fork::override_enabled_ = false;
Fork::child_postfork_func Fork::reset_child_polling_engine_ = nullptr;
} // namespace grpc_core

@ -33,6 +33,8 @@ class ThreadState;
class Fork {
public:
typedef void (*child_postfork_func)(void);
static void GlobalInit();
static void GlobalShutdown();
@ -46,6 +48,12 @@ class Fork {
// Decrement the count of active ExecCtxs
static void DecExecCtxCount();
// Provide a function that will be invoked in the child's postfork handler to
// reset the polling engine's internal state.
static void SetResetChildPollingEngineFunc(
child_postfork_func reset_child_polling_engine);
static child_postfork_func GetResetChildPollingEngineFunc();
// Check if there is a single active ExecCtx
// (the one used to invoke this function). If there are more,
// return false. Otherwise, return true and block creation of
@ -68,10 +76,11 @@ class Fork {
static void Enable(bool enable);
private:
static internal::ExecCtxState* execCtxState_;
static internal::ThreadState* threadState_;
static bool supportEnabled_;
static bool overrideEnabled_;
static internal::ExecCtxState* exec_ctx_state_;
static internal::ThreadState* thread_state_;
static bool support_enabled_;
static bool override_enabled_;
static child_postfork_func reset_child_polling_engine_;
};
} // namespace grpc_core

@ -163,7 +163,7 @@ static void done_write(void* arg, grpc_error* error) {
static void start_write(internal_request* req) {
grpc_slice_ref_internal(req->request_text);
grpc_slice_buffer_add(&req->outgoing, req->request_text);
grpc_endpoint_write(req->ep, &req->outgoing, &req->done_write);
grpc_endpoint_write(req->ep, &req->outgoing, &req->done_write, nullptr);
}
static void on_handshake_done(void* arg, grpc_endpoint* ep) {

@ -0,0 +1,134 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/buffer_list.h"
#include "src/core/lib/iomgr/port.h"
#include <grpc/support/log.h>
#ifdef GRPC_LINUX_ERRQUEUE
#include <time.h>
#include "src/core/lib/gprpp/memory.h"
namespace grpc_core {
void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no,
void* arg) {
GPR_DEBUG_ASSERT(head != nullptr);
TracedBuffer* new_elem = New<TracedBuffer>(seq_no, arg);
/* Store the current time as the sendmsg time. */
new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME);
if (*head == nullptr) {
*head = new_elem;
return;
}
/* Append at the end. */
TracedBuffer* ptr = *head;
while (ptr->next_ != nullptr) {
ptr = ptr->next_;
}
ptr->next_ = new_elem;
}
namespace {
/** Fills gpr_timespec gts based on values from timespec ts */
void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) {
gts->tv_sec = ts->tv_sec;
gts->tv_nsec = static_cast<int32_t>(ts->tv_nsec);
gts->clock_type = GPR_CLOCK_REALTIME;
}
/** The saved callback function that will be invoked when we get all the
* timestamps that we are going to get for a TracedBuffer. */
void (*timestamps_callback)(void*, grpc_core::Timestamps*,
grpc_error* shutdown_err);
} /* namespace */
void TracedBuffer::ProcessTimestamp(TracedBuffer** head,
struct sock_extended_err* serr,
struct scm_timestamping* tss) {
GPR_DEBUG_ASSERT(head != nullptr);
TracedBuffer* elem = *head;
TracedBuffer* next = nullptr;
while (elem != nullptr) {
/* The byte number refers to the sequence number of the last byte which this
* timestamp relates to. */
if (serr->ee_data >= elem->seq_no_) {
switch (serr->ee_info) {
case SCM_TSTAMP_SCHED:
fill_gpr_from_timestamp(&(elem->ts_.scheduled_time), &(tss->ts[0]));
elem = elem->next_;
break;
case SCM_TSTAMP_SND:
fill_gpr_from_timestamp(&(elem->ts_.sent_time), &(tss->ts[0]));
elem = elem->next_;
break;
case SCM_TSTAMP_ACK:
fill_gpr_from_timestamp(&(elem->ts_.acked_time), &(tss->ts[0]));
/* Got all timestamps. Do the callback and free this TracedBuffer.
* The thing below can be passed by value if we don't want the
* restriction on the lifetime. */
timestamps_callback(elem->arg_, &(elem->ts_), GRPC_ERROR_NONE);
next = elem->next_;
Delete<TracedBuffer>(elem);
*head = elem = next;
break;
default:
abort();
}
} else {
break;
}
}
}
void TracedBuffer::Shutdown(TracedBuffer** head, grpc_error* shutdown_err) {
GPR_DEBUG_ASSERT(head != nullptr);
TracedBuffer* elem = *head;
while (elem != nullptr) {
if (timestamps_callback) {
timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err);
}
auto* next = elem->next_;
Delete<TracedBuffer>(elem);
elem = next;
}
*head = nullptr;
GRPC_ERROR_UNREF(shutdown_err);
}
void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*,
grpc_core::Timestamps*,
grpc_error* error)) {
timestamps_callback = fn;
}
} /* namespace grpc_core */
#else /* GRPC_LINUX_ERRQUEUE */
namespace grpc_core {
void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*,
grpc_core::Timestamps*,
grpc_error* error)) {
gpr_log(GPR_DEBUG, "Timestamps callback is not enabled for this platform");
}
} /* namespace grpc_core */
#endif /* GRPC_LINUX_ERRQUEUE */

@ -0,0 +1,96 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H
#define GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/port.h"
#include <grpc/support/time.h>
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/internal_errqueue.h"
namespace grpc_core {
struct Timestamps {
/* TODO(yashykt): This would also need to store OPTSTAT once support is added
*/
gpr_timespec sendmsg_time;
gpr_timespec scheduled_time;
gpr_timespec sent_time;
gpr_timespec acked_time;
};
/** TracedBuffer is a class to keep track of timestamps for a specific buffer in
* the TCP layer. We are only tracking timestamps for Linux kernels and hence
* this class would only be used by Linux platforms. For all other platforms,
* TracedBuffer would be an empty class.
*
* The timestamps collected are according to grpc_core::Timestamps declared
* above.
*
* A TracedBuffer list is kept track of using the head element of the list. If
* the head element of the list is nullptr, then the list is empty.
*/
#ifdef GRPC_LINUX_ERRQUEUE
class TracedBuffer {
public:
/** Add a new entry in the TracedBuffer list pointed to by head. Also saves
* sendmsg_time with the current timestamp. */
static void AddNewEntry(grpc_core::TracedBuffer** head, uint32_t seq_no,
void* arg);
/** Processes a received timestamp based on sock_extended_err and
* scm_timestamping structures. It will invoke the timestamps callback if the
* timestamp type is SCM_TSTAMP_ACK. */
static void ProcessTimestamp(grpc_core::TracedBuffer** head,
struct sock_extended_err* serr,
struct scm_timestamping* tss);
/** Cleans the list by calling the callback for each traced buffer in the list
* with timestamps that it has. */
static void Shutdown(grpc_core::TracedBuffer** head,
grpc_error* shutdown_err);
private:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
TracedBuffer(int seq_no, void* arg)
: seq_no_(seq_no), arg_(arg), next_(nullptr) {}
uint32_t seq_no_; /* The sequence number for the last byte in the buffer */
void* arg_; /* The arg to pass to timestamps_callback */
grpc_core::Timestamps ts_; /* The timestamps corresponding to this buffer */
grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */
};
#else /* GRPC_LINUX_ERRQUEUE */
class TracedBuffer {};
#endif /* GRPC_LINUX_ERRQUEUE */
/** Sets the callback function to call when timestamps for a write are
* collected. The callback does not own a reference to error. */
void grpc_tcp_set_write_timestamps_callback(void (*fn)(void*,
grpc_core::Timestamps*,
grpc_error* error));
}; /* namespace grpc_core */
#endif /* GRPC_CORE_LIB_IOMGR_BUFFER_LIST_H */

@ -28,8 +28,8 @@ void grpc_endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* slices,
}
void grpc_endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* slices,
grpc_closure* cb) {
ep->vtable->write(ep, slices, cb);
grpc_closure* cb, void* arg) {
ep->vtable->write(ep, slices, cb, arg);
}
void grpc_endpoint_add_to_pollset(grpc_endpoint* ep, grpc_pollset* pollset) {

@ -33,10 +33,12 @@
typedef struct grpc_endpoint grpc_endpoint;
typedef struct grpc_endpoint_vtable grpc_endpoint_vtable;
class Timestamps;
struct grpc_endpoint_vtable {
void (*read)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb);
void (*write)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb);
void (*write)(grpc_endpoint* ep, grpc_slice_buffer* slices, grpc_closure* cb,
void* arg);
void (*add_to_pollset)(grpc_endpoint* ep, grpc_pollset* pollset);
void (*add_to_pollset_set)(grpc_endpoint* ep, grpc_pollset_set* pollset);
void (*delete_from_pollset_set)(grpc_endpoint* ep, grpc_pollset_set* pollset);
@ -70,9 +72,11 @@ int grpc_endpoint_get_fd(grpc_endpoint* ep);
\a slices may be mutated at will by the endpoint until cb is called.
No guarantee is made to the content of slices after a write EXCEPT that
it is a valid slice buffer.
\a arg is platform specific. It is currently only used by TCP on linux
platforms as an argument that would be forwarded to the timestamps callback.
*/
void grpc_endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* slices,
grpc_closure* cb);
grpc_closure* cb, void* arg);
/* Causes any pending and future read/write callbacks to run immediately with
success==0 */

@ -268,7 +268,7 @@ static void CFStreamRead(grpc_endpoint* ep, grpc_slice_buffer* slices,
}
static void CFStreamWrite(grpc_endpoint* ep, grpc_slice_buffer* slices,
grpc_closure* cb) {
grpc_closure* cb, void* arg) {
CFStreamEndpoint* ep_impl = reinterpret_cast<CFStreamEndpoint*>(ep);
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_DEBUG, "CFStream endpoint:%p write (%p, %p) length:%zu",

@ -59,11 +59,11 @@ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char* name,
grpc_core::ExecCtx exec_ctx;
gpr_asprintf(&final_name, "%s:client", name);
p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, false), args,
p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, true), args,
"socketpair-server");
gpr_free(final_name);
gpr_asprintf(&final_name, "%s:server", name);
p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, false), args,
p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, true), args,
"socketpair-client");
gpr_free(final_name);

@ -131,6 +131,13 @@ static void epoll_set_shutdown() {
* Fd Declarations
*/
/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
struct grpc_fork_fd_list {
grpc_fd* fd;
grpc_fd* next;
grpc_fd* prev;
};
struct grpc_fd {
int fd;
@ -141,6 +148,9 @@ struct grpc_fd {
struct grpc_fd* freelist_next;
grpc_iomgr_object iomgr_object;
/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
grpc_fork_fd_list* fork_fd_list;
};
static void fd_global_init(void);
@ -256,6 +266,10 @@ static bool append_error(grpc_error** composite, grpc_error* error,
static grpc_fd* fd_freelist = nullptr;
static gpr_mu fd_freelist_mu;
/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
static grpc_fd* fork_fd_list_head = nullptr;
static gpr_mu fork_fd_list_mu;
static void fd_global_init(void) { gpr_mu_init(&fd_freelist_mu); }
static void fd_global_shutdown(void) {
@ -269,6 +283,38 @@ static void fd_global_shutdown(void) {
gpr_mu_destroy(&fd_freelist_mu);
}
static void fork_fd_list_add_grpc_fd(grpc_fd* fd) {
if (grpc_core::Fork::Enabled()) {
gpr_mu_lock(&fork_fd_list_mu);
fd->fork_fd_list =
static_cast<grpc_fork_fd_list*>(gpr_malloc(sizeof(grpc_fork_fd_list)));
fd->fork_fd_list->next = fork_fd_list_head;
fd->fork_fd_list->prev = nullptr;
if (fork_fd_list_head != nullptr) {
fork_fd_list_head->fork_fd_list->prev = fd;
}
fork_fd_list_head = fd;
gpr_mu_unlock(&fork_fd_list_mu);
}
}
static void fork_fd_list_remove_grpc_fd(grpc_fd* fd) {
if (grpc_core::Fork::Enabled()) {
gpr_mu_lock(&fork_fd_list_mu);
if (fork_fd_list_head == fd) {
fork_fd_list_head = fd->fork_fd_list->next;
}
if (fd->fork_fd_list->prev != nullptr) {
fd->fork_fd_list->prev->fork_fd_list->next = fd->fork_fd_list->next;
}
if (fd->fork_fd_list->next != nullptr) {
fd->fork_fd_list->next->fork_fd_list->prev = fd->fork_fd_list->prev;
}
gpr_free(fd->fork_fd_list);
gpr_mu_unlock(&fork_fd_list_mu);
}
}
static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
grpc_fd* new_fd = nullptr;
@ -295,6 +341,7 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
char* fd_name;
gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name);
fork_fd_list_add_grpc_fd(new_fd);
#ifndef NDEBUG
if (grpc_trace_fd_refcount.enabled()) {
gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, new_fd, fd_name);
@ -361,6 +408,7 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_REF(error));
grpc_iomgr_unregister_object(&fd->iomgr_object);
fork_fd_list_remove_grpc_fd(fd);
fd->read_closure->DestroyEvent();
fd->write_closure->DestroyEvent();
fd->error_closure->DestroyEvent();
@ -1190,6 +1238,10 @@ static void shutdown_engine(void) {
fd_global_shutdown();
pollset_global_shutdown();
epoll_set_shutdown();
if (grpc_core::Fork::Enabled()) {
gpr_mu_destroy(&fork_fd_list_mu);
grpc_core::Fork::SetResetChildPollingEngineFunc(nullptr);
}
}
static const grpc_event_engine_vtable vtable = {
@ -1227,6 +1279,21 @@ static const grpc_event_engine_vtable vtable = {
shutdown_engine,
};
/* Called by the child process's post-fork handler to close open fds, including
* the global epoll fd. This allows gRPC to shutdown in the child process
* without interfering with connections or RPCs ongoing in the parent. */
static void reset_event_manager_on_fork() {
gpr_mu_lock(&fork_fd_list_mu);
while (fork_fd_list_head != nullptr) {
close(fork_fd_list_head->fd);
fork_fd_list_head->fd = -1;
fork_fd_list_head = fork_fd_list_head->fork_fd_list->next;
}
gpr_mu_unlock(&fork_fd_list_mu);
shutdown_engine();
grpc_init_epoll1_linux(true);
}
/* It is possible that GLIBC has epoll but the underlying kernel doesn't.
* Create epoll_fd (epoll_set_init() takes care of that) to make sure epoll
* support is available */
@ -1248,6 +1315,11 @@ const grpc_event_engine_vtable* grpc_init_epoll1_linux(bool explicit_request) {
return nullptr;
}
if (grpc_core::Fork::Enabled()) {
gpr_mu_init(&fork_fd_list_mu);
grpc_core::Fork::SetResetChildPollingEngineFunc(
reset_event_manager_on_fork);
}
return &vtable;
}

@ -60,6 +60,19 @@ typedef struct grpc_fd_watcher {
grpc_fd* fd;
} grpc_fd_watcher;
typedef struct grpc_cached_wakeup_fd grpc_cached_wakeup_fd;
/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
struct grpc_fork_fd_list {
/* Only one of fd or cached_wakeup_fd will be set. The unused field will be
set to nullptr. */
grpc_fd* fd;
grpc_cached_wakeup_fd* cached_wakeup_fd;
grpc_fork_fd_list* next;
grpc_fork_fd_list* prev;
};
struct grpc_fd {
int fd;
/* refst format:
@ -108,8 +121,18 @@ struct grpc_fd {
grpc_closure* on_done_closure;
grpc_iomgr_object iomgr_object;
/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
grpc_fork_fd_list* fork_fd_list;
};
/* True when GRPC_ENABLE_FORK_SUPPORT=1. We do not support fork with poll-cv */
static bool track_fds_for_fork = false;
/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
static grpc_fork_fd_list* fork_fd_list_head = nullptr;
static gpr_mu fork_fd_list_mu;
/* Begin polling on an fd.
Registers that the given pollset is interested in this fd - so that if read
or writability interest changes, the pollset can be kicked to pick up that
@ -156,6 +179,9 @@ static void fd_unref(grpc_fd* fd);
typedef struct grpc_cached_wakeup_fd {
grpc_wakeup_fd fd;
struct grpc_cached_wakeup_fd* next;
/* Only used when GRPC_ENABLE_FORK_SUPPORT=1 */
grpc_fork_fd_list* fork_fd_list;
} grpc_cached_wakeup_fd;
struct grpc_pollset_worker {
@ -281,9 +307,61 @@ poll_hash_table poll_cache;
grpc_cv_fd_table g_cvfds;
/*******************************************************************************
* fd_posix.c
* functions to track opened fds. No-ops unless track_fds_for_fork is true.
*/
static void fork_fd_list_remove_node(grpc_fork_fd_list* node) {
if (track_fds_for_fork) {
gpr_mu_lock(&fork_fd_list_mu);
if (fork_fd_list_head == node) {
fork_fd_list_head = node->next;
}
if (node->prev != nullptr) {
node->prev->next = node->next;
}
if (node->next != nullptr) {
node->next->prev = node->prev;
}
gpr_free(node);
gpr_mu_unlock(&fork_fd_list_mu);
}
}
static void fork_fd_list_add_node(grpc_fork_fd_list* node) {
gpr_mu_lock(&fork_fd_list_mu);
node->next = fork_fd_list_head;
node->prev = nullptr;
if (fork_fd_list_head != nullptr) {
fork_fd_list_head->prev = node;
}
fork_fd_list_head = node;
gpr_mu_unlock(&fork_fd_list_mu);
}
static void fork_fd_list_add_grpc_fd(grpc_fd* fd) {
if (track_fds_for_fork) {
fd->fork_fd_list =
static_cast<grpc_fork_fd_list*>(gpr_malloc(sizeof(grpc_fork_fd_list)));
fd->fork_fd_list->fd = fd;
fd->fork_fd_list->cached_wakeup_fd = nullptr;
fork_fd_list_add_node(fd->fork_fd_list);
}
}
static void fork_fd_list_add_wakeup_fd(grpc_cached_wakeup_fd* fd) {
if (track_fds_for_fork) {
fd->fork_fd_list =
static_cast<grpc_fork_fd_list*>(gpr_malloc(sizeof(grpc_fork_fd_list)));
fd->fork_fd_list->cached_wakeup_fd = fd;
fd->fork_fd_list->fd = nullptr;
fork_fd_list_add_node(fd->fork_fd_list);
}
}
/*******************************************************************************
* fd_posix.c
*/
#ifndef NDEBUG
#define REF_BY(fd, n, reason) ref_by(fd, n, reason, __FILE__, __LINE__)
#define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__)
@ -319,6 +397,7 @@ static void unref_by(grpc_fd* fd, int n) {
if (old == n) {
gpr_mu_destroy(&fd->mu);
grpc_iomgr_unregister_object(&fd->iomgr_object);
fork_fd_list_remove_node(fd->fork_fd_list);
if (fd->shutdown) GRPC_ERROR_UNREF(fd->shutdown_error);
gpr_free(fd);
} else {
@ -347,6 +426,7 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
gpr_asprintf(&name2, "%s fd=%d", name, fd);
grpc_iomgr_register_object(&r->iomgr_object, name2);
gpr_free(name2);
fork_fd_list_add_grpc_fd(r);
return r;
}
@ -822,6 +902,7 @@ static void pollset_destroy(grpc_pollset* pollset) {
GPR_ASSERT(!pollset_has_workers(pollset));
while (pollset->local_wakeup_cache) {
grpc_cached_wakeup_fd* next = pollset->local_wakeup_cache->next;
fork_fd_list_remove_node(pollset->local_wakeup_cache->fork_fd_list);
grpc_wakeup_fd_destroy(&pollset->local_wakeup_cache->fd);
gpr_free(pollset->local_wakeup_cache);
pollset->local_wakeup_cache = next;
@ -895,6 +976,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
worker.wakeup_fd = static_cast<grpc_cached_wakeup_fd*>(
gpr_malloc(sizeof(*worker.wakeup_fd)));
error = grpc_wakeup_fd_init(&worker.wakeup_fd->fd);
fork_fd_list_add_wakeup_fd(worker.wakeup_fd);
if (error != GRPC_ERROR_NONE) {
GRPC_LOG_IF_ERROR("pollset_work", GRPC_ERROR_REF(error));
return error;
@ -1705,6 +1787,10 @@ static void shutdown_engine(void) {
if (grpc_cv_wakeup_fds_enabled()) {
global_cv_fd_table_shutdown();
}
if (track_fds_for_fork) {
gpr_mu_destroy(&fork_fd_list_mu);
grpc_core::Fork::SetResetChildPollingEngineFunc(nullptr);
}
}
static const grpc_event_engine_vtable vtable = {
@ -1742,6 +1828,26 @@ static const grpc_event_engine_vtable vtable = {
shutdown_engine,
};
/* Called by the child process's post-fork handler to close open fds, including
* worker wakeup fds. This allows gRPC to shutdown in the child process without
* interfering with connections or RPCs ongoing in the parent. */
static void reset_event_manager_on_fork() {
gpr_mu_lock(&fork_fd_list_mu);
while (fork_fd_list_head != nullptr) {
if (fork_fd_list_head->fd != nullptr) {
close(fork_fd_list_head->fd->fd);
fork_fd_list_head->fd->fd = -1;
} else {
close(fork_fd_list_head->cached_wakeup_fd->fd.read_fd);
fork_fd_list_head->cached_wakeup_fd->fd.read_fd = -1;
close(fork_fd_list_head->cached_wakeup_fd->fd.write_fd);
fork_fd_list_head->cached_wakeup_fd->fd.write_fd = -1;
}
fork_fd_list_head = fork_fd_list_head->next;
}
gpr_mu_unlock(&fork_fd_list_mu);
}
const grpc_event_engine_vtable* grpc_init_poll_posix(bool explicit_request) {
if (!grpc_has_wakeup_fd()) {
gpr_log(GPR_ERROR, "Skipping poll because of no wakeup fd.");
@ -1750,6 +1856,12 @@ const grpc_event_engine_vtable* grpc_init_poll_posix(bool explicit_request) {
if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) {
return nullptr;
}
if (grpc_core::Fork::Enabled()) {
track_fds_for_fork = true;
gpr_mu_init(&fork_fd_list_mu);
grpc_core::Fork::SetResetChildPollingEngineFunc(
reset_event_manager_on_fork);
}
return &vtable;
}

@ -237,14 +237,19 @@ void grpc_event_engine_shutdown(void) {
}
bool grpc_event_engine_can_track_errors(void) {
/* Only track errors if platform supports errqueue. */
#ifdef GRPC_LINUX_ERRQUEUE
return g_event_engine->can_track_err;
#else
return false;
#endif /* GRPC_LINUX_ERRQUEUE */
}
grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) {
GRPC_POLLING_API_TRACE("fd_create(%d, %s, %d)", fd, name, track_err);
GRPC_FD_TRACE("fd_create(%d, %s, %d)", fd, name, track_err);
GPR_DEBUG_ASSERT(!track_err || g_event_engine->can_track_err);
return g_event_engine->fd_create(fd, name, track_err);
return g_event_engine->fd_create(fd, name,
track_err && g_event_engine->can_track_err);
}
int grpc_fd_wrapped_fd(grpc_fd* fd) {

@ -109,6 +109,12 @@ grpc_closure_scheduler* grpc_schedule_on_exec_ctx = &exec_ctx_scheduler;
namespace grpc_core {
GPR_TLS_CLASS_DEF(ExecCtx::exec_ctx_);
// WARNING: for testing purposes only!
void ExecCtx::TestOnlyGlobalInit(gpr_timespec new_val) {
g_start_time = new_val;
gpr_tls_init(&exec_ctx_);
}
void ExecCtx::GlobalInit(void) {
g_start_time = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_tls_init(&exec_ctx_);

@ -192,6 +192,8 @@ class ExecCtx {
now_is_valid_ = true;
}
static void TestOnlyGlobalInit(gpr_timespec new_val);
/** Global initialization for ExecCtx. Called by iomgr. */
static void GlobalInit(void);

@ -25,6 +25,7 @@
#include <string.h>
#include <grpc/fork.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/env.h"
@ -34,7 +35,6 @@
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/timer_manager.h"
#include "src/core/lib/iomgr/wakeup_fd_posix.h"
#include "src/core/lib/surface/init.h"
/*
* NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK
@ -58,6 +58,12 @@ void grpc_prefork() {
"environment variable GRPC_ENABLE_FORK_SUPPORT=1");
return;
}
if (strcmp(grpc_get_poll_strategy_name(), "epoll1") != 0 &&
strcmp(grpc_get_poll_strategy_name(), "poll") != 0) {
gpr_log(GPR_ERROR,
"Fork support is only compatible with the epoll1 and poll polling "
"strategies");
}
if (!grpc_core::Fork::BlockExecCtx()) {
gpr_log(GPR_INFO,
"Other threads are currently calling into gRPC, skipping fork() "
@ -84,6 +90,11 @@ void grpc_postfork_child() {
if (!skipped_handler) {
grpc_core::Fork::AllowExecCtx();
grpc_core::ExecCtx exec_ctx;
grpc_core::Fork::child_postfork_func reset_polling_engine =
grpc_core::Fork::GetResetChildPollingEngineFunc();
if (reset_polling_engine != nullptr) {
reset_polling_engine();
}
grpc_timer_manager_set_threading(true);
grpc_executor_set_threading(true);
}

@ -0,0 +1,36 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/port.h"
#include "src/core/lib/iomgr/internal_errqueue.h"
#ifdef GRPC_POSIX_SOCKET_TCP
bool kernel_supports_errqueue() {
#ifdef LINUX_VERSION_CODE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
return true;
#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) */
#endif /* LINUX_VERSION_CODE */
return false;
}
#endif /* GRPC_POSIX_SOCKET_TCP */

@ -0,0 +1,83 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/* This file contains constants defined in <linux/errqueue.h> and
* <linux/net_tstamp.h> so as to allow collecting network timestamps in the
* kernel. This file allows tcp_posix.cc to compile on platforms that do not
* have <linux/errqueue.h> and <linux/net_tstamp.h>.
*/
#ifndef GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H
#define GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET_TCP
#include <sys/types.h>
#include <time.h>
#ifdef GRPC_LINUX_ERRQUEUE
#include <linux/errqueue.h>
#include <linux/net_tstamp.h>
#include <sys/socket.h>
#endif /* GRPC_LINUX_ERRQUEUE */
namespace grpc_core {
#ifdef GRPC_LINUX_ERRQUEUE
/* Redefining scm_timestamping in the same way that <linux/errqueue.h> defines
* it, so that code compiles on systems that don't have it. */
struct scm_timestamping {
struct timespec ts[3];
};
/* Also redefine timestamp types */
/* The timestamp type for when the driver passed skb to NIC, or HW. */
constexpr int SCM_TSTAMP_SND = 0;
/* The timestamp type for when data entered the packet scheduler. */
constexpr int SCM_TSTAMP_SCHED = 1;
/* The timestamp type for when data acknowledged by peer. */
constexpr int SCM_TSTAMP_ACK = 2;
/* Redefine required constants from <linux/net_tstamp.h> */
constexpr uint32_t SOF_TIMESTAMPING_TX_SOFTWARE = 1u << 1;
constexpr uint32_t SOF_TIMESTAMPING_SOFTWARE = 1u << 4;
constexpr uint32_t SOF_TIMESTAMPING_OPT_ID = 1u << 7;
constexpr uint32_t SOF_TIMESTAMPING_TX_SCHED = 1u << 8;
constexpr uint32_t SOF_TIMESTAMPING_TX_ACK = 1u << 9;
constexpr uint32_t SOF_TIMESTAMPING_OPT_TSONLY = 1u << 11;
constexpr uint32_t kTimestampingSocketOptions = SOF_TIMESTAMPING_SOFTWARE |
SOF_TIMESTAMPING_OPT_ID |
SOF_TIMESTAMPING_OPT_TSONLY;
constexpr uint32_t kTimestampingRecordingOptions =
SOF_TIMESTAMPING_TX_SCHED | SOF_TIMESTAMPING_TX_SOFTWARE |
SOF_TIMESTAMPING_TX_ACK;
#endif /* GRPC_LINUX_ERRQUEUE */
/* Returns true if kernel is capable of supporting errqueue and timestamping.
* Currently allowing only linux kernels above 4.0.0
*/
bool kernel_supports_errqueue();
} // namespace grpc_core
#endif /* GRPC_POSIX_SOCKET_TCP */
#endif /* GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H */

@ -60,6 +60,11 @@
#define GRPC_HAVE_IP_PKTINFO 1
#define GRPC_HAVE_MSG_NOSIGNAL 1
#define GRPC_HAVE_UNIX_SOCKET 1
#ifdef LINUX_VERSION_CODE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
#define GRPC_LINUX_ERRQUEUE 1
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */
#endif /* LINUX_VERSION_CODE */
#define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1
#define GRPC_POSIX_FORK 1
#define GRPC_POSIX_HOST_NAME_MAX 1

@ -57,7 +57,7 @@ int grpc_socket_mutator_compare(grpc_socket_mutator* a,
void grpc_socket_mutator_unref(grpc_socket_mutator* mutator) {
if (gpr_unref(&mutator->refcount)) {
mutator->vtable->destory(mutator);
mutator->vtable->destroy(mutator);
}
}

@ -33,7 +33,7 @@ typedef struct {
/** Compare socket mutator \a a and \a b */
int (*compare)(grpc_socket_mutator* a, grpc_socket_mutator* b);
/** Destroys the socket mutator instance */
void (*destory)(grpc_socket_mutator* mutator);
void (*destroy)(grpc_socket_mutator* mutator);
} grpc_socket_mutator_vtable;
/** The Socket Mutator interface allows changes on socket options */

@ -279,7 +279,7 @@ grpc_error* grpc_tcp_client_prepare_fd(const grpc_channel_args* channel_args,
}
addr_str = grpc_sockaddr_to_uri(mapped_addr);
gpr_asprintf(&name, "tcp-client:%s", addr_str);
*fdobj = grpc_fd_create(fd, name, false);
*fdobj = grpc_fd_create(fd, name, true);
gpr_free(name);
gpr_free(addr_str);
return GRPC_ERROR_NONE;

@ -221,7 +221,7 @@ static void custom_write_callback(grpc_custom_socket* socket,
}
static void endpoint_write(grpc_endpoint* ep, grpc_slice_buffer* write_slices,
grpc_closure* cb) {
grpc_closure* cb, void* arg) {
custom_tcp_endpoint* tcp = (custom_tcp_endpoint*)ep;
GRPC_CUSTOM_IOMGR_ASSERT_SAME_THREAD();

@ -27,7 +27,9 @@
#include <errno.h>
#include <limits.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
@ -46,6 +48,7 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/buffer_list.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/profiling/timers.h"
@ -97,17 +100,42 @@ struct grpc_tcp {
grpc_closure read_done_closure;
grpc_closure write_done_closure;
grpc_closure error_closure;
char* peer_string;
grpc_resource_user* resource_user;
grpc_resource_user_slice_allocator slice_allocator;
grpc_core::TracedBuffer* tb_head; /* List of traced buffers */
gpr_mu tb_mu; /* Lock for access to list of traced buffers */
/* grpc_endpoint_write takes an argument which if non-null means that the
* transport layer wants the TCP layer to collect timestamps for this write.
* This arg is forwarded to the timestamps callback function when the ACK
* timestamp is received from the kernel. This arg is a (void *) which allows
* users of this API to pass in a pointer to any kind of structure. This
* structure could actually be a tag or any book-keeping object that the user
* can use to distinguish between different traced writes. The only
* requirement from the TCP endpoint layer is that this arg should be non-null
* if the user wants timestamps for the write. */
void* outgoing_buffer_arg;
/* A counter which starts at 0. It is initialized the first time the socket
* options for collecting timestamps are set, and is incremented with each
* byte sent. */
int bytes_counter;
bool socket_ts_enabled; /* True if timestamping options are set on the socket
*/
gpr_atm
stop_error_notification; /* Set to 1 if we do not want to be notified on
errors anymore */
};
struct backup_poller {
gpr_mu* pollset_mu;
grpc_closure run_poller;
};
} // namespace
#define BACKUP_POLLER_POLLSET(b) ((grpc_pollset*)((b) + 1))
@ -302,6 +330,7 @@ static void tcp_free(grpc_tcp* tcp) {
grpc_slice_buffer_destroy_internal(&tcp->last_read_buffer);
grpc_resource_user_unref(tcp->resource_user);
gpr_free(tcp->peer_string);
gpr_mu_destroy(&tcp->tb_mu);
gpr_free(tcp);
}
@ -347,6 +376,10 @@ static void tcp_destroy(grpc_endpoint* ep) {
grpc_network_status_unregister_endpoint(ep);
grpc_tcp* tcp = reinterpret_cast<grpc_tcp*>(ep);
grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer);
if (grpc_event_engine_can_track_errors()) {
gpr_atm_no_barrier_store(&tcp->stop_error_notification, true);
grpc_fd_set_error(tcp->em_fd);
}
TCP_UNREF(tcp, "destroy");
}
@ -513,6 +546,235 @@ static void tcp_read(grpc_endpoint* ep, grpc_slice_buffer* incoming_buffer,
}
}
/* A wrapper around sendmsg. It sends \a msg over \a fd and returns the number
* of bytes sent. */
ssize_t tcp_send(int fd, const struct msghdr* msg) {
GPR_TIMER_SCOPE("sendmsg", 1);
ssize_t sent_length;
do {
/* TODO(klempner): Cork if this is a partial write */
GRPC_STATS_INC_SYSCALL_WRITE();
sent_length = sendmsg(fd, msg, SENDMSG_FLAGS);
} while (sent_length < 0 && errno == EINTR);
return sent_length;
}
/** This is to be called if outgoing_buffer_arg is not null. On linux platforms,
* this will call sendmsg with socket options set to collect timestamps inside
* the kernel. On return, sent_length is set to the return value of the sendmsg
* call. Returns false if setting the socket options failed. This is not
* implemented for non-linux platforms currently, and crashes out.
*/
static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg,
size_t sending_length,
ssize_t* sent_length, grpc_error** error);
/** The callback function to be invoked when we get an error on the socket. */
static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error);
#ifdef GRPC_LINUX_ERRQUEUE
static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg,
size_t sending_length,
ssize_t* sent_length,
grpc_error** error) {
if (!tcp->socket_ts_enabled) {
uint32_t opt = grpc_core::kTimestampingSocketOptions;
if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING,
static_cast<void*>(&opt), sizeof(opt)) != 0) {
*error = tcp_annotate_error(GRPC_OS_ERROR(errno, "setsockopt"), tcp);
grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer);
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_ERROR, "Failed to set timestamping options on the socket.");
}
return false;
}
tcp->bytes_counter = -1;
tcp->socket_ts_enabled = true;
}
/* Set control message to indicate that you want timestamps. */
union {
char cmsg_buf[CMSG_SPACE(sizeof(uint32_t))];
struct cmsghdr align;
} u;
cmsghdr* cmsg = reinterpret_cast<cmsghdr*>(u.cmsg_buf);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SO_TIMESTAMPING;
cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t));
*reinterpret_cast<int*>(CMSG_DATA(cmsg)) =
grpc_core::kTimestampingRecordingOptions;
msg->msg_control = u.cmsg_buf;
msg->msg_controllen = CMSG_SPACE(sizeof(uint32_t));
/* If there was an error on sendmsg the logic in tcp_flush will handle it. */
ssize_t length = tcp_send(tcp->fd, msg);
*sent_length = length;
/* Only save timestamps if all the bytes were taken by sendmsg. */
if (sending_length == static_cast<size_t>(length)) {
gpr_mu_lock(&tcp->tb_mu);
grpc_core::TracedBuffer::AddNewEntry(
&tcp->tb_head, static_cast<int>(tcp->bytes_counter + length),
tcp->outgoing_buffer_arg);
gpr_mu_unlock(&tcp->tb_mu);
tcp->outgoing_buffer_arg = nullptr;
}
return true;
}
/** Reads \a cmsg to derive timestamps from the control messages. If a valid
* timestamp is found, the traced buffer list is updated with this timestamp.
* The caller of this function should be looping on the control messages found
* in \a msg. \a cmsg should point to the control message that the caller wants
* processed.
* On return, a pointer to a control message is returned. On the next iteration,
* CMSG_NXTHDR(msg, ret_val) should be passed as \a cmsg. */
struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg,
struct cmsghdr* cmsg) {
auto next_cmsg = CMSG_NXTHDR(msg, cmsg);
if (next_cmsg == nullptr) {
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_ERROR, "Received timestamp without extended error");
}
return cmsg;
}
if (!(next_cmsg->cmsg_level == SOL_IP || next_cmsg->cmsg_level == SOL_IPV6) ||
!(next_cmsg->cmsg_type == IP_RECVERR ||
next_cmsg->cmsg_type == IPV6_RECVERR)) {
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_ERROR, "Unexpected control message");
}
return cmsg;
}
auto tss =
reinterpret_cast<struct grpc_core::scm_timestamping*>(CMSG_DATA(cmsg));
auto serr = reinterpret_cast<struct sock_extended_err*>(CMSG_DATA(next_cmsg));
if (serr->ee_errno != ENOMSG ||
serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) {
gpr_log(GPR_ERROR, "Unexpected control message");
return cmsg;
}
/* The error handling can potentially be done on another thread so we need
* to protect the traced buffer list. A lock free list might be better. Using
* a simple mutex for now. */
gpr_mu_lock(&tcp->tb_mu);
grpc_core::TracedBuffer::ProcessTimestamp(&tcp->tb_head, serr, tss);
gpr_mu_unlock(&tcp->tb_mu);
return next_cmsg;
}
/** For linux platforms, reads the socket's error queue and processes error
* messages from the queue. Returns true if all the errors processed were
* timestamps. Returns false if any of the errors were not timestamps. For
* non-linux platforms, error processing is not used/enabled currently.
*/
static bool process_errors(grpc_tcp* tcp) {
while (true) {
struct iovec iov;
iov.iov_base = nullptr;
iov.iov_len = 0;
struct msghdr msg;
msg.msg_name = nullptr;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 0;
msg.msg_flags = 0;
union {
char rbuf[1024 /*CMSG_SPACE(sizeof(scm_timestamping)) +
CMSG_SPACE(sizeof(sock_extended_err) + sizeof(sockaddr_in))*/];
struct cmsghdr align;
} aligned_buf;
memset(&aligned_buf, 0, sizeof(aligned_buf));
msg.msg_control = aligned_buf.rbuf;
msg.msg_controllen = sizeof(aligned_buf.rbuf);
int r, saved_errno;
do {
r = recvmsg(tcp->fd, &msg, MSG_ERRQUEUE);
saved_errno = errno;
} while (r < 0 && saved_errno == EINTR);
if (r == -1 && saved_errno == EAGAIN) {
return true; /* No more errors to process */
}
if (r == -1) {
return false;
}
if (grpc_tcp_trace.enabled()) {
if ((msg.msg_flags & MSG_CTRUNC) == 1) {
gpr_log(GPR_INFO, "Error message was truncated.");
}
}
if (msg.msg_controllen == 0) {
/* There was no control message found. It was probably spurious. */
return true;
}
for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg && cmsg->cmsg_len;
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level != SOL_SOCKET ||
cmsg->cmsg_type != SCM_TIMESTAMPING) {
/* Got a control message that is not a timestamp. Don't know how to
* handle this. */
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_INFO,
"unknown control message cmsg_level:%d cmsg_type:%d",
cmsg->cmsg_level, cmsg->cmsg_type);
}
return false;
}
process_timestamp(tcp, &msg, cmsg);
}
}
}
static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) {
grpc_tcp* tcp = static_cast<grpc_tcp*>(arg);
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_INFO, "TCP:%p got_error: %s", tcp, grpc_error_string(error));
}
if (error != GRPC_ERROR_NONE ||
static_cast<bool>(gpr_atm_acq_load(&tcp->stop_error_notification))) {
/* We aren't going to register to hear on error anymore, so it is safe to
* unref. */
grpc_core::TracedBuffer::Shutdown(&tcp->tb_head, GRPC_ERROR_REF(error));
TCP_UNREF(tcp, "error-tracking");
return;
}
/* We are still interested in collecting timestamps, so let's try reading
* them. */
if (!process_errors(tcp)) {
/* This was not a timestamps error. This was an actual error. Set the
* read and write closures to be ready.
*/
grpc_fd_set_readable(tcp->em_fd);
grpc_fd_set_writable(tcp->em_fd);
}
GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp,
grpc_schedule_on_exec_ctx);
grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure);
}
#else /* GRPC_LINUX_ERRQUEUE */
static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg,
size_t sending_length,
ssize_t* sent_length,
grpc_error** error) {
gpr_log(GPR_ERROR, "Write with timestamps not supported for this platform");
GPR_ASSERT(0);
return false;
}
static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) {
gpr_log(GPR_ERROR, "Error handling is not supported for this platform");
GPR_ASSERT(0);
}
#endif /* GRPC_LINUX_ERRQUEUE */
/* returns true if done, false if pending; if returning true, *error is set */
#if defined(IOV_MAX) && IOV_MAX < 1000
#define MAX_WRITE_IOVEC IOV_MAX
@ -557,19 +819,20 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
msg.msg_namelen = 0;
msg.msg_iov = iov;
msg.msg_iovlen = iov_size;
msg.msg_control = nullptr;
msg.msg_controllen = 0;
msg.msg_flags = 0;
if (tcp->outgoing_buffer_arg != nullptr) {
if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length,
error))
return true; /* something went wrong with timestamps */
} else {
msg.msg_control = nullptr;
msg.msg_controllen = 0;
GRPC_STATS_INC_TCP_WRITE_SIZE(sending_length);
GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(iov_size);
GRPC_STATS_INC_TCP_WRITE_SIZE(sending_length);
GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(iov_size);
GPR_TIMER_SCOPE("sendmsg", 1);
do {
/* TODO(klempner): Cork if this is a partial write */
GRPC_STATS_INC_SYSCALL_WRITE();
sent_length = sendmsg(tcp->fd, &msg, SENDMSG_FLAGS);
} while (sent_length < 0 && errno == EINTR);
sent_length = tcp_send(tcp->fd, &msg);
}
if (sent_length < 0) {
if (errno == EAGAIN) {
@ -593,6 +856,7 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
}
GPR_ASSERT(tcp->outgoing_byte_idx == 0);
tcp->bytes_counter += sent_length;
trailing = sending_length - static_cast<size_t>(sent_length);
while (trailing > 0) {
size_t slice_length;
@ -607,7 +871,6 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
trailing -= slice_length;
}
}
if (outgoing_slice_idx == tcp->outgoing_buffer->count) {
*error = GRPC_ERROR_NONE;
grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer);
@ -640,14 +903,13 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) {
const char* str = grpc_error_string(error);
gpr_log(GPR_INFO, "write: %s", str);
}
GRPC_CLOSURE_SCHED(cb, error);
TCP_UNREF(tcp, "write");
}
}
static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf,
grpc_closure* cb) {
grpc_closure* cb, void* arg) {
GPR_TIMER_SCOPE("tcp_write", 0);
grpc_tcp* tcp = reinterpret_cast<grpc_tcp*>(ep);
grpc_error* error = GRPC_ERROR_NONE;
@ -675,6 +937,10 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf,
}
tcp->outgoing_buffer = buf;
tcp->outgoing_byte_idx = 0;
tcp->outgoing_buffer_arg = arg;
if (arg) {
GPR_ASSERT(grpc_event_engine_can_track_errors());
}
if (!tcp_flush(tcp, &error)) {
TCP_REF(tcp, "write");
@ -792,6 +1058,8 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd,
tcp->bytes_read_this_round = 0;
/* Will be set to false by the very first endpoint read function */
tcp->is_first_read = true;
tcp->bytes_counter = -1;
tcp->socket_ts_enabled = false;
/* paired with unref in grpc_tcp_destroy */
gpr_ref_init(&tcp->refcount, 1);
gpr_atm_no_barrier_store(&tcp->shutdown_count, 0);
@ -803,6 +1071,19 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd,
/* Tell network status tracker about new endpoint */
grpc_network_status_register_endpoint(&tcp->base);
grpc_resource_quota_unref_internal(resource_quota);
gpr_mu_init(&tcp->tb_mu);
tcp->tb_head = nullptr;
/* Start being notified on errors if event engine can track errors. */
if (grpc_event_engine_can_track_errors()) {
/* Grab a ref to tcp so that we can safely access the tcp struct when
* processing errors. We unref when we no longer want to track errors
* separately. */
TCP_REF(tcp, "error-tracking");
gpr_atm_rel_store(&tcp->stop_error_notification, 0);
GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp,
grpc_schedule_on_exec_ctx);
grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure);
}
return &tcp->base;
}
@ -821,6 +1102,11 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd,
tcp->release_fd = fd;
tcp->release_fd_cb = done;
grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer);
if (grpc_event_engine_can_track_errors()) {
/* Stop errors notification. */
gpr_atm_no_barrier_store(&tcp->stop_error_notification, true);
grpc_fd_set_error(tcp->em_fd);
}
TCP_UNREF(tcp, "destroy");
}

@ -31,7 +31,10 @@
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/port.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/buffer_list.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/ev_posix.h"

@ -226,7 +226,7 @@ static void on_read(void* arg, grpc_error* err) {
gpr_log(GPR_INFO, "SERVER_CONNECT: incoming connection: %s", addr_str);
}
grpc_fd* fdobj = grpc_fd_create(fd, name, false);
grpc_fd* fdobj = grpc_fd_create(fd, name, true);
read_notifier_pollset =
sp->server->pollsets[static_cast<size_t>(gpr_atm_no_barrier_fetch_add(
@ -362,7 +362,7 @@ static grpc_error* clone_port(grpc_tcp_listener* listener, unsigned count) {
listener->sibling = sp;
sp->server = listener->server;
sp->fd = fd;
sp->emfd = grpc_fd_create(fd, name, false);
sp->emfd = grpc_fd_create(fd, name, true);
memcpy(&sp->addr, &listener->addr, sizeof(grpc_resolved_address));
sp->port = port;
sp->port_index = listener->port_index;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save