Merge branch 'slice_interning' into eliminate_mdstr

reviewable/pr8842/r1
Craig Tiller 8 years ago
commit 66b14c125e
  1. 16
      BUILD
  2. 6
      CMakeLists.txt
  3. 128
      Makefile
  4. 2
      binding.gyp
  5. 30
      build.yaml
  6. 2
      config.m4
  7. 3
      doc/PROTOCOL-WEB.md
  8. 6
      gRPC-Core.podspec
  9. 5
      grpc.def
  10. 4
      grpc.gemspec
  11. 2
      include/grpc++/impl/codegen/completion_queue.h
  12. 14
      include/grpc++/support/channel_arguments.h
  13. 2
      include/grpc/impl/codegen/connectivity_state.h
  14. 6
      include/grpc/impl/codegen/exec_ctx_fwd.h
  15. 9
      include/grpc/impl/codegen/grpc_types.h
  16. 8
      include/grpc/impl/codegen/port_platform.h
  17. 4
      include/grpc/slice.h
  18. 2
      include/grpc/support/log.h
  19. 2
      include/grpc/support/string_util.h
  20. 4
      package.xml
  21. 2
      src/core/ext/census/census_log.h
  22. 2
      src/core/ext/census/mlog.h
  23. 4
      src/core/ext/client_channel/client_channel.c
  24. 6
      src/core/ext/client_channel/subchannel.c
  25. 4
      src/core/ext/client_channel/subchannel.h
  26. 31
      src/core/ext/lb_policy/grpclb/grpclb.c
  27. 2
      src/core/ext/lb_policy/pick_first/pick_first.c
  28. 313
      src/core/ext/lb_policy/round_robin/round_robin.c
  29. 6
      src/core/ext/load_reporting/load_reporting_filter.c
  30. 19
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  31. 3
      src/core/ext/transport/chttp2/transport/parsing.c
  32. 9
      src/core/ext/transport/cronet/transport/cronet_transport.c
  33. 6
      src/core/lib/channel/channel_args.c
  34. 8
      src/core/lib/channel/channel_args.h
  35. 5
      src/core/lib/channel/channel_stack.c
  36. 3
      src/core/lib/channel/channel_stack.h
  37. 3
      src/core/lib/channel/compress_filter.c
  38. 74
      src/core/lib/channel/http_client_filter.c
  39. 46
      src/core/lib/channel/http_server_filter.c
  40. 2
      src/core/lib/iomgr/endpoint.c
  41. 5
      src/core/lib/iomgr/endpoint.h
  42. 3
      src/core/lib/iomgr/ev_epoll_linux.c
  43. 2076
      src/core/lib/iomgr/ev_poll_and_epoll_posix.c
  44. 41
      src/core/lib/iomgr/ev_poll_and_epoll_posix.h
  45. 2
      src/core/lib/iomgr/ev_posix.c
  46. 6
      src/core/lib/iomgr/executor.c
  47. 2
      src/core/lib/iomgr/executor.h
  48. 12
      src/core/lib/iomgr/iomgr.c
  49. 6
      src/core/lib/iomgr/iomgr.h
  50. 98
      src/core/lib/iomgr/socket_mutator.c
  51. 80
      src/core/lib/iomgr/socket_mutator.h
  52. 9
      src/core/lib/iomgr/socket_utils_common_posix.c
  53. 5
      src/core/lib/iomgr/socket_utils_posix.h
  54. 1
      src/core/lib/iomgr/tcp_client.h
  55. 16
      src/core/lib/iomgr/tcp_client_posix.c
  56. 8
      src/core/lib/iomgr/tcp_posix.c
  57. 19
      src/core/lib/iomgr/tcp_uv.c
  58. 5
      src/core/lib/iomgr/tcp_windows.c
  59. 45
      src/core/lib/security/credentials/jwt/jwt_credentials.c
  60. 10
      src/core/lib/security/credentials/jwt/jwt_verifier.c
  61. 3
      src/core/lib/security/credentials/jwt/jwt_verifier.h
  62. 33
      src/core/lib/security/credentials/oauth2/oauth2_credentials.c
  63. 2
      src/core/lib/security/credentials/plugin/plugin_credentials.c
  64. 2
      src/core/lib/security/transport/handshake.c
  65. 13
      src/core/lib/security/transport/secure_endpoint.c
  66. 3
      src/core/lib/security/transport/server_auth_filter.c
  67. 8
      src/core/lib/slice/slice.c
  68. 5
      src/core/lib/slice/slice_buffer.c
  69. 6
      src/core/lib/slice/slice_internal.h
  70. 25
      src/core/lib/support/string.c
  71. 50
      src/core/lib/surface/call.c
  72. 4
      src/core/lib/surface/init.c
  73. 14
      src/core/lib/surface/server.c
  74. 3
      src/core/lib/transport/connectivity_state.c
  75. 7
      src/core/lib/transport/metadata.c
  76. 4
      src/core/lib/transport/metadata.h
  77. 8
      src/core/lib/transport/metadata_batch.c
  78. 3
      src/core/lib/transport/metadata_batch.h
  79. 2
      src/core/lib/transport/pid_controller.h
  80. 5
      src/core/lib/transport/transport.c
  81. 5
      src/core/lib/transport/transport.h
  82. 3
      src/core/lib/transport/transport_impl.h
  83. 25
      src/cpp/common/channel_arguments.cc
  84. 8
      src/cpp/common/channel_filter.cc
  85. 3
      src/cpp/common/channel_filter.h
  86. 97
      src/csharp/Grpc.Core/Internal/AsyncCall.cs
  87. 41
      src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
  88. 7
      src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
  89. 13
      src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
  90. 5
      src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
  91. 22
      src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
  92. 23
      src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
  93. 2
      src/csharp/Grpc.Core/Profiling/Profilers.cs
  94. 28
      src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs
  95. 6
      src/csharp/ext/grpc_csharp_ext.c
  96. 16
      src/node/src/common.js
  97. 2
      src/python/grpcio/grpc_core_dependencies.py
  98. 10
      src/ruby/ext/grpc/rb_grpc_imports.generated.c
  99. 21
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  100. 14
      test/core/channel/channel_args_test.c
  101. Some files were not shown because too many files have changed in this diff Show More

16
BUILD

@ -180,7 +180,6 @@ cc_library(
"src/core/lib/iomgr/endpoint_pair.h",
"src/core/lib/iomgr/error.h",
"src/core/lib/iomgr/ev_epoll_linux.h",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
"src/core/lib/iomgr/ev_poll_posix.h",
"src/core/lib/iomgr/ev_posix.h",
"src/core/lib/iomgr/exec_ctx.h",
@ -204,6 +203,7 @@ cc_library(
"src/core/lib/iomgr/sockaddr_posix.h",
"src/core/lib/iomgr/sockaddr_utils.h",
"src/core/lib/iomgr/sockaddr_windows.h",
"src/core/lib/iomgr/socket_mutator.h",
"src/core/lib/iomgr/socket_utils.h",
"src/core/lib/iomgr/socket_utils_posix.h",
"src/core/lib/iomgr/socket_windows.h",
@ -355,7 +355,6 @@ cc_library(
"src/core/lib/iomgr/endpoint_pair_windows.c",
"src/core/lib/iomgr/error.c",
"src/core/lib/iomgr/ev_epoll_linux.c",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
"src/core/lib/iomgr/ev_poll_posix.c",
"src/core/lib/iomgr/ev_posix.c",
"src/core/lib/iomgr/exec_ctx.c",
@ -377,6 +376,7 @@ cc_library(
"src/core/lib/iomgr/resolve_address_windows.c",
"src/core/lib/iomgr/resource_quota.c",
"src/core/lib/iomgr/sockaddr_utils.c",
"src/core/lib/iomgr/socket_mutator.c",
"src/core/lib/iomgr/socket_utils_common_posix.c",
"src/core/lib/iomgr/socket_utils_linux.c",
"src/core/lib/iomgr/socket_utils_posix.c",
@ -616,7 +616,6 @@ cc_library(
"src/core/lib/iomgr/endpoint_pair.h",
"src/core/lib/iomgr/error.h",
"src/core/lib/iomgr/ev_epoll_linux.h",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
"src/core/lib/iomgr/ev_poll_posix.h",
"src/core/lib/iomgr/ev_posix.h",
"src/core/lib/iomgr/exec_ctx.h",
@ -640,6 +639,7 @@ cc_library(
"src/core/lib/iomgr/sockaddr_posix.h",
"src/core/lib/iomgr/sockaddr_utils.h",
"src/core/lib/iomgr/sockaddr_windows.h",
"src/core/lib/iomgr/socket_mutator.h",
"src/core/lib/iomgr/socket_utils.h",
"src/core/lib/iomgr/socket_utils_posix.h",
"src/core/lib/iomgr/socket_windows.h",
@ -776,7 +776,6 @@ cc_library(
"src/core/lib/iomgr/endpoint_pair_windows.c",
"src/core/lib/iomgr/error.c",
"src/core/lib/iomgr/ev_epoll_linux.c",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
"src/core/lib/iomgr/ev_poll_posix.c",
"src/core/lib/iomgr/ev_posix.c",
"src/core/lib/iomgr/exec_ctx.c",
@ -798,6 +797,7 @@ cc_library(
"src/core/lib/iomgr/resolve_address_windows.c",
"src/core/lib/iomgr/resource_quota.c",
"src/core/lib/iomgr/sockaddr_utils.c",
"src/core/lib/iomgr/socket_mutator.c",
"src/core/lib/iomgr/socket_utils_common_posix.c",
"src/core/lib/iomgr/socket_utils_linux.c",
"src/core/lib/iomgr/socket_utils_posix.c",
@ -1007,7 +1007,6 @@ cc_library(
"src/core/lib/iomgr/endpoint_pair.h",
"src/core/lib/iomgr/error.h",
"src/core/lib/iomgr/ev_epoll_linux.h",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
"src/core/lib/iomgr/ev_poll_posix.h",
"src/core/lib/iomgr/ev_posix.h",
"src/core/lib/iomgr/exec_ctx.h",
@ -1031,6 +1030,7 @@ cc_library(
"src/core/lib/iomgr/sockaddr_posix.h",
"src/core/lib/iomgr/sockaddr_utils.h",
"src/core/lib/iomgr/sockaddr_windows.h",
"src/core/lib/iomgr/socket_mutator.h",
"src/core/lib/iomgr/socket_utils.h",
"src/core/lib/iomgr/socket_utils_posix.h",
"src/core/lib/iomgr/socket_windows.h",
@ -1159,7 +1159,6 @@ cc_library(
"src/core/lib/iomgr/endpoint_pair_windows.c",
"src/core/lib/iomgr/error.c",
"src/core/lib/iomgr/ev_epoll_linux.c",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
"src/core/lib/iomgr/ev_poll_posix.c",
"src/core/lib/iomgr/ev_posix.c",
"src/core/lib/iomgr/exec_ctx.c",
@ -1181,6 +1180,7 @@ cc_library(
"src/core/lib/iomgr/resolve_address_windows.c",
"src/core/lib/iomgr/resource_quota.c",
"src/core/lib/iomgr/sockaddr_utils.c",
"src/core/lib/iomgr/socket_mutator.c",
"src/core/lib/iomgr/socket_utils_common_posix.c",
"src/core/lib/iomgr/socket_utils_linux.c",
"src/core/lib/iomgr/socket_utils_posix.c",
@ -2026,7 +2026,6 @@ objc_library(
"src/core/lib/iomgr/endpoint_pair_windows.c",
"src/core/lib/iomgr/error.c",
"src/core/lib/iomgr/ev_epoll_linux.c",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
"src/core/lib/iomgr/ev_poll_posix.c",
"src/core/lib/iomgr/ev_posix.c",
"src/core/lib/iomgr/exec_ctx.c",
@ -2048,6 +2047,7 @@ objc_library(
"src/core/lib/iomgr/resolve_address_windows.c",
"src/core/lib/iomgr/resource_quota.c",
"src/core/lib/iomgr/sockaddr_utils.c",
"src/core/lib/iomgr/socket_mutator.c",
"src/core/lib/iomgr/socket_utils_common_posix.c",
"src/core/lib/iomgr/socket_utils_linux.c",
"src/core/lib/iomgr/socket_utils_posix.c",
@ -2266,7 +2266,6 @@ objc_library(
"src/core/lib/iomgr/endpoint_pair.h",
"src/core/lib/iomgr/error.h",
"src/core/lib/iomgr/ev_epoll_linux.h",
"src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
"src/core/lib/iomgr/ev_poll_posix.h",
"src/core/lib/iomgr/ev_posix.h",
"src/core/lib/iomgr/exec_ctx.h",
@ -2290,6 +2289,7 @@ objc_library(
"src/core/lib/iomgr/sockaddr_posix.h",
"src/core/lib/iomgr/sockaddr_utils.h",
"src/core/lib/iomgr/sockaddr_windows.h",
"src/core/lib/iomgr/socket_mutator.h",
"src/core/lib/iomgr/socket_utils.h",
"src/core/lib/iomgr/socket_utils_posix.h",
"src/core/lib/iomgr/socket_windows.h",

@ -310,7 +310,6 @@ add_library(grpc
src/core/lib/iomgr/endpoint_pair_windows.c
src/core/lib/iomgr/error.c
src/core/lib/iomgr/ev_epoll_linux.c
src/core/lib/iomgr/ev_poll_and_epoll_posix.c
src/core/lib/iomgr/ev_poll_posix.c
src/core/lib/iomgr/ev_posix.c
src/core/lib/iomgr/exec_ctx.c
@ -332,6 +331,7 @@ add_library(grpc
src/core/lib/iomgr/resolve_address_windows.c
src/core/lib/iomgr/resource_quota.c
src/core/lib/iomgr/sockaddr_utils.c
src/core/lib/iomgr/socket_mutator.c
src/core/lib/iomgr/socket_utils_common_posix.c
src/core/lib/iomgr/socket_utils_linux.c
src/core/lib/iomgr/socket_utils_posix.c
@ -591,7 +591,6 @@ add_library(grpc_cronet
src/core/lib/iomgr/endpoint_pair_windows.c
src/core/lib/iomgr/error.c
src/core/lib/iomgr/ev_epoll_linux.c
src/core/lib/iomgr/ev_poll_and_epoll_posix.c
src/core/lib/iomgr/ev_poll_posix.c
src/core/lib/iomgr/ev_posix.c
src/core/lib/iomgr/exec_ctx.c
@ -613,6 +612,7 @@ add_library(grpc_cronet
src/core/lib/iomgr/resolve_address_windows.c
src/core/lib/iomgr/resource_quota.c
src/core/lib/iomgr/sockaddr_utils.c
src/core/lib/iomgr/socket_mutator.c
src/core/lib/iomgr/socket_utils_common_posix.c
src/core/lib/iomgr/socket_utils_linux.c
src/core/lib/iomgr/socket_utils_posix.c
@ -844,7 +844,6 @@ add_library(grpc_unsecure
src/core/lib/iomgr/endpoint_pair_windows.c
src/core/lib/iomgr/error.c
src/core/lib/iomgr/ev_epoll_linux.c
src/core/lib/iomgr/ev_poll_and_epoll_posix.c
src/core/lib/iomgr/ev_poll_posix.c
src/core/lib/iomgr/ev_posix.c
src/core/lib/iomgr/exec_ctx.c
@ -866,6 +865,7 @@ add_library(grpc_unsecure
src/core/lib/iomgr/resolve_address_windows.c
src/core/lib/iomgr/resource_quota.c
src/core/lib/iomgr/sockaddr_utils.c
src/core/lib/iomgr/socket_mutator.c
src/core/lib/iomgr/socket_utils_common_posix.c
src/core/lib/iomgr/socket_utils_linux.c
src/core/lib/iomgr/socket_utils_posix.c

@ -1038,6 +1038,7 @@ slice_test: $(BINDIR)/$(CONFIG)/slice_test
sockaddr_resolver_test: $(BINDIR)/$(CONFIG)/sockaddr_resolver_test
sockaddr_utils_test: $(BINDIR)/$(CONFIG)/sockaddr_utils_test
socket_utils_test: $(BINDIR)/$(CONFIG)/socket_utils_test
ssl_server_fuzzer: $(BINDIR)/$(CONFIG)/ssl_server_fuzzer
tcp_client_posix_test: $(BINDIR)/$(CONFIG)/tcp_client_posix_test
tcp_posix_test: $(BINDIR)/$(CONFIG)/tcp_posix_test
tcp_server_posix_test: $(BINDIR)/$(CONFIG)/tcp_server_posix_test
@ -1056,6 +1057,7 @@ wakeup_fd_cv_test: $(BINDIR)/$(CONFIG)/wakeup_fd_cv_test
alarm_cpp_test: $(BINDIR)/$(CONFIG)/alarm_cpp_test
async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test
auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test
bm_fullstack: $(BINDIR)/$(CONFIG)/bm_fullstack
channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test
channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test
cli_call_test: $(BINDIR)/$(CONFIG)/cli_call_test
@ -1204,6 +1206,7 @@ nanopb_fuzzer_serverlist_test_one_entry: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serve
percent_decode_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry
percent_encode_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry
server_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry
ssl_server_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry
uri_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry
run_dep_checks:
@ -1434,6 +1437,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/server_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry \
@ -1442,6 +1446,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/alarm_cpp_test \
$(BINDIR)/$(CONFIG)/async_end2end_test \
$(BINDIR)/$(CONFIG)/auth_property_iterator_test \
$(BINDIR)/$(CONFIG)/bm_fullstack \
$(BINDIR)/$(CONFIG)/channel_arguments_test \
$(BINDIR)/$(CONFIG)/channel_filter_test \
$(BINDIR)/$(CONFIG)/cli_call_test \
@ -1534,6 +1539,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/alarm_cpp_test \
$(BINDIR)/$(CONFIG)/async_end2end_test \
$(BINDIR)/$(CONFIG)/auth_property_iterator_test \
$(BINDIR)/$(CONFIG)/bm_fullstack \
$(BINDIR)/$(CONFIG)/channel_arguments_test \
$(BINDIR)/$(CONFIG)/channel_filter_test \
$(BINDIR)/$(CONFIG)/cli_call_test \
@ -1839,6 +1845,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/async_end2end_test || ( echo test async_end2end_test failed ; exit 1 )
$(E) "[RUN] Testing auth_property_iterator_test"
$(Q) $(BINDIR)/$(CONFIG)/auth_property_iterator_test || ( echo test auth_property_iterator_test failed ; exit 1 )
$(E) "[RUN] Testing bm_fullstack"
$(Q) $(BINDIR)/$(CONFIG)/bm_fullstack || ( echo test bm_fullstack failed ; exit 1 )
$(E) "[RUN] Testing channel_arguments_test"
$(Q) $(BINDIR)/$(CONFIG)/channel_arguments_test || ( echo test channel_arguments_test failed ; exit 1 )
$(E) "[RUN] Testing channel_filter_test"
@ -2641,7 +2649,6 @@ LIBGRPC_SRC = \
src/core/lib/iomgr/endpoint_pair_windows.c \
src/core/lib/iomgr/error.c \
src/core/lib/iomgr/ev_epoll_linux.c \
src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
src/core/lib/iomgr/ev_poll_posix.c \
src/core/lib/iomgr/ev_posix.c \
src/core/lib/iomgr/exec_ctx.c \
@ -2663,6 +2670,7 @@ LIBGRPC_SRC = \
src/core/lib/iomgr/resolve_address_windows.c \
src/core/lib/iomgr/resource_quota.c \
src/core/lib/iomgr/sockaddr_utils.c \
src/core/lib/iomgr/socket_mutator.c \
src/core/lib/iomgr/socket_utils_common_posix.c \
src/core/lib/iomgr/socket_utils_linux.c \
src/core/lib/iomgr/socket_utils_posix.c \
@ -2940,7 +2948,6 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/iomgr/endpoint_pair_windows.c \
src/core/lib/iomgr/error.c \
src/core/lib/iomgr/ev_epoll_linux.c \
src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
src/core/lib/iomgr/ev_poll_posix.c \
src/core/lib/iomgr/ev_posix.c \
src/core/lib/iomgr/exec_ctx.c \
@ -2962,6 +2969,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/iomgr/resolve_address_windows.c \
src/core/lib/iomgr/resource_quota.c \
src/core/lib/iomgr/sockaddr_utils.c \
src/core/lib/iomgr/socket_mutator.c \
src/core/lib/iomgr/socket_utils_common_posix.c \
src/core/lib/iomgr/socket_utils_linux.c \
src/core/lib/iomgr/socket_utils_posix.c \
@ -3230,7 +3238,6 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/iomgr/endpoint_pair_windows.c \
src/core/lib/iomgr/error.c \
src/core/lib/iomgr/ev_epoll_linux.c \
src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
src/core/lib/iomgr/ev_poll_posix.c \
src/core/lib/iomgr/ev_posix.c \
src/core/lib/iomgr/exec_ctx.c \
@ -3252,6 +3259,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/iomgr/resolve_address_windows.c \
src/core/lib/iomgr/resource_quota.c \
src/core/lib/iomgr/sockaddr_utils.c \
src/core/lib/iomgr/socket_mutator.c \
src/core/lib/iomgr/socket_utils_common_posix.c \
src/core/lib/iomgr/socket_utils_linux.c \
src/core/lib/iomgr/socket_utils_posix.c \
@ -3449,7 +3457,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/iomgr/endpoint_pair_windows.c \
src/core/lib/iomgr/error.c \
src/core/lib/iomgr/ev_epoll_linux.c \
src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
src/core/lib/iomgr/ev_poll_posix.c \
src/core/lib/iomgr/ev_posix.c \
src/core/lib/iomgr/exec_ctx.c \
@ -3471,6 +3478,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/iomgr/resolve_address_windows.c \
src/core/lib/iomgr/resource_quota.c \
src/core/lib/iomgr/sockaddr_utils.c \
src/core/lib/iomgr/socket_mutator.c \
src/core/lib/iomgr/socket_utils_common_posix.c \
src/core/lib/iomgr/socket_utils_linux.c \
src/core/lib/iomgr/socket_utils_posix.c \
@ -7000,6 +7008,7 @@ LIBEND2END_TESTS_SRC = \
test/core/end2end/tests/empty_batch.c \
test/core/end2end/tests/filter_call_init_fails.c \
test/core/end2end/tests/filter_causes_close.c \
test/core/end2end/tests/filter_latency.c \
test/core/end2end/tests/graceful_server_shutdown.c \
test/core/end2end/tests/high_initial_seqno.c \
test/core/end2end/tests/hpack_size.c \
@ -7085,6 +7094,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \
test/core/end2end/tests/empty_batch.c \
test/core/end2end/tests/filter_call_init_fails.c \
test/core/end2end/tests/filter_causes_close.c \
test/core/end2end/tests/filter_latency.c \
test/core/end2end/tests/graceful_server_shutdown.c \
test/core/end2end/tests/high_initial_seqno.c \
test/core/end2end/tests/hpack_size.c \
@ -10885,6 +10895,38 @@ endif
endif
SSL_SERVER_FUZZER_SRC = \
test/core/security/ssl_server_fuzzer.c \
SSL_SERVER_FUZZER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SSL_SERVER_FUZZER_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/ssl_server_fuzzer: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/ssl_server_fuzzer: $(SSL_SERVER_FUZZER_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) $(LDXX) $(LDFLAGS) $(SSL_SERVER_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/ssl_server_fuzzer
endif
$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_ssl_server_fuzzer: $(SSL_SERVER_FUZZER_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(SSL_SERVER_FUZZER_OBJS:.o=.dep)
endif
endif
TCP_CLIENT_POSIX_TEST_SRC = \
test/core/iomgr/tcp_client_posix_test.c \
@ -11494,6 +11536,49 @@ endif
endif
BM_FULLSTACK_SRC = \
test/cpp/microbenchmarks/bm_fullstack.cc \
BM_FULLSTACK_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_FULLSTACK_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/bm_fullstack: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
$(BINDIR)/$(CONFIG)/bm_fullstack: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/bm_fullstack: $(PROTOBUF_DEP) $(BM_FULLSTACK_OBJS) $(LIBDIR)/$(CONFIG)/libgoogle_benchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(BM_FULLSTACK_OBJS) $(LIBDIR)/$(CONFIG)/libgoogle_benchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_fullstack
endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_fullstack.o: $(LIBDIR)/$(CONFIG)/libgoogle_benchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_bm_fullstack: $(BM_FULLSTACK_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(BM_FULLSTACK_OBJS:.o=.dep)
endif
endif
CHANNEL_ARGUMENTS_TEST_SRC = \
test/cpp/common/channel_arguments_test.cc \
@ -16406,6 +16491,41 @@ endif
endif
SSL_SERVER_FUZZER_ONE_ENTRY_SRC = \
test/core/security/ssl_server_fuzzer.c \
test/core/util/one_corpus_entry_fuzzer.c \
SSL_SERVER_FUZZER_ONE_ENTRY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SSL_SERVER_FUZZER_ONE_ENTRY_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_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) $(SSL_SERVER_FUZZER_ONE_ENTRY_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)/ssl_server_fuzzer_one_entry
endif
$(OBJDIR)/$(CONFIG)/test/core/security/ssl_server_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_ssl_server_fuzzer_one_entry: $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(SSL_SERVER_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
endif
endif
URI_FUZZER_TEST_ONE_ENTRY_SRC = \
test/core/client_channel/uri_fuzzer_test.c \
test/core/util/one_corpus_entry_fuzzer.c \

@ -589,7 +589,6 @@
'src/core/lib/iomgr/endpoint_pair_windows.c',
'src/core/lib/iomgr/error.c',
'src/core/lib/iomgr/ev_epoll_linux.c',
'src/core/lib/iomgr/ev_poll_and_epoll_posix.c',
'src/core/lib/iomgr/ev_poll_posix.c',
'src/core/lib/iomgr/ev_posix.c',
'src/core/lib/iomgr/exec_ctx.c',
@ -611,6 +610,7 @@
'src/core/lib/iomgr/resolve_address_windows.c',
'src/core/lib/iomgr/resource_quota.c',
'src/core/lib/iomgr/sockaddr_utils.c',
'src/core/lib/iomgr/socket_mutator.c',
'src/core/lib/iomgr/socket_utils_common_posix.c',
'src/core/lib/iomgr/socket_utils_linux.c',
'src/core/lib/iomgr/socket_utils_posix.c',

@ -187,7 +187,6 @@ filegroups:
- src/core/lib/iomgr/endpoint_pair.h
- src/core/lib/iomgr/error.h
- src/core/lib/iomgr/ev_epoll_linux.h
- src/core/lib/iomgr/ev_poll_and_epoll_posix.h
- src/core/lib/iomgr/ev_poll_posix.h
- src/core/lib/iomgr/ev_posix.h
- src/core/lib/iomgr/exec_ctx.h
@ -211,6 +210,7 @@ filegroups:
- src/core/lib/iomgr/sockaddr_posix.h
- src/core/lib/iomgr/sockaddr_utils.h
- src/core/lib/iomgr/sockaddr_windows.h
- src/core/lib/iomgr/socket_mutator.h
- src/core/lib/iomgr/socket_utils.h
- src/core/lib/iomgr/socket_utils_posix.h
- src/core/lib/iomgr/socket_windows.h
@ -286,7 +286,6 @@ filegroups:
- src/core/lib/iomgr/endpoint_pair_windows.c
- src/core/lib/iomgr/error.c
- src/core/lib/iomgr/ev_epoll_linux.c
- src/core/lib/iomgr/ev_poll_and_epoll_posix.c
- src/core/lib/iomgr/ev_poll_posix.c
- src/core/lib/iomgr/ev_posix.c
- src/core/lib/iomgr/exec_ctx.c
@ -308,6 +307,7 @@ filegroups:
- src/core/lib/iomgr/resolve_address_windows.c
- src/core/lib/iomgr/resource_quota.c
- src/core/lib/iomgr/sockaddr_utils.c
- src/core/lib/iomgr/socket_mutator.c
- src/core/lib/iomgr/socket_utils_common_posix.c
- src/core/lib/iomgr/socket_utils_linux.c
- src/core/lib/iomgr/socket_utils_posix.c
@ -2578,6 +2578,19 @@ targets:
- mac
- linux
- posix
- name: ssl_server_fuzzer
build: fuzzer
language: c
src:
- test/core/security/ssl_server_fuzzer.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
corpus_dirs:
- test/core/security/corpus/ssl_server_corpus
maxlen: 2048
- name: tcp_client_posix_test
cpu_cost: 0.5
build: test
@ -2810,6 +2823,19 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: bm_fullstack
build: test
language: c++
src:
- test/cpp/microbenchmarks/bm_fullstack.cc
deps:
- google_benchmark
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
- name: channel_arguments_test
gtest: true
build: test

@ -105,7 +105,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/iomgr/endpoint_pair_windows.c \
src/core/lib/iomgr/error.c \
src/core/lib/iomgr/ev_epoll_linux.c \
src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
src/core/lib/iomgr/ev_poll_posix.c \
src/core/lib/iomgr/ev_posix.c \
src/core/lib/iomgr/exec_ctx.c \
@ -127,6 +126,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/iomgr/resolve_address_windows.c \
src/core/lib/iomgr/resource_quota.c \
src/core/lib/iomgr/sockaddr_utils.c \
src/core/lib/iomgr/socket_mutator.c \
src/core/lib/iomgr/socket_utils_common_posix.c \
src/core/lib/iomgr/socket_utils_linux.c \
src/core/lib/iomgr/socket_utils_posix.c \

@ -60,8 +60,7 @@ HTTP/2 related behavior (specified in [gRPC over HTTP2](http://www.grpc.io/docs/
Message framing (vs. [http2-transport-mapping](http://www.grpc.io/docs/guides/wire.html#http2-transport-mapping))
1. Response status encoded as part of the response body
* Key-value pairs formatted as HTTP/1.1 headers block (without the empty
newline \r\n to terminate the block)
* Key-value pairs encoded in the HTTP/2 [literal header format](https://tools.ietf.org/html/rfc7541#section-6.2) as a single header block.
2. 8th (MSB) bit of the 1st gRPC frame byte
* 0: data
* 1: trailers

@ -270,7 +270,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/endpoint_pair.h',
'src/core/lib/iomgr/error.h',
'src/core/lib/iomgr/ev_epoll_linux.h',
'src/core/lib/iomgr/ev_poll_and_epoll_posix.h',
'src/core/lib/iomgr/ev_poll_posix.h',
'src/core/lib/iomgr/ev_posix.h',
'src/core/lib/iomgr/exec_ctx.h',
@ -294,6 +293,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/sockaddr_posix.h',
'src/core/lib/iomgr/sockaddr_utils.h',
'src/core/lib/iomgr/sockaddr_windows.h',
'src/core/lib/iomgr/socket_mutator.h',
'src/core/lib/iomgr/socket_utils.h',
'src/core/lib/iomgr/socket_utils_posix.h',
'src/core/lib/iomgr/socket_windows.h',
@ -449,7 +449,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/endpoint_pair_windows.c',
'src/core/lib/iomgr/error.c',
'src/core/lib/iomgr/ev_epoll_linux.c',
'src/core/lib/iomgr/ev_poll_and_epoll_posix.c',
'src/core/lib/iomgr/ev_poll_posix.c',
'src/core/lib/iomgr/ev_posix.c',
'src/core/lib/iomgr/exec_ctx.c',
@ -471,6 +470,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/resolve_address_windows.c',
'src/core/lib/iomgr/resource_quota.c',
'src/core/lib/iomgr/sockaddr_utils.c',
'src/core/lib/iomgr/socket_mutator.c',
'src/core/lib/iomgr/socket_utils_common_posix.c',
'src/core/lib/iomgr/socket_utils_linux.c',
'src/core/lib/iomgr/socket_utils_posix.c',
@ -674,7 +674,6 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/endpoint_pair.h',
'src/core/lib/iomgr/error.h',
'src/core/lib/iomgr/ev_epoll_linux.h',
'src/core/lib/iomgr/ev_poll_and_epoll_posix.h',
'src/core/lib/iomgr/ev_poll_posix.h',
'src/core/lib/iomgr/ev_posix.h',
'src/core/lib/iomgr/exec_ctx.h',
@ -698,6 +697,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/sockaddr_posix.h',
'src/core/lib/iomgr/sockaddr_utils.h',
'src/core/lib/iomgr/sockaddr_windows.h',
'src/core/lib/iomgr/socket_mutator.h',
'src/core/lib/iomgr/socket_utils.h',
'src/core/lib/iomgr/socket_utils_posix.h',
'src/core/lib/iomgr/socket_windows.h',

@ -92,8 +92,11 @@ EXPORTS
grpc_server_destroy
grpc_tracer_set_enabled
grpc_header_key_is_legal
grpc_header_key_slice_is_legal
grpc_header_nonbin_value_is_legal
grpc_header_nonbin_value_slice_is_legal
grpc_is_binary_header
grpc_slice_is_binary_header
grpc_call_error_to_string
grpc_resource_quota_create
grpc_resource_quota_ref
@ -154,7 +157,9 @@ EXPORTS
grpc_slice_str_cmp
grpc_slice_buf_cmp
grpc_slice_buf_start_eq
grpc_slice_rchr
grpc_slice_hash
grpc_slice_is_equivalent
grpc_slice_buffer_init
grpc_slice_buffer_destroy
grpc_slice_buffer_add

@ -190,7 +190,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/endpoint_pair.h )
s.files += %w( src/core/lib/iomgr/error.h )
s.files += %w( src/core/lib/iomgr/ev_epoll_linux.h )
s.files += %w( src/core/lib/iomgr/ev_poll_and_epoll_posix.h )
s.files += %w( src/core/lib/iomgr/ev_poll_posix.h )
s.files += %w( src/core/lib/iomgr/ev_posix.h )
s.files += %w( src/core/lib/iomgr/exec_ctx.h )
@ -214,6 +213,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/sockaddr_posix.h )
s.files += %w( src/core/lib/iomgr/sockaddr_utils.h )
s.files += %w( src/core/lib/iomgr/sockaddr_windows.h )
s.files += %w( src/core/lib/iomgr/socket_mutator.h )
s.files += %w( src/core/lib/iomgr/socket_utils.h )
s.files += %w( src/core/lib/iomgr/socket_utils_posix.h )
s.files += %w( src/core/lib/iomgr/socket_windows.h )
@ -369,7 +369,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/endpoint_pair_windows.c )
s.files += %w( src/core/lib/iomgr/error.c )
s.files += %w( src/core/lib/iomgr/ev_epoll_linux.c )
s.files += %w( src/core/lib/iomgr/ev_poll_and_epoll_posix.c )
s.files += %w( src/core/lib/iomgr/ev_poll_posix.c )
s.files += %w( src/core/lib/iomgr/ev_posix.c )
s.files += %w( src/core/lib/iomgr/exec_ctx.c )
@ -391,6 +390,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/resolve_address_windows.c )
s.files += %w( src/core/lib/iomgr/resource_quota.c )
s.files += %w( src/core/lib/iomgr/sockaddr_utils.c )
s.files += %w( src/core/lib/iomgr/socket_mutator.c )
s.files += %w( src/core/lib/iomgr/socket_utils_common_posix.c )
s.files += %w( src/core/lib/iomgr/socket_utils_linux.c )
s.files += %w( src/core/lib/iomgr/socket_utils_posix.c )

@ -240,7 +240,7 @@ class ServerCompletionQueue : public CompletionQueue {
private:
bool is_frequently_polled_;
friend class ServerBuilder;
/// \param is_frequently_polled Informs the GPRC library about whether the
/// \param is_frequently_polled Informs the GRPC library about whether the
/// server completion queue would be actively polled (by calling Next() or
/// AsyncNext()). By default all server completion queues are assumed to be
/// frequently polled.

@ -79,6 +79,9 @@ class ChannelArguments {
/// Set the compression algorithm for the channel.
void SetCompressionAlgorithm(grpc_compression_algorithm algorithm);
/// Set the socket mutator for the channel.
void SetSocketMutator(grpc_socket_mutator* mutator);
/// The given string will be sent at the front of the user agent string.
void SetUserAgentPrefix(const grpc::string& user_agent_prefix);
@ -104,6 +107,15 @@ class ChannelArguments {
/// Set a textual argument \a value under \a key.
void SetString(const grpc::string& key, const grpc::string& value);
/// Return (by value) a c grpc_channel_args structure which points to
/// arguments owned by this ChannelArguments instance
grpc_channel_args c_channel_args() {
grpc_channel_args out;
out.num_args = args_.size();
out.args = args_.empty() ? NULL : &args_[0];
return out;
}
private:
friend class SecureChannelCredentials;
friend class testing::ChannelArgumentsTest;
@ -111,7 +123,7 @@ class ChannelArguments {
/// Default pointer argument operations.
struct PointerVtableMembers {
static void* Copy(void* in) { return in; }
static void Destroy(void* in) {}
static void Destroy(grpc_exec_ctx* exec_ctx, void* in) {}
static int Compare(void* a, void* b) {
if (a < b) return -1;
if (a > b) return 1;

@ -40,6 +40,8 @@ extern "C" {
/** Connectivity state of a channel. */
typedef enum {
/** channel has just been initialized */
GRPC_CHANNEL_INIT = -1,
/** channel is idle */
GRPC_CHANNEL_IDLE,
/** channel is connecting */

@ -31,11 +31,11 @@
*
*/
#ifndef GRPC_EXEC_CTX_H
#define GRPC_EXEC_CTX_H
#ifndef GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H
#define GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H
/* forward declaration for exec_ctx.h */
struct grpc_exec_ctx;
typedef struct grpc_exec_ctx grpc_exec_ctx;
#endif
#endif /* GRPC_IMPL_CODEGEN_EXEC_CTX_FWD_H */

@ -34,10 +34,10 @@
#ifndef GRPC_IMPL_CODEGEN_GRPC_TYPES_H
#define GRPC_IMPL_CODEGEN_GRPC_TYPES_H
#include <grpc/impl/codegen/compression_types.h>
#include <grpc/impl/codegen/exec_ctx_fwd.h>
#include <grpc/impl/codegen/gpr_types.h>
#include <grpc/impl/codegen/slice.h>
#include <grpc/impl/codegen/compression_types.h>
#include <grpc/impl/codegen/status.h>
#include <stddef.h>
@ -84,6 +84,9 @@ typedef struct grpc_server grpc_server;
can have messages written to it and read from it. */
typedef struct grpc_call grpc_call;
/** The Socket Mutator interface allows changes on socket options */
typedef struct grpc_socket_mutator grpc_socket_mutator;
/** Type specifier for grpc_arg */
typedef enum {
GRPC_ARG_STRING,
@ -215,6 +218,8 @@ typedef struct {
/** Resolved addresses in a form used by the LB policy.
Not intended for external use. */
#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses"
/** The grpc_socket_mutator instance that set the socket options. A pointer. */
#define GRPC_ARG_SOCKET_MUTATOR "grpc.socket_mutator"
/** \} */
/** Result of a grpc call. If the caller satisfies the prerequisites of a

@ -368,14 +368,14 @@ typedef unsigned __int64 uint64_t;
#endif
#endif
#ifndef GPRC_PRINT_FORMAT_CHECK
#ifndef GPR_PRINT_FORMAT_CHECK
#ifdef __GNUC__
#define GPRC_PRINT_FORMAT_CHECK(FORMAT_STR, ARGS) \
#define GPR_PRINT_FORMAT_CHECK(FORMAT_STR, ARGS) \
__attribute__((format(printf, FORMAT_STR, ARGS)))
#else
#define GPRC_PRINT_FORMAT_CHECK(FORMAT_STR, ARGS)
#define GPR_PRINT_FORMAT_CHECK(FORMAT_STR, ARGS)
#endif
#endif /* GPRC_PRINT_FORMAT_CHECK */
#endif /* GPR_PRINT_FORMAT_CHECK */
#if GPR_FORBID_UNREACHABLE_CODE
#define GPR_UNREACHABLE_CODE(STATEMENT)

@ -134,6 +134,10 @@ GPRAPI int grpc_slice_rchr(grpc_slice s, char c);
GPRAPI uint32_t grpc_slice_hash(grpc_slice s);
/* Do two slices point at the same memory, with the same length
If a or b is inlined, actually compares data */
GPRAPI int grpc_slice_is_equivalent(grpc_slice a, grpc_slice b);
#ifdef __cplusplus
}
#endif

@ -75,7 +75,7 @@ const char *gpr_log_severity_string(gpr_log_severity severity);
/* Log a message. It's advised to use GPR_xxx above to generate the context
* for each message */
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity,
const char *format, ...) GPRC_PRINT_FORMAT_CHECK(4, 5);
const char *format, ...) GPR_PRINT_FORMAT_CHECK(4, 5);
GPRAPI void gpr_log_message(const char *file, int line,
gpr_log_severity severity, const char *message);

@ -55,7 +55,7 @@ GPRAPI char *gpr_strdup(const char *src);
On error, returns -1 and sets *strp to NULL. If the format string is bad,
the result is undefined. */
GPRAPI int gpr_asprintf(char **strp, const char *format, ...)
GPRC_PRINT_FORMAT_CHECK(2, 3);
GPR_PRINT_FORMAT_CHECK(2, 3);
#ifdef __cplusplus
}

@ -197,7 +197,6 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/error.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_epoll_linux.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_and_epoll_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/exec_ctx.h" role="src" />
@ -221,6 +220,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_utils.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_windows.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/socket_mutator.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_posix.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/socket_windows.h" role="src" />
@ -376,7 +376,6 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_windows.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/error.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_epoll_linux.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_and_epoll_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/ev_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/exec_ctx.c" role="src" />
@ -398,6 +397,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/resolve_address_windows.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/resource_quota.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_utils.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/socket_mutator.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_common_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_linux.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_posix.c" role="src" />

@ -84,7 +84,7 @@ const void *census_log_read_next(size_t *bytes_available);
*/
size_t census_log_remaining_space(void);
/* Returns the number of times gprc_stats_log_start_write() failed due to
/* Returns the number of times grpc_stats_log_start_write() failed due to
out-of-space. */
int census_log_out_of_space_count(void);

@ -88,7 +88,7 @@ const void* census_log_read_next(size_t* bytes_available);
*/
size_t census_log_remaining_space(void);
/* Returns the number of times gprc_stats_log_start_write() failed due to
/* Returns the number of times grpc_stats_log_start_write() failed due to
out-of-space. */
int64_t census_log_out_of_space_count(void);

@ -645,7 +645,7 @@ static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg,
grpc_subchannel_call *subchannel_call = NULL;
grpc_error *new_error = grpc_connected_subchannel_create_call(
exec_ctx, calld->connected_subchannel, calld->pollent, calld->path,
calld->deadline, &subchannel_call);
calld->call_start_time, calld->deadline, &subchannel_call);
if (new_error != GRPC_ERROR_NONE) {
new_error = grpc_error_add_child(new_error, error);
subchannel_call = CANCELLED_CALL;
@ -898,7 +898,7 @@ retry:
grpc_subchannel_call *subchannel_call = NULL;
grpc_error *error = grpc_connected_subchannel_create_call(
exec_ctx, calld->connected_subchannel, calld->pollent, calld->path,
calld->deadline, &subchannel_call);
calld->call_start_time, calld->deadline, &subchannel_call);
if (error != GRPC_ERROR_NONE) {
subchannel_call = CANCELLED_CALL;
fail_locked(exec_ctx, calld, GRPC_ERROR_REF(error));

@ -703,15 +703,15 @@ grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel(
grpc_error *grpc_connected_subchannel_create_call(
grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con,
grpc_polling_entity *pollent, grpc_slice path, gpr_timespec deadline,
grpc_subchannel_call **call) {
grpc_polling_entity *pollent, grpc_slice path, gpr_timespec start_time,
gpr_timespec deadline, grpc_subchannel_call **call) {
grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
*call = gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
(*call)->connection = con; // Ref is added below.
grpc_error *error =
grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, *call,
NULL, NULL, path, deadline, callstk);
NULL, NULL, path, start_time, deadline, callstk);
if (error != GRPC_ERROR_NONE) {
const char *error_string = grpc_error_string(error);
gpr_log(GPR_ERROR, "error: %s", error_string);

@ -111,8 +111,8 @@ void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx,
/** construct a subchannel call */
grpc_error *grpc_connected_subchannel_create_call(
grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel,
grpc_polling_entity *pollent, grpc_slice path, gpr_timespec deadline,
grpc_subchannel_call **subchannel_call);
grpc_polling_entity *pollent, grpc_slice path, gpr_timespec start_time,
gpr_timespec deadline, grpc_subchannel_call **subchannel_call);
/** process a transport level op */
void grpc_connected_subchannel_process_transport_op(

@ -762,17 +762,24 @@ static void glb_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
if (glb_policy->rr_policy) {
GRPC_LB_POLICY_UNREF(exec_ctx, glb_policy->rr_policy, "glb_shutdown");
}
if (glb_policy->started_picking) {
if (glb_policy->lb_call != NULL) {
grpc_call_cancel(glb_policy->lb_call, NULL);
/* lb_on_server_status_received will pick up the cancel and clean up */
}
}
grpc_connectivity_state_set(
exec_ctx, &glb_policy->state_tracker, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_CREATE("Channel Shutdown"), "glb_shutdown");
/* We need a copy of the lb_call pointer because we can't cancell the call
* while holding glb_policy->mu: lb_on_server_status_received, invoked due to
* the cancel, needs to acquire that same lock */
grpc_call *lb_call = glb_policy->lb_call;
glb_policy->lb_call = NULL;
gpr_mu_unlock(&glb_policy->mu);
/* glb_policy->lb_call and this local lb_call must be consistent at this point
* because glb_policy->lb_call is only assigned in lb_call_init_locked as part
* of query_for_backends_locked, which can only be invoked while
* glb_policy->shutting_down is false. */
if (lb_call != NULL) {
grpc_call_cancel(lb_call, NULL);
/* lb_on_server_status_received will pick up the cancel and clean up */
}
while (pp != NULL) {
pending_pick *next = pp->next;
*pp->target = NULL;
@ -956,9 +963,11 @@ static void lb_on_server_status_received(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error);
static void lb_on_response_received(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error);
static void lb_call_init(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy) {
static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
glb_lb_policy *glb_policy) {
GPR_ASSERT(glb_policy->server_name != NULL);
GPR_ASSERT(glb_policy->server_name[0] != '\0');
GPR_ASSERT(!glb_policy->shutting_down);
/* Note the following LB call progresses every time there's activity in \a
* glb_policy->base.interested_parties, which is comprised of the polling
@ -1011,7 +1020,9 @@ static void lb_call_destroy_locked(glb_lb_policy *glb_policy) {
static void query_for_backends_locked(grpc_exec_ctx *exec_ctx,
glb_lb_policy *glb_policy) {
GPR_ASSERT(glb_policy->lb_channel != NULL);
lb_call_init(exec_ctx, glb_policy);
if (glb_policy->shutting_down) return;
lb_call_init_locked(exec_ctx, glb_policy);
if (grpc_lb_glb_trace) {
gpr_log(GPR_INFO, "Query for backends (grpclb: %p, lb_call: %p)",
@ -1156,8 +1167,8 @@ static void lb_on_response_received(grpc_exec_ctx *exec_ctx, void *arg,
}
gpr_mu_unlock(&glb_policy->mu);
} else { /* empty payload: call cancelled. */
/* dispose of the "lb_on_response_received" weak ref taken in
* query_for_backends_locked() and reused in every reception loop */
/* dispose of the "lb_on_response_received" weak ref taken in
* query_for_backends_locked() and reused in every reception loop */
gpr_mu_unlock(&glb_policy->mu);
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
"lb_on_response_received_empty_payload");

@ -292,6 +292,8 @@ static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
} else {
loop:
switch (p->checking_connectivity) {
case GRPC_CHANNEL_INIT:
GPR_UNREACHABLE_CODE(return );
case GRPC_CHANNEL_READY:
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_READY, GRPC_ERROR_NONE,

@ -116,8 +116,13 @@ typedef struct {
grpc_closure connectivity_changed_closure;
/** this subchannels current position in subchannel->ready_list */
ready_list *ready_list_node;
/** last observed connectivity */
grpc_connectivity_state connectivity_state;
/** last observed connectivity. Not updated by
* \a grpc_subchannel_notify_on_state_change. Used to determine the previous
* state while processing the new state in \a rr_connectivity_changed */
grpc_connectivity_state prev_connectivity_state;
/** current connectivity state. Updated by \a
* grpc_subchannel_notify_on_state_change */
grpc_connectivity_state curr_connectivity_state;
/** the subchannel's target user data */
void *user_data;
/** vtable to operate over \a user_data */
@ -127,6 +132,7 @@ typedef struct {
struct round_robin_lb_policy {
/** base policy: must be first */
grpc_lb_policy base;
gpr_mu mu;
/** total number of addresses received at creation time */
size_t num_addresses;
@ -135,8 +141,11 @@ struct round_robin_lb_policy {
size_t num_subchannels;
subchannel_data **subchannels;
/** mutex protecting remaining members */
gpr_mu mu;
/** how many subchannels are in TRANSIENT_FAILURE */
size_t num_transient_failures;
/** how many subchannels are IDLE */
size_t num_idle;
/** have we started picking? */
int started_picking;
/** are we shutting down? */
@ -258,6 +267,10 @@ static void remove_disconnected_sc_locked(round_robin_lb_policy *p,
gpr_free(node);
}
static bool is_ready_list_empty(round_robin_lb_policy *p) {
return p->ready_list.prev == NULL;
}
static void rr_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
ready_list *elem;
@ -268,7 +281,7 @@ static void rr_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
for (size_t i = 0; i < p->num_subchannels; i++) {
subchannel_data *sd = p->subchannels[i];
GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "round_robin_destroy");
GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "rr_destroy");
if (sd->user_data != NULL) {
GPR_ASSERT(sd->user_data_vtable != NULL);
sd->user_data_vtable->destroy(exec_ctx, sd->user_data);
@ -381,18 +394,18 @@ static void start_picking(grpc_exec_ctx *exec_ctx, round_robin_lb_policy *p) {
size_t i;
p->started_picking = 1;
if (grpc_lb_round_robin_trace) {
gpr_log(GPR_DEBUG, "LB_POLICY: p=%p num_subchannels=%" PRIuPTR, (void *)p,
p->num_subchannels);
}
for (i = 0; i < p->num_subchannels; i++) {
subchannel_data *sd = p->subchannels[i];
sd->connectivity_state = GRPC_CHANNEL_IDLE;
/* use some sentinel value outside of the range of grpc_connectivity_state
* to signal an undefined previous state. We won't be referring to this
* value again and it'll be overwritten after the first call to
* rr_connectivity_changed */
sd->prev_connectivity_state = GRPC_CHANNEL_INIT;
sd->curr_connectivity_state = GRPC_CHANNEL_IDLE;
GRPC_LB_POLICY_WEAK_REF(&p->base, "rr_connectivity");
grpc_subchannel_notify_on_state_change(
exec_ctx, sd->subchannel, p->base.interested_parties,
&sd->connectivity_state, &sd->connectivity_changed_closure);
GRPC_LB_POLICY_WEAK_REF(&p->base, "round_robin_connectivity");
&sd->curr_connectivity_state, &sd->connectivity_changed_closure);
}
}
@ -422,7 +435,7 @@ static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
/* readily available, report right away */
*target = GRPC_CONNECTED_SUBCHANNEL_REF(
grpc_subchannel_get_connected_subchannel(selected->subchannel),
"picked");
"rr_picked");
if (user_data != NULL) {
*user_data = selected->user_data;
@ -453,125 +466,184 @@ static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
}
}
static void update_state_counters(subchannel_data *sd) {
round_robin_lb_policy *p = sd->policy;
/* update p->num_transient_failures (resp. p->num_idle): if the previous
* state was TRANSIENT_FAILURE (resp. IDLE), decrement
* p->num_transient_failures (resp. p->num_idle). */
if (sd->prev_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
GPR_ASSERT(p->num_transient_failures > 0);
--p->num_transient_failures;
} else if (sd->prev_connectivity_state == GRPC_CHANNEL_IDLE) {
GPR_ASSERT(p->num_idle > 0);
--p->num_idle;
}
}
/* sd is the subchannel_data associted with the updated subchannel.
* shutdown_error will only be used upon policy transition to TRANSIENT_FAILURE
* or SHUTDOWN */
static grpc_connectivity_state update_lb_connectivity_status(
grpc_exec_ctx *exec_ctx, subchannel_data *sd, grpc_error *error) {
/* In priority order. The first rule to match terminates the search (ie, if we
* are on rule n, all previous rules were unfulfilled).
*
* 1) RULE: ANY subchannel is READY => policy is READY.
* CHECK: At least one subchannel is ready iff p->ready_list is NOT empty.
*
* 2) RULE: ANY subchannel is CONNECTING => policy is CONNECTING.
* CHECK: sd->curr_connectivity_state == CONNECTING.
*
* 3) RULE: ALL subchannels are SHUTDOWN => policy is SHUTDOWN.
* CHECK: p->num_subchannels = 0.
*
* 4) RULE: ALL subchannels are TRANSIENT_FAILURE => policy is
* TRANSIENT_FAILURE.
* CHECK: p->num_transient_failures == p->num_subchannels.
*
* 5) RULE: ALL subchannels are IDLE => policy is IDLE.
* CHECK: p->num_idle == p->num_subchannels.
*/
round_robin_lb_policy *p = sd->policy;
if (!is_ready_list_empty(p)) { /* 1) READY */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "rr_ready");
return GRPC_CHANNEL_READY;
} else if (sd->curr_connectivity_state ==
GRPC_CHANNEL_CONNECTING) { /* 2) CONNECTING */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
"rr_connecting");
return GRPC_CHANNEL_CONNECTING;
} else if (p->num_subchannels == 0) { /* 3) SHUTDOWN */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error),
"rr_shutdown");
return GRPC_CHANNEL_SHUTDOWN;
} else if (p->num_transient_failures ==
p->num_subchannels) { /* 4) TRANSIENT_FAILURE */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "rr_transient_failure");
return GRPC_CHANNEL_TRANSIENT_FAILURE;
} else if (p->num_idle == p->num_subchannels) { /* 5) IDLE */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker, GRPC_CHANNEL_IDLE,
GRPC_ERROR_NONE, "rr_idle");
return GRPC_CHANNEL_IDLE;
}
/* no change */
return sd->curr_connectivity_state;
}
static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
subchannel_data *sd = arg;
round_robin_lb_policy *p = sd->policy;
pending_pick *pp;
int unref = 0;
GRPC_ERROR_REF(error);
gpr_mu_lock(&p->mu);
if (p->shutdown) {
unref = 1;
} else {
switch (sd->connectivity_state) {
case GRPC_CHANNEL_READY:
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_READY, GRPC_ERROR_REF(error),
"connecting_ready");
/* add the newly connected subchannel to the list of connected ones.
* Note that it goes to the "end of the line". */
sd->ready_list_node = add_connected_sc_locked(p, sd);
/* at this point we know there's at least one suitable subchannel. Go
* ahead and pick one and notify the pending suitors in
* p->pending_picks. This preemtively replicates rr_pick()'s actions. */
ready_list *selected = peek_next_connected_locked(p);
GPR_ASSERT(selected != NULL);
if (p->pending_picks != NULL) {
/* if the selected subchannel is going to be used for the pending
* picks, update the last picked pointer */
advance_last_picked_locked(p);
gpr_mu_unlock(&p->mu);
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "rr_connectivity");
GRPC_ERROR_UNREF(error);
return;
}
switch (sd->curr_connectivity_state) {
case GRPC_CHANNEL_INIT:
GPR_UNREACHABLE_CODE(return );
case GRPC_CHANNEL_READY:
/* add the newly connected subchannel to the list of connected ones.
* Note that it goes to the "end of the line". */
sd->ready_list_node = add_connected_sc_locked(p, sd);
/* at this point we know there's at least one suitable subchannel. Go
* ahead and pick one and notify the pending suitors in
* p->pending_picks. This preemtively replicates rr_pick()'s actions. */
ready_list *selected = peek_next_connected_locked(p);
GPR_ASSERT(selected != NULL);
if (p->pending_picks != NULL) {
/* if the selected subchannel is going to be used for the pending
* picks, update the last picked pointer */
advance_last_picked_locked(p);
}
while ((pp = p->pending_picks)) {
p->pending_picks = pp->next;
*pp->target = GRPC_CONNECTED_SUBCHANNEL_REF(
grpc_subchannel_get_connected_subchannel(selected->subchannel),
"rr_picked");
if (pp->user_data != NULL) {
*pp->user_data = selected->user_data;
}
if (grpc_lb_round_robin_trace) {
gpr_log(GPR_DEBUG,
"[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)",
(void *)selected->subchannel, (void *)selected);
}
grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL);
gpr_free(pp);
}
update_lb_connectivity_status(exec_ctx, sd, error);
sd->prev_connectivity_state = sd->curr_connectivity_state;
/* renew notification: reuses the "rr_connectivity" weak ref */
grpc_subchannel_notify_on_state_change(
exec_ctx, sd->subchannel, p->base.interested_parties,
&sd->curr_connectivity_state, &sd->connectivity_changed_closure);
break;
case GRPC_CHANNEL_IDLE:
++p->num_idle;
/* fallthrough */
case GRPC_CHANNEL_CONNECTING:
update_state_counters(sd);
update_lb_connectivity_status(exec_ctx, sd, error);
sd->prev_connectivity_state = sd->curr_connectivity_state;
/* renew notification: reuses the "rr_connectivity" weak ref */
grpc_subchannel_notify_on_state_change(
exec_ctx, sd->subchannel, p->base.interested_parties,
&sd->curr_connectivity_state, &sd->connectivity_changed_closure);
break;
case GRPC_CHANNEL_TRANSIENT_FAILURE:
++p->num_transient_failures;
/* remove from ready list if still present */
if (sd->ready_list_node != NULL) {
remove_disconnected_sc_locked(p, sd->ready_list_node);
sd->ready_list_node = NULL;
}
update_lb_connectivity_status(exec_ctx, sd, error);
sd->prev_connectivity_state = sd->curr_connectivity_state;
/* renew notification: reuses the "rr_connectivity" weak ref */
grpc_subchannel_notify_on_state_change(
exec_ctx, sd->subchannel, p->base.interested_parties,
&sd->curr_connectivity_state, &sd->connectivity_changed_closure);
break;
case GRPC_CHANNEL_SHUTDOWN:
update_state_counters(sd);
if (sd->ready_list_node != NULL) {
remove_disconnected_sc_locked(p, sd->ready_list_node);
sd->ready_list_node = NULL;
}
--p->num_subchannels;
GPR_SWAP(subchannel_data *, p->subchannels[sd->index],
p->subchannels[p->num_subchannels]);
GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "rr_subchannel_shutdown");
p->subchannels[sd->index]->index = sd->index;
if (update_lb_connectivity_status(exec_ctx, sd, error) ==
GRPC_CHANNEL_SHUTDOWN) {
/* the policy is shutting down. Flush all the pending picks... */
while ((pp = p->pending_picks)) {
p->pending_picks = pp->next;
*pp->target = GRPC_CONNECTED_SUBCHANNEL_REF(
grpc_subchannel_get_connected_subchannel(selected->subchannel),
"picked");
if (pp->user_data != NULL) {
*pp->user_data = selected->user_data;
}
if (grpc_lb_round_robin_trace) {
gpr_log(GPR_DEBUG,
"[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)",
(void *)selected->subchannel, (void *)selected);
}
*pp->target = NULL;
grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL);
gpr_free(pp);
}
grpc_subchannel_notify_on_state_change(
exec_ctx, sd->subchannel, p->base.interested_parties,
&sd->connectivity_state, &sd->connectivity_changed_closure);
break;
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_IDLE:
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, sd->connectivity_state,
GRPC_ERROR_REF(error), "connecting_changed");
grpc_subchannel_notify_on_state_change(
exec_ctx, sd->subchannel, p->base.interested_parties,
&sd->connectivity_state, &sd->connectivity_changed_closure);
break;
case GRPC_CHANNEL_TRANSIENT_FAILURE:
/* renew state notification */
grpc_subchannel_notify_on_state_change(
exec_ctx, sd->subchannel, p->base.interested_parties,
&sd->connectivity_state, &sd->connectivity_changed_closure);
/* remove from ready list if still present */
if (sd->ready_list_node != NULL) {
remove_disconnected_sc_locked(p, sd->ready_list_node);
sd->ready_list_node = NULL;
}
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "connecting_transient_failure");
break;
case GRPC_CHANNEL_SHUTDOWN:
if (sd->ready_list_node != NULL) {
remove_disconnected_sc_locked(p, sd->ready_list_node);
sd->ready_list_node = NULL;
}
p->num_subchannels--;
GPR_SWAP(subchannel_data *, p->subchannels[sd->index],
p->subchannels[p->num_subchannels]);
GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "round_robin");
p->subchannels[sd->index]->index = sd->index;
gpr_free(sd);
unref = 1;
if (p->num_subchannels == 0) {
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_CREATE_REFERENCING("Round Robin Channels Exhausted",
&error, 1),
"no_more_channels");
while ((pp = p->pending_picks)) {
p->pending_picks = pp->next;
*pp->target = NULL;
grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE,
NULL);
gpr_free(pp);
}
} else {
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "subchannel_failed");
}
} /* switch */
} /* !unref */
gpr_mu_unlock(&p->mu);
if (unref) {
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "round_robin_connectivity");
}
gpr_free(sd);
/* unref the "rr_connectivity" weak ref from start_picking */
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &p->base, "rr_connectivity");
break;
}
gpr_mu_unlock(&p->mu);
GRPC_ERROR_UNREF(error);
}
@ -607,9 +679,9 @@ static void rr_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
gpr_mu_unlock(&p->mu);
target = GRPC_CONNECTED_SUBCHANNEL_REF(
grpc_subchannel_get_connected_subchannel(selected->subchannel),
"picked");
"rr_picked");
grpc_connected_subchannel_ping(exec_ctx, target, closure);
GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, target, "picked");
GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, target, "rr_picked");
} else {
gpr_mu_unlock(&p->mu);
grpc_exec_ctx_sched(exec_ctx, closure,
@ -705,6 +777,11 @@ static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
grpc_lb_policy_init(&p->base, &round_robin_lb_policy_vtable);
grpc_connectivity_state_init(&p->state_tracker, GRPC_CHANNEL_IDLE,
"round_robin");
if (grpc_lb_round_robin_trace) {
gpr_log(GPR_DEBUG, "Created RR policy at %p with %lu subchannels",
(void *)p, (unsigned long)p->num_subchannels);
}
gpr_mu_init(&p->mu);
return &p->base;
}

@ -68,7 +68,8 @@ typedef struct {
grpc_exec_ctx *exec_ctx;
} recv_md_filter_args;
static grpc_mdelem *recv_md_filter(void *user_data, grpc_mdelem *md) {
static grpc_mdelem *recv_md_filter(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_mdelem *md) {
recv_md_filter_args *a = user_data;
grpc_call_element *elem = a->elem;
call_data *calld = elem->call_data;
@ -189,7 +190,8 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
*/
}
static grpc_mdelem *lr_trailing_md_filter(void *user_data, grpc_mdelem *md) {
static grpc_mdelem *lr_trailing_md_filter(grpc_exec_ctx *exec_ctx,
void *user_data, grpc_mdelem *md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;

@ -1040,7 +1040,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
"op.send_initial_metadata");
}
} else {
s->send_trailing_metadata = NULL;
s->send_initial_metadata = NULL;
grpc_chttp2_complete_closure_step(
exec_ctx, t, s, &s->send_initial_metadata_finished,
GRPC_ERROR_CREATE(
@ -1525,13 +1525,17 @@ static void fail_pending_writes(grpc_exec_ctx *exec_ctx,
grpc_error *error) {
error =
removal_error(error, s, "Pending writes failed due to stream closure");
s->fetching_send_message = NULL;
s->send_initial_metadata = NULL;
grpc_chttp2_complete_closure_step(
exec_ctx, t, s, &s->send_initial_metadata_finished, GRPC_ERROR_REF(error),
"send_initial_metadata_finished");
s->send_trailing_metadata = NULL;
grpc_chttp2_complete_closure_step(
exec_ctx, t, s, &s->send_trailing_metadata_finished,
GRPC_ERROR_REF(error), "send_trailing_metadata_finished");
s->fetching_send_message = NULL;
grpc_chttp2_complete_closure_step(
exec_ctx, t, s, &s->fetching_send_message_finished, GRPC_ERROR_REF(error),
"fetching_send_message_finished");
@ -2296,6 +2300,14 @@ static char *chttp2_get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *t) {
return gpr_strdup(((grpc_chttp2_transport *)t)->peer_string);
}
/*******************************************************************************
* MONITORING
*/
static grpc_endpoint *chttp2_get_endpoint(grpc_exec_ctx *exec_ctx,
grpc_transport *t) {
return ((grpc_chttp2_transport *)t)->ep;
}
static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream),
"chttp2",
init_stream,
@ -2305,7 +2317,8 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream),
perform_transport_op,
destroy_stream,
destroy_transport,
chttp2_get_peer};
chttp2_get_peer,
chttp2_get_endpoint};
grpc_transport *grpc_create_chttp2_transport(
grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args,

@ -471,7 +471,8 @@ static void on_initial_header(grpc_exec_ctx *exec_ctx, void *tp,
grpc_mdstr_as_c_string(md->value));
*cached_timeout = gpr_inf_future(GPR_TIMESPAN);
}
grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
cached_timeout =
grpc_mdelem_set_user_data(md, free_timeout, cached_timeout);
}
grpc_chttp2_incoming_metadata_buffer_set_deadline(
&s->metadata_buffer[0],

@ -42,6 +42,7 @@
#include <grpc/support/useful.h>
#include "src/core/ext/transport/chttp2/transport/incoming_metadata.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/channel.h"
@ -1095,6 +1096,11 @@ static char *get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {
return NULL;
}
static grpc_endpoint *get_endpoint(grpc_exec_ctx *exec_ctx,
grpc_transport *gt) {
return NULL;
}
static void perform_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
grpc_transport_op *op) {}
@ -1107,4 +1113,5 @@ const grpc_transport_vtable grpc_cronet_vtable = {sizeof(stream_obj),
perform_op,
destroy_stream,
destroy_transport,
get_peer};
get_peer,
get_endpoint};

@ -300,6 +300,12 @@ uint32_t grpc_channel_args_compression_algorithm_get_states(
}
}
grpc_channel_args *grpc_channel_args_set_socket_mutator(
grpc_channel_args *a, grpc_socket_mutator *mutator) {
grpc_arg tmp = grpc_socket_mutator_to_arg(mutator);
return grpc_channel_args_copy_and_add(a, &tmp, 1);
}
int grpc_channel_args_compare(const grpc_channel_args *a,
const grpc_channel_args *b) {
int c = GPR_ICMP(a->num_args, b->num_args);

@ -36,6 +36,7 @@
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include "src/core/lib/iomgr/socket_mutator.h"
// Channel args are intentionally immutable, to avoid the need for locking.
@ -101,6 +102,13 @@ uint32_t grpc_channel_args_compression_algorithm_get_states(
int grpc_channel_args_compare(const grpc_channel_args *a,
const grpc_channel_args *b);
/** Returns a channel arg instance with socket mutator added. The socket mutator
* will perform its mutate_fd method on all file descriptors used by the
* channel.
* If \a a is non-MULL, its args are copied. */
grpc_channel_args *grpc_channel_args_set_socket_mutator(
grpc_channel_args *a, grpc_socket_mutator *mutator);
/** Returns the value of argument \a name from \a args, or NULL if not found. */
const grpc_arg *grpc_channel_args_find(const grpc_channel_args *args,
const char *name);

@ -162,7 +162,8 @@ grpc_error *grpc_call_stack_init(
grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack,
int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg,
grpc_call_context_element *context, const void *transport_server_data,
grpc_slice path, gpr_timespec deadline, grpc_call_stack *call_stack) {
grpc_slice path, gpr_timespec start_time, gpr_timespec deadline,
grpc_call_stack *call_stack) {
grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(channel_stack);
grpc_call_element_args args;
size_t count = channel_stack->count;
@ -179,7 +180,7 @@ grpc_error *grpc_call_stack_init(
/* init per-filter data */
grpc_error *first_error = GRPC_ERROR_NONE;
args.start_time = gpr_now(GPR_CLOCK_MONOTONIC);
args.start_time = start_time;
for (i = 0; i < count; i++) {
args.call_stack = call_stack;
args.server_transport_data = transport_server_data;

@ -231,7 +231,8 @@ grpc_error *grpc_call_stack_init(
grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack,
int initial_refs, grpc_iomgr_cb_func destroy, void *destroy_arg,
grpc_call_context_element *context, const void *transport_server_data,
grpc_slice path, gpr_timespec deadline, grpc_call_stack *call_stack);
grpc_slice path, gpr_timespec start_time, gpr_timespec deadline,
grpc_call_stack *call_stack);
/* Set a pollset or a pollset_set for a call stack: must occur before the first
* op is started */
void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,

@ -84,7 +84,8 @@ typedef struct channel_data {
/** For each \a md element from the incoming metadata, filter out the entry for
* "grpc-encoding", using its value to populate the call data's
* compression_algorithm field. */
static grpc_mdelem *compression_md_filter(void *user_data, grpc_mdelem *md) {
static grpc_mdelem *compression_md_filter(grpc_exec_ctx *exec_ctx,
void *user_data, grpc_mdelem *md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data;

@ -36,6 +36,7 @@
#include <grpc/support/string_util.h>
#include <string.h>
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/percent_encoding.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
@ -58,6 +59,7 @@ typedef struct call_data {
grpc_linked_mdelem payload_bin;
grpc_metadata_batch *recv_initial_metadata;
grpc_metadata_batch *recv_trailing_metadata;
uint8_t *payload_bytes;
/* Vars to read data off of send_message */
@ -71,14 +73,16 @@ typedef struct call_data {
bool send_message_blocked;
/** Closure to call when finished with the hc_on_recv hook */
grpc_closure *on_done_recv;
grpc_closure *on_done_recv_initial_metadata;
grpc_closure *on_done_recv_trailing_metadata;
grpc_closure *on_complete;
grpc_closure *post_send;
/** Receive closures are chained: we inject this closure as the on_done_recv
up-call on transport_op, and remember to call our on_done_recv member
after handling it. */
grpc_closure hc_on_recv;
grpc_closure hc_on_recv_initial_metadata;
grpc_closure hc_on_recv_trailing_metadata;
grpc_closure hc_on_complete;
grpc_closure got_slice;
grpc_closure send_done;
@ -90,13 +94,9 @@ typedef struct channel_data {
size_t max_payload_size_for_get;
} channel_data;
typedef struct {
grpc_call_element *elem;
grpc_exec_ctx *exec_ctx;
} client_recv_filter_args;
static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) {
client_recv_filter_args *a = user_data;
static grpc_mdelem *client_recv_filter(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_mdelem *md) {
grpc_call_element *elem = user_data;
if (md == GRPC_MDELEM_STATUS_200) {
return NULL;
} else if (grpc_slice_cmp(md->key, GRPC_MDSTR_STATUS) == 0) {
@ -106,9 +106,19 @@ static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) {
grpc_slice message = grpc_slice_from_copied_string(message_string);
gpr_free(message_string);
gpr_free(val);
grpc_call_element_send_close_with_message(a->exec_ctx, a->elem,
grpc_call_element_send_close_with_message(exec_ctx, elem,
GRPC_STATUS_CANCELLED, &message);
return NULL;
} else if (grpc_slice_cmp(md->key, GRPC_MDSTR_GRPC_MESSAGE) == 0) {
grpc_slice pct_decoded_msg =
grpc_permissive_percent_decode_slice(md->value);
if (grpc_slice_is_equivalent(pct_decoded_msg, md->value)) {
grpc_slice_unref(pct_decoded_msg);
return md;
} else {
return grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
pct_decoded_msg);
}
} else if (md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
return NULL;
} else if (grpc_slice_cmp(md->key, GRPC_MDSTR_CONTENT_TYPE) == 0) {
@ -134,16 +144,24 @@ static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) {
return md;
}
static void hc_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_error *error) {
static void hc_on_recv_initial_metadata(grpc_exec_ctx *exec_ctx,
void *user_data, grpc_error *error) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
client_recv_filter_args a;
a.elem = elem;
a.exec_ctx = exec_ctx;
grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
client_recv_filter, &a);
calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, error);
client_recv_filter, elem);
grpc_closure_run(exec_ctx, calld->on_done_recv_initial_metadata,
GRPC_ERROR_REF(error));
}
static void hc_on_recv_trailing_metadata(grpc_exec_ctx *exec_ctx,
void *user_data, grpc_error *error) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
grpc_metadata_batch_filter(exec_ctx, calld->recv_trailing_metadata,
client_recv_filter, elem);
grpc_closure_run(exec_ctx, calld->on_done_recv_trailing_metadata,
GRPC_ERROR_REF(error));
}
static void hc_on_complete(grpc_exec_ctx *exec_ctx, void *user_data,
@ -164,7 +182,8 @@ static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error);
}
static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) {
static grpc_mdelem *client_strip_filter(grpc_exec_ctx *exec_ctx,
void *user_data, grpc_mdelem *md) {
/* eat the things we'd like to set ourselves */
if (grpc_slice_cmp(md->key, GRPC_MDSTR_METHOD) == 0) return NULL;
if (grpc_slice_cmp(md->key, GRPC_MDSTR_SCHEME) == 0) return NULL;
@ -286,8 +305,15 @@ static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
if (op->recv_initial_metadata != NULL) {
/* substitute our callback for the higher callback */
calld->recv_initial_metadata = op->recv_initial_metadata;
calld->on_done_recv = op->recv_initial_metadata_ready;
op->recv_initial_metadata_ready = &calld->hc_on_recv;
calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready;
op->recv_initial_metadata_ready = &calld->hc_on_recv_initial_metadata;
}
if (op->recv_trailing_metadata != NULL) {
/* substitute our callback for the higher callback */
calld->recv_trailing_metadata = op->recv_trailing_metadata;
calld->on_done_recv_trailing_metadata = op->on_complete;
op->on_complete = &calld->hc_on_recv_trailing_metadata;
}
}
@ -313,11 +339,15 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_call_element_args *args) {
call_data *calld = elem->call_data;
calld->on_done_recv = NULL;
calld->on_done_recv_initial_metadata = NULL;
calld->on_done_recv_trailing_metadata = NULL;
calld->on_complete = NULL;
calld->payload_bytes = NULL;
grpc_slice_buffer_init(&calld->slices);
grpc_closure_init(&calld->hc_on_recv, hc_on_recv, elem);
grpc_closure_init(&calld->hc_on_recv_initial_metadata,
hc_on_recv_initial_metadata, elem);
grpc_closure_init(&calld->hc_on_recv_trailing_metadata,
hc_on_recv_trailing_metadata, elem);
grpc_closure_init(&calld->hc_on_complete, hc_on_complete, elem);
grpc_closure_init(&calld->got_slice, got_slice, elem);
grpc_closure_init(&calld->send_done, send_done, elem);

@ -37,6 +37,7 @@
#include <grpc/support/log.h>
#include <string.h>
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/percent_encoding.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/transport/static_metadata.h"
@ -83,14 +84,27 @@ typedef struct call_data {
typedef struct channel_data { uint8_t unused; } channel_data;
typedef struct {
grpc_call_element *elem;
grpc_exec_ctx *exec_ctx;
} server_filter_args;
static grpc_mdelem *server_filter_outgoing_metadata(grpc_exec_ctx *exec_ctx,
void *user_data,
grpc_mdelem *md) {
if (grpc_slice_cmp(md->key, GRPC_MDSTR_GRPC_MESSAGE) == 0) {
grpc_slice pct_encoded_msg = grpc_percent_encode_slice(
md->value, grpc_compatible_percent_encoding_unreserved_bytes);
if (grpc_slice_is_equivalent(pct_encoded_msg, md->value)) {
grpc_slice_unref_internal(exec_ctx, pct_encoded_msg);
return md;
} else {
return grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_GRPC_MESSAGE,
pct_encoded_msg);
}
} else {
return md;
}
}
static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
server_filter_args *a = user_data;
grpc_call_element *elem = a->elem;
static grpc_mdelem *server_filter(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_mdelem *md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
/* Check if it is one of the headers we care about. */
@ -145,9 +159,9 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
/* swallow it and error everything out. */
/* TODO(klempner): We ought to generate more descriptive error messages
on the wire here. */
grpc_call_element_send_cancel(a->exec_ctx, elem);
gpr_free(key);
gpr_free(value);
grpc_call_element_send_cancel(exec_ctx, elem);
return NULL;
} else if (grpc_slice_cmp(md->key, GRPC_MDSTR_PATH) == 0) {
if (calld->seen_path) {
@ -163,7 +177,7 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
/* translate host to :authority since :authority may be
omitted */
grpc_mdelem *authority = grpc_mdelem_from_slices(
a->exec_ctx, GRPC_MDSTR_AUTHORITY, grpc_slice_ref(md->value));
exec_ctx, GRPC_MDSTR_AUTHORITY, grpc_slice_ref(md->value));
calld->seen_authority = 1;
return authority;
} else if (grpc_slice_cmp(md->key, GRPC_MDSTR_GRPC_PAYLOAD_BIN) == 0) {
@ -185,11 +199,8 @@ static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
if (err == GRPC_ERROR_NONE) {
server_filter_args a;
a.elem = elem;
a.exec_ctx = exec_ctx;
grpc_metadata_batch_filter(exec_ctx, calld->recv_initial_metadata,
server_filter, &a);
server_filter, elem);
/* Have we seen the required http2 transport headers?
(:method, :scheme, content-type, with :path and :authority covered
at the channel level right now) */
@ -263,7 +274,7 @@ static void hs_recv_message_ready(grpc_exec_ctx *exec_ctx, void *user_data,
}
}
static void hs_mutate_op(grpc_call_element *elem,
static void hs_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_transport_stream_op *op) {
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
@ -299,6 +310,11 @@ static void hs_mutate_op(grpc_call_element *elem,
op->on_complete = &calld->hs_on_complete;
}
}
if (op->send_trailing_metadata) {
grpc_metadata_batch_filter(exec_ctx, op->send_trailing_metadata,
server_filter_outgoing_metadata, elem);
}
}
static void hs_start_transport_op(grpc_exec_ctx *exec_ctx,
@ -306,7 +322,7 @@ static void hs_start_transport_op(grpc_exec_ctx *exec_ctx,
grpc_transport_stream_op *op) {
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
GPR_TIMER_BEGIN("hs_start_transport_op", 0);
hs_mutate_op(elem, op);
hs_mutate_op(exec_ctx, elem, op);
grpc_call_next_op(exec_ctx, elem, op);
GPR_TIMER_END("hs_start_transport_op", 0);
}

@ -66,6 +66,8 @@ char* grpc_endpoint_get_peer(grpc_endpoint* ep) {
return ep->vtable->get_peer(ep);
}
int grpc_endpoint_get_fd(grpc_endpoint* ep) { return ep->vtable->get_fd(ep); }
grpc_workqueue* grpc_endpoint_get_workqueue(grpc_endpoint* ep) {
return ep->vtable->get_workqueue(ep);
}

@ -61,6 +61,7 @@ struct grpc_endpoint_vtable {
void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep);
grpc_resource_user *(*get_resource_user)(grpc_endpoint *ep);
char *(*get_peer)(grpc_endpoint *ep);
int (*get_fd)(grpc_endpoint *ep);
};
/* When data is available on the connection, calls the callback with slices.
@ -73,6 +74,10 @@ void grpc_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
char *grpc_endpoint_get_peer(grpc_endpoint *ep);
/* Get the file descriptor used by \a ep. Return -1 if \a ep is not using an fd.
*/
int grpc_endpoint_get_fd(grpc_endpoint *ep);
/* Retrieve a reference to the workqueue associated with this endpoint */
grpc_workqueue *grpc_endpoint_get_workqueue(grpc_endpoint *ep);

@ -31,7 +31,6 @@
*
*/
#include <grpc/grpc_posix.h>
#include "src/core/lib/iomgr/port.h"
/* This polling engine is only relevant on linux kernels supporting epoll() */
@ -163,7 +162,7 @@ static void fd_global_shutdown(void);
#define PI_ADD_REF(p, r) pi_add_ref((p))
#define PI_UNREF(exec_ctx, p, r) pi_unref((exec_ctx), (p))
#endif /* !defined(GPRC_PI_REF_COUNT_DEBUG) */
#endif /* !defined(GRPC_PI_REF_COUNT_DEBUG) */
/* This is also used as grpc_workqueue (by directly casing it) */
typedef struct polling_island {

File diff suppressed because it is too large Load Diff

@ -1,41 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_LIB_IOMGR_EV_POLL_AND_EPOLL_POSIX_H
#define GRPC_CORE_LIB_IOMGR_EV_POLL_AND_EPOLL_POSIX_H
#include "src/core/lib/iomgr/ev_posix.h"
const grpc_event_engine_vtable *grpc_init_poll_and_epoll_posix(void);
#endif /* GRPC_CORE_LIB_IOMGR_EV_POLL_AND_EPOLL_POSIX_H */

@ -45,7 +45,6 @@
#include <grpc/support/useful.h>
#include "src/core/lib/iomgr/ev_epoll_linux.h"
#include "src/core/lib/iomgr/ev_poll_and_epoll_posix.h"
#include "src/core/lib/iomgr/ev_poll_posix.h"
#include "src/core/lib/support/env.h"
@ -67,7 +66,6 @@ static const event_engine_factory g_factories[] = {
{"epoll", grpc_init_epoll_linux},
{"poll", grpc_init_poll_posix},
{"poll-cv", grpc_init_poll_cv_posix},
{"legacy", grpc_init_poll_and_epoll_posix},
};
static void add(const char *beg, const char *end, char ***ss, size_t *ns) {

@ -121,9 +121,8 @@ void grpc_executor_push(grpc_closure *closure, grpc_error *error) {
gpr_mu_unlock(&g_executor.mu);
}
void grpc_executor_shutdown() {
void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx) {
int pending_join;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_mu_lock(&g_executor.mu);
pending_join = g_executor.pending_join;
@ -133,8 +132,7 @@ void grpc_executor_shutdown() {
* list below because we aren't accepting new work */
/* Execute pending callbacks, some may be performing cleanups */
grpc_exec_ctx_enqueue_list(&exec_ctx, &g_executor.closures, NULL);
grpc_exec_ctx_finish(&exec_ctx);
grpc_exec_ctx_enqueue_list(exec_ctx, &g_executor.closures, NULL);
GPR_ASSERT(grpc_closure_list_empty(g_executor.closures));
if (pending_join) {
gpr_thd_join(g_executor.tid);

@ -48,6 +48,6 @@ void grpc_executor_init();
void grpc_executor_push(grpc_closure *closure, grpc_error *error);
/** Shutdown the executor, running all pending work as part of the call */
void grpc_executor_shutdown();
void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx);
#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */

@ -83,11 +83,10 @@ static void dump_objects(const char *kind) {
}
}
void grpc_iomgr_shutdown(void) {
void grpc_iomgr_shutdown(grpc_exec_ctx *exec_ctx) {
gpr_timespec shutdown_deadline = gpr_time_add(
gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(10, GPR_TIMESPAN));
gpr_timespec last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_iomgr_platform_flush();
@ -104,10 +103,9 @@ void grpc_iomgr_shutdown(void) {
}
last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
}
if (grpc_timer_check(&exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC),
NULL)) {
if (grpc_timer_check(exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL)) {
gpr_mu_unlock(&g_mu);
grpc_exec_ctx_flush(&exec_ctx);
grpc_exec_ctx_flush(exec_ctx);
gpr_mu_lock(&g_mu);
continue;
}
@ -138,8 +136,8 @@ void grpc_iomgr_shutdown(void) {
}
gpr_mu_unlock(&g_mu);
grpc_timer_list_shutdown(&exec_ctx);
grpc_exec_ctx_finish(&exec_ctx);
grpc_timer_list_shutdown(exec_ctx);
grpc_exec_ctx_flush(exec_ctx);
/* ensure all threads have left g_mu */
gpr_mu_lock(&g_mu);

@ -34,12 +34,14 @@
#ifndef GRPC_CORE_LIB_IOMGR_IOMGR_H
#define GRPC_CORE_LIB_IOMGR_IOMGR_H
#include <grpc/impl/codegen/exec_ctx_fwd.h>
#include "src/core/lib/iomgr/port.h"
/** Initializes the iomgr. */
void grpc_iomgr_init(void);
/** Signals the intention to shutdown the iomgr. */
void grpc_iomgr_shutdown(void);
/** Signals the intention to shutdown the iomgr. Expects to be able to flush
* exec_ctx. */
void grpc_iomgr_shutdown(grpc_exec_ctx *exec_ctx);
#endif /* GRPC_CORE_LIB_IOMGR_IOMGR_H */

@ -0,0 +1,98 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/lib/iomgr/socket_mutator.h"
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/sync.h>
#include <grpc/support/useful.h>
void grpc_socket_mutator_init(grpc_socket_mutator *mutator,
const grpc_socket_mutator_vtable *vtable) {
mutator->vtable = vtable;
gpr_ref_init(&mutator->refcount, 1);
}
grpc_socket_mutator *grpc_socket_mutator_ref(grpc_socket_mutator *mutator) {
gpr_ref(&mutator->refcount);
return mutator;
}
bool grpc_socket_mutator_mutate_fd(grpc_socket_mutator *mutator, int fd) {
return mutator->vtable->mutate_fd(fd, mutator);
}
int grpc_socket_mutator_compare(grpc_socket_mutator *a,
grpc_socket_mutator *b) {
int c = GPR_ICMP(a, b);
if (c != 0) {
grpc_socket_mutator *sma = a;
grpc_socket_mutator *smb = b;
c = GPR_ICMP(sma->vtable, smb->vtable);
if (c == 0) {
c = sma->vtable->compare(sma, smb);
}
}
return c;
}
void grpc_socket_mutator_unref(grpc_socket_mutator *mutator) {
if (gpr_unref(&mutator->refcount)) {
mutator->vtable->destory(mutator);
}
}
static void *socket_mutator_arg_copy(void *p) {
return grpc_socket_mutator_ref(p);
}
static void socket_mutator_arg_destroy(grpc_exec_ctx *exec_ctx, void *p) {
grpc_socket_mutator_unref(p);
}
static int socket_mutator_cmp(void *a, void *b) {
return grpc_socket_mutator_compare((grpc_socket_mutator *)a,
(grpc_socket_mutator *)b);
}
static const grpc_arg_pointer_vtable socket_mutator_arg_vtable = {
socket_mutator_arg_copy, socket_mutator_arg_destroy, socket_mutator_cmp};
grpc_arg grpc_socket_mutator_to_arg(grpc_socket_mutator *mutator) {
grpc_arg arg;
arg.type = GRPC_ARG_POINTER;
arg.key = GRPC_ARG_SOCKET_MUTATOR;
arg.value.pointer.vtable = &socket_mutator_arg_vtable;
arg.value.pointer.p = mutator;
return arg;
}

@ -0,0 +1,80 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_LIB_IOMGR_SOCKET_MUTATOR_H
#define GRPC_CORE_LIB_IOMGR_SOCKET_MUTATOR_H
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/sync.h>
#ifdef __cplusplus
extern "C" {
#endif
/** The virtual table of grpc_socket_mutator */
typedef struct {
/** Mutates the socket opitons of \a fd */
bool (*mutate_fd)(int fd, grpc_socket_mutator *mutator);
/** 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);
} grpc_socket_mutator_vtable;
/** The Socket Mutator interface allows changes on socket options */
struct grpc_socket_mutator {
const grpc_socket_mutator_vtable *vtable;
gpr_refcount refcount;
};
/** called by concrete implementations to initialize the base struct */
void grpc_socket_mutator_init(grpc_socket_mutator *mutator,
const grpc_socket_mutator_vtable *vtable);
/** Wrap \a mutator as a grpc_arg */
grpc_arg grpc_socket_mutator_to_arg(grpc_socket_mutator *mutator);
/** Perform the file descriptor mutation operation of \a mutator on \a fd */
bool grpc_socket_mutator_mutate_fd(grpc_socket_mutator *mutator, int fd);
/** Compare if \a a and \a b are the same mutator or have same settings */
int grpc_socket_mutator_compare(grpc_socket_mutator *a, grpc_socket_mutator *b);
grpc_socket_mutator *grpc_socket_mutator_ref(grpc_socket_mutator *mutator);
void grpc_socket_mutator_unref(grpc_socket_mutator *mutator);
#ifdef __cplusplus
}
#endif
#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_MUTATOR_H */

@ -209,6 +209,15 @@ grpc_error *grpc_set_socket_low_latency(int fd, int low_latency) {
return GRPC_ERROR_NONE;
}
/* set a socket using a grpc_socket_mutator */
grpc_error *grpc_set_socket_with_mutator(int fd, grpc_socket_mutator *mutator) {
GPR_ASSERT(mutator);
if (!grpc_socket_mutator_mutate_fd(mutator, fd)) {
return GRPC_ERROR_CREATE("grpc_socket_mutator failed.");
}
return GRPC_ERROR_NONE;
}
static gpr_once g_probe_ipv6_once = GPR_ONCE_INIT;
static int g_ipv6_loopback_available;

@ -39,7 +39,9 @@
#include <sys/socket.h>
#include <unistd.h>
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/socket_mutator.h"
/* a wrapper for accept or accept4 */
int grpc_accept4(int sockfd, grpc_resolved_address *resolved_addr, int nonblock,
@ -88,6 +90,9 @@ grpc_error *grpc_set_socket_sndbuf(int fd, int buffer_size_bytes);
/* Tries to set the socket's receive buffer to given size. */
grpc_error *grpc_set_socket_rcvbuf(int fd, int buffer_size_bytes);
/* Tries to set the socket using a grpc_socket_mutator */
grpc_error *grpc_set_socket_with_mutator(int fd, grpc_socket_mutator *mutator);
/* An enum to keep track of IPv4/IPv6 socket modes.
Currently, this information is only used when a socket is first created, but

@ -34,6 +34,7 @@
#ifndef GRPC_CORE_LIB_IOMGR_TCP_CLIENT_H
#define GRPC_CORE_LIB_IOMGR_TCP_CLIENT_H
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/time.h>
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/pollset_set.h"

@ -51,6 +51,7 @@
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/iomgr_posix.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/socket_mutator.h"
#include "src/core/lib/iomgr/socket_utils_posix.h"
#include "src/core/lib/iomgr/tcp_posix.h"
#include "src/core/lib/iomgr/timer.h"
@ -73,7 +74,8 @@ typedef struct {
grpc_channel_args *channel_args;
} async_connect;
static grpc_error *prepare_socket(const grpc_resolved_address *addr, int fd) {
static grpc_error *prepare_socket(const grpc_resolved_address *addr, int fd,
const grpc_channel_args *channel_args) {
grpc_error *err = GRPC_ERROR_NONE;
GPR_ASSERT(fd >= 0);
@ -88,6 +90,16 @@ static grpc_error *prepare_socket(const grpc_resolved_address *addr, int fd) {
}
err = grpc_set_socket_no_sigpipe_if_possible(fd);
if (err != GRPC_ERROR_NONE) goto error;
if (channel_args) {
for (size_t i = 0; i < channel_args->num_args; i++) {
if (0 == strcmp(channel_args->args[i].key, GRPC_ARG_SOCKET_MUTATOR)) {
GPR_ASSERT(channel_args->args[i].type == GRPC_ARG_POINTER);
grpc_socket_mutator *mutator = channel_args->args[i].value.pointer.p;
err = grpc_set_socket_with_mutator(fd, mutator);
if (err != GRPC_ERROR_NONE) goto error;
}
}
}
goto done;
error:
@ -287,7 +299,7 @@ static void tcp_client_connect_impl(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(grpc_sockaddr_is_v4mapped(addr, &addr4_copy));
addr = &addr4_copy;
}
if ((error = prepare_socket(addr, fd)) != GRPC_ERROR_NONE) {
if ((error = prepare_socket(addr, fd, channel_args)) != GRPC_ERROR_NONE) {
grpc_exec_ctx_sched(exec_ctx, closure, error, NULL);
return;
}

@ -497,6 +497,11 @@ static char *tcp_get_peer(grpc_endpoint *ep) {
return gpr_strdup(tcp->peer_string);
}
static int tcp_get_fd(grpc_endpoint *ep) {
grpc_tcp *tcp = (grpc_tcp *)ep;
return tcp->fd;
}
static grpc_workqueue *tcp_get_workqueue(grpc_endpoint *ep) {
grpc_tcp *tcp = (grpc_tcp *)ep;
return grpc_fd_get_workqueue(tcp->em_fd);
@ -515,7 +520,8 @@ static const grpc_endpoint_vtable vtable = {tcp_read,
tcp_shutdown,
tcp_destroy,
tcp_get_resource_user,
tcp_get_peer};
tcp_get_peer,
tcp_get_fd};
grpc_endpoint *grpc_tcp_create(grpc_fd *em_fd,
grpc_resource_quota *resource_quota,

@ -87,10 +87,12 @@ static void tcp_free(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp) {
/*#define GRPC_TCP_REFCOUNT_DEBUG*/
#ifdef GRPC_TCP_REFCOUNT_DEBUG
#define TCP_UNREF(exec_ctx, tcp, reason) tcp_unref((exec_ctx), (tcp), (reason), __FILE__, __LINE__)
#define TCP_REF(tcp, reason) tcp_ref((exec_ctx), (tcp), (reason), __FILE__, __LINE__)
static void tcp_unref(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp, const char *reason, const char *file,
int line) {
#define TCP_UNREF(exec_ctx, tcp, reason) \
tcp_unref((exec_ctx), (tcp), (reason), __FILE__, __LINE__)
#define TCP_REF(tcp, reason) \
tcp_ref((exec_ctx), (tcp), (reason), __FILE__, __LINE__)
static void tcp_unref(grpc_exec_ctx *exec_ctx, grpc_tcp *tcp,
const char *reason, const char *file, int line) {
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "TCP unref %p : %s %d -> %d", tcp,
reason, tcp->refcount.count, tcp->refcount.count - 1);
if (gpr_unref(&tcp->refcount)) {
@ -157,7 +159,7 @@ static void read_callback(uv_stream_t *stream, ssize_t nread,
grpc_error_free_string(str);
for (i = 0; i < tcp->read_slices->count; i++) {
char *dump = grpc_dump_slice(tcp->read_slices->slices[i],
GPR_DUMP_HEX | GPR_DUMP_ASCII);
GPR_DUMP_HEX | GPR_DUMP_ASCII);
gpr_log(GPR_DEBUG, "READ %p (peer=%s): %s", tcp, tcp->peer_string,
dump);
gpr_free(dump);
@ -234,7 +236,7 @@ static void uv_endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
for (j = 0; j < write_slices->count; j++) {
char *data = grpc_dump_slice(write_slices->slices[j],
GPR_DUMP_HEX | GPR_DUMP_ASCII);
GPR_DUMP_HEX | GPR_DUMP_ASCII);
gpr_log(GPR_DEBUG, "WRITE %p (peer=%s): %s", tcp, tcp->peer_string, data);
gpr_free(data);
}
@ -323,10 +325,13 @@ static grpc_resource_user *uv_get_resource_user(grpc_endpoint *ep) {
static grpc_workqueue *uv_get_workqueue(grpc_endpoint *ep) { return NULL; }
static int uv_get_fd(grpc_endpoint *ep) { return -1; }
static grpc_endpoint_vtable vtable = {
uv_endpoint_read, uv_endpoint_write, uv_get_workqueue,
uv_add_to_pollset, uv_add_to_pollset_set, uv_endpoint_shutdown,
uv_destroy, uv_get_resource_user, uv_get_peer};
uv_destroy, uv_get_resource_user, uv_get_peer,
uv_get_fd};
grpc_endpoint *grpc_tcp_create(uv_tcp_t *handle,
grpc_resource_quota *resource_quota,

@ -402,6 +402,8 @@ static grpc_resource_user *win_get_resource_user(grpc_endpoint *ep) {
return tcp->resource_user;
}
static int win_get_fd(grpc_endpoint *ep) { return -1; }
static grpc_endpoint_vtable vtable = {win_read,
win_write,
win_get_workqueue,
@ -410,7 +412,8 @@ static grpc_endpoint_vtable vtable = {win_read,
win_shutdown,
win_destroy,
win_get_resource_user,
win_get_peer};
win_get_peer,
win_get_fd};
grpc_endpoint *grpc_tcp_create(grpc_winsocket *socket,
grpc_resource_quota *resource_quota,

@ -147,17 +147,44 @@ grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
return &c->base;
}
static char *redact_private_key(const char *json_key) {
char *json_copy = gpr_strdup(json_key);
grpc_json *json = grpc_json_parse_string(json_copy);
if (!json) {
gpr_free(json_copy);
return gpr_strdup("<Json failed to parse.>");
}
const char *redacted = "<redacted>";
grpc_json *current = json->child;
while (current) {
if (current->type == GRPC_JSON_STRING &&
strcmp(current->key, "private_key") == 0) {
current->value = (char *)redacted;
break;
}
current = current->next;
}
char *clean_json = grpc_json_dump_to_string(json, 2);
gpr_free(json_copy);
grpc_json_destroy(json);
return clean_json;
}
grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
const char *json_key, gpr_timespec token_lifetime, void *reserved) {
GRPC_API_TRACE(
"grpc_service_account_jwt_access_credentials_create("
"json_key=%s, "
"token_lifetime="
"gpr_timespec { tv_sec: %" PRId64
", tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
5, (json_key, token_lifetime.tv_sec, token_lifetime.tv_nsec,
(int)token_lifetime.clock_type, reserved));
if (grpc_api_trace) {
char *clean_json = redact_private_key(json_key);
gpr_log(GPR_INFO,
"grpc_service_account_jwt_access_credentials_create("
"json_key=%s, "
"token_lifetime="
"gpr_timespec { tv_sec: %" PRId64
", tv_nsec: %d, clock_type: %d }, "
"reserved=%p)",
clean_json, token_lifetime.tv_sec, token_lifetime.tv_nsec,
(int)token_lifetime.clock_type, reserved);
gpr_free(clean_json);
}
GPR_ASSERT(reserved == NULL);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_call_credentials *creds =

@ -629,7 +629,7 @@ static void on_keys_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
end:
if (json != NULL) grpc_json_destroy(json);
if (verification_key != NULL) EVP_PKEY_free(verification_key);
ctx->user_cb(ctx->user_data, status, claims);
ctx->user_cb(exec_ctx, ctx->user_data, status, claims);
verifier_cb_ctx_destroy(exec_ctx, ctx);
}
@ -682,7 +682,8 @@ static void on_openid_config_retrieved(grpc_exec_ctx *exec_ctx, void *user_data,
error:
if (json != NULL) grpc_json_destroy(json);
ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL);
ctx->user_cb(exec_ctx, ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR,
NULL);
verifier_cb_ctx_destroy(exec_ctx, ctx);
}
@ -793,7 +794,8 @@ static void retrieve_key_and_verify(grpc_exec_ctx *exec_ctx,
return;
error:
ctx->user_cb(ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR, NULL);
ctx->user_cb(exec_ctx, ctx->user_data, GRPC_JWT_VERIFIER_KEY_RETRIEVAL_ERROR,
NULL);
verifier_cb_ctx_destroy(exec_ctx, ctx);
}
@ -844,7 +846,7 @@ void grpc_jwt_verifier_verify(grpc_exec_ctx *exec_ctx,
error:
if (header != NULL) jose_header_destroy(exec_ctx, header);
if (claims != NULL) grpc_jwt_claims_destroy(exec_ctx, claims);
cb(user_data, GRPC_JWT_VERIFIER_BAD_FORMAT, NULL);
cb(exec_ctx, user_data, GRPC_JWT_VERIFIER_BAD_FORMAT, NULL);
}
grpc_jwt_verifier *grpc_jwt_verifier_create(

@ -115,7 +115,8 @@ void grpc_jwt_verifier_destroy(grpc_jwt_verifier *verifier);
is done (maybe in another thread).
It is the responsibility of the callee to call grpc_jwt_claims_destroy on
the claims. */
typedef void (*grpc_jwt_verification_done_cb)(void *user_data,
typedef void (*grpc_jwt_verification_done_cb)(grpc_exec_ctx *exec_ctx,
void *user_data,
grpc_jwt_verifier_status status,
grpc_jwt_claims *claims);

@ -394,15 +394,32 @@ grpc_refresh_token_credentials_create_from_auth_refresh_token(
return &c->base.base;
}
static char *create_loggable_refresh_token(grpc_auth_refresh_token *token) {
if (strcmp(token->type, GRPC_AUTH_JSON_TYPE_INVALID) == 0) {
return gpr_strdup("<Invalid json token>");
}
char *loggable_token = NULL;
gpr_asprintf(&loggable_token,
"{\n type: %s\n client_id: %s\n client_secret: "
"<redacted>\n refresh_token: <redacted>\n}",
token->type, token->client_id);
return loggable_token;
}
grpc_call_credentials *grpc_google_refresh_token_credentials_create(
const char *json_refresh_token, void *reserved) {
GRPC_API_TRACE(
"grpc_refresh_token_credentials_create(json_refresh_token=%s, "
"reserved=%p)",
2, (json_refresh_token, reserved));
grpc_auth_refresh_token token =
grpc_auth_refresh_token_create_from_string(json_refresh_token);
if (grpc_api_trace) {
char *loggable_token = create_loggable_refresh_token(&token);
gpr_log(GPR_INFO,
"grpc_refresh_token_credentials_create(json_refresh_token=%s, "
"reserved=%p)",
loggable_token, reserved);
gpr_free(loggable_token);
}
GPR_ASSERT(reserved == NULL);
return grpc_refresh_token_credentials_create_from_auth_refresh_token(
grpc_auth_refresh_token_create_from_string(json_refresh_token));
return grpc_refresh_token_credentials_create_from_auth_refresh_token(token);
}
//
@ -433,9 +450,9 @@ grpc_call_credentials *grpc_access_token_credentials_create(
gpr_malloc(sizeof(grpc_access_token_credentials));
char *token_md_value;
GRPC_API_TRACE(
"grpc_access_token_credentials_create(access_token=%s, "
"grpc_access_token_credentials_create(access_token=<redacted>, "
"reserved=%p)",
2, (access_token, reserved));
1, (reserved));
GPR_ASSERT(reserved == NULL);
memset(c, 0, sizeof(grpc_access_token_credentials));
c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;

@ -106,6 +106,8 @@ static void plugin_md_request_metadata_ready(void *request,
grpc_slice_unref_internal(&exec_ctx, md_array[i].value);
}
gpr_free(md_array);
} else if (num_md == 0) {
r->cb(&exec_ctx, r->user_data, NULL, 0, GRPC_CREDENTIALS_OK, NULL);
}
}
gpr_free(r);

@ -127,7 +127,7 @@ static void security_handshake_done(grpc_exec_ctx *exec_ctx,
h->auth_context);
} else {
const char *msg = grpc_error_string(error);
gpr_log(GPR_INFO, "Security handshake failed: %s", msg);
gpr_log(GPR_DEBUG, "Security handshake failed: %s", msg);
grpc_error_free_string(msg);
if (h->secure_endpoint != NULL) {

@ -31,7 +31,12 @@
*
*/
#include "src/core/lib/security/transport/secure_endpoint.h"
/* With the addition of a libuv endpoint, sockaddr.h now includes uv.h when
using that endpoint. Because of various transitive includes in uv.h,
including windows.h on Windows, uv.h must be included before other system
headers. Therefore, sockaddr.h must always be included first */
#include "src/core/lib/iomgr/sockaddr.h"
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/alloc.h>
@ -39,6 +44,7 @@
#include <grpc/support/sync.h>
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/security/transport/tsi_error.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
@ -367,6 +373,8 @@ static char *endpoint_get_peer(grpc_endpoint *secure_ep) {
return grpc_endpoint_get_peer(ep->wrapped_ep);
}
static int endpoint_get_fd(grpc_endpoint *secure_ep) { return -1; }
static grpc_workqueue *endpoint_get_workqueue(grpc_endpoint *secure_ep) {
secure_endpoint *ep = (secure_endpoint *)secure_ep;
return grpc_endpoint_get_workqueue(ep->wrapped_ep);
@ -386,7 +394,8 @@ static const grpc_endpoint_vtable vtable = {endpoint_read,
endpoint_shutdown,
endpoint_destroy,
endpoint_get_resource_user,
endpoint_get_peer};
endpoint_get_peer,
endpoint_get_fd};
grpc_endpoint *grpc_secure_endpoint_create(
struct tsi_frame_protector *protector, grpc_endpoint *transport,

@ -83,7 +83,8 @@ static grpc_metadata_array metadata_batch_to_md_array(
return result;
}
static grpc_mdelem *remove_consumed_md(void *user_data, grpc_mdelem *md) {
static grpc_mdelem *remove_consumed_md(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_mdelem *md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
size_t i;

@ -368,3 +368,11 @@ int grpc_slice_str_cmp(grpc_slice a, const char *b) {
if (d != 0) return d;
return memcmp(GRPC_SLICE_START_PTR(a), b, b_length);
}
int grpc_slice_is_equivalent(grpc_slice a, grpc_slice b) {
if (a.refcount == NULL || b.refcount == NULL) {
return grpc_slice_cmp(a, b) == 0;
}
return a.data.refcounted.length == b.data.refcounted.length &&
a.data.refcounted.bytes == b.data.refcounted.bytes;
}

@ -75,10 +75,7 @@ void grpc_slice_buffer_destroy_internal(grpc_exec_ctx *exec_ctx,
void grpc_slice_buffer_destroy(grpc_slice_buffer *sb) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_slice_buffer_reset_and_unref_internal(&exec_ctx, sb);
if (sb->slices != sb->inlined) {
gpr_free(sb->slices);
}
grpc_slice_buffer_destroy_internal(&exec_ctx, sb);
grpc_exec_ctx_finish(&exec_ctx);
}

@ -31,8 +31,8 @@
*
*/
#ifndef GRPC_CORE_LIB_SUPPORT_SLICE_INTERNAL_H
#define GRPC_CORE_LIB_SUPPORT_SLICE_INTERNAL_H
#ifndef GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H
#define GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
@ -50,4 +50,4 @@ void grpc_slice_intern_init(void);
void grpc_slice_intern_shutdown(void);
void grpc_test_only_set_slice_interning_hash_seed(uint32_t key);
#endif
#endif /* GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H */

@ -267,5 +267,28 @@ int gpr_stricmp(const char *a, const char *b) {
return ca - cb;
}
static void add_string_to_split(const char *beg, const char *end, char ***strs,
size_t *nstrs, size_t *capstrs) {
char *out = gpr_malloc((size_t)(end - beg) + 1);
memcpy(out, beg, (size_t)(end - beg));
out[end - beg] = 0;
if (*nstrs == *capstrs) {
*capstrs = GPR_MAX(8, 2 * *capstrs);
*strs = gpr_realloc(*strs, sizeof(*strs) * *capstrs);
}
(*strs)[*nstrs] = out;
++*nstrs;
}
void gpr_string_split(const char *input, const char *sep, char ***strs,
size_t *nstrs) {}
size_t *nstrs) {
char *next;
*strs = NULL;
*nstrs = 0;
size_t capstrs = 0;
while ((next = strstr(input, sep))) {
add_string_to_split(input, next, strs, nstrs, &capstrs);
input = next + strlen(sep);
}
add_string_to_split(input, input + strlen(input), strs, nstrs, &capstrs);
}

@ -125,6 +125,7 @@ struct grpc_call {
grpc_channel *channel;
grpc_call *parent;
grpc_call *first_child;
gpr_timespec start_time;
/* TODO(ctiller): share with cq if possible? */
gpr_mu mu;
@ -241,6 +242,7 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
call->channel = args->channel;
call->cq = args->cq;
call->parent = args->parent_call;
call->start_time = gpr_now(GPR_CLOCK_MONOTONIC);
/* Always support no compression */
GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
call->is_client = args->server_transport_data == NULL;
@ -314,10 +316,10 @@ grpc_error *grpc_call_create(grpc_exec_ctx *exec_ctx,
GRPC_CHANNEL_INTERNAL_REF(args->channel, "call");
/* initial refcount dropped by grpc_call_destroy */
grpc_error *error =
grpc_call_stack_init(exec_ctx, channel_stack, 1, destroy_call, call,
call->context, args->server_transport_data, path,
send_deadline, CALL_STACK_FROM_CALL(call));
grpc_error *error = grpc_call_stack_init(
exec_ctx, channel_stack, 1, destroy_call, call, call->context,
args->server_transport_data, path, call->start_time, send_deadline,
CALL_STACK_FROM_CALL(call));
if (error != GRPC_ERROR_NONE) {
grpc_status_code status;
const char *error_str;
@ -429,6 +431,8 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
get_final_status(call, set_status_value_directly,
&c->final_info.final_status);
c->final_info.stats.latency =
gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time);
grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->final_info, c);
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, "call");
@ -618,9 +622,6 @@ static int prepare_application_metadata(
if (call->send_extra_metadata_count == 0) {
prepend_extra_metadata = 0;
} else {
for (i = 0; i < call->send_extra_metadata_count; i++) {
GRPC_MDELEM_REF(call->send_extra_metadata[i].md);
}
for (i = 1; i < call->send_extra_metadata_count; i++) {
call->send_extra_metadata[i].prev = &call->send_extra_metadata[i - 1];
}
@ -666,6 +667,7 @@ static int prepare_application_metadata(
&call->send_extra_metadata[call->send_extra_metadata_count - 1];
batch->list.head->prev = NULL;
batch->list.tail->next = NULL;
call->send_extra_metadata_count = 0;
break;
case 3: {
/* prepend AND md */
@ -681,6 +683,7 @@ static int prepare_application_metadata(
batch->list.tail = linked_from_md(last_md);
batch->list.head->prev = NULL;
batch->list.tail->next = NULL;
call->send_extra_metadata_count = 0;
break;
}
default:
@ -945,38 +948,35 @@ static grpc_mdelem *publish_app_metadata(grpc_call *call, grpc_mdelem *elem,
return elem;
}
typedef struct {
grpc_exec_ctx *exec_ctx;
grpc_call *call;
} recv_filter_args;
static grpc_mdelem *recv_initial_filter(void *args, grpc_mdelem *elem) {
recv_filter_args *a = args;
elem = recv_common_filter(a->exec_ctx, a->call, elem);
static grpc_mdelem *recv_initial_filter(grpc_exec_ctx *exec_ctx, void *args,
grpc_mdelem *elem) {
grpc_call *call = args;
elem = recv_common_filter(exec_ctx, call, elem);
if (elem == NULL) {
return NULL;
} else if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_ENCODING) == 0) {
GPR_TIMER_BEGIN("incoming_compression_algorithm", 0);
set_incoming_compression_algorithm(a->call, decode_compression(elem));
set_incoming_compression_algorithm(call, decode_compression(elem));
GPR_TIMER_END("incoming_compression_algorithm", 0);
return NULL;
} else if (grpc_slice_cmp(elem->key, GRPC_MDSTR_GRPC_ACCEPT_ENCODING) == 0) {
GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0);
set_encodings_accepted_by_peer(a->exec_ctx, a->call, elem);
set_encodings_accepted_by_peer(exec_ctx, call, elem);
GPR_TIMER_END("encodings_accepted_by_peer", 0);
return NULL;
} else {
return publish_app_metadata(a->call, elem, 0);
return publish_app_metadata(call, elem, 0);
}
}
static grpc_mdelem *recv_trailing_filter(void *args, grpc_mdelem *elem) {
recv_filter_args *a = args;
elem = recv_common_filter(a->exec_ctx, a->call, elem);
static grpc_mdelem *recv_trailing_filter(grpc_exec_ctx *exec_ctx, void *args,
grpc_mdelem *elem) {
grpc_call *call = args;
elem = recv_common_filter(exec_ctx, call, elem);
if (elem == NULL) {
return NULL;
} else {
return publish_app_metadata(a->call, elem, 1);
return publish_app_metadata(call, elem, 1);
}
}
@ -1222,8 +1222,7 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
if (error == GRPC_ERROR_NONE) {
grpc_metadata_batch *md =
&call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */];
recv_filter_args args = {exec_ctx, call};
grpc_metadata_batch_filter(exec_ctx, md, recv_initial_filter, &args);
grpc_metadata_batch_filter(exec_ctx, md, recv_initial_filter, call);
GPR_TIMER_BEGIN("validate_filtered_metadata", 0);
validate_filtered_metadata(exec_ctx, bctl);
@ -1289,8 +1288,7 @@ static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp,
if (bctl->recv_final_op) {
grpc_metadata_batch *md =
&call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
recv_filter_args args = {exec_ctx, call};
grpc_metadata_batch_filter(exec_ctx, md, recv_trailing_filter, &args);
grpc_metadata_batch_filter(exec_ctx, md, recv_trailing_filter, call);
call->received_final_op = true;
/* propagate cancellation to any interested children */

@ -229,9 +229,9 @@ void grpc_shutdown(void) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_mu_lock(&g_init_mu);
if (--g_initializations == 0) {
grpc_executor_shutdown();
grpc_executor_shutdown(&exec_ctx);
grpc_cq_global_shutdown();
grpc_iomgr_shutdown();
grpc_iomgr_shutdown(&exec_ctx);
gpr_timers_global_destroy();
grpc_tracer_shutdown();
for (i = g_number_of_plugins; i >= 0; i--) {

@ -199,6 +199,7 @@ struct grpc_server {
grpc_completion_queue **cqs;
grpc_pollset **pollsets;
size_t cq_count;
size_t pollset_count;
bool started;
/* The two following mutexes control access to server-state
@ -734,7 +735,8 @@ static void maybe_finish_shutdown(grpc_exec_ctx *exec_ctx,
}
}
static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
static grpc_mdelem *server_filter(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_mdelem *md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
if (grpc_slice_cmp(md->key, GRPC_MDSTR_PATH) == 0) {
@ -1079,7 +1081,7 @@ void grpc_server_start(grpc_server *server) {
GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server));
server->started = true;
size_t pollset_count = 0;
server->pollset_count = 0;
server->pollsets = gpr_malloc(sizeof(grpc_pollset *) * server->cq_count);
server->request_freelist_per_cq =
gpr_malloc(sizeof(*server->request_freelist_per_cq) * server->cq_count);
@ -1087,7 +1089,8 @@ void grpc_server_start(grpc_server *server) {
gpr_malloc(sizeof(*server->requested_calls_per_cq) * server->cq_count);
for (i = 0; i < server->cq_count; i++) {
if (!grpc_cq_is_non_listening_server_cq(server->cqs[i])) {
server->pollsets[pollset_count++] = grpc_cq_pollset(server->cqs[i]);
server->pollsets[server->pollset_count++] =
grpc_cq_pollset(server->cqs[i]);
}
server->request_freelist_per_cq[i] =
gpr_stack_lockfree_create((size_t)server->max_requested_calls_per_cq);
@ -1106,7 +1109,8 @@ void grpc_server_start(grpc_server *server) {
}
for (l = server->listeners; l; l = l->next) {
l->start(&exec_ctx, server, l->arg, server->pollsets, pollset_count);
l->start(&exec_ctx, server, l->arg, server->pollsets,
server->pollset_count);
}
grpc_exec_ctx_finish(&exec_ctx);
@ -1114,7 +1118,7 @@ void grpc_server_start(grpc_server *server) {
void grpc_server_get_pollsets(grpc_server *server, grpc_pollset ***pollsets,
size_t *pollset_count) {
*pollset_count = server->cq_count;
*pollset_count = server->pollset_count;
*pollsets = server->pollsets;
}

@ -43,6 +43,8 @@ int grpc_connectivity_state_trace = 0;
const char *grpc_connectivity_state_name(grpc_connectivity_state state) {
switch (state) {
case GRPC_CHANNEL_INIT:
return "INIT";
case GRPC_CHANNEL_IDLE:
return "IDLE";
case GRPC_CHANNEL_CONNECTING:
@ -159,6 +161,7 @@ void grpc_connectivity_state_set(grpc_exec_ctx *exec_ctx,
grpc_error_free_string(error_string);
}
switch (state) {
case GRPC_CHANNEL_INIT:
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_IDLE:
case GRPC_CHANNEL_READY:

@ -441,8 +441,8 @@ void *grpc_mdelem_get_user_data(grpc_mdelem *md, void (*destroy_func)(void *)) {
return result;
}
void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
void *user_data) {
void *grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
void *user_data) {
internal_metadata *im = (internal_metadata *)md;
GPR_ASSERT(!is_mdelem_static(md));
GPR_ASSERT((user_data == NULL) == (destroy_func == NULL));
@ -453,9 +453,10 @@ void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
if (destroy_func != NULL) {
destroy_func(user_data);
}
return;
return (void *)gpr_atm_no_barrier_load(&im->user_data);
}
gpr_atm_no_barrier_store(&im->user_data, (gpr_atm)user_data);
gpr_atm_rel_store(&im->destroy_user_data, (gpr_atm)destroy_func);
gpr_mu_unlock(&im->mu_user_data);
return user_data;
}

@ -94,8 +94,8 @@ size_t grpc_mdelem_get_size_in_hpack_table(grpc_mdelem *elem);
is used as a type tag and is checked during user_data fetch. */
void *grpc_mdelem_get_user_data(grpc_mdelem *md,
void (*if_destroy_func)(void *));
void grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
void *user_data);
void *grpc_mdelem_set_user_data(grpc_mdelem *md, void (*destroy_func)(void *),
void *user_data);
/* Reference counting */
//#define GRPC_METADATA_REFCOUNT_DEBUG

@ -143,7 +143,8 @@ void grpc_metadata_batch_move(grpc_metadata_batch *dst,
void grpc_metadata_batch_filter(grpc_exec_ctx *exec_ctx,
grpc_metadata_batch *batch,
grpc_mdelem *(*filter)(void *user_data,
grpc_mdelem *(*filter)(grpc_exec_ctx *exec_ctx,
void *user_data,
grpc_mdelem *elem),
void *user_data) {
grpc_linked_mdelem *l;
@ -154,7 +155,7 @@ void grpc_metadata_batch_filter(grpc_exec_ctx *exec_ctx,
assert_valid_list(&batch->list);
for (l = batch->list.head; l; l = next) {
grpc_mdelem *orig = l->md;
grpc_mdelem *filt = filter(user_data, orig);
grpc_mdelem *filt = filter(exec_ctx, user_data, orig);
next = l->next;
if (filt == NULL) {
if (l->prev) {
@ -181,7 +182,8 @@ void grpc_metadata_batch_filter(grpc_exec_ctx *exec_ctx,
GPR_TIMER_END("grpc_metadata_batch_filter", 0);
}
static grpc_mdelem *no_metadata_for_you(void *user_data, grpc_mdelem *elem) {
static grpc_mdelem *no_metadata_for_you(grpc_exec_ctx *exec_ctx,
void *user_data, grpc_mdelem *elem) {
return NULL;
}

@ -122,7 +122,8 @@ void grpc_metadata_batch_add_tail(grpc_metadata_batch *batch,
the element will be moved to the garbage list. */
void grpc_metadata_batch_filter(grpc_exec_ctx *exec_ctx,
grpc_metadata_batch *batch,
grpc_mdelem *(*filter)(void *user_data,
grpc_mdelem *(*filter)(grpc_exec_ctx *exec_ctx,
void *user_data,
grpc_mdelem *elem),
void *user_data);

@ -61,4 +61,4 @@ void grpc_pid_controller_reset(grpc_pid_controller *pid_controller);
double grpc_pid_controller_update(grpc_pid_controller *pid_controller,
double error, double dt);
#endif
#endif /* GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H */

@ -161,6 +161,11 @@ char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx,
return transport->vtable->get_peer(exec_ctx, transport);
}
grpc_endpoint *grpc_transport_get_endpoint(grpc_exec_ctx *exec_ctx,
grpc_transport *transport) {
return transport->vtable->get_endpoint(exec_ctx, transport);
}
void grpc_transport_stream_op_finish_with_failure(grpc_exec_ctx *exec_ctx,
grpc_transport_stream_op *op,
grpc_error *error) {

@ -37,6 +37,7 @@
#include <stddef.h>
#include "src/core/lib/channel/context.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/iomgr/pollset_set.h"
@ -296,6 +297,10 @@ void grpc_transport_destroy(grpc_exec_ctx *exec_ctx, grpc_transport *transport);
char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx,
grpc_transport *transport);
/* Get the endpoint used by \a transport */
grpc_endpoint *grpc_transport_get_endpoint(grpc_exec_ctx *exec_ctx,
grpc_transport *transport);
/* Allocate a grpc_transport_op, and preconfigure the on_consumed closure to
\a on_consumed and then delete the returned transport op */
grpc_transport_op *grpc_make_transport_op(grpc_closure *on_consumed);

@ -74,6 +74,9 @@ typedef struct grpc_transport_vtable {
/* implementation of grpc_transport_get_peer */
char *(*get_peer)(grpc_exec_ctx *exec_ctx, grpc_transport *self);
/* implementation of grpc_transport_get_endpoint */
grpc_endpoint *(*get_endpoint)(grpc_exec_ctx *exec_ctx, grpc_transport *self);
} grpc_transport_vtable;
/* an instance of a grpc transport */

@ -38,8 +38,11 @@
#include <grpc++/resource_quota.h>
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/log.h>
extern "C" {
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/socket_mutator.h"
}
namespace grpc {
ChannelArguments::ChannelArguments() {
@ -88,6 +91,26 @@ void ChannelArguments::SetCompressionAlgorithm(
SetInt(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, algorithm);
}
void ChannelArguments::SetSocketMutator(grpc_socket_mutator* mutator) {
if (!mutator) {
return;
}
grpc_arg mutator_arg = grpc_socket_mutator_to_arg(mutator);
bool replaced = false;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
for (auto it = args_.begin(); it != args_.end(); ++it) {
if (it->type == mutator_arg.type &&
grpc::string(it->key) == grpc::string(mutator_arg.key)) {
it->value.pointer.vtable->destroy(&exec_ctx, it->value.pointer.p);
it->value.pointer = mutator_arg.value.pointer;
}
}
grpc_exec_ctx_finish(&exec_ctx);
if (!replaced) {
args_.push_back(mutator_arg);
}
}
// Note: a second call to this will add in front the result of the first call.
// An example is calling this on a copy of ChannelArguments which already has a
// prefix. The user can build up a prefix string by calling this multiple times,

@ -40,11 +40,12 @@ namespace grpc {
// MetadataBatch
grpc_linked_mdelem *MetadataBatch::AddMetadata(const string &key,
grpc_linked_mdelem *MetadataBatch::AddMetadata(grpc_exec_ctx *exec_ctx,
const string &key,
const string &value) {
grpc_linked_mdelem *storage = new grpc_linked_mdelem;
memset(storage, 0, sizeof(grpc_linked_mdelem));
storage->md = grpc_mdelem_from_strings(key.c_str(), value.c_str());
storage->md = grpc_mdelem_from_strings(exec_ctx, key.c_str(), value.c_str());
grpc_metadata_batch_link_head(batch_, storage);
return storage;
}
@ -89,7 +90,8 @@ std::vector<FilterRecord> *channel_filters;
namespace {
bool MaybeAddFilter(grpc_channel_stack_builder *builder, void *arg) {
bool MaybeAddFilter(grpc_exec_ctx *exec_ctx,
grpc_channel_stack_builder *builder, void *arg) {
const FilterRecord &filter = *(FilterRecord *)arg;
if (filter.include_filter) {
const grpc_channel_args *args =

@ -70,7 +70,8 @@ class MetadataBatch {
/// Adds metadata and returns the newly allocated storage.
/// The caller takes ownership of the result, which must exist for the
/// lifetime of the gRPC call.
grpc_linked_mdelem *AddMetadata(const string &key, const string &value);
grpc_linked_mdelem *AddMetadata(grpc_exec_ctx *exec_ctx, const string &key,
const string &value);
class const_iterator : public std::iterator<std::bidirectional_iterator_tag,
const grpc_mdelem> {

@ -388,35 +388,29 @@ namespace Grpc.Core.Internal
private void Initialize(CompletionQueueSafeHandle cq)
{
using (Profilers.ForCurrentThread().NewScope("AsyncCall.Initialize"))
{
var call = CreateNativeCall(cq);
var call = CreateNativeCall(cq);
details.Channel.AddCallReference(this);
InitializeInternal(call);
RegisterCancellationCallback();
}
details.Channel.AddCallReference(this);
InitializeInternal(call);
RegisterCancellationCallback();
}
private INativeCall CreateNativeCall(CompletionQueueSafeHandle cq)
{
using (Profilers.ForCurrentThread().NewScope("AsyncCall.CreateNativeCall"))
{
if (injectedNativeCall != null)
{
return injectedNativeCall; // allows injecting a mock INativeCall in tests.
}
if (injectedNativeCall != null)
{
return injectedNativeCall; // allows injecting a mock INativeCall in tests.
}
var parentCall = details.Options.PropagationToken != null ? details.Options.PropagationToken.ParentCall : CallSafeHandle.NullInstance;
var parentCall = details.Options.PropagationToken != null ? details.Options.PropagationToken.ParentCall : CallSafeHandle.NullInstance;
var credentials = details.Options.Credentials;
using (var nativeCredentials = credentials != null ? credentials.ToNativeCredentials() : null)
{
var result = details.Channel.Handle.CreateCall(
parentCall, ContextPropagationToken.DefaultMask, cq,
details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value), nativeCredentials);
return result;
}
var credentials = details.Options.Credentials;
using (var nativeCredentials = credentials != null ? credentials.ToNativeCredentials() : null)
{
var result = details.Channel.Handle.CreateCall(
parentCall, ContextPropagationToken.DefaultMask, cq,
details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value), nativeCredentials);
return result;
}
}
@ -456,47 +450,44 @@ namespace Grpc.Core.Internal
// NOTE: because this event is a result of batch containing GRPC_OP_RECV_STATUS_ON_CLIENT,
// success will be always set to true.
using (Profilers.ForCurrentThread().NewScope("AsyncCall.HandleUnaryResponse"))
TaskCompletionSource<object> delayedStreamingWriteTcs = null;
TResponse msg = default(TResponse);
var deserializeException = TryDeserialize(receivedMessage, out msg);
lock (myLock)
{
TaskCompletionSource<object> delayedStreamingWriteTcs = null;
TResponse msg = default(TResponse);
var deserializeException = TryDeserialize(receivedMessage, out msg);
finished = true;
lock (myLock)
if (deserializeException != null && receivedStatus.Status.StatusCode == StatusCode.OK)
{
finished = true;
if (deserializeException != null && receivedStatus.Status.StatusCode == StatusCode.OK)
{
receivedStatus = new ClientSideStatus(DeserializeResponseFailureStatus, receivedStatus.Trailers);
}
finishedStatus = receivedStatus;
if (isStreamingWriteCompletionDelayed)
{
delayedStreamingWriteTcs = streamingWriteTcs;
streamingWriteTcs = null;
}
ReleaseResourcesIfPossible();
receivedStatus = new ClientSideStatus(DeserializeResponseFailureStatus, receivedStatus.Trailers);
}
finishedStatus = receivedStatus;
responseHeadersTcs.SetResult(responseHeaders);
if (delayedStreamingWriteTcs != null)
if (isStreamingWriteCompletionDelayed)
{
delayedStreamingWriteTcs.SetException(GetRpcExceptionClientOnly());
delayedStreamingWriteTcs = streamingWriteTcs;
streamingWriteTcs = null;
}
var status = receivedStatus.Status;
if (status.StatusCode != StatusCode.OK)
{
unaryResponseTcs.SetException(new RpcException(status));
return;
}
ReleaseResourcesIfPossible();
}
responseHeadersTcs.SetResult(responseHeaders);
unaryResponseTcs.SetResult(msg);
if (delayedStreamingWriteTcs != null)
{
delayedStreamingWriteTcs.SetException(GetRpcExceptionClientOnly());
}
var status = receivedStatus.Status;
if (status.StatusCode != StatusCode.OK)
{
unaryResponseTcs.SetException(new RpcException(status));
return;
}
unaryResponseTcs.SetResult(msg);
}
/// <summary>

@ -181,19 +181,16 @@ namespace Grpc.Core.Internal
/// </summary>
protected bool ReleaseResourcesIfPossible()
{
using (Profilers.ForCurrentThread().NewScope("AsyncCallBase.ReleaseResourcesIfPossible"))
if (!disposed && call != null)
{
if (!disposed && call != null)
bool noMoreSendCompletions = streamingWriteTcs == null && (halfcloseRequested || cancelRequested || finished);
if (noMoreSendCompletions && readingDone && finished)
{
bool noMoreSendCompletions = streamingWriteTcs == null && (halfcloseRequested || cancelRequested || finished);
if (noMoreSendCompletions && readingDone && finished)
{
ReleaseResources();
return true;
}
ReleaseResources();
return true;
}
return false;
}
return false;
}
protected abstract bool IsClient
@ -229,28 +226,20 @@ namespace Grpc.Core.Internal
protected byte[] UnsafeSerialize(TWrite msg)
{
using (Profilers.ForCurrentThread().NewScope("AsyncCallBase.UnsafeSerialize"))
{
return serializer(msg);
}
return serializer(msg);
}
protected Exception TryDeserialize(byte[] payload, out TRead msg)
{
using (Profilers.ForCurrentThread().NewScope("AsyncCallBase.TryDeserialize"))
try
{
try
{
msg = deserializer(payload);
return null;
}
catch (Exception e)
{
msg = default(TRead);
return e;
}
msg = deserializer(payload);
return null;
}
catch (Exception e)
{
msg = default(TRead);
return e;
}
}

@ -76,11 +76,8 @@ namespace Grpc.Core.Internal
public void StartUnary(BatchContextSafeHandle ctx, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
{
using (Profilers.ForCurrentThread().NewScope("CallSafeHandle.StartUnary"))
{
Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags)
.CheckOk();
}
Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags)
.CheckOk();
}
public void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray)

@ -65,16 +65,13 @@ namespace Grpc.Core.Internal
public CallSafeHandle CreateCall(CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline, CallCredentialsSafeHandle credentials)
{
using (Profilers.ForCurrentThread().NewScope("ChannelSafeHandle.CreateCall"))
var result = Native.grpcsharp_channel_create_call(this, parentCall, propagationMask, cq, method, host, deadline);
if (credentials != null)
{
var result = Native.grpcsharp_channel_create_call(this, parentCall, propagationMask, cq, method, host, deadline);
if (credentials != null)
{
result.SetCredentials(credentials);
}
result.Initialize(cq);
return result;
result.SetCredentials(credentials);
}
result.Initialize(cq);
return result;
}
public ChannelState CheckConnectivityState(bool tryToConnect)

@ -70,10 +70,7 @@ namespace Grpc.Core.Internal
public CompletionQueueEvent Pluck(IntPtr tag)
{
using (Profilers.ForCurrentThread().NewScope("CompletionQueueSafeHandle.Pluck"))
{
return Native.grpcsharp_completion_queue_pluck(this, tag);
}
return Native.grpcsharp_completion_queue_pluck(this, tag);
}
/// <summary>

@ -37,6 +37,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core.Logging;
using Grpc.Core.Profiling;
using Grpc.Core.Utils;
namespace Grpc.Core.Internal
@ -54,6 +55,8 @@ namespace Grpc.Core.Internal
readonly int poolSize;
readonly int completionQueueCount;
readonly List<BasicProfiler> threadProfilers = new List<BasicProfiler>(); // profilers assigned to threadpool threads
bool stopRequested;
IReadOnlyCollection<CompletionQueueSafeHandle> completionQueues;
@ -82,7 +85,8 @@ namespace Grpc.Core.Internal
for (int i = 0; i < poolSize; i++)
{
threads.Add(CreateAndStartThread(i));
var optionalProfiler = i < threadProfilers.Count ? threadProfilers[i] : null;
threads.Add(CreateAndStartThread(i, optionalProfiler));
}
}
}
@ -111,6 +115,11 @@ namespace Grpc.Core.Internal
{
cq.Dispose();
}
for (int i = 0; i < threadProfilers.Count; i++)
{
threadProfilers[i].Dump(string.Format("grpc_trace_thread_{0}.txt", i));
}
});
}
@ -137,12 +146,12 @@ namespace Grpc.Core.Internal
}
}
private Thread CreateAndStartThread(int threadIndex)
private Thread CreateAndStartThread(int threadIndex, IProfiler optionalProfiler)
{
var cqIndex = threadIndex % completionQueues.Count;
var cq = completionQueues.ElementAt(cqIndex);
var thread = new Thread(new ThreadStart(() => RunHandlerLoop(cq)));
var thread = new Thread(new ThreadStart(() => RunHandlerLoop(cq, optionalProfiler)));
thread.IsBackground = true;
thread.Name = string.Format("grpc {0} (cq {1})", threadIndex, cqIndex);
thread.Start();
@ -153,8 +162,13 @@ namespace Grpc.Core.Internal
/// <summary>
/// Body of the polling thread.
/// </summary>
private void RunHandlerLoop(CompletionQueueSafeHandle cq)
private void RunHandlerLoop(CompletionQueueSafeHandle cq, IProfiler optionalProfiler)
{
if (optionalProfiler != null)
{
Profilers.SetForCurrentThread(optionalProfiler);
}
CompletionQueueEvent ev;
do
{

@ -48,22 +48,19 @@ namespace Grpc.Core.Internal
public static MetadataArraySafeHandle Create(Metadata metadata)
{
using (Profilers.ForCurrentThread().NewScope("MetadataArraySafeHandle.Create"))
if (metadata.Count == 0)
{
if (metadata.Count == 0)
{
return new MetadataArraySafeHandle();
}
return new MetadataArraySafeHandle();
}
// TODO(jtattermusch): we might wanna check that the metadata is readonly
var metadataArray = Native.grpcsharp_metadata_array_create(new UIntPtr((ulong)metadata.Count));
for (int i = 0; i < metadata.Count; i++)
{
var valueBytes = metadata[i].GetSerializedValueUnsafe();
Native.grpcsharp_metadata_array_add(metadataArray, metadata[i].Key, valueBytes, new UIntPtr((ulong)valueBytes.Length));
}
return metadataArray;
// TODO(jtattermusch): we might wanna check that the metadata is readonly
var metadataArray = Native.grpcsharp_metadata_array_create(new UIntPtr((ulong)metadata.Count));
for (int i = 0; i < metadata.Count; i++)
{
var valueBytes = metadata[i].GetSerializedValueUnsafe();
Native.grpcsharp_metadata_array_add(metadataArray, metadata[i].Key, valueBytes, new UIntPtr((ulong)valueBytes.Length));
}
return metadataArray;
}
/// <summary>

@ -80,7 +80,7 @@ namespace Grpc.Core.Profiling
ProfilerEntry[] entries;
int count;
public BasicProfiler() : this(1024*1024)
public BasicProfiler() : this(20*1024*1024)
{
}

@ -103,6 +103,34 @@ namespace Grpc.IntegrationTesting
client.UnaryCall(new SimpleRequest { }, new CallOptions(credentials: callCredentials));
}
[Test]
public void MetadataCredentials_InterceptorLeavesMetadataEmpty()
{
var channelCredentials = ChannelCredentials.Create(TestCredentials.CreateSslCredentials(),
CallCredentials.FromInterceptor(new AsyncAuthInterceptor((context, metadata) => TaskUtils.CompletedTask)));
channel = new Channel(Host, server.Ports.Single().BoundPort, channelCredentials, options);
client = new TestService.TestServiceClient(channel);
var ex = Assert.Throws<RpcException>(() => client.UnaryCall(new SimpleRequest { }));
// StatusCode.Unknown as the server-side handler throws an exception after not receiving the authorization header.
Assert.AreEqual(StatusCode.Unknown, ex.Status.StatusCode);
}
[Test]
public void MetadataCredentials_InterceptorThrows()
{
var callCredentials = CallCredentials.FromInterceptor(new AsyncAuthInterceptor((context, metadata) =>
{
throw new Exception("Auth interceptor throws");
}));
var channelCredentials = ChannelCredentials.Create(TestCredentials.CreateSslCredentials(), callCredentials);
channel = new Channel(Host, server.Ports.Single().BoundPort, channelCredentials, options);
client = new TestService.TestServiceClient(channel);
var ex = Assert.Throws<RpcException>(() => client.UnaryCall(new SimpleRequest { }));
Assert.AreEqual(StatusCode.Unauthenticated, ex.Status.StatusCode);
}
private class FakeTestService : TestService.TestServiceBase
{
public override Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)

@ -991,7 +991,11 @@ GPR_EXPORT void GPR_CALLTYPE grpcsharp_metadata_credentials_notify_from_plugin(
grpc_credentials_plugin_metadata_cb cb,
void *user_data, grpc_metadata_array *metadata,
grpc_status_code status, const char *error_details) {
cb(user_data, metadata->metadata, metadata->count, status, error_details);
if (metadata) {
cb(user_data, metadata->metadata, metadata->count, status, error_details);
} else {
cb(user_data, NULL, 0, status, error_details);
}
}
typedef void(GPR_CALLTYPE *grpcsharp_metadata_interceptor_func)(

@ -141,8 +141,14 @@ exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service,
binaryAsBase64 = options.binaryAsBase64;
longsAsStrings = options.longsAsStrings;
}
return _.fromPairs(_.map(service.children, function(method) {
return [_.camelCase(method.name), {
/* This slightly awkward construction is used to make sure we only use
lodash@3.10.1-compatible functions. A previous version used
_.fromPairs, which would be cleaner, but was introduced in lodash
version 4 */
return _.zipObject(_.map(service.children, function(method) {
return _.camelCase(method.name);
}), _.map(service.children, function(method) {
return {
path: prefix + method.name,
requestStream: method.requestStream,
responseStream: method.responseStream,
@ -150,11 +156,11 @@ exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service,
responseType: method.resolvedResponseType,
requestSerialize: serializeCls(method.resolvedRequestType.build()),
requestDeserialize: deserializeCls(method.resolvedRequestType.build(),
binaryAsBase64, longsAsStrings),
binaryAsBase64, longsAsStrings),
responseSerialize: serializeCls(method.resolvedResponseType.build()),
responseDeserialize: deserializeCls(method.resolvedResponseType.build(),
binaryAsBase64, longsAsStrings)
}];
binaryAsBase64, longsAsStrings)
};
}));
};

@ -99,7 +99,6 @@ CORE_SOURCE_FILES = [
'src/core/lib/iomgr/endpoint_pair_windows.c',
'src/core/lib/iomgr/error.c',
'src/core/lib/iomgr/ev_epoll_linux.c',
'src/core/lib/iomgr/ev_poll_and_epoll_posix.c',
'src/core/lib/iomgr/ev_poll_posix.c',
'src/core/lib/iomgr/ev_posix.c',
'src/core/lib/iomgr/exec_ctx.c',
@ -121,6 +120,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/iomgr/resolve_address_windows.c',
'src/core/lib/iomgr/resource_quota.c',
'src/core/lib/iomgr/sockaddr_utils.c',
'src/core/lib/iomgr/socket_mutator.c',
'src/core/lib/iomgr/socket_utils_common_posix.c',
'src/core/lib/iomgr/socket_utils_linux.c',
'src/core/lib/iomgr/socket_utils_posix.c',

@ -130,8 +130,11 @@ grpc_server_cancel_all_calls_type grpc_server_cancel_all_calls_import;
grpc_server_destroy_type grpc_server_destroy_import;
grpc_tracer_set_enabled_type grpc_tracer_set_enabled_import;
grpc_header_key_is_legal_type grpc_header_key_is_legal_import;
grpc_header_key_slice_is_legal_type grpc_header_key_slice_is_legal_import;
grpc_header_nonbin_value_is_legal_type grpc_header_nonbin_value_is_legal_import;
grpc_header_nonbin_value_slice_is_legal_type grpc_header_nonbin_value_slice_is_legal_import;
grpc_is_binary_header_type grpc_is_binary_header_import;
grpc_slice_is_binary_header_type grpc_slice_is_binary_header_import;
grpc_call_error_to_string_type grpc_call_error_to_string_import;
grpc_resource_quota_create_type grpc_resource_quota_create_import;
grpc_resource_quota_ref_type grpc_resource_quota_ref_import;
@ -192,7 +195,9 @@ grpc_slice_cmp_type grpc_slice_cmp_import;
grpc_slice_str_cmp_type grpc_slice_str_cmp_import;
grpc_slice_buf_cmp_type grpc_slice_buf_cmp_import;
grpc_slice_buf_start_eq_type grpc_slice_buf_start_eq_import;
grpc_slice_rchr_type grpc_slice_rchr_import;
grpc_slice_hash_type grpc_slice_hash_import;
grpc_slice_is_equivalent_type grpc_slice_is_equivalent_import;
grpc_slice_buffer_init_type grpc_slice_buffer_init_import;
grpc_slice_buffer_destroy_type grpc_slice_buffer_destroy_import;
grpc_slice_buffer_add_type grpc_slice_buffer_add_import;
@ -409,8 +414,11 @@ void grpc_rb_load_imports(HMODULE library) {
grpc_server_destroy_import = (grpc_server_destroy_type) GetProcAddress(library, "grpc_server_destroy");
grpc_tracer_set_enabled_import = (grpc_tracer_set_enabled_type) GetProcAddress(library, "grpc_tracer_set_enabled");
grpc_header_key_is_legal_import = (grpc_header_key_is_legal_type) GetProcAddress(library, "grpc_header_key_is_legal");
grpc_header_key_slice_is_legal_import = (grpc_header_key_slice_is_legal_type) GetProcAddress(library, "grpc_header_key_slice_is_legal");
grpc_header_nonbin_value_is_legal_import = (grpc_header_nonbin_value_is_legal_type) GetProcAddress(library, "grpc_header_nonbin_value_is_legal");
grpc_header_nonbin_value_slice_is_legal_import = (grpc_header_nonbin_value_slice_is_legal_type) GetProcAddress(library, "grpc_header_nonbin_value_slice_is_legal");
grpc_is_binary_header_import = (grpc_is_binary_header_type) GetProcAddress(library, "grpc_is_binary_header");
grpc_slice_is_binary_header_import = (grpc_slice_is_binary_header_type) GetProcAddress(library, "grpc_slice_is_binary_header");
grpc_call_error_to_string_import = (grpc_call_error_to_string_type) GetProcAddress(library, "grpc_call_error_to_string");
grpc_resource_quota_create_import = (grpc_resource_quota_create_type) GetProcAddress(library, "grpc_resource_quota_create");
grpc_resource_quota_ref_import = (grpc_resource_quota_ref_type) GetProcAddress(library, "grpc_resource_quota_ref");
@ -471,7 +479,9 @@ void grpc_rb_load_imports(HMODULE library) {
grpc_slice_str_cmp_import = (grpc_slice_str_cmp_type) GetProcAddress(library, "grpc_slice_str_cmp");
grpc_slice_buf_cmp_import = (grpc_slice_buf_cmp_type) GetProcAddress(library, "grpc_slice_buf_cmp");
grpc_slice_buf_start_eq_import = (grpc_slice_buf_start_eq_type) GetProcAddress(library, "grpc_slice_buf_start_eq");
grpc_slice_rchr_import = (grpc_slice_rchr_type) GetProcAddress(library, "grpc_slice_rchr");
grpc_slice_hash_import = (grpc_slice_hash_type) GetProcAddress(library, "grpc_slice_hash");
grpc_slice_is_equivalent_import = (grpc_slice_is_equivalent_type) GetProcAddress(library, "grpc_slice_is_equivalent");
grpc_slice_buffer_init_import = (grpc_slice_buffer_init_type) GetProcAddress(library, "grpc_slice_buffer_init");
grpc_slice_buffer_destroy_import = (grpc_slice_buffer_destroy_type) GetProcAddress(library, "grpc_slice_buffer_destroy");
grpc_slice_buffer_add_import = (grpc_slice_buffer_add_type) GetProcAddress(library, "grpc_slice_buffer_add");

@ -254,7 +254,7 @@ extern grpc_channel_check_connectivity_state_type grpc_channel_check_connectivit
typedef void(*grpc_channel_watch_connectivity_state_type)(grpc_channel *channel, grpc_connectivity_state last_observed_state, gpr_timespec deadline, grpc_completion_queue *cq, void *tag);
extern grpc_channel_watch_connectivity_state_type grpc_channel_watch_connectivity_state_import;
#define grpc_channel_watch_connectivity_state grpc_channel_watch_connectivity_state_import
typedef grpc_call *(*grpc_channel_create_call_type)(grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, const char *method, const char *host, gpr_timespec deadline, void *reserved);
typedef grpc_call *(*grpc_channel_create_call_type)(grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, grpc_slice method, const grpc_slice *host, gpr_timespec deadline, void *reserved);
extern grpc_channel_create_call_type grpc_channel_create_call_import;
#define grpc_channel_create_call grpc_channel_create_call_import
typedef void(*grpc_channel_ping_type)(grpc_channel *channel, grpc_completion_queue *cq, void *tag, void *reserved);
@ -341,12 +341,21 @@ extern grpc_tracer_set_enabled_type grpc_tracer_set_enabled_import;
typedef int(*grpc_header_key_is_legal_type)(const char *key, size_t length);
extern grpc_header_key_is_legal_type grpc_header_key_is_legal_import;
#define grpc_header_key_is_legal grpc_header_key_is_legal_import
typedef int(*grpc_header_key_slice_is_legal_type)(grpc_slice slice);
extern grpc_header_key_slice_is_legal_type grpc_header_key_slice_is_legal_import;
#define grpc_header_key_slice_is_legal grpc_header_key_slice_is_legal_import
typedef int(*grpc_header_nonbin_value_is_legal_type)(const char *value, size_t length);
extern grpc_header_nonbin_value_is_legal_type grpc_header_nonbin_value_is_legal_import;
#define grpc_header_nonbin_value_is_legal grpc_header_nonbin_value_is_legal_import
typedef int(*grpc_header_nonbin_value_slice_is_legal_type)(grpc_slice slice);
extern grpc_header_nonbin_value_slice_is_legal_type grpc_header_nonbin_value_slice_is_legal_import;
#define grpc_header_nonbin_value_slice_is_legal grpc_header_nonbin_value_slice_is_legal_import
typedef int(*grpc_is_binary_header_type)(const char *key, size_t length);
extern grpc_is_binary_header_type grpc_is_binary_header_import;
#define grpc_is_binary_header grpc_is_binary_header_import
typedef int(*grpc_slice_is_binary_header_type)(grpc_slice slice);
extern grpc_slice_is_binary_header_type grpc_slice_is_binary_header_import;
#define grpc_slice_is_binary_header grpc_slice_is_binary_header_import
typedef const char *(*grpc_call_error_to_string_type)(grpc_call_error error);
extern grpc_call_error_to_string_type grpc_call_error_to_string_import;
#define grpc_call_error_to_string grpc_call_error_to_string_import
@ -527,9 +536,15 @@ extern grpc_slice_buf_cmp_type grpc_slice_buf_cmp_import;
typedef int(*grpc_slice_buf_start_eq_type)(grpc_slice a, const void *b, size_t blen);
extern grpc_slice_buf_start_eq_type grpc_slice_buf_start_eq_import;
#define grpc_slice_buf_start_eq grpc_slice_buf_start_eq_import
typedef int(*grpc_slice_rchr_type)(grpc_slice s, char c);
extern grpc_slice_rchr_type grpc_slice_rchr_import;
#define grpc_slice_rchr grpc_slice_rchr_import
typedef uint32_t(*grpc_slice_hash_type)(grpc_slice s);
extern grpc_slice_hash_type grpc_slice_hash_import;
#define grpc_slice_hash grpc_slice_hash_import
typedef int(*grpc_slice_is_equivalent_type)(grpc_slice a, grpc_slice b);
extern grpc_slice_is_equivalent_type grpc_slice_is_equivalent_import;
#define grpc_slice_is_equivalent grpc_slice_is_equivalent_import
typedef void(*grpc_slice_buffer_init_type)(grpc_slice_buffer *sb);
extern grpc_slice_buffer_init_type grpc_slice_buffer_init_import;
#define grpc_slice_buffer_init grpc_slice_buffer_init_import
@ -698,7 +713,7 @@ extern gpr_join_host_port_type gpr_join_host_port_import;
typedef int(*gpr_split_host_port_type)(const char *name, char **host, char **port);
extern gpr_split_host_port_type gpr_split_host_port_import;
#define gpr_split_host_port gpr_split_host_port_import
typedef void(*gpr_log_type)(const char *file, int line, gpr_log_severity severity, const char *format, ...) GPRC_PRINT_FORMAT_CHECK(4, 5);
typedef void(*gpr_log_type)(const char *file, int line, gpr_log_severity severity, const char *format, ...) GPR_PRINT_FORMAT_CHECK(4, 5);
extern gpr_log_type gpr_log_import;
#define gpr_log gpr_log_import
typedef void(*gpr_log_message_type)(const char *file, int line, gpr_log_severity severity, const char *message);
@ -719,7 +734,7 @@ extern gpr_format_message_type gpr_format_message_import;
typedef char *(*gpr_strdup_type)(const char *src);
extern gpr_strdup_type gpr_strdup_import;
#define gpr_strdup gpr_strdup_import
typedef int(*gpr_asprintf_type)(char **strp, const char *format, ...) GPRC_PRINT_FORMAT_CHECK(2, 3);
typedef int(*gpr_asprintf_type)(char **strp, const char *format, ...) GPR_PRINT_FORMAT_CHECK(2, 3);
extern gpr_asprintf_type gpr_asprintf_import;
#define gpr_asprintf gpr_asprintf_import
typedef const char *(*gpr_subprocess_binary_extension_type)();

@ -141,12 +141,26 @@ static void test_compression_algorithm_states(void) {
grpc_exec_ctx_finish(&exec_ctx);
}
static void test_set_socket_mutator(void) {
grpc_channel_args *ch_args;
grpc_socket_mutator mutator;
grpc_socket_mutator_init(&mutator, NULL);
ch_args = grpc_channel_args_set_socket_mutator(NULL, &mutator);
GPR_ASSERT(ch_args->num_args == 1);
GPR_ASSERT(strcmp(ch_args->args[0].key, GRPC_ARG_SOCKET_MUTATOR) == 0);
GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_POINTER);
grpc_channel_args_destroy(ch_args);
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
grpc_init();
test_create();
test_set_compression_algorithm();
test_compression_algorithm_states();
test_set_socket_mutator();
grpc_shutdown();
return 0;
}

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

Loading…
Cancel
Save