Merge branch 'master' of github.com:grpc/grpc into super_detect_flakes

pull/13226/head
David Garcia Quintas 7 years ago
commit eb81761f64
  1. 1
      .github/CODEOWNERS
  2. 4
      BUILD
  3. 202
      CMakeLists.txt
  4. 200
      Makefile
  5. 18
      README.md
  6. 4
      bazel/grpc_build_system.bzl
  7. 44
      build.yaml
  8. 8
      doc/PROTOCOL-HTTP2.md
  9. 11
      examples/python/helloworld/greeter_client.py
  10. 26
      examples/python/helloworld/greeter_server.py
  11. 68
      examples/python/interceptors/default_value/default_value_client_interceptor.py
  12. 38
      examples/python/interceptors/default_value/greeter_client.py
  13. 134
      examples/python/interceptors/default_value/helloworld_pb2.py
  14. 46
      examples/python/interceptors/default_value/helloworld_pb2_grpc.py
  15. 55
      examples/python/interceptors/headers/generic_client_interceptor.py
  16. 36
      examples/python/interceptors/headers/greeter_client.py
  17. 52
      examples/python/interceptors/headers/greeter_server.py
  18. 42
      examples/python/interceptors/headers/header_manipulator_client_interceptor.py
  19. 134
      examples/python/interceptors/headers/helloworld_pb2.py
  20. 46
      examples/python/interceptors/headers/helloworld_pb2_grpc.py
  21. 39
      examples/python/interceptors/headers/request_header_validator_interceptor.py
  22. 130
      examples/python/multiplex/multiplex_client.py
  23. 181
      examples/python/multiplex/multiplex_server.py
  24. 23
      examples/python/multiplex/route_guide_resources.py
  25. 23
      examples/python/multiplex/run_codegen.py
  26. 113
      examples/python/route_guide/route_guide_client.py
  27. 23
      examples/python/route_guide/route_guide_resources.py
  28. 175
      examples/python/route_guide/route_guide_server.py
  29. 12
      examples/python/route_guide/run_codegen.py
  30. 4
      gRPC-Core.podspec
  31. 17
      include/grpc++/generic/async_generic_service.h
  32. 7
      include/grpc++/impl/codegen/async_unary_call.h
  33. 15
      include/grpc++/impl/codegen/call.h
  34. 14
      include/grpc++/impl/codegen/client_context.h
  35. 2
      include/grpc++/support/channel_arguments.h
  36. 2
      include/grpc/impl/codegen/grpc_types.h
  37. 2
      include/grpc/impl/codegen/port_platform.h
  38. 2
      include/grpc/impl/codegen/slice.h
  39. 3
      include/grpc/slice_buffer.h
  40. 6
      include/grpc/support/log.h
  41. 5
      include/grpc/support/thd.h
  42. 6
      include/grpc/support/tls.h
  43. 5
      include/grpc/support/tls_gcc.h
  44. 9
      include/grpc/support/tls_msvc.h
  45. 9
      include/grpc/support/tls_pthread.h
  46. 7
      src/compiler/csharp_generator.cc
  47. 51
      src/core/ext/filters/client_channel/backup_poller.cc
  48. 4
      src/core/ext/filters/client_channel/backup_poller.h
  49. 52
      src/core/ext/filters/client_channel/channel_connectivity.cc
  50. 415
      src/core/ext/filters/client_channel/client_channel.cc
  51. 8
      src/core/ext/filters/client_channel/client_channel.h
  52. 23
      src/core/ext/filters/client_channel/client_channel_factory.cc
  53. 19
      src/core/ext/filters/client_channel/client_channel_factory.h
  54. 13
      src/core/ext/filters/client_channel/client_channel_plugin.cc
  55. 13
      src/core/ext/filters/client_channel/connector.cc
  56. 14
      src/core/ext/filters/client_channel/connector.h
  57. 84
      src/core/ext/filters/client_channel/http_connect_handshaker.cc
  58. 18
      src/core/ext/filters/client_channel/http_proxy.cc
  59. 82
      src/core/ext/filters/client_channel/lb_policy.cc
  60. 84
      src/core/ext/filters/client_channel/lb_policy.h
  61. 27
      src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
  62. 491
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  63. 6
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
  64. 4
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
  65. 10
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
  66. 9
      src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
  67. 1
      src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
  68. 7
      src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
  69. 21
      src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
  70. 194
      src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
  71. 163
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
  72. 54
      src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
  73. 18
      src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
  74. 15
      src/core/ext/filters/client_channel/lb_policy_factory.cc
  75. 11
      src/core/ext/filters/client_channel/lb_policy_factory.h
  76. 4
      src/core/ext/filters/client_channel/lb_policy_registry.cc
  77. 2
      src/core/ext/filters/client_channel/lb_policy_registry.h
  78. 14
      src/core/ext/filters/client_channel/proxy_mapper.cc
  79. 14
      src/core/ext/filters/client_channel/proxy_mapper.h
  80. 30
      src/core/ext/filters/client_channel/proxy_mapper_registry.cc
  81. 6
      src/core/ext/filters/client_channel/proxy_mapper_registry.h
  82. 24
      src/core/ext/filters/client_channel/resolver.cc
  83. 31
      src/core/ext/filters/client_channel/resolver.h
  84. 94
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  85. 6
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
  86. 52
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
  87. 70
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
  88. 12
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
  89. 20
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
  90. 90
      src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
  91. 52
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
  92. 2
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
  93. 55
      src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
  94. 5
      src/core/ext/filters/client_channel/resolver_factory.cc
  95. 6
      src/core/ext/filters/client_channel/resolver_factory.h
  96. 27
      src/core/ext/filters/client_channel/resolver_registry.cc
  97. 7
      src/core/ext/filters/client_channel/resolver_registry.h
  98. 245
      src/core/ext/filters/client_channel/subchannel.cc
  99. 78
      src/core/ext/filters/client_channel/subchannel.h
  100. 63
      src/core/ext/filters/client_channel/subchannel_index.cc
  101. Some files were not shown because too many files have changed in this diff Show More

@ -4,3 +4,4 @@
/**/OWNERS @markdroth @nicolasnoble @ctiller
/bazel/** @nicolasnoble @dgquintas @ctiller
/src/core/ext/filters/client_channel/** @markdroth @dgquintas @ctiller
/tools/run_tests/performance/** @ncteisen @matt-kwong @ctiller

@ -44,11 +44,11 @@ config_setting(
)
# This should be updated along with build.yaml
g_stands_for = "generous"
g_stands_for = "glossy"
core_version = "5.0.0-dev"
version = "1.8.0-dev"
version = "1.9.0-dev"
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",

@ -358,12 +358,12 @@ add_custom_target(plugins
add_custom_target(tools_c
DEPENDS
check_epollexclusive
gen_hpack_tables
gen_legal_metadata_characters
gen_percent_encoding_tables
grpc_create_jwt
grpc_print_google_default_creds_token
grpc_verify_jwt
gen_hpack_tables
gen_legal_metadata_characters
gen_percent_encoding_tables
)
add_custom_target(tools_cxx
@ -6021,104 +6021,6 @@ target_link_libraries(fling_test
endif()
endif (gRPC_BUILD_TESTS)
add_executable(gen_hpack_tables
tools/codegen/core/gen_hpack_tables.c
)
target_include_directories(gen_hpack_tables
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CARES_INCLUDE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
)
target_link_libraries(gen_hpack_tables
${_gRPC_ALLTARGETS_LIBRARIES}
gpr
grpc
)
if (gRPC_INSTALL)
install(TARGETS gen_hpack_tables EXPORT gRPCTargets
RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
)
endif()
add_executable(gen_legal_metadata_characters
tools/codegen/core/gen_legal_metadata_characters.c
)
target_include_directories(gen_legal_metadata_characters
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CARES_INCLUDE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
)
target_link_libraries(gen_legal_metadata_characters
${_gRPC_ALLTARGETS_LIBRARIES}
)
if (gRPC_INSTALL)
install(TARGETS gen_legal_metadata_characters EXPORT gRPCTargets
RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
)
endif()
add_executable(gen_percent_encoding_tables
tools/codegen/core/gen_percent_encoding_tables.c
)
target_include_directories(gen_percent_encoding_tables
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CARES_INCLUDE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
)
target_link_libraries(gen_percent_encoding_tables
${_gRPC_ALLTARGETS_LIBRARIES}
)
if (gRPC_INSTALL)
install(TARGETS gen_percent_encoding_tables EXPORT gRPCTargets
RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
)
endif()
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@ -12908,6 +12810,104 @@ target_link_libraries(public_headers_must_be_c89
)
endif (gRPC_BUILD_TESTS)
add_executable(gen_hpack_tables
tools/codegen/core/gen_hpack_tables.cc
)
target_include_directories(gen_hpack_tables
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CARES_INCLUDE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
)
target_link_libraries(gen_hpack_tables
${_gRPC_ALLTARGETS_LIBRARIES}
gpr
grpc
)
if (gRPC_INSTALL)
install(TARGETS gen_hpack_tables EXPORT gRPCTargets
RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
)
endif()
add_executable(gen_legal_metadata_characters
tools/codegen/core/gen_legal_metadata_characters.cc
)
target_include_directories(gen_legal_metadata_characters
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CARES_INCLUDE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
)
target_link_libraries(gen_legal_metadata_characters
${_gRPC_ALLTARGETS_LIBRARIES}
)
if (gRPC_INSTALL)
install(TARGETS gen_legal_metadata_characters EXPORT gRPCTargets
RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
)
endif()
add_executable(gen_percent_encoding_tables
tools/codegen/core/gen_percent_encoding_tables.cc
)
target_include_directories(gen_percent_encoding_tables
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CARES_INCLUDE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
)
target_link_libraries(gen_percent_encoding_tables
${_gRPC_ALLTARGETS_LIBRARIES}
)
if (gRPC_INSTALL)
install(TARGETS gen_percent_encoding_tables EXPORT gRPCTargets
RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
)
endif()
if (gRPC_BUILD_TESTS)
add_executable(badreq_bad_client_test

@ -980,9 +980,6 @@ fling_client: $(BINDIR)/$(CONFIG)/fling_client
fling_server: $(BINDIR)/$(CONFIG)/fling_server
fling_stream_test: $(BINDIR)/$(CONFIG)/fling_stream_test
fling_test: $(BINDIR)/$(CONFIG)/fling_test
gen_hpack_tables: $(BINDIR)/$(CONFIG)/gen_hpack_tables
gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters
gen_percent_encoding_tables: $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables
goaway_server_test: $(BINDIR)/$(CONFIG)/goaway_server_test
gpr_avl_test: $(BINDIR)/$(CONFIG)/gpr_avl_test
gpr_cmdline_test: $(BINDIR)/$(CONFIG)/gpr_cmdline_test
@ -1185,6 +1182,9 @@ thread_stress_test: $(BINDIR)/$(CONFIG)/thread_stress_test
transport_pid_controller_test: $(BINDIR)/$(CONFIG)/transport_pid_controller_test
writes_per_rpc_test: $(BINDIR)/$(CONFIG)/writes_per_rpc_test
public_headers_must_be_c89: $(BINDIR)/$(CONFIG)/public_headers_must_be_c89
gen_hpack_tables: $(BINDIR)/$(CONFIG)/gen_hpack_tables
gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters
gen_percent_encoding_tables: $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables
boringssl_aes_test: $(BINDIR)/$(CONFIG)/boringssl_aes_test
boringssl_asn1_test: $(BINDIR)/$(CONFIG)/boringssl_asn1_test
boringssl_base64_test: $(BINDIR)/$(CONFIG)/boringssl_base64_test
@ -2187,7 +2187,7 @@ test_python: static_c
tools: tools_c tools_cxx
tools_c: privatelibs_c $(BINDIR)/$(CONFIG)/check_epollexclusive $(BINDIR)/$(CONFIG)/gen_hpack_tables $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables $(BINDIR)/$(CONFIG)/grpc_create_jwt $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token $(BINDIR)/$(CONFIG)/grpc_verify_jwt
tools_c: privatelibs_c $(BINDIR)/$(CONFIG)/check_epollexclusive $(BINDIR)/$(CONFIG)/grpc_create_jwt $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token $(BINDIR)/$(CONFIG)/grpc_verify_jwt $(BINDIR)/$(CONFIG)/gen_hpack_tables $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables
tools_cxx: privatelibs_cxx
@ -9843,102 +9843,6 @@ endif
endif
GEN_HPACK_TABLES_SRC = \
tools/codegen/core/gen_hpack_tables.c \
GEN_HPACK_TABLES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GEN_HPACK_TABLES_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/gen_hpack_tables: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/gen_hpack_tables: $(GEN_HPACK_TABLES_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(GEN_HPACK_TABLES_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gen_hpack_tables
endif
$(OBJDIR)/$(CONFIG)/tools/codegen/core/gen_hpack_tables.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a
deps_gen_hpack_tables: $(GEN_HPACK_TABLES_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GEN_HPACK_TABLES_OBJS:.o=.dep)
endif
endif
GEN_LEGAL_METADATA_CHARACTERS_SRC = \
tools/codegen/core/gen_legal_metadata_characters.c \
GEN_LEGAL_METADATA_CHARACTERS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GEN_LEGAL_METADATA_CHARACTERS_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/gen_legal_metadata_characters: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/gen_legal_metadata_characters: $(GEN_LEGAL_METADATA_CHARACTERS_OBJS)
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(GEN_LEGAL_METADATA_CHARACTERS_OBJS) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters
endif
$(OBJDIR)/$(CONFIG)/tools/codegen/core/gen_legal_metadata_characters.o:
deps_gen_legal_metadata_characters: $(GEN_LEGAL_METADATA_CHARACTERS_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GEN_LEGAL_METADATA_CHARACTERS_OBJS:.o=.dep)
endif
endif
GEN_PERCENT_ENCODING_TABLES_SRC = \
tools/codegen/core/gen_percent_encoding_tables.c \
GEN_PERCENT_ENCODING_TABLES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GEN_PERCENT_ENCODING_TABLES_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/gen_percent_encoding_tables: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/gen_percent_encoding_tables: $(GEN_PERCENT_ENCODING_TABLES_OBJS)
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(GEN_PERCENT_ENCODING_TABLES_OBJS) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables
endif
$(OBJDIR)/$(CONFIG)/tools/codegen/core/gen_percent_encoding_tables.o:
deps_gen_percent_encoding_tables: $(GEN_PERCENT_ENCODING_TABLES_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GEN_PERCENT_ENCODING_TABLES_OBJS:.o=.dep)
endif
endif
GOAWAY_SERVER_TEST_SRC = \
test/core/end2end/goaway_server_test.cc \
@ -17431,6 +17335,102 @@ endif
endif
GEN_HPACK_TABLES_SRC = \
tools/codegen/core/gen_hpack_tables.cc \
GEN_HPACK_TABLES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GEN_HPACK_TABLES_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/gen_hpack_tables: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/gen_hpack_tables: $(GEN_HPACK_TABLES_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(GEN_HPACK_TABLES_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gen_hpack_tables
endif
$(OBJDIR)/$(CONFIG)/tools/codegen/core/gen_hpack_tables.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a
deps_gen_hpack_tables: $(GEN_HPACK_TABLES_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GEN_HPACK_TABLES_OBJS:.o=.dep)
endif
endif
GEN_LEGAL_METADATA_CHARACTERS_SRC = \
tools/codegen/core/gen_legal_metadata_characters.cc \
GEN_LEGAL_METADATA_CHARACTERS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GEN_LEGAL_METADATA_CHARACTERS_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/gen_legal_metadata_characters: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/gen_legal_metadata_characters: $(GEN_LEGAL_METADATA_CHARACTERS_OBJS)
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(GEN_LEGAL_METADATA_CHARACTERS_OBJS) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters
endif
$(OBJDIR)/$(CONFIG)/tools/codegen/core/gen_legal_metadata_characters.o:
deps_gen_legal_metadata_characters: $(GEN_LEGAL_METADATA_CHARACTERS_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GEN_LEGAL_METADATA_CHARACTERS_OBJS:.o=.dep)
endif
endif
GEN_PERCENT_ENCODING_TABLES_SRC = \
tools/codegen/core/gen_percent_encoding_tables.cc \
GEN_PERCENT_ENCODING_TABLES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GEN_PERCENT_ENCODING_TABLES_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/gen_percent_encoding_tables: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/gen_percent_encoding_tables: $(GEN_PERCENT_ENCODING_TABLES_OBJS)
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(GEN_PERCENT_ENCODING_TABLES_OBJS) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables
endif
$(OBJDIR)/$(CONFIG)/tools/codegen/core/gen_percent_encoding_tables.o:
deps_gen_percent_encoding_tables: $(GEN_PERCENT_ENCODING_TABLES_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GEN_PERCENT_ENCODING_TABLES_OBJS:.o=.dep)
endif
endif
# boringssl needs an override to ensure that it does not include
# system openssl headers regardless of other configuration

@ -25,15 +25,15 @@ This repository contains source code for gRPC libraries for multiple languages w
Libraries in different languages may be in different states of development. We are seeking contributions for all of these libraries.
| Language | Source | Status |
|-------------------------|-------------------------------------|---------|
| Shared C [core library] | [src/core](src/core) | 1.6 |
| C++ | [src/cpp](src/cpp) | 1.6 |
| Ruby | [src/ruby](src/ruby) | 1.6 |
| Python | [src/python](src/python) | 1.6 |
| PHP | [src/php](src/php) | 1.6 |
| C# | [src/csharp](src/csharp) | 1.6 |
| Objective-C | [src/objective-c](src/objective-c) | 1.6 |
| Language | Source |
|-------------------------|-------------------------------------|
| Shared C [core library] | [src/core](src/core) |
| C++ | [src/cpp](src/cpp) |
| Ruby | [src/ruby](src/ruby) |
| Python | [src/python](src/python) |
| PHP | [src/php](src/php) |
| C# | [src/csharp](src/csharp) |
| Objective-C | [src/objective-c](src/objective-c) |
Java source code is in the [grpc-java](http://github.com/grpc/grpc-java)
repository. Go source code is in the

@ -87,7 +87,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
'linkopts': ["-pthread"],
}
if uses_polling:
native.cc_binary(testonly=True, **args)
native.cc_test(testonly=True, tags=['manual'], **args)
for poller in POLLERS:
native.sh_test(
name = name + '@poller=' + poller,
@ -98,7 +98,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
args = [
poller,
'$(location %s)' % name
],
] + args['args'],
)
else:
native.cc_test(**args)

@ -2121,28 +2121,6 @@ targets:
- mac
- linux
- posix
- name: gen_hpack_tables
build: tool
language: c
src:
- tools/codegen/core/gen_hpack_tables.c
deps:
- gpr
- grpc
uses_polling: false
- name: gen_legal_metadata_characters
build: tool
language: c
src:
- tools/codegen/core/gen_legal_metadata_characters.c
deps: []
- name: gen_percent_encoding_tables
build: tool
language: c
src:
- tools/codegen/core/gen_percent_encoding_tables.c
deps: []
uses_polling: false
- name: goaway_server_test
cpu_cost: 0.1
build: test
@ -4846,6 +4824,28 @@ targets:
deps:
- grpc
- gpr
- name: gen_hpack_tables
build: tool
language: cc
src:
- tools/codegen/core/gen_hpack_tables.cc
deps:
- gpr
- grpc
uses_polling: false
- name: gen_legal_metadata_characters
build: tool
language: cc
src:
- tools/codegen/core/gen_legal_metadata_characters.cc
deps: []
- name: gen_percent_encoding_tables
build: tool
language: cc
src:
- tools/codegen/core/gen_percent_encoding_tables.cc
deps: []
uses_polling: false
vspackages:
- linkage: static
name: grpc.dependencies.zlib

@ -1,7 +1,7 @@
# gRPC over HTTP2
## Introduction
This document serves as a detailed description for an implementation of gRPC carried over HTTP2 draft 17 framing. It assumes familiarity with the HTTP2 specification.
This document serves as a detailed description for an implementation of gRPC carried over <a href="https://tools.ietf.org/html/rfc7540">HTTP2 framing</a>. It assumes familiarity with the HTTP2 specification.
## Protocol
Production rules are using <a href="http://tools.ietf.org/html/rfc5234">ABNF syntax</a>.
@ -24,7 +24,7 @@ Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames.
* **Call-Definition** → Method Scheme Path TE [Authority] [Timeout] Content-Type [Message-Type] [Message-Encoding] [Message-Accept-Encoding] [User-Agent]
* **Method** → ":method POST"
* **Scheme** → ":scheme " ("http" / "https")
* **Path** → ":path" "/" Service-Name "/" {_method name_}
* **Path** → ":path" "/" Service-Name "/" {_method name_} # But see note below.
* **Service-Name** → {_IDL-specific service name_}
* **Authority** → ":authority" {_virtual host name of authority_}
* **TE** → "te" "trailers" # Used to detect incompatible proxies
@ -170,6 +170,7 @@ HEADERS (flags = END_STREAM, END_HEADERS)
grpc-status = 0 # OK
trace-proto-bin = jher831yy13JHy3hc
```
#### User Agents
While the protocol does not require a user-agent to function it is recommended that clients provide a structured user-agent string that provides a basic description of the calling library, version & platform to facilitate issue diagnosis in heterogeneous environments. The following structure is recommended to library developers
@ -197,7 +198,7 @@ Unless explicitly defined to be, gRPC Calls are not assumed to be idempotent. S
#### HTTP2 Transport Mapping
##### Stream Identification
All GRPC calls need to specify an internal ID. We will use HTTP2 stream-ids as call identifiers in this scheme. NOTE: These ids are contextual to an open HTTP2 session and will not be unique within a given process that is handling more than one HTTP2 session nor can they be used as GUIDs.
All GRPC calls need to specify an internal ID. We will use HTTP2 stream-ids as call identifiers in this scheme. NOTE: These ids are contextual to an open HTTP2 session and will not be unique within a given process that is handling more than one HTTP2 session nor can they be used as GUIDs.
##### Data Frames
DATA frame boundaries have no relation to **Length-Prefixed-Message** boundaries and implementations should make no assumptions about their alignment.
@ -232,6 +233,7 @@ INADEQUATE_SECURITY| PERMISSION_DENIED … with additional detail indicating tha
The HTTP2 specification mandates the use of TLS 1.2 or higher when TLS is used with HTTP2. It also places some additional constraints on the allowed ciphers in deployments to avoid known-problems as well as requiring SNI support. It is also expected that HTTP2 will be used in conjunction with proprietary transport security mechanisms about which the specification can make no meaningful recommendations.
##### Connection Management
###### GOAWAY Frame
Sent by servers to clients to indicate that they will no longer accept any new streams on the associated connections. This frame includes the id of the last successfully accepted stream by the server. Clients should consider any stream initiated after the last successfully accepted stream as UNAVAILABLE and retry the call elsewhere. Clients are free to continue working with the already accepted streams until they complete or the connection is terminated.

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The Python implementation of the GRPC helloworld.Greeter client."""
from __future__ import print_function
@ -23,11 +22,11 @@ import helloworld_pb2_grpc
def run():
channel = grpc.insecure_channel('localhost:50051')
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
print("Greeter client received: " + response.message)
channel = grpc.insecure_channel('localhost:50051')
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
print("Greeter client received: " + response.message)
if __name__ == '__main__':
run()
run()

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The Python implementation of the GRPC helloworld.Greeter server."""
from concurrent import futures
@ -27,20 +26,21 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()
serve()

@ -0,0 +1,68 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Interceptor that adds headers to outgoing requests."""
import collections
import grpc
class _ConcreteValue(grpc.Future):
def __init__(self, result):
self._result = result
def cancel(self):
return False
def cancelled(self):
return False
def running(self):
return False
def done(self):
return True
def result(self, timeout=None):
return self._result
def exception(self, timeout=None):
return None
def traceback(self, timeout=None):
return None
def add_done_callback(self, fn):
fn(self._result)
class DefaultValueClientInterceptor(grpc.UnaryUnaryClientInterceptor,
grpc.StreamUnaryClientInterceptor):
def __init__(self, value):
self._default = _ConcreteValue(value)
def _intercept_call(self, continuation, client_call_details,
request_or_iterator):
response = continuation(client_call_details, request_or_iterator)
return self._default if response.exception() else response
def intercept_unary_unary(self, continuation, client_call_details, request):
return self._intercept_call(continuation, client_call_details, request)
def intercept_stream_unary(self, continuation, client_call_details,
request_iterator):
return self._intercept_call(continuation, client_call_details,
request_iterator)

@ -0,0 +1,38 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The Python implementation of the gRPC helloworld.Greeter client."""
from __future__ import print_function
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
import default_value_client_interceptor
def run():
default_value = helloworld_pb2.HelloReply(
message='Hello from your local interceptor!')
default_value_interceptor = default_value_client_interceptor.DefaultValueClientInterceptor(
default_value)
channel = grpc.insecure_channel('localhost:50051')
channel = grpc.intercept_channel(channel, default_value_interceptor)
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
print("Greeter client received: " + response.message)
if __name__ == '__main__':
run()

@ -0,0 +1,134 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: helloworld.proto
import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf import descriptor_pb2
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='helloworld.proto',
package='helloworld',
syntax='proto3',
serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3')
)
_HELLOREQUEST = _descriptor.Descriptor(
name='HelloRequest',
full_name='helloworld.HelloRequest',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='name', full_name='helloworld.HelloRequest.name', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=32,
serialized_end=60,
)
_HELLOREPLY = _descriptor.Descriptor(
name='HelloReply',
full_name='helloworld.HelloReply',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='message', full_name='helloworld.HelloReply.message', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=62,
serialized_end=91,
)
DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST
DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict(
DESCRIPTOR = _HELLOREQUEST,
__module__ = 'helloworld_pb2'
# @@protoc_insertion_point(class_scope:helloworld.HelloRequest)
))
_sym_db.RegisterMessage(HelloRequest)
HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict(
DESCRIPTOR = _HELLOREPLY,
__module__ = 'helloworld_pb2'
# @@protoc_insertion_point(class_scope:helloworld.HelloReply)
))
_sym_db.RegisterMessage(HelloReply)
DESCRIPTOR.has_options = True
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW'))
_GREETER = _descriptor.ServiceDescriptor(
name='Greeter',
full_name='helloworld.Greeter',
file=DESCRIPTOR,
index=0,
options=None,
serialized_start=93,
serialized_end=166,
methods=[
_descriptor.MethodDescriptor(
name='SayHello',
full_name='helloworld.Greeter.SayHello',
index=0,
containing_service=None,
input_type=_HELLOREQUEST,
output_type=_HELLOREPLY,
options=None,
),
])
_sym_db.RegisterServiceDescriptor(_GREETER)
DESCRIPTOR.services_by_name['Greeter'] = _GREETER
# @@protoc_insertion_point(module_scope)

@ -0,0 +1,46 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
import grpc
import helloworld_pb2 as helloworld__pb2
class GreeterStub(object):
"""The greeting service definition.
"""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.SayHello = channel.unary_unary(
'/helloworld.Greeter/SayHello',
request_serializer=helloworld__pb2.HelloRequest.SerializeToString,
response_deserializer=helloworld__pb2.HelloReply.FromString,
)
class GreeterServicer(object):
"""The greeting service definition.
"""
def SayHello(self, request, context):
"""Sends a greeting
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_GreeterServicer_to_server(servicer, server):
rpc_method_handlers = {
'SayHello': grpc.unary_unary_rpc_method_handler(
servicer.SayHello,
request_deserializer=helloworld__pb2.HelloRequest.FromString,
response_serializer=helloworld__pb2.HelloReply.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'helloworld.Greeter', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))

@ -0,0 +1,55 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Base class for interceptors that operate on all RPC types."""
import grpc
class _GenericClientInterceptor(
grpc.UnaryUnaryClientInterceptor, grpc.UnaryStreamClientInterceptor,
grpc.StreamUnaryClientInterceptor, grpc.StreamStreamClientInterceptor):
def __init__(self, interceptor_function):
self._fn = interceptor_function
def intercept_unary_unary(self, continuation, client_call_details, request):
new_details, new_request_iterator, postprocess = self._fn(
client_call_details, iter((request,)), False, False)
response = continuation(new_details, next(new_request_iterator))
return postprocess(response) if postprocess else response
def intercept_unary_stream(self, continuation, client_call_details,
request):
new_details, new_request_iterator, postprocess = self._fn(
client_call_details, iter((request,)), False, True)
response_it = continuation(new_details, new_request_iterator)
return postprocess(response_it) if postprocess else response_it
def intercept_stream_unary(self, continuation, client_call_details,
request_iterator):
new_details, new_request_iterator, postprocess = self._fn(
client_call_details, request_iterator, True, False)
response = continuation(new_details, next(new_request_iterator))
return postprocess(response) if postprocess else response
def intercept_stream_stream(self, continuation, client_call_details,
request_iterator):
new_details, new_request_iterator, postprocess = self._fn(
client_call_details, request_iterator, True, True)
response_it = continuation(new_details, new_request_iterator)
return postprocess(response_it) if postprocess else response_it
def create(intercept_call):
return _GenericClientInterceptor(intercept_call)

@ -0,0 +1,36 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The Python implementation of the GRPC helloworld.Greeter client."""
from __future__ import print_function
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
import header_manipulator_client_interceptor
def run():
header_adder_interceptor = header_manipulator_client_interceptor.header_adder_interceptor(
'one-time-password', '42')
channel = grpc.insecure_channel('localhost:50051')
channel = grpc.intercept_channel(channel, header_adder_interceptor)
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
print("Greeter client received: " + response.message)
if __name__ == '__main__':
run()

@ -0,0 +1,52 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The Python implementation of the GRPC helloworld.Greeter server."""
from concurrent import futures
import time
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
from request_header_validator_interceptor import RequestHeaderValidatorInterceptor
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def serve():
header_validator = RequestHeaderValidatorInterceptor(
'one-time-password', '42', grpc.StatusCode.UNAUTHENTICATED,
'Access denied!')
server = grpc.server(
futures.ThreadPoolExecutor(max_workers=10),
interceptors=(header_validator,))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()

@ -0,0 +1,42 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Interceptor that adds headers to outgoing requests."""
import collections
import grpc
import generic_client_interceptor
class _ClientCallDetails(
collections.namedtuple('_ClientCallDetails',
('method', 'timeout', 'metadata',
'credentials')), grpc.ClientCallDetails):
pass
def header_adder_interceptor(header, value):
def intercept_call(client_call_details, request_iterator, request_streaming,
response_streaming):
metadata = []
if client_call_details.metadata is not None:
metadata = list(client_call_details.metadata)
metadata.append((header, value,))
client_call_details = _ClientCallDetails(
client_call_details.method, client_call_details.timeout, metadata,
client_call_details.credentials)
return client_call_details, request_iterator, None
return generic_client_interceptor.create(intercept_call)

@ -0,0 +1,134 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: helloworld.proto
import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf import descriptor_pb2
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='helloworld.proto',
package='helloworld',
syntax='proto3',
serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3')
)
_HELLOREQUEST = _descriptor.Descriptor(
name='HelloRequest',
full_name='helloworld.HelloRequest',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='name', full_name='helloworld.HelloRequest.name', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=32,
serialized_end=60,
)
_HELLOREPLY = _descriptor.Descriptor(
name='HelloReply',
full_name='helloworld.HelloReply',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='message', full_name='helloworld.HelloReply.message', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=62,
serialized_end=91,
)
DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST
DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict(
DESCRIPTOR = _HELLOREQUEST,
__module__ = 'helloworld_pb2'
# @@protoc_insertion_point(class_scope:helloworld.HelloRequest)
))
_sym_db.RegisterMessage(HelloRequest)
HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict(
DESCRIPTOR = _HELLOREPLY,
__module__ = 'helloworld_pb2'
# @@protoc_insertion_point(class_scope:helloworld.HelloReply)
))
_sym_db.RegisterMessage(HelloReply)
DESCRIPTOR.has_options = True
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW'))
_GREETER = _descriptor.ServiceDescriptor(
name='Greeter',
full_name='helloworld.Greeter',
file=DESCRIPTOR,
index=0,
options=None,
serialized_start=93,
serialized_end=166,
methods=[
_descriptor.MethodDescriptor(
name='SayHello',
full_name='helloworld.Greeter.SayHello',
index=0,
containing_service=None,
input_type=_HELLOREQUEST,
output_type=_HELLOREPLY,
options=None,
),
])
_sym_db.RegisterServiceDescriptor(_GREETER)
DESCRIPTOR.services_by_name['Greeter'] = _GREETER
# @@protoc_insertion_point(module_scope)

@ -0,0 +1,46 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
import grpc
import helloworld_pb2 as helloworld__pb2
class GreeterStub(object):
"""The greeting service definition.
"""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.SayHello = channel.unary_unary(
'/helloworld.Greeter/SayHello',
request_serializer=helloworld__pb2.HelloRequest.SerializeToString,
response_deserializer=helloworld__pb2.HelloReply.FromString,
)
class GreeterServicer(object):
"""The greeting service definition.
"""
def SayHello(self, request, context):
"""Sends a greeting
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_GreeterServicer_to_server(servicer, server):
rpc_method_handlers = {
'SayHello': grpc.unary_unary_rpc_method_handler(
servicer.SayHello,
request_deserializer=helloworld__pb2.HelloRequest.FromString,
response_serializer=helloworld__pb2.HelloReply.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'helloworld.Greeter', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))

@ -0,0 +1,39 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Interceptor that ensures a specific header is present."""
import grpc
def _unary_unary_rpc_terminator(code, details):
def terminate(ignored_request, context):
context.abort(code, details)
return grpc.unary_unary_rpc_method_handler(terminate)
class RequestHeaderValidatorInterceptor(grpc.ServerInterceptor):
def __init__(self, header, value, code, details):
self._header = header
self._value = value
self._terminator = _unary_unary_rpc_terminator(code, details)
def intercept_service(self, continuation, handler_call_details):
if (self._header,
self._value) in handler_call_details.invocation_metadata:
return continuation(handler_call_details)
else:
return self._terminator

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A client that makes both Greeter and RouteGuide RPCs."""
from __future__ import print_function
@ -29,98 +28,99 @@ import route_guide_resources
def make_route_note(message, latitude, longitude):
return route_guide_pb2.RouteNote(
message=message,
location=route_guide_pb2.Point(latitude=latitude, longitude=longitude))
return route_guide_pb2.RouteNote(
message=message,
location=route_guide_pb2.Point(latitude=latitude, longitude=longitude))
def guide_get_one_feature(route_guide_stub, point):
feature = route_guide_stub.GetFeature(point)
if not feature.location:
print("Server returned incomplete feature")
return
feature = route_guide_stub.GetFeature(point)
if not feature.location:
print("Server returned incomplete feature")
return
if feature.name:
print("Feature called %s at %s" % (feature.name, feature.location))
else:
print("Found no feature at %s" % feature.location)
if feature.name:
print("Feature called %s at %s" % (feature.name, feature.location))
else:
print("Found no feature at %s" % feature.location)
def guide_get_feature(route_guide_stub):
guide_get_one_feature(
route_guide_stub,
route_guide_pb2.Point(latitude=409146138, longitude=-746188906))
guide_get_one_feature(
route_guide_stub, route_guide_pb2.Point(latitude=0, longitude=0))
guide_get_one_feature(
route_guide_stub,
route_guide_pb2.Point(latitude=409146138, longitude=-746188906))
guide_get_one_feature(route_guide_stub,
route_guide_pb2.Point(latitude=0, longitude=0))
def guide_list_features(route_guide_stub):
rectangle = route_guide_pb2.Rectangle(
lo=route_guide_pb2.Point(latitude=400000000, longitude=-750000000),
hi=route_guide_pb2.Point(latitude=420000000, longitude=-730000000))
print("Looking for features between 40, -75 and 42, -73")
rectangle = route_guide_pb2.Rectangle(
lo=route_guide_pb2.Point(latitude=400000000, longitude=-750000000),
hi=route_guide_pb2.Point(latitude=420000000, longitude=-730000000))
print("Looking for features between 40, -75 and 42, -73")
features = route_guide_stub.ListFeatures(rectangle)
features = route_guide_stub.ListFeatures(rectangle)
for feature in features:
print("Feature called %s at %s" % (feature.name, feature.location))
for feature in features:
print("Feature called %s at %s" % (feature.name, feature.location))
def generate_route(feature_list):
for _ in range(0, 10):
random_feature = feature_list[random.randint(0, len(feature_list) - 1)]
print("Visiting point %s" % random_feature.location)
yield random_feature.location
time.sleep(random.uniform(0.5, 1.5))
for _ in range(0, 10):
random_feature = feature_list[random.randint(0, len(feature_list) - 1)]
print("Visiting point %s" % random_feature.location)
yield random_feature.location
time.sleep(random.uniform(0.5, 1.5))
def guide_record_route(route_guide_stub):
feature_list = route_guide_resources.read_route_guide_database()
feature_list = route_guide_resources.read_route_guide_database()
route_iterator = generate_route(feature_list)
route_summary = route_guide_stub.RecordRoute(route_iterator)
print("Finished trip with %s points " % route_summary.point_count)
print("Passed %s features " % route_summary.feature_count)
print("Travelled %s meters " % route_summary.distance)
print("It took %s seconds " % route_summary.elapsed_time)
route_iterator = generate_route(feature_list)
route_summary = route_guide_stub.RecordRoute(route_iterator)
print("Finished trip with %s points " % route_summary.point_count)
print("Passed %s features " % route_summary.feature_count)
print("Travelled %s meters " % route_summary.distance)
print("It took %s seconds " % route_summary.elapsed_time)
def generate_messages():
messages = [
make_route_note("First message", 0, 0),
make_route_note("Second message", 0, 1),
make_route_note("Third message", 1, 0),
make_route_note("Fourth message", 0, 0),
make_route_note("Fifth message", 1, 0),
]
for msg in messages:
print("Sending %s at %s" % (msg.message, msg.location))
yield msg
time.sleep(random.uniform(0.5, 1.0))
messages = [
make_route_note("First message", 0, 0),
make_route_note("Second message", 0, 1),
make_route_note("Third message", 1, 0),
make_route_note("Fourth message", 0, 0),
make_route_note("Fifth message", 1, 0),
]
for msg in messages:
print("Sending %s at %s" % (msg.message, msg.location))
yield msg
time.sleep(random.uniform(0.5, 1.0))
def guide_route_chat(route_guide_stub):
responses = route_guide_stub.RouteChat(generate_messages())
for response in responses:
print("Received message %s at %s" % (response.message, response.location))
responses = route_guide_stub.RouteChat(generate_messages())
for response in responses:
print("Received message %s at %s" %
(response.message, response.location))
def run():
channel = grpc.insecure_channel('localhost:50051')
greeter_stub = helloworld_pb2_grpc.GreeterStub(channel)
route_guide_stub = route_guide_pb2_grpc.RouteGuideStub(channel)
greeter_response = greeter_stub.SayHello(
helloworld_pb2.HelloRequest(name='you'))
print("Greeter client received: " + greeter_response.message)
print("-------------- GetFeature --------------")
guide_get_feature(route_guide_stub)
print("-------------- ListFeatures --------------")
guide_list_features(route_guide_stub)
print("-------------- RecordRoute --------------")
guide_record_route(route_guide_stub)
print("-------------- RouteChat --------------")
guide_route_chat(route_guide_stub)
channel = grpc.insecure_channel('localhost:50051')
greeter_stub = helloworld_pb2_grpc.GreeterStub(channel)
route_guide_stub = route_guide_pb2_grpc.RouteGuideStub(channel)
greeter_response = greeter_stub.SayHello(
helloworld_pb2.HelloRequest(name='you'))
print("Greeter client received: " + greeter_response.message)
print("-------------- GetFeature --------------")
guide_get_feature(route_guide_stub)
print("-------------- ListFeatures --------------")
guide_list_features(route_guide_stub)
print("-------------- RecordRoute --------------")
guide_record_route(route_guide_stub)
print("-------------- RouteChat --------------")
guide_route_chat(route_guide_stub)
if __name__ == '__main__':
run()
run()

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A gRPC server servicing both Greeter and RouteGuide RPCs."""
from concurrent import futures
@ -30,107 +29,111 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24
def _get_feature(feature_db, point):
"""Returns Feature at given location or None."""
for feature in feature_db:
if feature.location == point:
return feature
return None
"""Returns Feature at given location or None."""
for feature in feature_db:
if feature.location == point:
return feature
return None
def _get_distance(start, end):
"""Distance between two points."""
coord_factor = 10000000.0
lat_1 = start.latitude / coord_factor
lat_2 = end.latitude / coord_factor
lon_1 = start.longitude / coord_factor
lon_2 = end.longitude / coord_factor
lat_rad_1 = math.radians(lat_1)
lat_rad_2 = math.radians(lat_2)
delta_lat_rad = math.radians(lat_2 - lat_1)
delta_lon_rad = math.radians(lon_2 - lon_1)
a = (pow(math.sin(delta_lat_rad / 2), 2) +
(math.cos(lat_rad_1) * math.cos(lat_rad_2) *
pow(math.sin(delta_lon_rad / 2), 2)))
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
R = 6371000; # metres
return R * c;
"""Distance between two points."""
coord_factor = 10000000.0
lat_1 = start.latitude / coord_factor
lat_2 = end.latitude / coord_factor
lon_1 = start.longitude / coord_factor
lon_2 = end.longitude / coord_factor
lat_rad_1 = math.radians(lat_1)
lat_rad_2 = math.radians(lat_2)
delta_lat_rad = math.radians(lat_2 - lat_1)
delta_lon_rad = math.radians(lon_2 - lon_1)
a = (pow(math.sin(delta_lat_rad / 2), 2) +
(math.cos(lat_rad_1) * math.cos(lat_rad_2) * pow(
math.sin(delta_lon_rad / 2), 2)))
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
R = 6371000
# metres
return R * c
class _GreeterServicer(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, {}!'.format(request.name))
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(
message='Hello, {}!'.format(request.name))
class _RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
"""Provides methods that implement functionality of route guide server."""
def __init__(self):
self.db = route_guide_resources.read_route_guide_database()
def GetFeature(self, request, context):
feature = _get_feature(self.db, request)
if feature is None:
return route_guide_pb2.Feature(name="", location=request)
else:
return feature
def ListFeatures(self, request, context):
left = min(request.lo.longitude, request.hi.longitude)
right = max(request.lo.longitude, request.hi.longitude)
top = max(request.lo.latitude, request.hi.latitude)
bottom = min(request.lo.latitude, request.hi.latitude)
for feature in self.db:
if (feature.location.longitude >= left and
feature.location.longitude <= right and
feature.location.latitude >= bottom and
feature.location.latitude <= top):
yield feature
def RecordRoute(self, request_iterator, context):
point_count = 0
feature_count = 0
distance = 0.0
prev_point = None
start_time = time.time()
for point in request_iterator:
point_count += 1
if _get_feature(self.db, point):
feature_count += 1
if prev_point:
distance += _get_distance(prev_point, point)
prev_point = point
elapsed_time = time.time() - start_time
return route_guide_pb2.RouteSummary(point_count=point_count,
feature_count=feature_count,
distance=int(distance),
elapsed_time=int(elapsed_time))
def RouteChat(self, request_iterator, context):
prev_notes = []
for new_note in request_iterator:
for prev_note in prev_notes:
if prev_note.location == new_note.location:
yield prev_note
prev_notes.append(new_note)
"""Provides methods that implement functionality of route guide server."""
def __init__(self):
self.db = route_guide_resources.read_route_guide_database()
def GetFeature(self, request, context):
feature = _get_feature(self.db, request)
if feature is None:
return route_guide_pb2.Feature(name="", location=request)
else:
return feature
def ListFeatures(self, request, context):
left = min(request.lo.longitude, request.hi.longitude)
right = max(request.lo.longitude, request.hi.longitude)
top = max(request.lo.latitude, request.hi.latitude)
bottom = min(request.lo.latitude, request.hi.latitude)
for feature in self.db:
if (feature.location.longitude >= left and
feature.location.longitude <= right and
feature.location.latitude >= bottom and
feature.location.latitude <= top):
yield feature
def RecordRoute(self, request_iterator, context):
point_count = 0
feature_count = 0
distance = 0.0
prev_point = None
start_time = time.time()
for point in request_iterator:
point_count += 1
if _get_feature(self.db, point):
feature_count += 1
if prev_point:
distance += _get_distance(prev_point, point)
prev_point = point
elapsed_time = time.time() - start_time
return route_guide_pb2.RouteSummary(
point_count=point_count,
feature_count=feature_count,
distance=int(distance),
elapsed_time=int(elapsed_time))
def RouteChat(self, request_iterator, context):
prev_notes = []
for new_note in request_iterator:
for prev_note in prev_notes:
if prev_note.location == new_note.location:
yield prev_note
prev_notes.append(new_note)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(_GreeterServicer(), server)
route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
_RouteGuideServicer(), server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(_GreeterServicer(),
server)
route_guide_pb2_grpc.add_RouteGuideServicer_to_server(_RouteGuideServicer(),
server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()
serve()

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Common resources used in the gRPC route guide example."""
import json
@ -20,19 +19,19 @@ import route_guide_pb2
def read_route_guide_database():
"""Reads the route guide database.
"""Reads the route guide database.
Returns:
The full contents of the route guide database as a sequence of
route_guide_pb2.Features.
"""
feature_list = []
with open("route_guide_db.json") as route_guide_db_file:
for item in json.load(route_guide_db_file):
feature = route_guide_pb2.Feature(
name=item["name"],
location=route_guide_pb2.Point(
latitude=item["location"]["latitude"],
longitude=item["location"]["longitude"]))
feature_list.append(feature)
return feature_list
feature_list = []
with open("route_guide_db.json") as route_guide_db_file:
for item in json.load(route_guide_db_file):
feature = route_guide_pb2.Feature(
name=item["name"],
location=route_guide_pb2.Point(
latitude=item["location"]["latitude"],
longitude=item["location"]["longitude"]))
feature_list.append(feature)
return feature_list

@ -11,26 +11,11 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Generates protocol messages and gRPC stubs."""
from grpc_tools import protoc
protoc.main(
(
'',
'-I../../protos',
'--python_out=.',
'--grpc_python_out=.',
'../../protos/helloworld.proto',
)
)
protoc.main(
(
'',
'-I../../protos',
'--python_out=.',
'--grpc_python_out=.',
'../../protos/route_guide.proto',
)
)
protoc.main(('', '-I../../protos', '--python_out=.', '--grpc_python_out=.',
'../../protos/helloworld.proto',))
protoc.main(('', '-I../../protos', '--python_out=.', '--grpc_python_out=.',
'../../protos/route_guide.proto',))

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The Python implementation of the gRPC route guide client."""
from __future__ import print_function
@ -26,89 +25,91 @@ import route_guide_resources
def make_route_note(message, latitude, longitude):
return route_guide_pb2.RouteNote(
message=message,
location=route_guide_pb2.Point(latitude=latitude, longitude=longitude))
return route_guide_pb2.RouteNote(
message=message,
location=route_guide_pb2.Point(latitude=latitude, longitude=longitude))
def guide_get_one_feature(stub, point):
feature = stub.GetFeature(point)
if not feature.location:
print("Server returned incomplete feature")
return
feature = stub.GetFeature(point)
if not feature.location:
print("Server returned incomplete feature")
return
if feature.name:
print("Feature called %s at %s" % (feature.name, feature.location))
else:
print("Found no feature at %s" % feature.location)
if feature.name:
print("Feature called %s at %s" % (feature.name, feature.location))
else:
print("Found no feature at %s" % feature.location)
def guide_get_feature(stub):
guide_get_one_feature(stub, route_guide_pb2.Point(latitude=409146138, longitude=-746188906))
guide_get_one_feature(stub, route_guide_pb2.Point(latitude=0, longitude=0))
guide_get_one_feature(
stub, route_guide_pb2.Point(latitude=409146138, longitude=-746188906))
guide_get_one_feature(stub, route_guide_pb2.Point(latitude=0, longitude=0))
def guide_list_features(stub):
rectangle = route_guide_pb2.Rectangle(
lo=route_guide_pb2.Point(latitude=400000000, longitude=-750000000),
hi=route_guide_pb2.Point(latitude=420000000, longitude=-730000000))
print("Looking for features between 40, -75 and 42, -73")
rectangle = route_guide_pb2.Rectangle(
lo=route_guide_pb2.Point(latitude=400000000, longitude=-750000000),
hi=route_guide_pb2.Point(latitude=420000000, longitude=-730000000))
print("Looking for features between 40, -75 and 42, -73")
features = stub.ListFeatures(rectangle)
features = stub.ListFeatures(rectangle)
for feature in features:
print("Feature called %s at %s" % (feature.name, feature.location))
for feature in features:
print("Feature called %s at %s" % (feature.name, feature.location))
def generate_route(feature_list):
for _ in range(0, 10):
random_feature = feature_list[random.randint(0, len(feature_list) - 1)]
print("Visiting point %s" % random_feature.location)
yield random_feature.location
for _ in range(0, 10):
random_feature = feature_list[random.randint(0, len(feature_list) - 1)]
print("Visiting point %s" % random_feature.location)
yield random_feature.location
def guide_record_route(stub):
feature_list = route_guide_resources.read_route_guide_database()
feature_list = route_guide_resources.read_route_guide_database()
route_iterator = generate_route(feature_list)
route_summary = stub.RecordRoute(route_iterator)
print("Finished trip with %s points " % route_summary.point_count)
print("Passed %s features " % route_summary.feature_count)
print("Travelled %s meters " % route_summary.distance)
print("It took %s seconds " % route_summary.elapsed_time)
route_iterator = generate_route(feature_list)
route_summary = stub.RecordRoute(route_iterator)
print("Finished trip with %s points " % route_summary.point_count)
print("Passed %s features " % route_summary.feature_count)
print("Travelled %s meters " % route_summary.distance)
print("It took %s seconds " % route_summary.elapsed_time)
def generate_messages():
messages = [
make_route_note("First message", 0, 0),
make_route_note("Second message", 0, 1),
make_route_note("Third message", 1, 0),
make_route_note("Fourth message", 0, 0),
make_route_note("Fifth message", 1, 0),
]
for msg in messages:
print("Sending %s at %s" % (msg.message, msg.location))
yield msg
messages = [
make_route_note("First message", 0, 0),
make_route_note("Second message", 0, 1),
make_route_note("Third message", 1, 0),
make_route_note("Fourth message", 0, 0),
make_route_note("Fifth message", 1, 0),
]
for msg in messages:
print("Sending %s at %s" % (msg.message, msg.location))
yield msg
def guide_route_chat(stub):
responses = stub.RouteChat(generate_messages())
for response in responses:
print("Received message %s at %s" % (response.message, response.location))
responses = stub.RouteChat(generate_messages())
for response in responses:
print("Received message %s at %s" %
(response.message, response.location))
def run():
channel = grpc.insecure_channel('localhost:50051')
stub = route_guide_pb2_grpc.RouteGuideStub(channel)
print("-------------- GetFeature --------------")
guide_get_feature(stub)
print("-------------- ListFeatures --------------")
guide_list_features(stub)
print("-------------- RecordRoute --------------")
guide_record_route(stub)
print("-------------- RouteChat --------------")
guide_route_chat(stub)
channel = grpc.insecure_channel('localhost:50051')
stub = route_guide_pb2_grpc.RouteGuideStub(channel)
print("-------------- GetFeature --------------")
guide_get_feature(stub)
print("-------------- ListFeatures --------------")
guide_list_features(stub)
print("-------------- RecordRoute --------------")
guide_record_route(stub)
print("-------------- RouteChat --------------")
guide_route_chat(stub)
if __name__ == '__main__':
run()
run()

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Common resources used in the gRPC route guide example."""
import json
@ -20,19 +19,19 @@ import route_guide_pb2
def read_route_guide_database():
"""Reads the route guide database.
"""Reads the route guide database.
Returns:
The full contents of the route guide database as a sequence of
route_guide_pb2.Features.
"""
feature_list = []
with open("route_guide_db.json") as route_guide_db_file:
for item in json.load(route_guide_db_file):
feature = route_guide_pb2.Feature(
name=item["name"],
location=route_guide_pb2.Point(
latitude=item["location"]["latitude"],
longitude=item["location"]["longitude"]))
feature_list.append(feature)
return feature_list
feature_list = []
with open("route_guide_db.json") as route_guide_db_file:
for item in json.load(route_guide_db_file):
feature = route_guide_pb2.Feature(
name=item["name"],
location=route_guide_pb2.Point(
latitude=item["location"]["latitude"],
longitude=item["location"]["longitude"]))
feature_list.append(feature)
return feature_list

@ -11,7 +11,6 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""The Python implementation of the gRPC route guide server."""
from concurrent import futures
@ -28,98 +27,102 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24
def get_feature(feature_db, point):
"""Returns Feature at given location or None."""
for feature in feature_db:
if feature.location == point:
return feature
return None
"""Returns Feature at given location or None."""
for feature in feature_db:
if feature.location == point:
return feature
return None
def get_distance(start, end):
"""Distance between two points."""
coord_factor = 10000000.0
lat_1 = start.latitude / coord_factor
lat_2 = end.latitude / coord_factor
lon_1 = start.longitude / coord_factor
lon_2 = end.longitude / coord_factor
lat_rad_1 = math.radians(lat_1)
lat_rad_2 = math.radians(lat_2)
delta_lat_rad = math.radians(lat_2 - lat_1)
delta_lon_rad = math.radians(lon_2 - lon_1)
a = (pow(math.sin(delta_lat_rad / 2), 2) +
(math.cos(lat_rad_1) * math.cos(lat_rad_2) *
pow(math.sin(delta_lon_rad / 2), 2)))
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
R = 6371000; # metres
return R * c;
"""Distance between two points."""
coord_factor = 10000000.0
lat_1 = start.latitude / coord_factor
lat_2 = end.latitude / coord_factor
lon_1 = start.longitude / coord_factor
lon_2 = end.longitude / coord_factor
lat_rad_1 = math.radians(lat_1)
lat_rad_2 = math.radians(lat_2)
delta_lat_rad = math.radians(lat_2 - lat_1)
delta_lon_rad = math.radians(lon_2 - lon_1)
a = (pow(math.sin(delta_lat_rad / 2), 2) +
(math.cos(lat_rad_1) * math.cos(lat_rad_2) * pow(
math.sin(delta_lon_rad / 2), 2)))
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
R = 6371000
# metres
return R * c
class RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):
"""Provides methods that implement functionality of route guide server."""
def __init__(self):
self.db = route_guide_resources.read_route_guide_database()
def GetFeature(self, request, context):
feature = get_feature(self.db, request)
if feature is None:
return route_guide_pb2.Feature(name="", location=request)
else:
return feature
def ListFeatures(self, request, context):
left = min(request.lo.longitude, request.hi.longitude)
right = max(request.lo.longitude, request.hi.longitude)
top = max(request.lo.latitude, request.hi.latitude)
bottom = min(request.lo.latitude, request.hi.latitude)
for feature in self.db:
if (feature.location.longitude >= left and
feature.location.longitude <= right and
feature.location.latitude >= bottom and
feature.location.latitude <= top):
yield feature
def RecordRoute(self, request_iterator, context):
point_count = 0
feature_count = 0
distance = 0.0
prev_point = None
start_time = time.time()
for point in request_iterator:
point_count += 1
if get_feature(self.db, point):
feature_count += 1
if prev_point:
distance += get_distance(prev_point, point)
prev_point = point
elapsed_time = time.time() - start_time
return route_guide_pb2.RouteSummary(point_count=point_count,
feature_count=feature_count,
distance=int(distance),
elapsed_time=int(elapsed_time))
def RouteChat(self, request_iterator, context):
prev_notes = []
for new_note in request_iterator:
for prev_note in prev_notes:
if prev_note.location == new_note.location:
yield prev_note
prev_notes.append(new_note)
"""Provides methods that implement functionality of route guide server."""
def __init__(self):
self.db = route_guide_resources.read_route_guide_database()
def GetFeature(self, request, context):
feature = get_feature(self.db, request)
if feature is None:
return route_guide_pb2.Feature(name="", location=request)
else:
return feature
def ListFeatures(self, request, context):
left = min(request.lo.longitude, request.hi.longitude)
right = max(request.lo.longitude, request.hi.longitude)
top = max(request.lo.latitude, request.hi.latitude)
bottom = min(request.lo.latitude, request.hi.latitude)
for feature in self.db:
if (feature.location.longitude >= left and
feature.location.longitude <= right and
feature.location.latitude >= bottom and
feature.location.latitude <= top):
yield feature
def RecordRoute(self, request_iterator, context):
point_count = 0
feature_count = 0
distance = 0.0
prev_point = None
start_time = time.time()
for point in request_iterator:
point_count += 1
if get_feature(self.db, point):
feature_count += 1
if prev_point:
distance += get_distance(prev_point, point)
prev_point = point
elapsed_time = time.time() - start_time
return route_guide_pb2.RouteSummary(
point_count=point_count,
feature_count=feature_count,
distance=int(distance),
elapsed_time=int(elapsed_time))
def RouteChat(self, request_iterator, context):
prev_notes = []
for new_note in request_iterator:
for prev_note in prev_notes:
if prev_note.location == new_note.location:
yield prev_note
prev_notes.append(new_note)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
RouteGuideServicer(), server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
route_guide_pb2_grpc.add_RouteGuideServicer_to_server(RouteGuideServicer(),
server)
server.add_insecure_port('[::]:50051')
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()
serve()

@ -11,17 +11,9 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Runs protoc with the gRPC plugin to generate messages and gRPC stubs."""
from grpc_tools import protoc
protoc.main(
(
'',
'-I../../protos',
'--python_out=.',
'--grpc_python_out=.',
'../../protos/route_guide.proto',
)
)
protoc.main(('', '-I../../protos', '--python_out=.', '--grpc_python_out=.',
'../../protos/route_guide.proto',))

@ -34,6 +34,10 @@ Pod::Spec.new do |s|
:tag => "v#{version}",
}
# gRPC podspecs depend on fix for https://github.com/CocoaPods/CocoaPods/issues/6024,
# which was released in Cocoapods v1.2.0.
s.cocoapods_version = '>= 1.2.0'
s.ios.deployment_target = '7.0'
s.osx.deployment_target = '10.9'
s.requires_arc = false

@ -42,6 +42,23 @@ class GenericServerContext final : public ServerContext {
grpc::string host_;
};
// A generic service at the server side accepts all RPC methods and hosts. It is
// typically used in proxies. The generic service can be registered to a server
// which also has other services.
// Sample usage:
// ServerBuilder builder;
// auto cq = builder.AddCompletionQueue();
// AsyncGenericService generic_service;
// builder.RegisterAsyncGeneicService(&generic_service);
// auto server = builder.BuildAndStart();
//
// // request a new call
// GenericServerContext context;
// GenericAsyncReaderWriter stream;
// generic_service.RequestCall(&context, &stream, cq.get(), cq.get(), tag);
//
// When tag is retrieved from cq->Next(), context.method() can be used to look
// at the method and the RPC can be handled accordingly.
class AsyncGenericService final {
public:
AsyncGenericService() : server_(nullptr) {}

@ -103,6 +103,13 @@ class ClientAsyncResponseReader final
assert(size == sizeof(ClientAsyncResponseReader));
}
// This operator should never be called as the memory should be freed as part
// of the arena destruction. It only exists to provide a matching operator
// delete to the operator new so that some compilers will not complain (see
// https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
// there are no tests catching the compiler warning.
static void operator delete(void*, void*) { assert(0); }
void StartCall() override {
assert(!started_);
started_ = true;

@ -558,10 +558,12 @@ class CallOpRecvInitialMetadata {
class CallOpClientRecvStatus {
public:
CallOpClientRecvStatus() : recv_status_(nullptr) {}
CallOpClientRecvStatus()
: recv_status_(nullptr), debug_error_string_(nullptr) {}
void ClientRecvStatus(ClientContext* context, Status* status) {
metadata_map_ = &context->trailing_metadata_;
client_context_ = context;
metadata_map_ = &client_context_->trailing_metadata_;
recv_status_ = status;
error_message_ = g_core_codegen_interface->grpc_empty_slice();
}
@ -574,7 +576,7 @@ class CallOpClientRecvStatus {
op->data.recv_status_on_client.trailing_metadata = metadata_map_->arr();
op->data.recv_status_on_client.status = &status_code_;
op->data.recv_status_on_client.status_details = &error_message_;
op->data.recv_status_on_client.error_string = nullptr;
op->data.recv_status_on_client.error_string = &debug_error_string_;
op->flags = 0;
op->reserved = NULL;
}
@ -592,13 +594,20 @@ class CallOpClientRecvStatus {
grpc::string(GRPC_SLICE_START_PTR(error_message_),
GRPC_SLICE_END_PTR(error_message_)),
binary_error_details);
client_context_->set_debug_error_string(
debug_error_string_ != nullptr ? debug_error_string_ : "");
g_core_codegen_interface->grpc_slice_unref(error_message_);
if (debug_error_string_ != nullptr) {
g_core_codegen_interface->gpr_free((void*)debug_error_string_);
}
recv_status_ = nullptr;
}
private:
ClientContext* client_context_;
MetadataMap* metadata_map_;
Status* recv_status_;
const char* debug_error_string_;
grpc_status_code status_code_;
grpc_slice error_message_;
};

@ -348,6 +348,13 @@ class ClientContext {
/// Applications never need to call this method.
grpc_call* c_call() { return call_; }
/// EXPERIMENTAL debugging API
///
/// if status is not ok() for an RPC, this will return a detailed string
/// of the gRPC Core error that led to the failure. It should not be relied
/// upon for anything other than gaining more debug data in failure cases.
grpc::string debug_error_string() const { return debug_error_string_; }
private:
// Disallow copy and assign.
ClientContext(const ClientContext&);
@ -374,6 +381,11 @@ class ClientContext {
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
// Used by friend class CallOpClientRecvStatus
void set_debug_error_string(const grpc::string& debug_error_string) {
debug_error_string_ = debug_error_string;
}
grpc_call* call() const { return call_; }
void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
@ -412,6 +424,8 @@ class ClientContext {
grpc_compression_algorithm compression_algorithm_;
bool initial_metadata_corked_;
grpc::string debug_error_string_;
};
} // namespace grpc

@ -122,7 +122,7 @@ class ChannelArguments {
/// Default pointer argument operations.
struct PointerVtableMembers {
static void* Copy(void* in) { return in; }
static void Destroy(grpc_exec_ctx* exec_ctx, void* in) {}
static void Destroy(void* in) {}
static int Compare(void* a, void* b) {
if (a < b) return -1;
if (a > b) return 1;

@ -85,7 +85,7 @@ typedef enum {
typedef struct grpc_arg_pointer_vtable {
void* (*copy)(void* p);
void (*destroy)(grpc_exec_ctx* exec_ctx, void* p);
void (*destroy)(void* p);
int (*cmp)(void* p, void* q);
} grpc_arg_pointer_vtable;

@ -173,6 +173,7 @@
#endif /* _LP64 */
#ifdef __GLIBC__
#define GPR_POSIX_CRASH_HANDLER 1
#define GPR_LINUX_PTHREAD_NAME 1
#else /* musl libc */
#define GPR_MUSL_LIBC_COMPAT 1
#endif
@ -195,6 +196,7 @@
#else /* __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 */
#define GPR_CPU_POSIX 1
#define GPR_GCC_TLS 1
#define GPR_APPLE_PTHREAD_NAME 1
#endif
#else /* __MAC_OS_X_VERSION_MIN_REQUIRED */
#define GPR_CPU_POSIX 1

@ -43,7 +43,7 @@ typedef struct grpc_slice grpc_slice;
typedef struct grpc_slice_refcount_vtable {
void (*ref)(void*);
void (*unref)(grpc_exec_ctx* exec_ctx, void*);
void (*unref)(void*);
int (*eq)(grpc_slice a, grpc_slice b);
uint32_t (*hash)(grpc_slice slice);
} grpc_slice_refcount_vtable;

@ -67,8 +67,7 @@ GPRAPI void grpc_slice_buffer_move_first_no_ref(grpc_slice_buffer* src,
size_t n,
grpc_slice_buffer* dst);
/** move the first n bytes of src into dst (copying them) */
GPRAPI void grpc_slice_buffer_move_first_into_buffer(grpc_exec_ctx* exec_ctx,
grpc_slice_buffer* src,
GPRAPI void grpc_slice_buffer_move_first_into_buffer(grpc_slice_buffer* src,
size_t n, void* dst);
/** take the first slice in the slice buffer */
GPRAPI grpc_slice grpc_slice_buffer_take_first(grpc_slice_buffer* src);

@ -73,12 +73,14 @@ GPRAPI void gpr_log_verbosity_init(void);
/** Log overrides: applications can use this API to intercept logging calls
and use their own implementations */
typedef struct {
struct gpr_log_func_args {
const char* file;
int line;
gpr_log_severity severity;
const char* message;
} gpr_log_func_args;
};
typedef struct gpr_log_func_args gpr_log_func_args;
typedef void (*gpr_log_func)(gpr_log_func_args* args);
GPRAPI void gpr_set_log_function(gpr_log_func func);

@ -42,9 +42,12 @@ typedef struct {
/** Create a new thread running (*thd_body)(arg) and place its thread identifier
in *t, and return true. If there are insufficient resources, return false.
thd_name is the name of the thread for identification purposes on platforms
that support thread naming.
If options==NULL, default options are used.
The thread is immediately runnable, and exits when (*thd_body)() returns. */
GPRAPI int gpr_thd_new(gpr_thd_id* t, void (*thd_body)(void* arg), void* arg,
GPRAPI int gpr_thd_new(gpr_thd_id* t, const char* thd_name,
void (*thd_body)(void* arg), void* arg,
const gpr_thd_options* options);
/** Return a gpr_thd_options struct with all fields set to defaults. */

@ -32,6 +32,12 @@
GPR_TLS_DECL(foo);
Thread locals always have static scope.
Declaring a thread local class variable 'foo':
GPR_TLS_CLASS_DECL(foo);
Defining the thread local class variable:
GPR_TLS_CLASS_DEF(foo);
Initializing a thread local (must be done at library initialization
time):
gpr_tls_init(&foo);

@ -33,6 +33,11 @@ struct gpr_gcc_thread_local {
#define GPR_TLS_DECL(name) \
static __thread struct gpr_gcc_thread_local name = {0}
#define GPR_TLS_CLASS_DECL(name) \
static __thread struct gpr_gcc_thread_local name
#define GPR_TLS_CLASS_DEF(name) __thread struct gpr_gcc_thread_local name = {0}
#define gpr_tls_init(tls) \
do { \
} while (0)

@ -26,9 +26,18 @@ struct gpr_msvc_thread_local {
intptr_t value;
};
/** Use GPR_TLS_DECL to declare tls static variables outside a class */
#define GPR_TLS_DECL(name) \
static __declspec(thread) struct gpr_msvc_thread_local name = {0}
/** Use GPR_TLS_CLASS_DECL to declare tls static variable members of a class.
* GPR_TLS_CLASS_DEF needs to be called to define this member. */
#define GPR_TLS_CLASS_DECL(name) \
static __declspec(thread) struct gpr_msvc_thread_local name
#define GPR_TLS_CLASS_DEF(name) \
__declspec(thread) struct gpr_msvc_thread_local name = {0}
#define gpr_tls_init(tls) \
do { \
} while (0)

@ -29,8 +29,17 @@ struct gpr_pthread_thread_local {
pthread_key_t key;
};
/** Use GPR_TLS_DECL to declare tls static variables outside a class */
#define GPR_TLS_DECL(name) static struct gpr_pthread_thread_local name = {0}
/** Use GPR_TLS_CLASS_DECL to declare tls static variable members of a class.
* GPR_TLS_CLASS_DEF needs to be called to define this member. */
#define GPR_TLS_CLASS_DECL(name) static struct gpr_pthread_thread_local name
/** Use GPR_TLS_CLASS_DEF to declare tls static variable members of a class.
* GPR_TLS_CLASS_DEF needs to be called to define this member. */
#define GPR_TLS_CLASS_DEF(name) struct gpr_pthread_thread_local name = {0}
#define gpr_tls_init(tls) GPR_ASSERT(0 == pthread_key_create(&(tls)->key, NULL))
#define gpr_tls_destroy(tls) pthread_key_delete((tls)->key)
#define gpr_tls_get(tls) ((intptr_t)pthread_getspecific((tls)->key))

@ -659,8 +659,11 @@ grpc::string GetServices(const FileDescriptor* file, bool generate_client,
}
// Write out a file header.
out.Print("// Generated by the protocol buffer compiler. DO NOT EDIT!\n");
out.Print("// source: $filename$\n", "filename", file->name());
out.Print("// <auto-generated>\n");
out.Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n");
out.Print("// source: $filename$\n", "filename", file->name());
out.Print("// </auto-generated>\n");
// use C++ style as there are no file-level XML comments in .NET
grpc::string leading_comments = GetCsharpComments(file, true);

@ -69,61 +69,62 @@ static void init_globals() {
gpr_free(env);
}
static void backup_poller_shutdown_unref(grpc_exec_ctx* exec_ctx,
backup_poller* p) {
static void backup_poller_shutdown_unref(backup_poller* p) {
if (gpr_unref(&p->shutdown_refs)) {
grpc_pollset_destroy(exec_ctx, p->pollset);
grpc_pollset_destroy(p->pollset);
gpr_free(p->pollset);
gpr_free(p);
}
}
static void done_poller(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
backup_poller_shutdown_unref(exec_ctx, (backup_poller*)arg);
static void done_poller(void* arg, grpc_error* error) {
backup_poller_shutdown_unref((backup_poller*)arg);
}
static void g_poller_unref(grpc_exec_ctx* exec_ctx) {
static void g_poller_unref() {
gpr_mu_lock(&g_poller_mu);
if (gpr_unref(&g_poller->refs)) {
gpr_mu_lock(&g_poller_mu);
backup_poller* p = g_poller;
g_poller = nullptr;
gpr_mu_unlock(&g_poller_mu);
gpr_mu_lock(p->pollset_mu);
p->shutting_down = true;
grpc_pollset_shutdown(exec_ctx, p->pollset,
GRPC_CLOSURE_INIT(&p->shutdown_closure, done_poller,
p, grpc_schedule_on_exec_ctx));
grpc_pollset_shutdown(
p->pollset, GRPC_CLOSURE_INIT(&p->shutdown_closure, done_poller, p,
grpc_schedule_on_exec_ctx));
gpr_mu_unlock(p->pollset_mu);
grpc_timer_cancel(exec_ctx, &p->polling_timer);
grpc_timer_cancel(&p->polling_timer);
} else {
gpr_mu_unlock(&g_poller_mu);
}
}
static void run_poller(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
static void run_poller(void* arg, grpc_error* error) {
backup_poller* p = (backup_poller*)arg;
if (error != GRPC_ERROR_NONE) {
if (error != GRPC_ERROR_CANCELLED) {
GRPC_LOG_IF_ERROR("run_poller", GRPC_ERROR_REF(error));
}
backup_poller_shutdown_unref(exec_ctx, p);
backup_poller_shutdown_unref(p);
return;
}
gpr_mu_lock(p->pollset_mu);
if (p->shutting_down) {
gpr_mu_unlock(p->pollset_mu);
backup_poller_shutdown_unref(exec_ctx, p);
backup_poller_shutdown_unref(p);
return;
}
grpc_error* err = grpc_pollset_work(exec_ctx, p->pollset, nullptr,
grpc_exec_ctx_now(exec_ctx));
grpc_error* err =
grpc_pollset_work(p->pollset, nullptr, grpc_core::ExecCtx::Get()->Now());
gpr_mu_unlock(p->pollset_mu);
GRPC_LOG_IF_ERROR("Run client channel backup poller", err);
grpc_timer_init(exec_ctx, &p->polling_timer,
grpc_exec_ctx_now(exec_ctx) + g_poll_interval_ms,
grpc_timer_init(&p->polling_timer,
grpc_core::ExecCtx::Get()->Now() + g_poll_interval_ms,
&p->run_poller_closure);
}
void grpc_client_channel_start_backup_polling(
grpc_exec_ctx* exec_ctx, grpc_pollset_set* interested_parties) {
grpc_pollset_set* interested_parties) {
gpr_once_init(&g_once, init_globals);
if (g_poll_interval_ms == 0) {
return;
@ -139,8 +140,8 @@ void grpc_client_channel_start_backup_polling(
gpr_ref_init(&g_poller->shutdown_refs, 2);
GRPC_CLOSURE_INIT(&g_poller->run_poller_closure, run_poller, g_poller,
grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &g_poller->polling_timer,
grpc_exec_ctx_now(exec_ctx) + g_poll_interval_ms,
grpc_timer_init(&g_poller->polling_timer,
grpc_core::ExecCtx::Get()->Now() + g_poll_interval_ms,
&g_poller->run_poller_closure);
}
@ -152,14 +153,14 @@ void grpc_client_channel_start_backup_polling(
grpc_pollset* pollset = g_poller->pollset;
gpr_mu_unlock(&g_poller_mu);
grpc_pollset_set_add_pollset(exec_ctx, interested_parties, pollset);
grpc_pollset_set_add_pollset(interested_parties, pollset);
}
void grpc_client_channel_stop_backup_polling(
grpc_exec_ctx* exec_ctx, grpc_pollset_set* interested_parties) {
grpc_pollset_set* interested_parties) {
if (g_poll_interval_ms == 0) {
return;
}
grpc_pollset_set_del_pollset(exec_ctx, interested_parties, g_poller->pollset);
g_poller_unref(exec_ctx);
grpc_pollset_set_del_pollset(interested_parties, g_poller->pollset);
g_poller_unref();
}

@ -25,10 +25,10 @@
/* Start polling \a interested_parties periodically in the timer thread */
void grpc_client_channel_start_backup_polling(
grpc_exec_ctx* exec_ctx, grpc_pollset_set* interested_parties);
grpc_pollset_set* interested_parties);
/* Stop polling \a interested_parties */
void grpc_client_channel_stop_backup_polling(
grpc_exec_ctx* exec_ctx, grpc_pollset_set* interested_parties);
grpc_pollset_set* interested_parties);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_BACKUP_POLLER_H */

@ -33,22 +33,22 @@ grpc_connectivity_state grpc_channel_check_connectivity_state(
/* forward through to the underlying client channel */
grpc_channel_element* client_channel_elem =
grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_core::ExecCtx exec_ctx;
grpc_connectivity_state state;
GRPC_API_TRACE(
"grpc_channel_check_connectivity_state(channel=%p, try_to_connect=%d)", 2,
(channel, try_to_connect));
if (client_channel_elem->filter == &grpc_client_channel_filter) {
state = grpc_client_channel_check_connectivity_state(
&exec_ctx, client_channel_elem, try_to_connect);
grpc_exec_ctx_finish(&exec_ctx);
state = grpc_client_channel_check_connectivity_state(client_channel_elem,
try_to_connect);
return state;
}
gpr_log(GPR_ERROR,
"grpc_channel_check_connectivity_state called on something that is "
"not a client channel, but '%s'",
client_channel_elem->filter->name);
grpc_exec_ctx_finish(&exec_ctx);
return GRPC_CHANNEL_SHUTDOWN;
}
@ -73,12 +73,11 @@ typedef struct {
void* tag;
} state_watcher;
static void delete_state_watcher(grpc_exec_ctx* exec_ctx, state_watcher* w) {
static void delete_state_watcher(state_watcher* w) {
grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element(
grpc_channel_get_channel_stack(w->channel));
if (client_channel_elem->filter == &grpc_client_channel_filter) {
GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, w->channel,
"watch_channel_connectivity");
GRPC_CHANNEL_INTERNAL_UNREF(w->channel, "watch_channel_connectivity");
} else {
abort();
}
@ -86,8 +85,7 @@ static void delete_state_watcher(grpc_exec_ctx* exec_ctx, state_watcher* w) {
gpr_free(w);
}
static void finished_completion(grpc_exec_ctx* exec_ctx, void* pw,
grpc_cq_completion* ignored) {
static void finished_completion(void* pw, grpc_cq_completion* ignored) {
bool should_delete = false;
state_watcher* w = (state_watcher*)pw;
gpr_mu_lock(&w->mu);
@ -102,19 +100,19 @@ static void finished_completion(grpc_exec_ctx* exec_ctx, void* pw,
gpr_mu_unlock(&w->mu);
if (should_delete) {
delete_state_watcher(exec_ctx, w);
delete_state_watcher(w);
}
}
static void partly_done(grpc_exec_ctx* exec_ctx, state_watcher* w,
bool due_to_completion, grpc_error* error) {
static void partly_done(state_watcher* w, bool due_to_completion,
grpc_error* error) {
if (due_to_completion) {
grpc_timer_cancel(exec_ctx, &w->alarm);
grpc_timer_cancel(&w->alarm);
} else {
grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element(
grpc_channel_get_channel_stack(w->channel));
grpc_client_channel_watch_connectivity_state(
exec_ctx, client_channel_elem,
client_channel_elem,
grpc_polling_entity_create_from_pollset(grpc_cq_pollset(w->cq)),
nullptr, &w->on_complete, nullptr);
}
@ -149,7 +147,7 @@ static void partly_done(grpc_exec_ctx* exec_ctx, state_watcher* w,
w->error = error;
}
w->phase = CALLING_BACK_AND_FINISHED;
grpc_cq_end_op(exec_ctx, w->cq, w->tag, w->error, finished_completion, w,
grpc_cq_end_op(w->cq, w->tag, w->error, finished_completion, w,
&w->completion_storage);
break;
case CALLING_BACK_AND_FINISHED:
@ -161,14 +159,12 @@ static void partly_done(grpc_exec_ctx* exec_ctx, state_watcher* w,
GRPC_ERROR_UNREF(error);
}
static void watch_complete(grpc_exec_ctx* exec_ctx, void* pw,
grpc_error* error) {
partly_done(exec_ctx, (state_watcher*)pw, true, GRPC_ERROR_REF(error));
static void watch_complete(void* pw, grpc_error* error) {
partly_done((state_watcher*)pw, true, GRPC_ERROR_REF(error));
}
static void timeout_complete(grpc_exec_ctx* exec_ctx, void* pw,
grpc_error* error) {
partly_done(exec_ctx, (state_watcher*)pw, false, GRPC_ERROR_REF(error));
static void timeout_complete(void* pw, grpc_error* error) {
partly_done((state_watcher*)pw, false, GRPC_ERROR_REF(error));
}
int grpc_channel_num_external_connectivity_watchers(grpc_channel* channel) {
@ -183,12 +179,10 @@ typedef struct watcher_timer_init_arg {
gpr_timespec deadline;
} watcher_timer_init_arg;
static void watcher_timer_init(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error_ignored) {
static void watcher_timer_init(void* arg, grpc_error* error_ignored) {
watcher_timer_init_arg* wa = (watcher_timer_init_arg*)arg;
grpc_timer_init(exec_ctx, &wa->w->alarm,
grpc_timespec_to_millis_round_up(wa->deadline),
grpc_timer_init(&wa->w->alarm, grpc_timespec_to_millis_round_up(wa->deadline),
&wa->w->on_timeout);
gpr_free(wa);
}
@ -204,7 +198,7 @@ void grpc_channel_watch_connectivity_state(
gpr_timespec deadline, grpc_completion_queue* cq, void* tag) {
grpc_channel_element* client_channel_elem =
grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_core::ExecCtx exec_ctx;
state_watcher* w = (state_watcher*)gpr_malloc(sizeof(*w));
GRPC_API_TRACE(
@ -241,12 +235,10 @@ void grpc_channel_watch_connectivity_state(
if (client_channel_elem->filter == &grpc_client_channel_filter) {
GRPC_CHANNEL_INTERNAL_REF(channel, "watch_channel_connectivity");
grpc_client_channel_watch_connectivity_state(
&exec_ctx, client_channel_elem,
client_channel_elem,
grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq)), &w->state,
&w->on_complete, &w->watcher_timer_init);
} else {
abort();
}
grpc_exec_ctx_finish(&exec_ctx);
}

File diff suppressed because it is too large Load Diff

@ -38,15 +38,15 @@ extern grpc_core::TraceFlag grpc_client_channel_trace;
extern const grpc_channel_filter grpc_client_channel_filter;
grpc_connectivity_state grpc_client_channel_check_connectivity_state(
grpc_exec_ctx* exec_ctx, grpc_channel_element* elem, int try_to_connect);
grpc_channel_element* elem, int try_to_connect);
int grpc_client_channel_num_external_connectivity_watchers(
grpc_channel_element* elem);
void grpc_client_channel_watch_connectivity_state(
grpc_exec_ctx* exec_ctx, grpc_channel_element* elem,
grpc_polling_entity pollent, grpc_connectivity_state* state,
grpc_closure* on_complete, grpc_closure* watcher_timer_init);
grpc_channel_element* elem, grpc_polling_entity pollent,
grpc_connectivity_state* state, grpc_closure* on_complete,
grpc_closure* watcher_timer_init);
/* Debug helper: pull the subchannel call from a call stack element */
grpc_subchannel_call* grpc_client_channel_get_subchannel_call(

@ -23,23 +23,19 @@ void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory) {
factory->vtable->ref(factory);
}
void grpc_client_channel_factory_unref(grpc_exec_ctx* exec_ctx,
grpc_client_channel_factory* factory) {
factory->vtable->unref(exec_ctx, factory);
void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory) {
factory->vtable->unref(factory);
}
grpc_subchannel* grpc_client_channel_factory_create_subchannel(
grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* factory,
const grpc_subchannel_args* args) {
return factory->vtable->create_subchannel(exec_ctx, factory, args);
grpc_client_channel_factory* factory, const grpc_subchannel_args* args) {
return factory->vtable->create_subchannel(factory, args);
}
grpc_channel* grpc_client_channel_factory_create_channel(
grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* factory,
const char* target, grpc_client_channel_type type,
const grpc_channel_args* args) {
return factory->vtable->create_client_channel(exec_ctx, factory, target, type,
args);
grpc_client_channel_factory* factory, const char* target,
grpc_client_channel_type type, const grpc_channel_args* args) {
return factory->vtable->create_client_channel(factory, target, type, args);
}
static void* factory_arg_copy(void* factory) {
@ -47,9 +43,8 @@ static void* factory_arg_copy(void* factory) {
return factory;
}
static void factory_arg_destroy(grpc_exec_ctx* exec_ctx, void* factory) {
grpc_client_channel_factory_unref(exec_ctx,
(grpc_client_channel_factory*)factory);
static void factory_arg_destroy(void* factory) {
grpc_client_channel_factory_unref((grpc_client_channel_factory*)factory);
}
static int factory_arg_cmp(void* factory1, void* factory2) {

@ -45,31 +45,26 @@ struct grpc_client_channel_factory {
struct grpc_client_channel_factory_vtable {
void (*ref)(grpc_client_channel_factory* factory);
void (*unref)(grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* factory);
grpc_subchannel* (*create_subchannel)(grpc_exec_ctx* exec_ctx,
grpc_client_channel_factory* factory,
void (*unref)(grpc_client_channel_factory* factory);
grpc_subchannel* (*create_subchannel)(grpc_client_channel_factory* factory,
const grpc_subchannel_args* args);
grpc_channel* (*create_client_channel)(grpc_exec_ctx* exec_ctx,
grpc_client_channel_factory* factory,
grpc_channel* (*create_client_channel)(grpc_client_channel_factory* factory,
const char* target,
grpc_client_channel_type type,
const grpc_channel_args* args);
};
void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory);
void grpc_client_channel_factory_unref(grpc_exec_ctx* exec_ctx,
grpc_client_channel_factory* factory);
void grpc_client_channel_factory_unref(grpc_client_channel_factory* factory);
/** Create a new grpc_subchannel */
grpc_subchannel* grpc_client_channel_factory_create_subchannel(
grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* factory,
const grpc_subchannel_args* args);
grpc_client_channel_factory* factory, const grpc_subchannel_args* args);
/** Create a new grpc_channel */
grpc_channel* grpc_client_channel_factory_create_channel(
grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* factory,
const char* target, grpc_client_channel_type type,
const grpc_channel_args* args);
grpc_client_channel_factory* factory, const char* target,
grpc_client_channel_type type, const grpc_channel_args* args);
grpc_arg grpc_client_channel_factory_create_channel_arg(
grpc_client_channel_factory* factory);

@ -34,14 +34,12 @@
#include "src/core/ext/filters/client_channel/subchannel_index.h"
#include "src/core/lib/surface/channel_init.h"
static bool append_filter(grpc_exec_ctx* exec_ctx,
grpc_channel_stack_builder* builder, void* arg) {
static bool append_filter(grpc_channel_stack_builder* builder, void* arg) {
return grpc_channel_stack_builder_append_filter(
builder, (const grpc_channel_filter*)arg, nullptr, nullptr);
}
static bool set_default_host_if_unset(grpc_exec_ctx* exec_ctx,
grpc_channel_stack_builder* builder,
static bool set_default_host_if_unset(grpc_channel_stack_builder* builder,
void* unused) {
const grpc_channel_args* args =
grpc_channel_stack_builder_get_channel_arguments(builder);
@ -52,15 +50,14 @@ static bool set_default_host_if_unset(grpc_exec_ctx* exec_ctx,
}
}
char* default_authority = grpc_get_default_authority(
exec_ctx, grpc_channel_stack_builder_get_target(builder));
grpc_channel_stack_builder_get_target(builder));
if (default_authority != nullptr) {
grpc_arg arg = grpc_channel_arg_string_create(
(char*)GRPC_ARG_DEFAULT_AUTHORITY, default_authority);
grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
grpc_channel_stack_builder_set_channel_arguments(exec_ctx, builder,
new_args);
grpc_channel_stack_builder_set_channel_arguments(builder, new_args);
gpr_free(default_authority);
grpc_channel_args_destroy(exec_ctx, new_args);
grpc_channel_args_destroy(new_args);
}
return true;
}

@ -23,18 +23,17 @@ grpc_connector* grpc_connector_ref(grpc_connector* connector) {
return connector;
}
void grpc_connector_unref(grpc_exec_ctx* exec_ctx, grpc_connector* connector) {
connector->vtable->unref(exec_ctx, connector);
void grpc_connector_unref(grpc_connector* connector) {
connector->vtable->unref(connector);
}
void grpc_connector_connect(grpc_exec_ctx* exec_ctx, grpc_connector* connector,
void grpc_connector_connect(grpc_connector* connector,
const grpc_connect_in_args* in_args,
grpc_connect_out_args* out_args,
grpc_closure* notify) {
connector->vtable->connect(exec_ctx, connector, in_args, out_args, notify);
connector->vtable->connect(connector, in_args, out_args, notify);
}
void grpc_connector_shutdown(grpc_exec_ctx* exec_ctx, grpc_connector* connector,
grpc_error* why) {
connector->vtable->shutdown(exec_ctx, connector, why);
void grpc_connector_shutdown(grpc_connector* connector, grpc_error* why) {
connector->vtable->shutdown(connector, why);
}

@ -49,25 +49,23 @@ typedef struct {
struct grpc_connector_vtable {
void (*ref)(grpc_connector* connector);
void (*unref)(grpc_exec_ctx* exec_ctx, grpc_connector* connector);
void (*unref)(grpc_connector* connector);
/** Implementation of grpc_connector_shutdown */
void (*shutdown)(grpc_exec_ctx* exec_ctx, grpc_connector* connector,
grpc_error* why);
void (*shutdown)(grpc_connector* connector, grpc_error* why);
/** Implementation of grpc_connector_connect */
void (*connect)(grpc_exec_ctx* exec_ctx, grpc_connector* connector,
void (*connect)(grpc_connector* connector,
const grpc_connect_in_args* in_args,
grpc_connect_out_args* out_args, grpc_closure* notify);
};
grpc_connector* grpc_connector_ref(grpc_connector* connector);
void grpc_connector_unref(grpc_exec_ctx* exec_ctx, grpc_connector* connector);
void grpc_connector_unref(grpc_connector* connector);
/** Connect using the connector: max one outstanding call at a time */
void grpc_connector_connect(grpc_exec_ctx* exec_ctx, grpc_connector* connector,
void grpc_connector_connect(grpc_connector* connector,
const grpc_connect_in_args* in_args,
grpc_connect_out_args* out_args,
grpc_closure* notify);
/** Cancel any pending connection */
void grpc_connector_shutdown(grpc_exec_ctx* exec_ctx, grpc_connector* connector,
grpc_error* why);
void grpc_connector_shutdown(grpc_connector* connector, grpc_error* why);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONNECTOR_H */

@ -61,41 +61,38 @@ typedef struct http_connect_handshaker {
} http_connect_handshaker;
// Unref and clean up handshaker.
static void http_connect_handshaker_unref(grpc_exec_ctx* exec_ctx,
http_connect_handshaker* handshaker) {
static void http_connect_handshaker_unref(http_connect_handshaker* handshaker) {
if (gpr_unref(&handshaker->refcount)) {
gpr_mu_destroy(&handshaker->mu);
if (handshaker->endpoint_to_destroy != nullptr) {
grpc_endpoint_destroy(exec_ctx, handshaker->endpoint_to_destroy);
grpc_endpoint_destroy(handshaker->endpoint_to_destroy);
}
if (handshaker->read_buffer_to_destroy != nullptr) {
grpc_slice_buffer_destroy_internal(exec_ctx,
handshaker->read_buffer_to_destroy);
grpc_slice_buffer_destroy_internal(handshaker->read_buffer_to_destroy);
gpr_free(handshaker->read_buffer_to_destroy);
}
grpc_slice_buffer_destroy_internal(exec_ctx, &handshaker->write_buffer);
grpc_slice_buffer_destroy_internal(&handshaker->write_buffer);
grpc_http_parser_destroy(&handshaker->http_parser);
grpc_http_response_destroy(&handshaker->http_response);
gpr_free(handshaker);
}
}
// Set args fields to NULL, saving the endpoint and read buffer for
// Set args fields to nullptr, saving the endpoint and read buffer for
// later destruction.
static void cleanup_args_for_failure_locked(
grpc_exec_ctx* exec_ctx, http_connect_handshaker* handshaker) {
http_connect_handshaker* handshaker) {
handshaker->endpoint_to_destroy = handshaker->args->endpoint;
handshaker->args->endpoint = nullptr;
handshaker->read_buffer_to_destroy = handshaker->args->read_buffer;
handshaker->args->read_buffer = nullptr;
grpc_channel_args_destroy(exec_ctx, handshaker->args->args);
grpc_channel_args_destroy(handshaker->args->args);
handshaker->args->args = nullptr;
}
// If the handshake failed or we're shutting down, clean up and invoke the
// callback with the error.
static void handshake_failed_locked(grpc_exec_ctx* exec_ctx,
http_connect_handshaker* handshaker,
static void handshake_failed_locked(http_connect_handshaker* handshaker,
grpc_error* error) {
if (error == GRPC_ERROR_NONE) {
// If we were shut down after an endpoint operation succeeded but
@ -108,34 +105,32 @@ static void handshake_failed_locked(grpc_exec_ctx* exec_ctx,
// before destroying them, even if we know that there are no
// pending read/write callbacks. This should be fixed, at which
// point this can be removed.
grpc_endpoint_shutdown(exec_ctx, handshaker->args->endpoint,
GRPC_ERROR_REF(error));
grpc_endpoint_shutdown(handshaker->args->endpoint, GRPC_ERROR_REF(error));
// Not shutting down, so the handshake failed. Clean up before
// invoking the callback.
cleanup_args_for_failure_locked(exec_ctx, handshaker);
cleanup_args_for_failure_locked(handshaker);
// Set shutdown to true so that subsequent calls to
// http_connect_handshaker_shutdown() do nothing.
handshaker->shutdown = true;
}
// Invoke callback.
GRPC_CLOSURE_SCHED(exec_ctx, handshaker->on_handshake_done, error);
GRPC_CLOSURE_SCHED(handshaker->on_handshake_done, error);
}
// Callback invoked when finished writing HTTP CONNECT request.
static void on_write_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void on_write_done(void* arg, grpc_error* error) {
http_connect_handshaker* handshaker = (http_connect_handshaker*)arg;
gpr_mu_lock(&handshaker->mu);
if (error != GRPC_ERROR_NONE || handshaker->shutdown) {
// If the write failed or we're shutting down, clean up and invoke the
// callback with the error.
handshake_failed_locked(exec_ctx, handshaker, GRPC_ERROR_REF(error));
handshake_failed_locked(handshaker, GRPC_ERROR_REF(error));
gpr_mu_unlock(&handshaker->mu);
http_connect_handshaker_unref(exec_ctx, handshaker);
http_connect_handshaker_unref(handshaker);
} else {
// Otherwise, read the response.
// The read callback inherits our ref to the handshaker.
grpc_endpoint_read(exec_ctx, handshaker->args->endpoint,
grpc_endpoint_read(handshaker->args->endpoint,
handshaker->args->read_buffer,
&handshaker->response_read_closure);
gpr_mu_unlock(&handshaker->mu);
@ -143,14 +138,13 @@ static void on_write_done(grpc_exec_ctx* exec_ctx, void* arg,
}
// Callback invoked for reading HTTP CONNECT response.
static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void on_read_done(void* arg, grpc_error* error) {
http_connect_handshaker* handshaker = (http_connect_handshaker*)arg;
gpr_mu_lock(&handshaker->mu);
if (error != GRPC_ERROR_NONE || handshaker->shutdown) {
// If the read failed or we're shutting down, clean up and invoke the
// callback with the error.
handshake_failed_locked(exec_ctx, handshaker, GRPC_ERROR_REF(error));
handshake_failed_locked(handshaker, GRPC_ERROR_REF(error));
goto done;
}
// Add buffer to parser.
@ -161,7 +155,7 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
handshaker->args->read_buffer->slices[i],
&body_start_offset);
if (error != GRPC_ERROR_NONE) {
handshake_failed_locked(exec_ctx, handshaker, error);
handshake_failed_locked(handshaker, error);
goto done;
}
if (handshaker->http_parser.state == GRPC_HTTP_BODY) {
@ -180,7 +174,7 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
&handshaker->args->read_buffer->slices[i + 1],
handshaker->args->read_buffer->count - i - 1);
grpc_slice_buffer_swap(handshaker->args->read_buffer, &tmp_buffer);
grpc_slice_buffer_destroy_internal(exec_ctx, &tmp_buffer);
grpc_slice_buffer_destroy_internal(&tmp_buffer);
break;
}
}
@ -197,9 +191,8 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
// complete (e.g., handling chunked transfer encoding or looking
// at the Content-Length: header).
if (handshaker->http_parser.state != GRPC_HTTP_BODY) {
grpc_slice_buffer_reset_and_unref_internal(exec_ctx,
handshaker->args->read_buffer);
grpc_endpoint_read(exec_ctx, handshaker->args->endpoint,
grpc_slice_buffer_reset_and_unref_internal(handshaker->args->read_buffer);
grpc_endpoint_read(handshaker->args->endpoint,
handshaker->args->read_buffer,
&handshaker->response_read_closure);
gpr_mu_unlock(&handshaker->mu);
@ -213,48 +206,44 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
handshaker->http_response.status);
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
handshake_failed_locked(exec_ctx, handshaker, error);
handshake_failed_locked(handshaker, error);
goto done;
}
// Success. Invoke handshake-done callback.
GRPC_CLOSURE_SCHED(exec_ctx, handshaker->on_handshake_done, error);
GRPC_CLOSURE_SCHED(handshaker->on_handshake_done, error);
done:
// Set shutdown to true so that subsequent calls to
// http_connect_handshaker_shutdown() do nothing.
handshaker->shutdown = true;
gpr_mu_unlock(&handshaker->mu);
http_connect_handshaker_unref(exec_ctx, handshaker);
http_connect_handshaker_unref(handshaker);
}
//
// Public handshaker methods
//
static void http_connect_handshaker_destroy(grpc_exec_ctx* exec_ctx,
grpc_handshaker* handshaker_in) {
static void http_connect_handshaker_destroy(grpc_handshaker* handshaker_in) {
http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
http_connect_handshaker_unref(exec_ctx, handshaker);
http_connect_handshaker_unref(handshaker);
}
static void http_connect_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
grpc_handshaker* handshaker_in,
static void http_connect_handshaker_shutdown(grpc_handshaker* handshaker_in,
grpc_error* why) {
http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
gpr_mu_lock(&handshaker->mu);
if (!handshaker->shutdown) {
handshaker->shutdown = true;
grpc_endpoint_shutdown(exec_ctx, handshaker->args->endpoint,
GRPC_ERROR_REF(why));
cleanup_args_for_failure_locked(exec_ctx, handshaker);
grpc_endpoint_shutdown(handshaker->args->endpoint, GRPC_ERROR_REF(why));
cleanup_args_for_failure_locked(handshaker);
}
gpr_mu_unlock(&handshaker->mu);
GRPC_ERROR_UNREF(why);
}
static void http_connect_handshaker_do_handshake(
grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker_in,
grpc_tcp_server_acceptor* acceptor, grpc_closure* on_handshake_done,
grpc_handshaker_args* args) {
grpc_handshaker* handshaker_in, grpc_tcp_server_acceptor* acceptor,
grpc_closure* on_handshake_done, grpc_handshaker_args* args) {
http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
// Check for HTTP CONNECT channel arg.
// If not found, invoke on_handshake_done without doing anything.
@ -266,7 +255,7 @@ static void http_connect_handshaker_do_handshake(
gpr_mu_lock(&handshaker->mu);
handshaker->shutdown = true;
gpr_mu_unlock(&handshaker->mu);
GRPC_CLOSURE_SCHED(exec_ctx, on_handshake_done, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(on_handshake_done, GRPC_ERROR_NONE);
return;
}
GPR_ASSERT(arg->type == GRPC_ARG_STRING);
@ -324,7 +313,7 @@ static void http_connect_handshaker_do_handshake(
gpr_free(header_strings);
// Take a new ref to be held by the write callback.
gpr_ref(&handshaker->refcount);
grpc_endpoint_write(exec_ctx, args->endpoint, &handshaker->write_buffer,
grpc_endpoint_write(args->endpoint, &handshaker->write_buffer,
&handshaker->request_done_closure);
gpr_mu_unlock(&handshaker->mu);
}
@ -355,14 +344,13 @@ static grpc_handshaker* grpc_http_connect_handshaker_create() {
//
static void handshaker_factory_add_handshakers(
grpc_exec_ctx* exec_ctx, grpc_handshaker_factory* factory,
const grpc_channel_args* args, grpc_handshake_manager* handshake_mgr) {
grpc_handshaker_factory* factory, const grpc_channel_args* args,
grpc_handshake_manager* handshake_mgr) {
grpc_handshake_manager_add(handshake_mgr,
grpc_http_connect_handshaker_create());
}
static void handshaker_factory_destroy(grpc_exec_ctx* exec_ctx,
grpc_handshaker_factory* factory) {}
static void handshaker_factory_destroy(grpc_handshaker_factory* factory) {}
static const grpc_handshaker_factory_vtable handshaker_factory_vtable = {
handshaker_factory_add_handshakers, handshaker_factory_destroy};

@ -36,19 +36,18 @@
/**
* Parses the 'http_proxy' env var and returns the proxy hostname to resolve or
* NULL on error. Also sets 'user_cred' to user credentials if present in the
* nullptr on error. Also sets 'user_cred' to user credentials if present in the
* 'http_proxy' env var, otherwise leaves it unchanged. It is caller's
* responsibility to gpr_free user_cred.
*/
static char* get_http_proxy_server(grpc_exec_ctx* exec_ctx, char** user_cred) {
static char* get_http_proxy_server(char** user_cred) {
GPR_ASSERT(user_cred != nullptr);
char* proxy_name = nullptr;
char* uri_str = gpr_getenv("http_proxy");
char** authority_strs = nullptr;
size_t authority_nstrs;
if (uri_str == nullptr) return nullptr;
grpc_uri* uri =
grpc_uri_parse(exec_ctx, uri_str, false /* suppress_errors */);
grpc_uri* uri = grpc_uri_parse(uri_str, false /* suppress_errors */);
if (uri == nullptr || uri->authority == nullptr) {
gpr_log(GPR_ERROR, "cannot parse value of 'http_proxy' env var");
goto done;
@ -82,18 +81,16 @@ done:
return proxy_name;
}
static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper* mapper,
static bool proxy_mapper_map_name(grpc_proxy_mapper* mapper,
const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args) {
char* user_cred = nullptr;
*name_to_resolve = get_http_proxy_server(exec_ctx, &user_cred);
*name_to_resolve = get_http_proxy_server(&user_cred);
if (*name_to_resolve == nullptr) return false;
char* no_proxy_str = nullptr;
grpc_uri* uri =
grpc_uri_parse(exec_ctx, server_uri, false /* suppress_errors */);
grpc_uri* uri = grpc_uri_parse(server_uri, false /* suppress_errors */);
if (uri == nullptr || uri->path[0] == '\0') {
gpr_log(GPR_ERROR,
"'http_proxy' environment variable set, but cannot "
@ -174,8 +171,7 @@ no_use_proxy:
return false;
}
static bool proxy_mapper_map_address(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper* mapper,
static bool proxy_mapper_map_address(grpc_proxy_mapper* mapper,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,

@ -63,15 +63,13 @@ void grpc_lb_policy_ref(grpc_lb_policy* policy REF_FUNC_EXTRA_ARGS) {
ref_mutate(policy, 1 << WEAK_REF_BITS, 0 REF_MUTATE_PASS_ARGS("STRONG_REF"));
}
static void shutdown_locked(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void shutdown_locked(void* arg, grpc_error* error) {
grpc_lb_policy* policy = (grpc_lb_policy*)arg;
policy->vtable->shutdown_locked(exec_ctx, policy);
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, policy, "strong-unref");
policy->vtable->shutdown_locked(policy);
GRPC_LB_POLICY_WEAK_UNREF(policy, "strong-unref");
}
void grpc_lb_policy_unref(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy REF_FUNC_EXTRA_ARGS) {
void grpc_lb_policy_unref(grpc_lb_policy* policy REF_FUNC_EXTRA_ARGS) {
gpr_atm old_val =
ref_mutate(policy, (gpr_atm)1 - (gpr_atm)(1 << WEAK_REF_BITS),
1 REF_MUTATE_PASS_ARGS("STRONG_UNREF"));
@ -79,13 +77,11 @@ void grpc_lb_policy_unref(grpc_exec_ctx* exec_ctx,
gpr_atm check = 1 << WEAK_REF_BITS;
if ((old_val & mask) == check) {
GRPC_CLOSURE_SCHED(
exec_ctx,
GRPC_CLOSURE_CREATE(shutdown_locked, policy,
grpc_combiner_scheduler(policy->combiner)),
GRPC_ERROR_NONE);
} else {
grpc_lb_policy_weak_unref(exec_ctx,
policy REF_FUNC_PASS_ARGS("strong-unref"));
grpc_lb_policy_weak_unref(policy REF_FUNC_PASS_ARGS("strong-unref"));
}
}
@ -93,88 +89,76 @@ void grpc_lb_policy_weak_ref(grpc_lb_policy* policy REF_FUNC_EXTRA_ARGS) {
ref_mutate(policy, 1, 0 REF_MUTATE_PASS_ARGS("WEAK_REF"));
}
void grpc_lb_policy_weak_unref(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy REF_FUNC_EXTRA_ARGS) {
void grpc_lb_policy_weak_unref(grpc_lb_policy* policy REF_FUNC_EXTRA_ARGS) {
gpr_atm old_val =
ref_mutate(policy, -(gpr_atm)1, 1 REF_MUTATE_PASS_ARGS("WEAK_UNREF"));
if (old_val == 1) {
grpc_pollset_set_destroy(exec_ctx, policy->interested_parties);
grpc_pollset_set_destroy(policy->interested_parties);
grpc_combiner* combiner = policy->combiner;
policy->vtable->destroy(exec_ctx, policy);
GRPC_COMBINER_UNREF(exec_ctx, combiner, "lb_policy");
policy->vtable->destroy(policy);
GRPC_COMBINER_UNREF(combiner, "lb_policy");
}
}
int grpc_lb_policy_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
int grpc_lb_policy_pick_locked(grpc_lb_policy* policy,
const grpc_lb_policy_pick_args* pick_args,
grpc_connected_subchannel** target,
grpc_call_context_element* context,
void** user_data, grpc_closure* on_complete) {
return policy->vtable->pick_locked(exec_ctx, policy, pick_args, target,
context, user_data, on_complete);
return policy->vtable->pick_locked(policy, pick_args, target, context,
user_data, on_complete);
}
void grpc_lb_policy_cancel_pick_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy,
void grpc_lb_policy_cancel_pick_locked(grpc_lb_policy* policy,
grpc_connected_subchannel** target,
grpc_error* error) {
policy->vtable->cancel_pick_locked(exec_ctx, policy, target, error);
policy->vtable->cancel_pick_locked(policy, target, error);
}
void grpc_lb_policy_cancel_picks_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy,
void grpc_lb_policy_cancel_picks_locked(grpc_lb_policy* policy,
uint32_t initial_metadata_flags_mask,
uint32_t initial_metadata_flags_eq,
grpc_error* error) {
policy->vtable->cancel_picks_locked(exec_ctx, policy,
initial_metadata_flags_mask,
policy->vtable->cancel_picks_locked(policy, initial_metadata_flags_mask,
initial_metadata_flags_eq, error);
}
void grpc_lb_policy_exit_idle_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy) {
policy->vtable->exit_idle_locked(exec_ctx, policy);
void grpc_lb_policy_exit_idle_locked(grpc_lb_policy* policy) {
policy->vtable->exit_idle_locked(policy);
}
void grpc_lb_policy_ping_one_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy,
grpc_closure* closure) {
policy->vtable->ping_one_locked(exec_ctx, policy, closure);
void grpc_lb_policy_ping_one_locked(grpc_lb_policy* policy,
grpc_closure* on_initiate,
grpc_closure* on_ack) {
policy->vtable->ping_one_locked(policy, on_initiate, on_ack);
}
void grpc_lb_policy_notify_on_state_change_locked(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
grpc_connectivity_state* state, grpc_closure* closure) {
policy->vtable->notify_on_state_change_locked(exec_ctx, policy, state,
closure);
grpc_lb_policy* policy, grpc_connectivity_state* state,
grpc_closure* closure) {
policy->vtable->notify_on_state_change_locked(policy, state, closure);
}
grpc_connectivity_state grpc_lb_policy_check_connectivity_locked(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
grpc_error** connectivity_error) {
return policy->vtable->check_connectivity_locked(exec_ctx, policy,
connectivity_error);
grpc_lb_policy* policy, grpc_error** connectivity_error) {
return policy->vtable->check_connectivity_locked(policy, connectivity_error);
}
void grpc_lb_policy_update_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy,
void grpc_lb_policy_update_locked(grpc_lb_policy* policy,
const grpc_lb_policy_args* lb_policy_args) {
policy->vtable->update_locked(exec_ctx, policy, lb_policy_args);
policy->vtable->update_locked(policy, lb_policy_args);
}
void grpc_lb_policy_set_reresolve_closure_locked(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
grpc_closure* request_reresolution) {
policy->vtable->set_reresolve_closure_locked(exec_ctx, policy,
request_reresolution);
grpc_lb_policy* policy, grpc_closure* request_reresolution) {
policy->vtable->set_reresolve_closure_locked(policy, request_reresolution);
}
void grpc_lb_policy_try_reresolve(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy,
void grpc_lb_policy_try_reresolve(grpc_lb_policy* policy,
grpc_core::TraceFlag* grpc_lb_trace,
grpc_error* error) {
if (policy->request_reresolution != nullptr) {
GRPC_CLOSURE_SCHED(exec_ctx, policy->request_reresolution, error);
GRPC_CLOSURE_SCHED(policy->request_reresolution, error);
policy->request_reresolution = nullptr;
if (grpc_lb_trace->enabled()) {
gpr_log(GPR_DEBUG,

@ -55,53 +55,50 @@ typedef struct grpc_lb_policy_pick_args {
} grpc_lb_policy_pick_args;
struct grpc_lb_policy_vtable {
void (*destroy)(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy);
void (*shutdown_locked)(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy);
void (*destroy)(grpc_lb_policy* policy);
void (*shutdown_locked)(grpc_lb_policy* policy);
/** \see grpc_lb_policy_pick */
int (*pick_locked)(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
int (*pick_locked)(grpc_lb_policy* policy,
const grpc_lb_policy_pick_args* pick_args,
grpc_connected_subchannel** target,
grpc_call_context_element* context, void** user_data,
grpc_closure* on_complete);
/** \see grpc_lb_policy_cancel_pick */
void (*cancel_pick_locked)(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
void (*cancel_pick_locked)(grpc_lb_policy* policy,
grpc_connected_subchannel** target,
grpc_error* error);
/** \see grpc_lb_policy_cancel_picks */
void (*cancel_picks_locked)(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
void (*cancel_picks_locked)(grpc_lb_policy* policy,
uint32_t initial_metadata_flags_mask,
uint32_t initial_metadata_flags_eq,
grpc_error* error);
/** \see grpc_lb_policy_ping_one */
void (*ping_one_locked)(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
grpc_closure* closure);
void (*ping_one_locked)(grpc_lb_policy* policy, grpc_closure* on_initiate,
grpc_closure* on_ack);
/** Try to enter a READY connectivity state */
void (*exit_idle_locked)(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy);
void (*exit_idle_locked)(grpc_lb_policy* policy);
/** check the current connectivity of the lb_policy */
grpc_connectivity_state (*check_connectivity_locked)(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
grpc_error** connectivity_error);
grpc_lb_policy* policy, grpc_error** connectivity_error);
/** call notify when the connectivity state of a channel changes from *state.
Updates *state with the new state of the policy. Calling with a NULL \a
state cancels the subscription. */
void (*notify_on_state_change_locked)(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy,
void (*notify_on_state_change_locked)(grpc_lb_policy* policy,
grpc_connectivity_state* state,
grpc_closure* closure);
void (*update_locked)(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
void (*update_locked)(grpc_lb_policy* policy,
const grpc_lb_policy_args* args);
/** \see grpc_lb_policy_set_reresolve_closure */
void (*set_reresolve_closure_locked)(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy,
void (*set_reresolve_closure_locked)(grpc_lb_policy* policy,
grpc_closure* request_reresolution);
};
@ -110,33 +107,33 @@ struct grpc_lb_policy_vtable {
/* Strong references: the policy will shutdown when they reach zero */
#define GRPC_LB_POLICY_REF(p, r) \
grpc_lb_policy_ref((p), __FILE__, __LINE__, (r))
#define GRPC_LB_POLICY_UNREF(exec_ctx, p, r) \
grpc_lb_policy_unref((exec_ctx), (p), __FILE__, __LINE__, (r))
#define GRPC_LB_POLICY_UNREF(p, r) \
grpc_lb_policy_unref((p), __FILE__, __LINE__, (r))
/* Weak references: they don't prevent the shutdown of the LB policy. When no
* strong references are left but there are still weak ones, shutdown is called.
* Once the weak reference also reaches zero, the LB policy is destroyed. */
#define GRPC_LB_POLICY_WEAK_REF(p, r) \
grpc_lb_policy_weak_ref((p), __FILE__, __LINE__, (r))
#define GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, p, r) \
grpc_lb_policy_weak_unref((exec_ctx), (p), __FILE__, __LINE__, (r))
#define GRPC_LB_POLICY_WEAK_UNREF(p, r) \
grpc_lb_policy_weak_unref((p), __FILE__, __LINE__, (r))
void grpc_lb_policy_ref(grpc_lb_policy* policy, const char* file, int line,
const char* reason);
void grpc_lb_policy_unref(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
const char* file, int line, const char* reason);
void grpc_lb_policy_unref(grpc_lb_policy* policy, const char* file, int line,
const char* reason);
void grpc_lb_policy_weak_ref(grpc_lb_policy* policy, const char* file, int line,
const char* reason);
void grpc_lb_policy_weak_unref(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
const char* file, int line, const char* reason);
void grpc_lb_policy_weak_unref(grpc_lb_policy* policy, const char* file,
int line, const char* reason);
#else
#define GRPC_LB_POLICY_REF(p, r) grpc_lb_policy_ref((p))
#define GRPC_LB_POLICY_UNREF(cl, p, r) grpc_lb_policy_unref((cl), (p))
#define GRPC_LB_POLICY_UNREF(p, r) grpc_lb_policy_unref((p))
#define GRPC_LB_POLICY_WEAK_REF(p, r) grpc_lb_policy_weak_ref((p))
#define GRPC_LB_POLICY_WEAK_UNREF(cl, p, r) grpc_lb_policy_weak_unref((cl), (p))
#define GRPC_LB_POLICY_WEAK_UNREF(p, r) grpc_lb_policy_weak_unref((p))
void grpc_lb_policy_ref(grpc_lb_policy* policy);
void grpc_lb_policy_unref(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy);
void grpc_lb_policy_unref(grpc_lb_policy* policy);
void grpc_lb_policy_weak_ref(grpc_lb_policy* policy);
void grpc_lb_policy_weak_unref(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy);
void grpc_lb_policy_weak_unref(grpc_lb_policy* policy);
#endif
/** called by concrete implementations to initialize the base struct */
@ -161,7 +158,7 @@ void grpc_lb_policy_init(grpc_lb_policy* policy,
Any IO should be done under the \a interested_parties \a grpc_pollset_set
in the \a grpc_lb_policy struct. */
int grpc_lb_policy_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
int grpc_lb_policy_pick_locked(grpc_lb_policy* policy,
const grpc_lb_policy_pick_args* pick_args,
grpc_connected_subchannel** target,
grpc_call_context_element* context,
@ -169,55 +166,48 @@ int grpc_lb_policy_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
/** Perform a connected subchannel ping (see \a grpc_connected_subchannel_ping)
against one of the connected subchannels managed by \a policy. */
void grpc_lb_policy_ping_one_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy,
grpc_closure* closure);
void grpc_lb_policy_ping_one_locked(grpc_lb_policy* policy,
grpc_closure* on_initiate,
grpc_closure* on_ack);
/** Cancel picks for \a target.
The \a on_complete callback of the pending picks will be invoked with \a
*target set to NULL. */
void grpc_lb_policy_cancel_pick_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy,
void grpc_lb_policy_cancel_pick_locked(grpc_lb_policy* policy,
grpc_connected_subchannel** target,
grpc_error* error);
/** Cancel all pending picks for which their \a initial_metadata_flags (as given
in the call to \a grpc_lb_policy_pick) matches \a initial_metadata_flags_eq
when AND'd with \a initial_metadata_flags_mask */
void grpc_lb_policy_cancel_picks_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy,
void grpc_lb_policy_cancel_picks_locked(grpc_lb_policy* policy,
uint32_t initial_metadata_flags_mask,
uint32_t initial_metadata_flags_eq,
grpc_error* error);
/** Try to enter a READY connectivity state */
void grpc_lb_policy_exit_idle_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy);
void grpc_lb_policy_exit_idle_locked(grpc_lb_policy* policy);
/* Call notify when the connectivity state of a channel changes from \a *state.
* Updates \a *state with the new state of the policy */
void grpc_lb_policy_notify_on_state_change_locked(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
grpc_connectivity_state* state, grpc_closure* closure);
grpc_lb_policy* policy, grpc_connectivity_state* state,
grpc_closure* closure);
grpc_connectivity_state grpc_lb_policy_check_connectivity_locked(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
grpc_error** connectivity_error);
grpc_lb_policy* policy, grpc_error** connectivity_error);
/** Update \a policy with \a lb_policy_args. */
void grpc_lb_policy_update_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy,
void grpc_lb_policy_update_locked(grpc_lb_policy* policy,
const grpc_lb_policy_args* lb_policy_args);
/** Set the re-resolution closure to \a request_reresolution. */
void grpc_lb_policy_set_reresolve_closure_locked(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
grpc_closure* request_reresolution);
grpc_lb_policy* policy, grpc_closure* request_reresolution);
/** Try to request a re-resolution. It's NOT a public API; it's only for use by
the LB policy implementations. */
void grpc_lb_policy_try_reresolve(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* policy,
void grpc_lb_policy_try_reresolve(grpc_lb_policy* policy,
grpc_core::TraceFlag* grpc_lb_trace,
grpc_error* error);

@ -25,14 +25,12 @@
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/profiling/timers.h"
static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
grpc_channel_element* elem,
static grpc_error* init_channel_elem(grpc_channel_element* elem,
grpc_channel_element_args* args) {
return GRPC_ERROR_NONE;
}
static void destroy_channel_elem(grpc_exec_ctx* exec_ctx,
grpc_channel_element* elem) {}
static void destroy_channel_elem(grpc_channel_element* elem) {}
typedef struct {
// Stats object to update.
@ -47,28 +45,24 @@ typedef struct {
bool recv_initial_metadata_succeeded;
} call_data;
static void on_complete_for_send(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void on_complete_for_send(void* arg, grpc_error* error) {
call_data* calld = (call_data*)arg;
if (error == GRPC_ERROR_NONE) {
calld->send_initial_metadata_succeeded = true;
}
GRPC_CLOSURE_RUN(exec_ctx, calld->original_on_complete_for_send,
GRPC_ERROR_REF(error));
GRPC_CLOSURE_RUN(calld->original_on_complete_for_send, GRPC_ERROR_REF(error));
}
static void recv_initial_metadata_ready(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void recv_initial_metadata_ready(void* arg, grpc_error* error) {
call_data* calld = (call_data*)arg;
if (error == GRPC_ERROR_NONE) {
calld->recv_initial_metadata_succeeded = true;
}
GRPC_CLOSURE_RUN(exec_ctx, calld->original_recv_initial_metadata_ready,
GRPC_CLOSURE_RUN(calld->original_recv_initial_metadata_ready,
GRPC_ERROR_REF(error));
}
static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
grpc_call_element* elem,
static grpc_error* init_call_elem(grpc_call_element* elem,
const grpc_call_element_args* args) {
call_data* calld = (call_data*)elem->call_data;
// Get stats object from context and take a ref.
@ -81,7 +75,7 @@ static grpc_error* init_call_elem(grpc_exec_ctx* exec_ctx,
return GRPC_ERROR_NONE;
}
static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
static void destroy_call_elem(grpc_call_element* elem,
const grpc_call_final_info* final_info,
grpc_closure* ignored) {
call_data* calld = (call_data*)elem->call_data;
@ -96,8 +90,7 @@ static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
}
static void start_transport_stream_op_batch(
grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
grpc_transport_stream_op_batch* batch) {
grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
call_data* calld = (call_data*)elem->call_data;
GPR_TIMER_BEGIN("clr_start_transport_stream_op_batch", 0);
// Intercept send_initial_metadata.
@ -118,7 +111,7 @@ static void start_transport_stream_op_batch(
&calld->recv_initial_metadata_ready;
}
// Chain to next filter.
grpc_call_next_op(exec_ctx, elem, batch);
grpc_call_next_op(elem, batch);
GPR_TIMER_END("clr_start_transport_stream_op_batch", 0);
}

@ -26,17 +26,17 @@
#include "src/core/lib/support/string.h"
grpc_channel* grpc_lb_policy_grpclb_create_lb_channel(
grpc_exec_ctx* exec_ctx, const char* lb_service_target_addresses,
const char* lb_service_target_addresses,
grpc_client_channel_factory* client_channel_factory,
grpc_channel_args* args) {
grpc_channel* lb_channel = grpc_client_channel_factory_create_channel(
exec_ctx, client_channel_factory, lb_service_target_addresses,
client_channel_factory, lb_service_target_addresses,
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, args);
return lb_channel;
}
grpc_channel_args* grpc_lb_policy_grpclb_build_lb_channel_args(
grpc_exec_ctx* exec_ctx, grpc_slice_hash_table* targets_info,
grpc_slice_hash_table* targets_info,
grpc_fake_resolver_response_generator* response_generator,
const grpc_channel_args* args) {
const grpc_arg to_add[] = {

@ -31,12 +31,12 @@
* \a client_channel_factory will be used for the creation of the LB channel,
* alongside the channel args passed in \a args. */
grpc_channel* grpc_lb_policy_grpclb_create_lb_channel(
grpc_exec_ctx* exec_ctx, const char* lb_service_target_addresses,
const char* lb_service_target_addresses,
grpc_client_channel_factory* client_channel_factory,
grpc_channel_args* args);
grpc_channel_args* grpc_lb_policy_grpclb_build_lb_channel_args(
grpc_exec_ctx* exec_ctx, grpc_slice_hash_table* targets_info,
grpc_slice_hash_table* targets_info,
grpc_fake_resolver_response_generator* response_generator,
const grpc_channel_args* args);

@ -29,7 +29,7 @@
#include "src/core/lib/support/string.h"
grpc_channel* grpc_lb_policy_grpclb_create_lb_channel(
grpc_exec_ctx* exec_ctx, const char* lb_service_target_addresses,
const char* lb_service_target_addresses,
grpc_client_channel_factory* client_channel_factory,
grpc_channel_args* args) {
grpc_channel_args* new_args = args;
@ -50,19 +50,19 @@ grpc_channel* grpc_lb_policy_grpclb_create_lb_channel(
new_args = grpc_channel_args_copy_and_add_and_remove(
args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
grpc_channel_credentials_unref(exec_ctx, creds_sans_call_creds);
grpc_channel_credentials_unref(creds_sans_call_creds);
}
grpc_channel* lb_channel = grpc_client_channel_factory_create_channel(
exec_ctx, client_channel_factory, lb_service_target_addresses,
client_channel_factory, lb_service_target_addresses,
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, new_args);
if (channel_credentials != nullptr) {
grpc_channel_args_destroy(exec_ctx, new_args);
grpc_channel_args_destroy(new_args);
}
return lb_channel;
}
grpc_channel_args* grpc_lb_policy_grpclb_build_lb_channel_args(
grpc_exec_ctx* exec_ctx, grpc_slice_hash_table* targets_info,
grpc_slice_hash_table* targets_info,
grpc_fake_resolver_response_generator* response_generator,
const grpc_channel_args* args) {
const grpc_arg to_add[] = {

@ -215,9 +215,6 @@ grpc_grpclb_serverlist* grpc_grpclb_response_parse_serverlist(
return nullptr;
}
}
if (res.server_list.has_expiration_interval) {
sl->expiration_interval = res.server_list.expiration_interval;
}
return sl;
}
@ -237,8 +234,6 @@ grpc_grpclb_serverlist* grpc_grpclb_serverlist_copy(
grpc_grpclb_serverlist* copy =
(grpc_grpclb_serverlist*)gpr_zalloc(sizeof(grpc_grpclb_serverlist));
copy->num_servers = sl->num_servers;
memcpy(&copy->expiration_interval, &sl->expiration_interval,
sizeof(grpc_grpclb_duration));
copy->servers = (grpc_grpclb_server**)gpr_malloc(sizeof(grpc_grpclb_server*) *
sl->num_servers);
for (size_t i = 0; i < sl->num_servers; i++) {
@ -257,10 +252,6 @@ bool grpc_grpclb_serverlist_equals(const grpc_grpclb_serverlist* lhs,
if (lhs->num_servers != rhs->num_servers) {
return false;
}
if (grpc_grpclb_duration_compare(&lhs->expiration_interval,
&rhs->expiration_interval) != 0) {
return false;
}
for (size_t i = 0; i < lhs->num_servers; i++) {
if (!grpc_grpclb_server_equals(lhs->servers[i], rhs->servers[i])) {
return false;

@ -35,7 +35,6 @@ typedef grpc_lb_v1_Duration grpc_grpclb_duration;
typedef struct {
grpc_grpclb_server** servers;
size_t num_servers;
grpc_grpclb_duration expiration_interval;
} grpc_grpclb_serverlist;
/** Create a request for a gRPC LB service under \a lb_service_name */

@ -61,9 +61,8 @@ const pb_field_t grpc_lb_v1_InitialLoadBalanceResponse_fields[3] = {
PB_LAST_FIELD
};
const pb_field_t grpc_lb_v1_ServerList_fields[3] = {
const pb_field_t grpc_lb_v1_ServerList_fields[2] = {
PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, grpc_lb_v1_ServerList, servers, servers, &grpc_lb_v1_Server_fields),
PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, grpc_lb_v1_ServerList, expiration_interval, servers, &grpc_lb_v1_Duration_fields),
PB_LAST_FIELD
};
@ -85,7 +84,7 @@ const pb_field_t grpc_lb_v1_Server_fields[5] = {
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
* field descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 65536 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 65536 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 65536 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 65536 && pb_membersize(grpc_lb_v1_ServerList, servers) < 65536 && pb_membersize(grpc_lb_v1_ServerList, expiration_interval) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v1_Duration_grpc_lb_v1_Timestamp_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 65536 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 65536 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 65536 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 65536 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 65536 && pb_membersize(grpc_lb_v1_ServerList, servers) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_grpc_lb_v1_Duration_grpc_lb_v1_Timestamp_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
#endif
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
@ -96,7 +95,7 @@ PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request)
* numbers or field sizes that are larger than what can fit in the default
* 8 bit descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256 && pb_membersize(grpc_lb_v1_ServerList, expiration_interval) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v1_Duration_grpc_lb_v1_Timestamp_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
PB_STATIC_ASSERT((pb_membersize(grpc_lb_v1_LoadBalanceRequest, initial_request) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceRequest, client_stats) < 256 && pb_membersize(grpc_lb_v1_ClientStats, timestamp) < 256 && pb_membersize(grpc_lb_v1_ClientStats, calls_finished_with_drop) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, initial_response) < 256 && pb_membersize(grpc_lb_v1_LoadBalanceResponse, server_list) < 256 && pb_membersize(grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval) < 256 && pb_membersize(grpc_lb_v1_ServerList, servers) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_grpc_lb_v1_Duration_grpc_lb_v1_Timestamp_grpc_lb_v1_LoadBalanceRequest_grpc_lb_v1_InitialLoadBalanceRequest_grpc_lb_v1_ClientStatsPerToken_grpc_lb_v1_ClientStats_grpc_lb_v1_LoadBalanceResponse_grpc_lb_v1_InitialLoadBalanceResponse_grpc_lb_v1_ServerList_grpc_lb_v1_Server)
#endif

@ -14,6 +14,11 @@ extern "C" {
#endif
/* Struct definitions */
typedef struct _grpc_lb_v1_ServerList {
pb_callback_t servers;
/* @@protoc_insertion_point(struct:grpc_lb_v1_ServerList) */
} grpc_lb_v1_ServerList;
typedef struct _grpc_lb_v1_ClientStatsPerToken {
pb_callback_t load_balance_token;
bool has_num_calls;
@ -79,13 +84,6 @@ typedef struct _grpc_lb_v1_InitialLoadBalanceResponse {
/* @@protoc_insertion_point(struct:grpc_lb_v1_InitialLoadBalanceResponse) */
} grpc_lb_v1_InitialLoadBalanceResponse;
typedef struct _grpc_lb_v1_ServerList {
pb_callback_t servers;
bool has_expiration_interval;
grpc_lb_v1_Duration expiration_interval;
/* @@protoc_insertion_point(struct:grpc_lb_v1_ServerList) */
} grpc_lb_v1_ServerList;
typedef struct _grpc_lb_v1_LoadBalanceRequest {
bool has_initial_request;
grpc_lb_v1_InitialLoadBalanceRequest initial_request;
@ -113,7 +111,7 @@ typedef struct _grpc_lb_v1_LoadBalanceResponse {
#define grpc_lb_v1_ClientStats_init_default {false, grpc_lb_v1_Timestamp_init_default, false, 0, false, 0, false, 0, false, 0, {{NULL}, NULL}}
#define grpc_lb_v1_LoadBalanceResponse_init_default {false, grpc_lb_v1_InitialLoadBalanceResponse_init_default, false, grpc_lb_v1_ServerList_init_default}
#define grpc_lb_v1_InitialLoadBalanceResponse_init_default {false, "", false, grpc_lb_v1_Duration_init_default}
#define grpc_lb_v1_ServerList_init_default {{{NULL}, NULL}, false, grpc_lb_v1_Duration_init_default}
#define grpc_lb_v1_ServerList_init_default {{{NULL}, NULL}}
#define grpc_lb_v1_Server_init_default {false, {0, {0}}, false, 0, false, "", false, 0}
#define grpc_lb_v1_Duration_init_zero {false, 0, false, 0}
#define grpc_lb_v1_Timestamp_init_zero {false, 0, false, 0}
@ -123,10 +121,11 @@ typedef struct _grpc_lb_v1_LoadBalanceResponse {
#define grpc_lb_v1_ClientStats_init_zero {false, grpc_lb_v1_Timestamp_init_zero, false, 0, false, 0, false, 0, false, 0, {{NULL}, NULL}}
#define grpc_lb_v1_LoadBalanceResponse_init_zero {false, grpc_lb_v1_InitialLoadBalanceResponse_init_zero, false, grpc_lb_v1_ServerList_init_zero}
#define grpc_lb_v1_InitialLoadBalanceResponse_init_zero {false, "", false, grpc_lb_v1_Duration_init_zero}
#define grpc_lb_v1_ServerList_init_zero {{{NULL}, NULL}, false, grpc_lb_v1_Duration_init_zero}
#define grpc_lb_v1_ServerList_init_zero {{{NULL}, NULL}}
#define grpc_lb_v1_Server_init_zero {false, {0, {0}}, false, 0, false, "", false, 0}
/* Field tags (for use in manual encoding/decoding) */
#define grpc_lb_v1_ServerList_servers_tag 1
#define grpc_lb_v1_ClientStatsPerToken_load_balance_token_tag 1
#define grpc_lb_v1_ClientStatsPerToken_num_calls_tag 2
#define grpc_lb_v1_Duration_seconds_tag 1
@ -146,8 +145,6 @@ typedef struct _grpc_lb_v1_LoadBalanceResponse {
#define grpc_lb_v1_ClientStats_calls_finished_with_drop_tag 8
#define grpc_lb_v1_InitialLoadBalanceResponse_load_balancer_delegate_tag 1
#define grpc_lb_v1_InitialLoadBalanceResponse_client_stats_report_interval_tag 2
#define grpc_lb_v1_ServerList_servers_tag 1
#define grpc_lb_v1_ServerList_expiration_interval_tag 3
#define grpc_lb_v1_LoadBalanceRequest_initial_request_tag 1
#define grpc_lb_v1_LoadBalanceRequest_client_stats_tag 2
#define grpc_lb_v1_LoadBalanceResponse_initial_response_tag 1
@ -162,7 +159,7 @@ extern const pb_field_t grpc_lb_v1_ClientStatsPerToken_fields[3];
extern const pb_field_t grpc_lb_v1_ClientStats_fields[7];
extern const pb_field_t grpc_lb_v1_LoadBalanceResponse_fields[3];
extern const pb_field_t grpc_lb_v1_InitialLoadBalanceResponse_fields[3];
extern const pb_field_t grpc_lb_v1_ServerList_fields[3];
extern const pb_field_t grpc_lb_v1_ServerList_fields[2];
extern const pb_field_t grpc_lb_v1_Server_fields[5];
/* Maximum encoded size of messages (where known) */

@ -57,12 +57,12 @@ typedef struct {
grpc_connectivity_state_tracker state_tracker;
} pick_first_lb_policy;
static void pf_destroy(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol) {
static void pf_destroy(grpc_lb_policy* pol) {
pick_first_lb_policy* p = (pick_first_lb_policy*)pol;
GPR_ASSERT(p->subchannel_list == nullptr);
GPR_ASSERT(p->latest_pending_subchannel_list == nullptr);
GPR_ASSERT(p->pending_picks == nullptr);
grpc_connectivity_state_destroy(exec_ctx, &p->state_tracker);
grpc_connectivity_state_destroy(&p->state_tracker);
gpr_free(p);
grpc_subchannel_index_unref();
if (grpc_lb_pick_first_trace.enabled()) {
@ -70,7 +70,7 @@ static void pf_destroy(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol) {
}
}
static void pf_shutdown_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol) {
static void pf_shutdown_locked(grpc_lb_policy* pol) {
pick_first_lb_policy* p = (pick_first_lb_policy*)pol;
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
if (grpc_lb_pick_first_trace.enabled()) {
@ -81,28 +81,27 @@ static void pf_shutdown_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol) {
while ((pp = p->pending_picks) != nullptr) {
p->pending_picks = pp->next;
*pp->target = nullptr;
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete, GRPC_ERROR_REF(error));
GRPC_CLOSURE_SCHED(pp->on_complete, GRPC_ERROR_REF(error));
gpr_free(pp);
}
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error),
"shutdown");
grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_REF(error), "shutdown");
if (p->subchannel_list != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
"pf_shutdown");
p->subchannel_list = nullptr;
}
if (p->latest_pending_subchannel_list != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(
exec_ctx, p->latest_pending_subchannel_list, "pf_shutdown");
p->latest_pending_subchannel_list, "pf_shutdown");
p->latest_pending_subchannel_list = nullptr;
}
grpc_lb_policy_try_reresolve(exec_ctx, &p->base, &grpc_lb_pick_first_trace,
grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_pick_first_trace,
GRPC_ERROR_CANCELLED);
GRPC_ERROR_UNREF(error);
}
static void pf_cancel_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
static void pf_cancel_pick_locked(grpc_lb_policy* pol,
grpc_connected_subchannel** target,
grpc_error* error) {
pick_first_lb_policy* p = (pick_first_lb_policy*)pol;
@ -112,7 +111,7 @@ static void pf_cancel_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
pending_pick* next = pp->next;
if (pp->target == target) {
*target = nullptr;
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete,
GRPC_CLOSURE_SCHED(pp->on_complete,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick Cancelled", &error, 1));
gpr_free(pp);
@ -125,7 +124,7 @@ static void pf_cancel_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
GRPC_ERROR_UNREF(error);
}
static void pf_cancel_picks_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
static void pf_cancel_picks_locked(grpc_lb_policy* pol,
uint32_t initial_metadata_flags_mask,
uint32_t initial_metadata_flags_eq,
grpc_error* error) {
@ -136,7 +135,7 @@ static void pf_cancel_picks_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
pending_pick* next = pp->next;
if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
initial_metadata_flags_eq) {
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete,
GRPC_CLOSURE_SCHED(pp->on_complete,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick Cancelled", &error, 1));
gpr_free(pp);
@ -149,8 +148,7 @@ static void pf_cancel_picks_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
GRPC_ERROR_UNREF(error);
}
static void start_picking_locked(grpc_exec_ctx* exec_ctx,
pick_first_lb_policy* p) {
static void start_picking_locked(pick_first_lb_policy* p) {
p->started_picking = true;
if (p->subchannel_list != nullptr &&
p->subchannel_list->num_subchannels > 0) {
@ -160,21 +158,21 @@ static void start_picking_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_subchannel_list_ref_for_connectivity_watch(
p->subchannel_list, "connectivity_watch+start_picking");
grpc_lb_subchannel_data_start_connectivity_watch(
exec_ctx, &p->subchannel_list->subchannels[i]);
&p->subchannel_list->subchannels[i]);
break;
}
}
}
}
static void pf_exit_idle_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol) {
static void pf_exit_idle_locked(grpc_lb_policy* pol) {
pick_first_lb_policy* p = (pick_first_lb_policy*)pol;
if (!p->started_picking) {
start_picking_locked(exec_ctx, p);
start_picking_locked(p);
}
}
static int pf_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
static int pf_pick_locked(grpc_lb_policy* pol,
const grpc_lb_policy_pick_args* pick_args,
grpc_connected_subchannel** target,
grpc_call_context_element* context, void** user_data,
@ -188,7 +186,7 @@ static int pf_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
}
// No subchannel selected yet, so handle asynchronously.
if (!p->started_picking) {
start_picking_locked(exec_ctx, p);
start_picking_locked(p);
}
pending_pick* pp = (pending_pick*)gpr_malloc(sizeof(*pp));
pp->next = p->pending_picks;
@ -199,48 +197,47 @@ static int pf_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
return 0;
}
static void destroy_unselected_subchannels_locked(grpc_exec_ctx* exec_ctx,
pick_first_lb_policy* p) {
static void destroy_unselected_subchannels_locked(pick_first_lb_policy* p) {
for (size_t i = 0; i < p->subchannel_list->num_subchannels; ++i) {
grpc_lb_subchannel_data* sd = &p->subchannel_list->subchannels[i];
if (p->selected != sd) {
grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd,
grpc_lb_subchannel_data_unref_subchannel(sd,
"selected_different_subchannel");
}
}
}
static grpc_connectivity_state pf_check_connectivity_locked(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol, grpc_error** error) {
grpc_lb_policy* pol, grpc_error** error) {
pick_first_lb_policy* p = (pick_first_lb_policy*)pol;
return grpc_connectivity_state_get(&p->state_tracker, error);
}
static void pf_notify_on_state_change_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* pol,
static void pf_notify_on_state_change_locked(grpc_lb_policy* pol,
grpc_connectivity_state* current,
grpc_closure* notify) {
pick_first_lb_policy* p = (pick_first_lb_policy*)pol;
grpc_connectivity_state_notify_on_state_change(exec_ctx, &p->state_tracker,
current, notify);
grpc_connectivity_state_notify_on_state_change(&p->state_tracker, current,
notify);
}
static void pf_ping_one_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
grpc_closure* closure) {
static void pf_ping_one_locked(grpc_lb_policy* pol, grpc_closure* on_initiate,
grpc_closure* on_ack) {
pick_first_lb_policy* p = (pick_first_lb_policy*)pol;
if (p->selected) {
grpc_connected_subchannel_ping(exec_ctx, p->selected->connected_subchannel,
closure);
grpc_connected_subchannel_ping(p->selected->connected_subchannel,
on_initiate, on_ack);
} else {
GRPC_CLOSURE_SCHED(exec_ctx, closure,
GRPC_CLOSURE_SCHED(on_initiate,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected"));
GRPC_CLOSURE_SCHED(on_ack,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected"));
}
}
static void pf_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error);
static void pf_connectivity_changed_locked(void* arg, grpc_error* error);
static void pf_update_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
static void pf_update_locked(grpc_lb_policy* policy,
const grpc_lb_policy_args* args) {
pick_first_lb_policy* p = (pick_first_lb_policy*)policy;
const grpc_arg* arg =
@ -249,7 +246,7 @@ static void pf_update_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
if (p->subchannel_list == nullptr) {
// If we don't have a current subchannel list, go into TRANSIENT FAILURE.
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
&p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"),
"pf_update_missing");
} else {
@ -268,17 +265,17 @@ static void pf_update_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
(void*)p, (unsigned long)addresses->num_addresses);
}
grpc_lb_subchannel_list* subchannel_list = grpc_lb_subchannel_list_create(
exec_ctx, &p->base, &grpc_lb_pick_first_trace, addresses, args,
&p->base, &grpc_lb_pick_first_trace, addresses, args,
pf_connectivity_changed_locked);
if (subchannel_list->num_subchannels == 0) {
// Empty update or no valid subchannels. Unsubscribe from all current
// subchannels and put the channel in TRANSIENT_FAILURE.
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
&p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
"pf_update_empty");
if (p->subchannel_list != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
"sl_shutdown_empty_update");
}
p->subchannel_list = subchannel_list; // Empty list.
@ -289,7 +286,7 @@ static void pf_update_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
// We don't yet have a selected subchannel, so replace the current
// subchannel list immediately.
if (p->subchannel_list != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
"pf_update_before_selected");
}
p->subchannel_list = subchannel_list;
@ -314,19 +311,19 @@ static void pf_update_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
p->selected = sd;
if (p->subchannel_list != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(
exec_ctx, p->subchannel_list, "pf_update_includes_selected");
p->subchannel_list, "pf_update_includes_selected");
}
p->subchannel_list = subchannel_list;
destroy_unselected_subchannels_locked(exec_ctx, p);
destroy_unselected_subchannels_locked(p);
grpc_lb_subchannel_list_ref_for_connectivity_watch(
subchannel_list, "connectivity_watch+replace_selected");
grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_start_connectivity_watch(sd);
// If there was a previously pending update (which may or may
// not have contained the currently selected subchannel), drop
// it, so that it doesn't override what we've done here.
if (p->latest_pending_subchannel_list != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(
exec_ctx, p->latest_pending_subchannel_list,
p->latest_pending_subchannel_list,
"pf_update_includes_selected+outdated");
p->latest_pending_subchannel_list = nullptr;
}
@ -346,8 +343,7 @@ static void pf_update_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
(void*)subchannel_list);
}
grpc_lb_subchannel_list_shutdown_and_unref(
exec_ctx, p->latest_pending_subchannel_list,
"sl_outdated_dont_smash");
p->latest_pending_subchannel_list, "sl_outdated_dont_smash");
}
p->latest_pending_subchannel_list = subchannel_list;
}
@ -357,12 +353,11 @@ static void pf_update_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
grpc_lb_subchannel_list_ref_for_connectivity_watch(
subchannel_list, "connectivity_watch+update");
grpc_lb_subchannel_data_start_connectivity_watch(
exec_ctx, &subchannel_list->subchannels[0]);
&subchannel_list->subchannels[0]);
}
}
static void pf_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void pf_connectivity_changed_locked(void* arg, grpc_error* error) {
grpc_lb_subchannel_data* sd = (grpc_lb_subchannel_data*)arg;
pick_first_lb_policy* p = (pick_first_lb_policy*)sd->subchannel_list->policy;
if (grpc_lb_pick_first_trace.enabled()) {
@ -380,18 +375,18 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
}
// If the policy is shutting down, unref and return.
if (p->shutdown) {
grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd, "pf_shutdown");
grpc_lb_subchannel_list_unref_for_connectivity_watch(
exec_ctx, sd->subchannel_list, "pf_shutdown");
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
grpc_lb_subchannel_data_unref_subchannel(sd, "pf_shutdown");
grpc_lb_subchannel_list_unref_for_connectivity_watch(sd->subchannel_list,
"pf_shutdown");
return;
}
// If the subchannel list is shutting down, stop watching.
if (sd->subchannel_list->shutting_down || error == GRPC_ERROR_CANCELLED) {
grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd, "pf_sl_shutdown");
grpc_lb_subchannel_list_unref_for_connectivity_watch(
exec_ctx, sd->subchannel_list, "pf_sl_shutdown");
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
grpc_lb_subchannel_data_unref_subchannel(sd, "pf_sl_shutdown");
grpc_lb_subchannel_list_unref_for_connectivity_watch(sd->subchannel_list,
"pf_sl_shutdown");
return;
}
// If we're still here, the notification must be for a subchannel in
@ -407,15 +402,15 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
if (sd->curr_connectivity_state != GRPC_CHANNEL_READY &&
p->latest_pending_subchannel_list != nullptr) {
p->selected = nullptr;
grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
grpc_lb_subchannel_list_unref_for_connectivity_watch(
exec_ctx, sd->subchannel_list, "selected_not_ready+switch_to_update");
sd->subchannel_list, "selected_not_ready+switch_to_update");
grpc_lb_subchannel_list_shutdown_and_unref(
exec_ctx, p->subchannel_list, "selected_not_ready+switch_to_update");
p->subchannel_list, "selected_not_ready+switch_to_update");
p->subchannel_list = p->latest_pending_subchannel_list;
p->latest_pending_subchannel_list = nullptr;
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
&p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "selected_not_ready+switch_to_update");
} else {
// TODO(juanlishen): we re-resolve when the selected subchannel goes to
@ -426,27 +421,26 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
if (sd->curr_connectivity_state == GRPC_CHANNEL_SHUTDOWN ||
sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
// If the selected channel goes bad, request a re-resolution.
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE,
grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_IDLE,
GRPC_ERROR_NONE,
"selected_changed+reresolve");
p->started_picking = false;
grpc_lb_policy_try_reresolve(
exec_ctx, &p->base, &grpc_lb_pick_first_trace, GRPC_ERROR_NONE);
grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_pick_first_trace,
GRPC_ERROR_NONE);
} else {
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
grpc_connectivity_state_set(&p->state_tracker,
sd->curr_connectivity_state,
GRPC_ERROR_REF(error), "selected_changed");
}
if (sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN) {
// Renew notification.
grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_start_connectivity_watch(sd);
} else {
p->selected = nullptr;
grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
grpc_lb_subchannel_list_unref_for_connectivity_watch(
exec_ctx, sd->subchannel_list, "pf_selected_shutdown");
grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd,
"pf_selected_shutdown");
sd->subchannel_list, "pf_selected_shutdown");
grpc_lb_subchannel_data_unref_subchannel(sd, "pf_selected_shutdown");
}
}
return;
@ -466,15 +460,14 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
// p->subchannel_list.
if (sd->subchannel_list == p->latest_pending_subchannel_list) {
GPR_ASSERT(p->subchannel_list != nullptr);
grpc_lb_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
"finish_update");
p->subchannel_list = p->latest_pending_subchannel_list;
p->latest_pending_subchannel_list = nullptr;
}
// Cases 1 and 2.
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_READY, GRPC_ERROR_NONE,
"connecting_ready");
grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "connecting_ready");
sd->connected_subchannel = GRPC_CONNECTED_SUBCHANNEL_REF(
grpc_subchannel_get_connected_subchannel(sd->subchannel),
"connected");
@ -484,7 +477,7 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
(void*)sd->subchannel);
}
// Drop all other subchannels, since we are now connected.
destroy_unselected_subchannels_locked(exec_ctx, p);
destroy_unselected_subchannels_locked(p);
// Update any calls that were waiting for a pick.
pending_pick* pp;
while ((pp = p->pending_picks)) {
@ -496,15 +489,15 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
"Servicing pending pick with selected subchannel %p",
(void*)p->selected);
}
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(pp->on_complete, GRPC_ERROR_NONE);
gpr_free(pp);
}
// Renew notification.
grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_start_connectivity_watch(sd);
break;
}
case GRPC_CHANNEL_TRANSIENT_FAILURE: {
grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
do {
sd->subchannel_list->checking_subchannel =
(sd->subchannel_list->checking_subchannel + 1) %
@ -517,29 +510,28 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
if (sd->subchannel_list->checking_subchannel == 0 &&
sd->subchannel_list == p->subchannel_list) {
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
&p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "connecting_transient_failure");
}
// Reuses the connectivity refs from the previous watch.
grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_start_connectivity_watch(sd);
break;
}
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_IDLE: {
// Only update connectivity state in case 1.
if (sd->subchannel_list == p->subchannel_list) {
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_CONNECTING,
GRPC_ERROR_REF(error), "connecting_changed");
grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_CONNECTING,
GRPC_ERROR_REF(error),
"connecting_changed");
}
// Renew notification.
grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_start_connectivity_watch(sd);
break;
}
case GRPC_CHANNEL_SHUTDOWN: {
grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd,
"pf_candidate_shutdown");
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
grpc_lb_subchannel_data_unref_subchannel(sd, "pf_candidate_shutdown");
// Advance to next subchannel and check its state.
grpc_lb_subchannel_data* original_sd = sd;
do {
@ -551,31 +543,30 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
} while (sd->subchannel == nullptr && sd != original_sd);
if (sd == original_sd) {
grpc_lb_subchannel_list_unref_for_connectivity_watch(
exec_ctx, sd->subchannel_list, "pf_exhausted_subchannels");
sd->subchannel_list, "pf_exhausted_subchannels");
if (sd->subchannel_list == p->subchannel_list) {
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_IDLE, GRPC_ERROR_NONE,
grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_IDLE,
GRPC_ERROR_NONE,
"exhausted_subchannels+reresolve");
p->started_picking = false;
grpc_lb_policy_try_reresolve(
exec_ctx, &p->base, &grpc_lb_pick_first_trace, GRPC_ERROR_NONE);
grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_pick_first_trace,
GRPC_ERROR_NONE);
}
} else {
if (sd->subchannel_list == p->subchannel_list) {
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
&p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "subchannel_failed");
}
// Reuses the connectivity refs from the previous watch.
grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_start_connectivity_watch(sd);
}
}
}
}
static void pf_set_reresolve_closure_locked(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
grpc_closure* request_reresolution) {
grpc_lb_policy* policy, grpc_closure* request_reresolution) {
pick_first_lb_policy* p = (pick_first_lb_policy*)policy;
GPR_ASSERT(!p->shutdown);
GPR_ASSERT(policy->request_reresolution == nullptr);
@ -599,15 +590,14 @@ static void pick_first_factory_ref(grpc_lb_policy_factory* factory) {}
static void pick_first_factory_unref(grpc_lb_policy_factory* factory) {}
static grpc_lb_policy* create_pick_first(grpc_exec_ctx* exec_ctx,
grpc_lb_policy_factory* factory,
static grpc_lb_policy* create_pick_first(grpc_lb_policy_factory* factory,
grpc_lb_policy_args* args) {
GPR_ASSERT(args->client_channel_factory != nullptr);
pick_first_lb_policy* p = (pick_first_lb_policy*)gpr_zalloc(sizeof(*p));
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_DEBUG, "Pick First %p created.", (void*)p);
}
pf_update_locked(exec_ctx, &p->base, args);
pf_update_locked(&p->base, args);
grpc_lb_policy_init(&p->base, &pick_first_lb_policy_vtable, args->combiner);
grpc_subchannel_index_ref();
return &p->base;

@ -154,7 +154,7 @@ static void update_last_ready_subchannel_index_locked(round_robin_lb_policy* p,
}
}
static void rr_destroy(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol) {
static void rr_destroy(grpc_lb_policy* pol) {
round_robin_lb_policy* p = (round_robin_lb_policy*)pol;
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG, "[RR %p] Destroying Round Robin policy at %p",
@ -162,12 +162,12 @@ static void rr_destroy(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol) {
}
GPR_ASSERT(p->subchannel_list == nullptr);
GPR_ASSERT(p->latest_pending_subchannel_list == nullptr);
grpc_connectivity_state_destroy(exec_ctx, &p->state_tracker);
grpc_connectivity_state_destroy(&p->state_tracker);
grpc_subchannel_index_unref();
gpr_free(p);
}
static void rr_shutdown_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol) {
static void rr_shutdown_locked(grpc_lb_policy* pol) {
round_robin_lb_policy* p = (round_robin_lb_policy*)pol;
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
if (grpc_lb_round_robin_trace.enabled()) {
@ -178,29 +178,27 @@ static void rr_shutdown_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol) {
while ((pp = p->pending_picks) != nullptr) {
p->pending_picks = pp->next;
*pp->target = nullptr;
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete, GRPC_ERROR_REF(error));
GRPC_CLOSURE_SCHED(pp->on_complete, GRPC_ERROR_REF(error));
gpr_free(pp);
}
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error),
"rr_shutdown");
grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_REF(error), "rr_shutdown");
if (p->subchannel_list != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
"sl_shutdown_rr_shutdown");
p->subchannel_list = nullptr;
}
if (p->latest_pending_subchannel_list != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(
exec_ctx, p->latest_pending_subchannel_list,
"sl_shutdown_pending_rr_shutdown");
p->latest_pending_subchannel_list, "sl_shutdown_pending_rr_shutdown");
p->latest_pending_subchannel_list = nullptr;
}
grpc_lb_policy_try_reresolve(exec_ctx, &p->base, &grpc_lb_round_robin_trace,
grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_round_robin_trace,
GRPC_ERROR_CANCELLED);
GRPC_ERROR_UNREF(error);
}
static void rr_cancel_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
static void rr_cancel_pick_locked(grpc_lb_policy* pol,
grpc_connected_subchannel** target,
grpc_error* error) {
round_robin_lb_policy* p = (round_robin_lb_policy*)pol;
@ -210,7 +208,7 @@ static void rr_cancel_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
pending_pick* next = pp->next;
if (pp->target == target) {
*target = nullptr;
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete,
GRPC_CLOSURE_SCHED(pp->on_complete,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick cancelled", &error, 1));
gpr_free(pp);
@ -223,7 +221,7 @@ static void rr_cancel_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
GRPC_ERROR_UNREF(error);
}
static void rr_cancel_picks_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
static void rr_cancel_picks_locked(grpc_lb_policy* pol,
uint32_t initial_metadata_flags_mask,
uint32_t initial_metadata_flags_eq,
grpc_error* error) {
@ -235,7 +233,7 @@ static void rr_cancel_picks_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
initial_metadata_flags_eq) {
*pp->target = nullptr;
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete,
GRPC_CLOSURE_SCHED(pp->on_complete,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick cancelled", &error, 1));
gpr_free(pp);
@ -248,27 +246,26 @@ static void rr_cancel_picks_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
GRPC_ERROR_UNREF(error);
}
static void start_picking_locked(grpc_exec_ctx* exec_ctx,
round_robin_lb_policy* p) {
static void start_picking_locked(round_robin_lb_policy* p) {
p->started_picking = true;
for (size_t i = 0; i < p->subchannel_list->num_subchannels; i++) {
if (p->subchannel_list->subchannels[i].subchannel != nullptr) {
grpc_lb_subchannel_list_ref_for_connectivity_watch(p->subchannel_list,
"connectivity_watch");
grpc_lb_subchannel_data_start_connectivity_watch(
exec_ctx, &p->subchannel_list->subchannels[i]);
&p->subchannel_list->subchannels[i]);
}
}
}
static void rr_exit_idle_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol) {
static void rr_exit_idle_locked(grpc_lb_policy* pol) {
round_robin_lb_policy* p = (round_robin_lb_policy*)pol;
if (!p->started_picking) {
start_picking_locked(exec_ctx, p);
start_picking_locked(p);
}
}
static int rr_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
static int rr_pick_locked(grpc_lb_policy* pol,
const grpc_lb_policy_pick_args* pick_args,
grpc_connected_subchannel** target,
grpc_call_context_element* context, void** user_data,
@ -305,7 +302,7 @@ static int rr_pick_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
}
/* no pick currently available. Save for later in list of pending picks */
if (!p->started_picking) {
start_picking_locked(exec_ctx, p);
start_picking_locked(p);
}
pending_pick* pp = (pending_pick*)gpr_malloc(sizeof(*pp));
pp->next = p->pending_picks;
@ -348,8 +345,7 @@ static void update_state_counters_locked(grpc_lb_subchannel_data* sd) {
* (the grpc_lb_subchannel_data associated with the updated subchannel) and the
* subchannel list \a sd belongs to (sd->subchannel_list). \a error will be used
* only if the policy transitions to state TRANSIENT_FAILURE. */
static void update_lb_connectivity_status_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_subchannel_data* sd,
static void update_lb_connectivity_status_locked(grpc_lb_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).
@ -365,55 +361,45 @@ static void update_lb_connectivity_status_locked(grpc_exec_ctx* exec_ctx,
* CHECK: subchannel_list->num_shutdown ==
* subchannel_list->num_subchannels.
*
* 4) RULE: ALL subchannels are TRANSIENT_FAILURE => policy is
* 4) RULE: ALL subchannels are SHUTDOWN or TRANSIENT_FAILURE => policy is
* TRANSIENT_FAILURE.
* CHECK: subchannel_list->num_transient_failures ==
* CHECK: subchannel_list->num_shutdown +
* subchannel_list->num_transient_failures ==
* subchannel_list->num_subchannels.
*
* 5) RULE: ALL subchannels are IDLE => policy is IDLE.
* CHECK: subchannel_list->num_idle == subchannel_list->num_subchannels.
* (Note that all the subchannels will transition from IDLE to CONNECTING
* in batch when we start trying to connect.)
*/
// TODO(juanlishen): if the subchannel states are mixed by {SHUTDOWN,
// TRANSIENT_FAILURE}, we don't change the state. We may want to improve on
// this.
// TODO(juanlishen): For rule 4, we may want to re-resolve instead.
grpc_lb_subchannel_list* subchannel_list = sd->subchannel_list;
round_robin_lb_policy* p = (round_robin_lb_policy*)subchannel_list->policy;
GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_IDLE);
if (subchannel_list->num_ready > 0) {
/* 1) READY */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker, GRPC_CHANNEL_READY,
grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "rr_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");
grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_CONNECTING,
GRPC_ERROR_NONE, "rr_connecting");
} else if (subchannel_list->num_shutdown ==
subchannel_list->num_subchannels) {
/* 3) IDLE and re-resolve */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker, GRPC_CHANNEL_IDLE,
grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_IDLE,
GRPC_ERROR_NONE,
"rr_exhausted_subchannels+reresolve");
p->started_picking = false;
grpc_lb_policy_try_reresolve(exec_ctx, &p->base, &grpc_lb_round_robin_trace,
grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_round_robin_trace,
GRPC_ERROR_NONE);
} else if (subchannel_list->num_transient_failures ==
} else if (subchannel_list->num_shutdown +
subchannel_list->num_transient_failures ==
subchannel_list->num_subchannels) {
/* 4) TRANSIENT_FAILURE */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
grpc_connectivity_state_set(&p->state_tracker,
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "rr_transient_failure");
} else if (subchannel_list->num_idle == subchannel_list->num_subchannels) {
/* 5) IDLE */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker, GRPC_CHANNEL_IDLE,
GRPC_ERROR_NONE, "rr_idle");
}
GRPC_ERROR_UNREF(error);
}
static void rr_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void rr_connectivity_changed_locked(void* arg, grpc_error* error) {
grpc_lb_subchannel_data* sd = (grpc_lb_subchannel_data*)arg;
round_robin_lb_policy* p =
(round_robin_lb_policy*)sd->subchannel_list->policy;
@ -431,18 +417,18 @@ static void rr_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
}
// If the policy is shutting down, unref and return.
if (p->shutdown) {
grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd, "rr_shutdown");
grpc_lb_subchannel_list_unref_for_connectivity_watch(
exec_ctx, sd->subchannel_list, "rr_shutdown");
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
grpc_lb_subchannel_data_unref_subchannel(sd, "rr_shutdown");
grpc_lb_subchannel_list_unref_for_connectivity_watch(sd->subchannel_list,
"rr_shutdown");
return;
}
// If the subchannel list is shutting down, stop watching.
if (sd->subchannel_list->shutting_down || error == GRPC_ERROR_CANCELLED) {
grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd, "rr_sl_shutdown");
grpc_lb_subchannel_list_unref_for_connectivity_watch(
exec_ctx, sd->subchannel_list, "rr_sl_shutdown");
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
grpc_lb_subchannel_data_unref_subchannel(sd, "rr_sl_shutdown");
grpc_lb_subchannel_list_unref_for_connectivity_watch(sd->subchannel_list,
"rr_sl_shutdown");
return;
}
// If we're still here, the notification must be for a subchannel in
@ -455,14 +441,13 @@ static void rr_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
sd->curr_connectivity_state = sd->pending_connectivity_state_unsafe;
// Update state counters and new overall state.
update_state_counters_locked(sd);
update_lb_connectivity_status_locked(exec_ctx, sd, GRPC_ERROR_REF(error));
update_lb_connectivity_status_locked(sd, GRPC_ERROR_REF(error));
// If the sd's new state is SHUTDOWN, unref the subchannel.
if (sd->curr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
grpc_lb_subchannel_data_stop_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd,
"rr_connectivity_shutdown");
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
grpc_lb_subchannel_data_unref_subchannel(sd, "rr_connectivity_shutdown");
grpc_lb_subchannel_list_unref_for_connectivity_watch(
exec_ctx, sd->subchannel_list, "rr_connectivity_shutdown");
sd->subchannel_list, "rr_connectivity_shutdown");
} else { // sd not in SHUTDOWN
if (sd->curr_connectivity_state == GRPC_CHANNEL_READY) {
if (sd->connected_subchannel == nullptr) {
@ -490,8 +475,8 @@ static void rr_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
}
if (p->subchannel_list != nullptr) {
// dispose of the current subchannel_list
grpc_lb_subchannel_list_shutdown_and_unref(
exec_ctx, p->subchannel_list, "sl_phase_out_shutdown");
grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
"sl_phase_out_shutdown");
}
p->subchannel_list = p->latest_pending_subchannel_list;
p->latest_pending_subchannel_list = nullptr;
@ -523,32 +508,31 @@ static void rr_connectivity_changed_locked(grpc_exec_ctx* exec_ctx, void* arg,
(void*)p, (void*)selected->subchannel,
(void*)p->subchannel_list, (unsigned long)next_ready_index);
}
GRPC_CLOSURE_SCHED(exec_ctx, pp->on_complete, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(pp->on_complete, GRPC_ERROR_NONE);
gpr_free(pp);
}
}
// Renew notification.
grpc_lb_subchannel_data_start_connectivity_watch(exec_ctx, sd);
grpc_lb_subchannel_data_start_connectivity_watch(sd);
}
}
static grpc_connectivity_state rr_check_connectivity_locked(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol, grpc_error** error) {
grpc_lb_policy* pol, grpc_error** error) {
round_robin_lb_policy* p = (round_robin_lb_policy*)pol;
return grpc_connectivity_state_get(&p->state_tracker, error);
}
static void rr_notify_on_state_change_locked(grpc_exec_ctx* exec_ctx,
grpc_lb_policy* pol,
static void rr_notify_on_state_change_locked(grpc_lb_policy* pol,
grpc_connectivity_state* current,
grpc_closure* notify) {
round_robin_lb_policy* p = (round_robin_lb_policy*)pol;
grpc_connectivity_state_notify_on_state_change(exec_ctx, &p->state_tracker,
current, notify);
grpc_connectivity_state_notify_on_state_change(&p->state_tracker, current,
notify);
}
static void rr_ping_one_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
grpc_closure* closure) {
static void rr_ping_one_locked(grpc_lb_policy* pol, grpc_closure* on_initiate,
grpc_closure* on_ack) {
round_robin_lb_policy* p = (round_robin_lb_policy*)pol;
const size_t next_ready_index = get_next_ready_subchannel_index_locked(p);
if (next_ready_index < p->subchannel_list->num_subchannels) {
@ -556,16 +540,17 @@ static void rr_ping_one_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* pol,
&p->subchannel_list->subchannels[next_ready_index];
grpc_connected_subchannel* target = GRPC_CONNECTED_SUBCHANNEL_REF(
selected->connected_subchannel, "rr_ping");
grpc_connected_subchannel_ping(exec_ctx, target, closure);
GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, target, "rr_ping");
grpc_connected_subchannel_ping(target, on_initiate, on_ack);
GRPC_CONNECTED_SUBCHANNEL_UNREF(target, "rr_ping");
} else {
GRPC_CLOSURE_SCHED(
exec_ctx, closure,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Round Robin not connected"));
GRPC_CLOSURE_SCHED(on_initiate, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Round Robin not connected"));
GRPC_CLOSURE_SCHED(on_ack, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Round Robin not connected"));
}
}
static void rr_update_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
static void rr_update_locked(grpc_lb_policy* policy,
const grpc_lb_policy_args* args) {
round_robin_lb_policy* p = (round_robin_lb_policy*)policy;
const grpc_arg* arg =
@ -576,7 +561,7 @@ static void rr_update_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
// Otherwise, keep using the current subchannel list (ignore this update).
if (p->subchannel_list == nullptr) {
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
&p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"),
"rr_update_missing");
}
@ -588,15 +573,15 @@ static void rr_update_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
addresses->num_addresses);
}
grpc_lb_subchannel_list* subchannel_list = grpc_lb_subchannel_list_create(
exec_ctx, &p->base, &grpc_lb_round_robin_trace, addresses, args,
&p->base, &grpc_lb_round_robin_trace, addresses, args,
rr_connectivity_changed_locked);
if (subchannel_list->num_subchannels == 0) {
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
&p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
"rr_update_empty");
if (p->subchannel_list != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(exec_ctx, p->subchannel_list,
grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
"sl_shutdown_empty_update");
}
p->subchannel_list = subchannel_list; // empty list
@ -612,7 +597,7 @@ static void rr_update_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
(void*)subchannel_list);
}
grpc_lb_subchannel_list_shutdown_and_unref(
exec_ctx, p->latest_pending_subchannel_list, "sl_outdated");
p->latest_pending_subchannel_list, "sl_outdated");
}
p->latest_pending_subchannel_list = subchannel_list;
for (size_t i = 0; i < subchannel_list->num_subchannels; ++i) {
@ -623,22 +608,21 @@ static void rr_update_locked(grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
grpc_lb_subchannel_list_ref_for_connectivity_watch(subchannel_list,
"connectivity_watch");
grpc_lb_subchannel_data_start_connectivity_watch(
exec_ctx, &subchannel_list->subchannels[i]);
&subchannel_list->subchannels[i]);
}
} else {
// The policy isn't picking yet. Save the update for later, disposing of
// previous version if any.
if (p->subchannel_list != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(
exec_ctx, p->subchannel_list, "rr_update_before_started_picking");
p->subchannel_list, "rr_update_before_started_picking");
}
p->subchannel_list = subchannel_list;
}
}
static void rr_set_reresolve_closure_locked(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* policy,
grpc_closure* request_reresolution) {
grpc_lb_policy* policy, grpc_closure* request_reresolution) {
round_robin_lb_policy* p = (round_robin_lb_policy*)policy;
GPR_ASSERT(!p->shutdown);
GPR_ASSERT(policy->request_reresolution == nullptr);
@ -662,8 +646,7 @@ static void round_robin_factory_ref(grpc_lb_policy_factory* factory) {}
static void round_robin_factory_unref(grpc_lb_policy_factory* factory) {}
static grpc_lb_policy* round_robin_create(grpc_exec_ctx* exec_ctx,
grpc_lb_policy_factory* factory,
static grpc_lb_policy* round_robin_create(grpc_lb_policy_factory* factory,
grpc_lb_policy_args* args) {
GPR_ASSERT(args->client_channel_factory != nullptr);
round_robin_lb_policy* p = (round_robin_lb_policy*)gpr_zalloc(sizeof(*p));
@ -671,7 +654,7 @@ static grpc_lb_policy* round_robin_create(grpc_exec_ctx* exec_ctx,
grpc_subchannel_index_ref();
grpc_connectivity_state_init(&p->state_tracker, GRPC_CHANNEL_IDLE,
"round_robin");
rr_update_locked(exec_ctx, &p->base, args);
rr_update_locked(&p->base, args);
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG, "[RR %p] Created with %lu subchannels", (void*)p,
(unsigned long)p->subchannel_list->num_subchannels);

@ -28,8 +28,7 @@
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/transport/connectivity_state.h"
void grpc_lb_subchannel_data_unref_subchannel(grpc_exec_ctx* exec_ctx,
grpc_lb_subchannel_data* sd,
void grpc_lb_subchannel_data_unref_subchannel(grpc_lb_subchannel_data* sd,
const char* reason) {
if (sd->subchannel != nullptr) {
if (sd->subchannel_list->tracer->enabled()) {
@ -41,23 +40,22 @@ void grpc_lb_subchannel_data_unref_subchannel(grpc_exec_ctx* exec_ctx,
(size_t)(sd - sd->subchannel_list->subchannels),
sd->subchannel_list->num_subchannels, sd->subchannel);
}
GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, reason);
GRPC_SUBCHANNEL_UNREF(sd->subchannel, reason);
sd->subchannel = nullptr;
if (sd->connected_subchannel != nullptr) {
GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, sd->connected_subchannel,
reason);
GRPC_CONNECTED_SUBCHANNEL_UNREF(sd->connected_subchannel, reason);
sd->connected_subchannel = nullptr;
}
if (sd->user_data != nullptr) {
GPR_ASSERT(sd->user_data_vtable != nullptr);
sd->user_data_vtable->destroy(exec_ctx, sd->user_data);
sd->user_data_vtable->destroy(sd->user_data);
sd->user_data = nullptr;
}
}
}
void grpc_lb_subchannel_data_start_connectivity_watch(
grpc_exec_ctx* exec_ctx, grpc_lb_subchannel_data* sd) {
grpc_lb_subchannel_data* sd) {
if (sd->subchannel_list->tracer->enabled()) {
gpr_log(GPR_DEBUG,
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
@ -69,13 +67,13 @@ void grpc_lb_subchannel_data_start_connectivity_watch(
}
sd->connectivity_notification_pending = true;
grpc_subchannel_notify_on_state_change(
exec_ctx, sd->subchannel, sd->subchannel_list->policy->interested_parties,
sd->subchannel, sd->subchannel_list->policy->interested_parties,
&sd->pending_connectivity_state_unsafe,
&sd->connectivity_changed_closure);
}
void grpc_lb_subchannel_data_stop_connectivity_watch(
grpc_exec_ctx* exec_ctx, grpc_lb_subchannel_data* sd) {
grpc_lb_subchannel_data* sd) {
if (sd->subchannel_list->tracer->enabled()) {
gpr_log(GPR_DEBUG,
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
@ -90,7 +88,7 @@ void grpc_lb_subchannel_data_stop_connectivity_watch(
}
grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* p, grpc_core::TraceFlag* tracer,
grpc_lb_policy* p, grpc_core::TraceFlag* tracer,
const grpc_lb_addresses* addresses, const grpc_lb_policy_args* args,
grpc_iomgr_cb_func connectivity_changed_cb) {
grpc_lb_subchannel_list* subchannel_list =
@ -124,8 +122,8 @@ grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
gpr_free(addr_arg.value.string);
sc_args.args = new_args;
grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel(
exec_ctx, args->client_channel_factory, &sc_args);
grpc_channel_args_destroy(exec_ctx, new_args);
args->client_channel_factory, &sc_args);
grpc_channel_args_destroy(new_args);
if (subchannel == nullptr) {
// Subchannel could not be created.
if (tracer->enabled()) {
@ -172,8 +170,7 @@ grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
return subchannel_list;
}
static void subchannel_list_destroy(grpc_exec_ctx* exec_ctx,
grpc_lb_subchannel_list* subchannel_list) {
static void subchannel_list_destroy(grpc_lb_subchannel_list* subchannel_list) {
if (subchannel_list->tracer->enabled()) {
gpr_log(GPR_DEBUG, "[%s %p] Destroying subchannel_list %p",
subchannel_list->tracer->name(), subchannel_list->policy,
@ -181,8 +178,7 @@ static void subchannel_list_destroy(grpc_exec_ctx* exec_ctx,
}
for (size_t i = 0; i < subchannel_list->num_subchannels; i++) {
grpc_lb_subchannel_data* sd = &subchannel_list->subchannels[i];
grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd,
"subchannel_list_destroy");
grpc_lb_subchannel_data_unref_subchannel(sd, "subchannel_list_destroy");
}
gpr_free(subchannel_list->subchannels);
gpr_free(subchannel_list);
@ -200,8 +196,7 @@ void grpc_lb_subchannel_list_ref(grpc_lb_subchannel_list* subchannel_list,
}
}
void grpc_lb_subchannel_list_unref(grpc_exec_ctx* exec_ctx,
grpc_lb_subchannel_list* subchannel_list,
void grpc_lb_subchannel_list_unref(grpc_lb_subchannel_list* subchannel_list,
const char* reason) {
const bool done = gpr_unref(&subchannel_list->refcount);
if (subchannel_list->tracer->enabled()) {
@ -212,7 +207,7 @@ void grpc_lb_subchannel_list_unref(grpc_exec_ctx* exec_ctx,
reason);
}
if (done) {
subchannel_list_destroy(exec_ctx, subchannel_list);
subchannel_list_destroy(subchannel_list);
}
}
@ -223,14 +218,13 @@ void grpc_lb_subchannel_list_ref_for_connectivity_watch(
}
void grpc_lb_subchannel_list_unref_for_connectivity_watch(
grpc_exec_ctx* exec_ctx, grpc_lb_subchannel_list* subchannel_list,
const char* reason) {
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, subchannel_list->policy, reason);
grpc_lb_subchannel_list_unref(exec_ctx, subchannel_list, reason);
grpc_lb_subchannel_list* subchannel_list, const char* reason) {
GRPC_LB_POLICY_WEAK_UNREF(subchannel_list->policy, reason);
grpc_lb_subchannel_list_unref(subchannel_list, reason);
}
static void subchannel_data_cancel_connectivity_watch(
grpc_exec_ctx* exec_ctx, grpc_lb_subchannel_data* sd, const char* reason) {
grpc_lb_subchannel_data* sd, const char* reason) {
if (sd->subchannel_list->tracer->enabled()) {
gpr_log(GPR_DEBUG,
"[%s %p] subchannel list %p index %" PRIuPTR " of %" PRIuPTR
@ -240,14 +234,12 @@ static void subchannel_data_cancel_connectivity_watch(
(size_t)(sd - sd->subchannel_list->subchannels),
sd->subchannel_list->num_subchannels, sd->subchannel, reason);
}
grpc_subchannel_notify_on_state_change(exec_ctx, sd->subchannel, nullptr,
nullptr,
grpc_subchannel_notify_on_state_change(sd->subchannel, nullptr, nullptr,
&sd->connectivity_changed_closure);
}
void grpc_lb_subchannel_list_shutdown_and_unref(
grpc_exec_ctx* exec_ctx, grpc_lb_subchannel_list* subchannel_list,
const char* reason) {
grpc_lb_subchannel_list* subchannel_list, const char* reason) {
if (subchannel_list->tracer->enabled()) {
gpr_log(GPR_DEBUG, "[%s %p] Shutting down subchannel_list %p (%s)",
subchannel_list->tracer->name(), subchannel_list->policy,
@ -261,10 +253,10 @@ void grpc_lb_subchannel_list_shutdown_and_unref(
// the callback is responsible for unreffing the subchannel.
// Otherwise, unref the subchannel directly.
if (sd->connectivity_notification_pending) {
subchannel_data_cancel_connectivity_watch(exec_ctx, sd, reason);
subchannel_data_cancel_connectivity_watch(sd, reason);
} else if (sd->subchannel != nullptr) {
grpc_lb_subchannel_data_unref_subchannel(exec_ctx, sd, reason);
grpc_lb_subchannel_data_unref_subchannel(sd, reason);
}
}
grpc_lb_subchannel_list_unref(exec_ctx, subchannel_list, reason);
grpc_lb_subchannel_list_unref(subchannel_list, reason);
}

@ -65,8 +65,7 @@ typedef struct {
} grpc_lb_subchannel_data;
/// Unrefs the subchannel contained in sd.
void grpc_lb_subchannel_data_unref_subchannel(grpc_exec_ctx* exec_ctx,
grpc_lb_subchannel_data* sd,
void grpc_lb_subchannel_data_unref_subchannel(grpc_lb_subchannel_data* sd,
const char* reason);
/// Starts watching the connectivity state of the subchannel.
@ -74,11 +73,11 @@ void grpc_lb_subchannel_data_unref_subchannel(grpc_exec_ctx* exec_ctx,
/// grpc_lb_subchannel_data_stop_connectivity_watch() or again call
/// grpc_lb_subchannel_data_start_connectivity_watch().
void grpc_lb_subchannel_data_start_connectivity_watch(
grpc_exec_ctx* exec_ctx, grpc_lb_subchannel_data* sd);
grpc_lb_subchannel_data* sd);
/// Stops watching the connectivity state of the subchannel.
void grpc_lb_subchannel_data_stop_connectivity_watch(
grpc_exec_ctx* exec_ctx, grpc_lb_subchannel_data* sd);
grpc_lb_subchannel_data* sd);
struct grpc_lb_subchannel_list {
/** backpointer to owning policy */
@ -117,15 +116,14 @@ struct grpc_lb_subchannel_list {
};
grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
grpc_exec_ctx* exec_ctx, grpc_lb_policy* p, grpc_core::TraceFlag* tracer,
grpc_lb_policy* p, grpc_core::TraceFlag* tracer,
const grpc_lb_addresses* addresses, const grpc_lb_policy_args* args,
grpc_iomgr_cb_func connectivity_changed_cb);
void grpc_lb_subchannel_list_ref(grpc_lb_subchannel_list* subchannel_list,
const char* reason);
void grpc_lb_subchannel_list_unref(grpc_exec_ctx* exec_ctx,
grpc_lb_subchannel_list* subchannel_list,
void grpc_lb_subchannel_list_unref(grpc_lb_subchannel_list* subchannel_list,
const char* reason);
/// Takes and releases refs needed for a connectivity notification.
@ -133,13 +131,11 @@ void grpc_lb_subchannel_list_unref(grpc_exec_ctx* exec_ctx,
void grpc_lb_subchannel_list_ref_for_connectivity_watch(
grpc_lb_subchannel_list* subchannel_list, const char* reason);
void grpc_lb_subchannel_list_unref_for_connectivity_watch(
grpc_exec_ctx* exec_ctx, grpc_lb_subchannel_list* subchannel_list,
const char* reason);
grpc_lb_subchannel_list* subchannel_list, const char* reason);
/// Mark subchannel_list as discarded. Unsubscribes all its subchannels. The
/// connectivity state notification callback will ultimately unref it.
void grpc_lb_subchannel_list_shutdown_and_unref(
grpc_exec_ctx* exec_ctx, grpc_lb_subchannel_list* subchannel_list,
const char* reason);
grpc_lb_subchannel_list* subchannel_list, const char* reason);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_SUBCHANNEL_LIST_H */

@ -112,13 +112,11 @@ int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1,
return 0;
}
void grpc_lb_addresses_destroy(grpc_exec_ctx* exec_ctx,
grpc_lb_addresses* addresses) {
void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses) {
for (size_t i = 0; i < addresses->num_addresses; ++i) {
gpr_free(addresses->addresses[i].balancer_name);
if (addresses->addresses[i].user_data != nullptr) {
addresses->user_data_vtable->destroy(exec_ctx,
addresses->addresses[i].user_data);
addresses->user_data_vtable->destroy(addresses->addresses[i].user_data);
}
}
gpr_free(addresses->addresses);
@ -128,8 +126,8 @@ void grpc_lb_addresses_destroy(grpc_exec_ctx* exec_ctx,
static void* lb_addresses_copy(void* addresses) {
return grpc_lb_addresses_copy((grpc_lb_addresses*)addresses);
}
static void lb_addresses_destroy(grpc_exec_ctx* exec_ctx, void* addresses) {
grpc_lb_addresses_destroy(exec_ctx, (grpc_lb_addresses*)addresses);
static void lb_addresses_destroy(void* addresses) {
grpc_lb_addresses_destroy((grpc_lb_addresses*)addresses);
}
static int lb_addresses_cmp(void* addresses1, void* addresses2) {
return grpc_lb_addresses_cmp((grpc_lb_addresses*)addresses1,
@ -162,8 +160,7 @@ void grpc_lb_policy_factory_unref(grpc_lb_policy_factory* factory) {
}
grpc_lb_policy* grpc_lb_policy_factory_create_lb_policy(
grpc_exec_ctx* exec_ctx, grpc_lb_policy_factory* factory,
grpc_lb_policy_args* args) {
grpc_lb_policy_factory* factory, grpc_lb_policy_args* args) {
if (factory == nullptr) return nullptr;
return factory->vtable->create_lb_policy(exec_ctx, factory, args);
return factory->vtable->create_lb_policy(factory, args);
}

@ -50,7 +50,7 @@ typedef struct grpc_lb_address {
typedef struct grpc_lb_user_data_vtable {
void* (*copy)(void*);
void (*destroy)(grpc_exec_ctx* exec_ctx, void*);
void (*destroy)(void*);
int (*cmp)(void*, void*);
} grpc_lb_user_data_vtable;
@ -91,8 +91,7 @@ int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1,
const grpc_lb_addresses* addresses2);
/** Destroys \a addresses. */
void grpc_lb_addresses_destroy(grpc_exec_ctx* exec_ctx,
grpc_lb_addresses* addresses);
void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses);
/** Returns a channel arg containing \a addresses. */
grpc_arg grpc_lb_addresses_create_channel_arg(
@ -114,8 +113,7 @@ struct grpc_lb_policy_factory_vtable {
void (*unref)(grpc_lb_policy_factory* factory);
/** Implementation of grpc_lb_policy_factory_create_lb_policy */
grpc_lb_policy* (*create_lb_policy)(grpc_exec_ctx* exec_ctx,
grpc_lb_policy_factory* factory,
grpc_lb_policy* (*create_lb_policy)(grpc_lb_policy_factory* factory,
grpc_lb_policy_args* args);
/** Name for the LB policy this factory implements */
@ -127,7 +125,6 @@ void grpc_lb_policy_factory_unref(grpc_lb_policy_factory* factory);
/** Create a lb_policy instance. */
grpc_lb_policy* grpc_lb_policy_factory_create_lb_policy(
grpc_exec_ctx* exec_ctx, grpc_lb_policy_factory* factory,
grpc_lb_policy_args* args);
grpc_lb_policy_factory* factory, grpc_lb_policy_args* args);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_FACTORY_H */

@ -61,10 +61,10 @@ static grpc_lb_policy_factory* lookup_factory(const char* name) {
return nullptr;
}
grpc_lb_policy* grpc_lb_policy_create(grpc_exec_ctx* exec_ctx, const char* name,
grpc_lb_policy* grpc_lb_policy_create(const char* name,
grpc_lb_policy_args* args) {
grpc_lb_policy_factory* factory = lookup_factory(name);
grpc_lb_policy* lb_policy =
grpc_lb_policy_factory_create_lb_policy(exec_ctx, factory, args);
grpc_lb_policy_factory_create_lb_policy(factory, args);
return lb_policy;
}

@ -34,7 +34,7 @@ void grpc_register_lb_policy(grpc_lb_policy_factory* factory);
*
* If \a name is NULL, the default factory from \a grpc_lb_policy_registry_init
* will be returned. */
grpc_lb_policy* grpc_lb_policy_create(grpc_exec_ctx* exec_ctx, const char* name,
grpc_lb_policy* grpc_lb_policy_create(const char* name,
grpc_lb_policy_args* args);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H */

@ -23,24 +23,22 @@ void grpc_proxy_mapper_init(const grpc_proxy_mapper_vtable* vtable,
mapper->vtable = vtable;
}
bool grpc_proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper* mapper,
bool grpc_proxy_mapper_map_name(grpc_proxy_mapper* mapper,
const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args) {
return mapper->vtable->map_name(exec_ctx, mapper, server_uri, args,
name_to_resolve, new_args);
return mapper->vtable->map_name(mapper, server_uri, args, name_to_resolve,
new_args);
}
bool grpc_proxy_mapper_map_address(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper* mapper,
bool grpc_proxy_mapper_map_address(grpc_proxy_mapper* mapper,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args) {
return mapper->vtable->map_address(exec_ctx, mapper, address, args,
new_address, new_args);
return mapper->vtable->map_address(mapper, address, args, new_address,
new_args);
}
void grpc_proxy_mapper_destroy(grpc_proxy_mapper* mapper) {

@ -32,14 +32,14 @@ typedef struct {
/// If no proxy is needed, returns false.
/// Otherwise, sets \a name_to_resolve, optionally sets \a new_args,
/// and returns true.
bool (*map_name)(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper,
const char* server_uri, const grpc_channel_args* args,
char** name_to_resolve, grpc_channel_args** new_args);
bool (*map_name)(grpc_proxy_mapper* mapper, const char* server_uri,
const grpc_channel_args* args, char** name_to_resolve,
grpc_channel_args** new_args);
/// Determines the proxy address to use to contact \a address.
/// If no proxy is needed, returns false.
/// Otherwise, sets \a new_address, optionally sets \a new_args, and
/// returns true.
bool (*map_address)(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper,
bool (*map_address)(grpc_proxy_mapper* mapper,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
@ -55,15 +55,13 @@ struct grpc_proxy_mapper {
void grpc_proxy_mapper_init(const grpc_proxy_mapper_vtable* vtable,
grpc_proxy_mapper* mapper);
bool grpc_proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper* mapper,
bool grpc_proxy_mapper_map_name(grpc_proxy_mapper* mapper,
const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args);
bool grpc_proxy_mapper_map_address(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper* mapper,
bool grpc_proxy_mapper_map_address(grpc_proxy_mapper* mapper,
const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,

@ -46,14 +46,13 @@ static void grpc_proxy_mapper_list_register(grpc_proxy_mapper_list* list,
++list->num_mappers;
}
static bool grpc_proxy_mapper_list_map_name(grpc_exec_ctx* exec_ctx,
grpc_proxy_mapper_list* list,
static bool grpc_proxy_mapper_list_map_name(grpc_proxy_mapper_list* list,
const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args) {
for (size_t i = 0; i < list->num_mappers; ++i) {
if (grpc_proxy_mapper_map_name(exec_ctx, list->list[i], server_uri, args,
if (grpc_proxy_mapper_map_name(list->list[i], server_uri, args,
name_to_resolve, new_args)) {
return true;
}
@ -62,12 +61,12 @@ static bool grpc_proxy_mapper_list_map_name(grpc_exec_ctx* exec_ctx,
}
static bool grpc_proxy_mapper_list_map_address(
grpc_exec_ctx* exec_ctx, grpc_proxy_mapper_list* list,
const grpc_resolved_address* address, const grpc_channel_args* args,
grpc_resolved_address** new_address, grpc_channel_args** new_args) {
grpc_proxy_mapper_list* list, const grpc_resolved_address* address,
const grpc_channel_args* args, grpc_resolved_address** new_address,
grpc_channel_args** new_args) {
for (size_t i = 0; i < list->num_mappers; ++i) {
if (grpc_proxy_mapper_map_address(exec_ctx, list->list[i], address, args,
new_address, new_args)) {
if (grpc_proxy_mapper_map_address(list->list[i], address, args, new_address,
new_args)) {
return true;
}
}
@ -105,20 +104,17 @@ void grpc_proxy_mapper_register(bool at_start, grpc_proxy_mapper* mapper) {
grpc_proxy_mapper_list_register(&g_proxy_mapper_list, at_start, mapper);
}
bool grpc_proxy_mappers_map_name(grpc_exec_ctx* exec_ctx,
const char* server_uri,
bool grpc_proxy_mappers_map_name(const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args) {
return grpc_proxy_mapper_list_map_name(exec_ctx, &g_proxy_mapper_list,
server_uri, args, name_to_resolve,
new_args);
return grpc_proxy_mapper_list_map_name(&g_proxy_mapper_list, server_uri, args,
name_to_resolve, new_args);
}
bool grpc_proxy_mappers_map_address(grpc_exec_ctx* exec_ctx,
const grpc_resolved_address* address,
bool grpc_proxy_mappers_map_address(const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args) {
return grpc_proxy_mapper_list_map_address(
exec_ctx, &g_proxy_mapper_list, address, args, new_address, new_args);
return grpc_proxy_mapper_list_map_address(&g_proxy_mapper_list, address, args,
new_address, new_args);
}

@ -29,14 +29,12 @@ void grpc_proxy_mapper_registry_shutdown();
/// the list. Otherwise, it will be added to the end.
void grpc_proxy_mapper_register(bool at_start, grpc_proxy_mapper* mapper);
bool grpc_proxy_mappers_map_name(grpc_exec_ctx* exec_ctx,
const char* server_uri,
bool grpc_proxy_mappers_map_name(const char* server_uri,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args);
bool grpc_proxy_mappers_map_address(grpc_exec_ctx* exec_ctx,
const grpc_resolved_address* address,
bool grpc_proxy_mappers_map_address(const grpc_resolved_address* address,
const grpc_channel_args* args,
grpc_resolved_address** new_address,
grpc_channel_args** new_args);

@ -46,8 +46,8 @@ void grpc_resolver_ref(grpc_resolver* resolver) {
}
#ifndef NDEBUG
void grpc_resolver_unref(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver,
const char* file, int line, const char* reason) {
void grpc_resolver_unref(grpc_resolver* resolver, const char* file, int line,
const char* reason) {
if (grpc_trace_resolver_refcount.enabled()) {
gpr_atm old_refs = gpr_atm_no_barrier_load(&resolver->refs.count);
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
@ -55,27 +55,25 @@ void grpc_resolver_unref(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver,
old_refs, old_refs - 1, reason);
}
#else
void grpc_resolver_unref(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver) {
void grpc_resolver_unref(grpc_resolver* resolver) {
#endif
if (gpr_unref(&resolver->refs)) {
grpc_combiner* combiner = resolver->combiner;
resolver->vtable->destroy(exec_ctx, resolver);
GRPC_COMBINER_UNREF(exec_ctx, combiner, "resolver");
resolver->vtable->destroy(resolver);
GRPC_COMBINER_UNREF(combiner, "resolver");
}
}
void grpc_resolver_shutdown_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver) {
resolver->vtable->shutdown_locked(exec_ctx, resolver);
void grpc_resolver_shutdown_locked(grpc_resolver* resolver) {
resolver->vtable->shutdown_locked(resolver);
}
void grpc_resolver_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver) {
resolver->vtable->channel_saw_error_locked(exec_ctx, resolver);
void grpc_resolver_channel_saw_error_locked(grpc_resolver* resolver) {
resolver->vtable->channel_saw_error_locked(resolver);
}
void grpc_resolver_next_locked(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver,
void grpc_resolver_next_locked(grpc_resolver* resolver,
grpc_channel_args** result,
grpc_closure* on_complete) {
resolver->vtable->next_locked(exec_ctx, resolver, result, on_complete);
resolver->vtable->next_locked(resolver, result, on_complete);
}

@ -35,43 +35,40 @@ struct grpc_resolver {
};
struct grpc_resolver_vtable {
void (*destroy)(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver);
void (*shutdown_locked)(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver);
void (*channel_saw_error_locked)(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver);
void (*next_locked)(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver,
grpc_channel_args** result, grpc_closure* on_complete);
void (*destroy)(grpc_resolver* resolver);
void (*shutdown_locked)(grpc_resolver* resolver);
void (*channel_saw_error_locked)(grpc_resolver* resolver);
void (*next_locked)(grpc_resolver* resolver, grpc_channel_args** result,
grpc_closure* on_complete);
};
#ifndef NDEBUG
#define GRPC_RESOLVER_REF(p, r) grpc_resolver_ref((p), __FILE__, __LINE__, (r))
#define GRPC_RESOLVER_UNREF(e, p, r) \
grpc_resolver_unref((e), (p), __FILE__, __LINE__, (r))
#define GRPC_RESOLVER_UNREF(p, r) \
grpc_resolver_unref((p), __FILE__, __LINE__, (r))
void grpc_resolver_ref(grpc_resolver* policy, const char* file, int line,
const char* reason);
void grpc_resolver_unref(grpc_exec_ctx* exec_ctx, grpc_resolver* policy,
const char* file, int line, const char* reason);
void grpc_resolver_unref(grpc_resolver* policy, const char* file, int line,
const char* reason);
#else
#define GRPC_RESOLVER_REF(p, r) grpc_resolver_ref((p))
#define GRPC_RESOLVER_UNREF(e, p, r) grpc_resolver_unref((e), (p))
#define GRPC_RESOLVER_UNREF(p, r) grpc_resolver_unref((p))
void grpc_resolver_ref(grpc_resolver* policy);
void grpc_resolver_unref(grpc_exec_ctx* exec_ctx, grpc_resolver* policy);
void grpc_resolver_unref(grpc_resolver* policy);
#endif
void grpc_resolver_init(grpc_resolver* resolver,
const grpc_resolver_vtable* vtable,
grpc_combiner* combiner);
void grpc_resolver_shutdown_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver);
void grpc_resolver_shutdown_locked(grpc_resolver* resolver);
/** Notification that the channel has seen an error on some address.
Can be used as a hint that re-resolution is desirable soon.
Must be called from the combiner passed as a resolver_arg at construction
time.*/
void grpc_resolver_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver);
void grpc_resolver_channel_saw_error_locked(grpc_resolver* resolver);
/** Get the next result from the resolver. Expected to set \a *result with
new channel args and then schedule \a on_complete for execution.
@ -81,7 +78,7 @@ void grpc_resolver_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
Must be called from the combiner passed as a resolver_arg at construction
time.*/
void grpc_resolver_next_locked(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver,
void grpc_resolver_next_locked(grpc_resolver* resolver,
grpc_channel_args** result,
grpc_closure* on_complete);

@ -97,17 +97,14 @@ typedef struct {
char* service_config_json;
} ares_dns_resolver;
static void dns_ares_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* r);
static void dns_ares_destroy(grpc_resolver* r);
static void dns_ares_start_resolving_locked(grpc_exec_ctx* exec_ctx,
ares_dns_resolver* r);
static void dns_ares_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx,
ares_dns_resolver* r);
static void dns_ares_start_resolving_locked(ares_dns_resolver* r);
static void dns_ares_maybe_finish_next_locked(ares_dns_resolver* r);
static void dns_ares_shutdown_locked(grpc_exec_ctx* exec_ctx, grpc_resolver* r);
static void dns_ares_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* r);
static void dns_ares_next_locked(grpc_exec_ctx* exec_ctx, grpc_resolver* r,
static void dns_ares_shutdown_locked(grpc_resolver* r);
static void dns_ares_channel_saw_error_locked(grpc_resolver* r);
static void dns_ares_next_locked(grpc_resolver* r,
grpc_channel_args** target_result,
grpc_closure* on_complete);
@ -115,43 +112,39 @@ static const grpc_resolver_vtable dns_ares_resolver_vtable = {
dns_ares_destroy, dns_ares_shutdown_locked,
dns_ares_channel_saw_error_locked, dns_ares_next_locked};
static void dns_ares_shutdown_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver) {
static void dns_ares_shutdown_locked(grpc_resolver* resolver) {
ares_dns_resolver* r = (ares_dns_resolver*)resolver;
if (r->have_retry_timer) {
grpc_timer_cancel(exec_ctx, &r->retry_timer);
grpc_timer_cancel(&r->retry_timer);
}
if (r->pending_request != nullptr) {
grpc_cancel_ares_request(exec_ctx, r->pending_request);
grpc_cancel_ares_request(r->pending_request);
}
if (r->next_completion != nullptr) {
*r->target_result = nullptr;
GRPC_CLOSURE_SCHED(
exec_ctx, r->next_completion,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver Shutdown"));
GRPC_CLOSURE_SCHED(r->next_completion, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Resolver Shutdown"));
r->next_completion = nullptr;
}
}
static void dns_ares_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver) {
static void dns_ares_channel_saw_error_locked(grpc_resolver* resolver) {
ares_dns_resolver* r = (ares_dns_resolver*)resolver;
if (!r->resolving) {
grpc_backoff_reset(&r->backoff_state);
dns_ares_start_resolving_locked(exec_ctx, r);
dns_ares_start_resolving_locked(r);
}
}
static void dns_ares_on_retry_timer_locked(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void dns_ares_on_retry_timer_locked(void* arg, grpc_error* error) {
ares_dns_resolver* r = (ares_dns_resolver*)arg;
r->have_retry_timer = false;
if (error == GRPC_ERROR_NONE) {
if (!r->resolving) {
dns_ares_start_resolving_locked(exec_ctx, r);
dns_ares_start_resolving_locked(r);
}
}
GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "retry-timer");
GRPC_RESOLVER_UNREF(&r->base, "retry-timer");
}
static bool value_in_json_array(grpc_json* array, const char* value) {
@ -226,8 +219,7 @@ static char* choose_service_config(char* service_config_choice_json) {
return service_config;
}
static void dns_ares_on_resolved_locked(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void dns_ares_on_resolved_locked(void* arg, grpc_error* error) {
ares_dns_resolver* r = (ares_dns_resolver*)arg;
grpc_channel_args* result = nullptr;
GPR_ASSERT(r->resolving);
@ -268,13 +260,13 @@ static void dns_ares_on_resolved_locked(grpc_exec_ctx* exec_ctx, void* arg,
num_args_to_add);
if (service_config != nullptr) grpc_service_config_destroy(service_config);
gpr_free(service_config_string);
grpc_lb_addresses_destroy(exec_ctx, r->lb_addresses);
grpc_lb_addresses_destroy(r->lb_addresses);
} else {
const char* msg = grpc_error_string(error);
gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg);
grpc_millis next_try =
grpc_backoff_step(exec_ctx, &r->backoff_state).next_attempt_start_time;
grpc_millis timeout = next_try - grpc_exec_ctx_now(exec_ctx);
grpc_backoff_step(&r->backoff_state).next_attempt_start_time;
grpc_millis timeout = next_try - grpc_core::ExecCtx::Get()->Now();
gpr_log(GPR_INFO, "dns resolution failed (will retry): %s",
grpc_error_string(error));
GPR_ASSERT(!r->have_retry_timer);
@ -285,20 +277,19 @@ static void dns_ares_on_resolved_locked(grpc_exec_ctx* exec_ctx, void* arg,
} else {
gpr_log(GPR_DEBUG, "retrying immediately");
}
grpc_timer_init(exec_ctx, &r->retry_timer, next_try,
grpc_timer_init(&r->retry_timer, next_try,
&r->dns_ares_on_retry_timer_locked);
}
if (r->resolved_result != nullptr) {
grpc_channel_args_destroy(exec_ctx, r->resolved_result);
grpc_channel_args_destroy(r->resolved_result);
}
r->resolved_result = result;
r->resolved_version++;
dns_ares_maybe_finish_next_locked(exec_ctx, r);
GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "dns-resolving");
dns_ares_maybe_finish_next_locked(r);
GRPC_RESOLVER_UNREF(&r->base, "dns-resolving");
}
static void dns_ares_next_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver,
static void dns_ares_next_locked(grpc_resolver* resolver,
grpc_channel_args** target_result,
grpc_closure* on_complete) {
gpr_log(GPR_DEBUG, "dns_ares_next is called.");
@ -308,56 +299,53 @@ static void dns_ares_next_locked(grpc_exec_ctx* exec_ctx,
r->target_result = target_result;
if (r->resolved_version == 0 && !r->resolving) {
grpc_backoff_reset(&r->backoff_state);
dns_ares_start_resolving_locked(exec_ctx, r);
dns_ares_start_resolving_locked(r);
} else {
dns_ares_maybe_finish_next_locked(exec_ctx, r);
dns_ares_maybe_finish_next_locked(r);
}
}
static void dns_ares_start_resolving_locked(grpc_exec_ctx* exec_ctx,
ares_dns_resolver* r) {
static void dns_ares_start_resolving_locked(ares_dns_resolver* r) {
GRPC_RESOLVER_REF(&r->base, "dns-resolving");
GPR_ASSERT(!r->resolving);
r->resolving = true;
r->lb_addresses = nullptr;
r->service_config_json = nullptr;
r->pending_request = grpc_dns_lookup_ares(
exec_ctx, r->dns_server, r->name_to_resolve, r->default_port,
r->interested_parties, &r->dns_ares_on_resolved_locked, &r->lb_addresses,
r->dns_server, r->name_to_resolve, r->default_port, r->interested_parties,
&r->dns_ares_on_resolved_locked, &r->lb_addresses,
true /* check_grpclb */,
r->request_service_config ? &r->service_config_json : nullptr);
}
static void dns_ares_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx,
ares_dns_resolver* r) {
static void dns_ares_maybe_finish_next_locked(ares_dns_resolver* r) {
if (r->next_completion != nullptr &&
r->resolved_version != r->published_version) {
*r->target_result = r->resolved_result == nullptr
? nullptr
: grpc_channel_args_copy(r->resolved_result);
gpr_log(GPR_DEBUG, "dns_ares_maybe_finish_next_locked");
GRPC_CLOSURE_SCHED(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(r->next_completion, GRPC_ERROR_NONE);
r->next_completion = nullptr;
r->published_version = r->resolved_version;
}
}
static void dns_ares_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* gr) {
static void dns_ares_destroy(grpc_resolver* gr) {
gpr_log(GPR_DEBUG, "dns_ares_destroy");
ares_dns_resolver* r = (ares_dns_resolver*)gr;
if (r->resolved_result != nullptr) {
grpc_channel_args_destroy(exec_ctx, r->resolved_result);
grpc_channel_args_destroy(r->resolved_result);
}
grpc_pollset_set_destroy(exec_ctx, r->interested_parties);
grpc_pollset_set_destroy(r->interested_parties);
gpr_free(r->dns_server);
gpr_free(r->name_to_resolve);
gpr_free(r->default_port);
grpc_channel_args_destroy(exec_ctx, r->channel_args);
grpc_channel_args_destroy(r->channel_args);
gpr_free(r);
}
static grpc_resolver* dns_ares_create(grpc_exec_ctx* exec_ctx,
grpc_resolver_args* args,
static grpc_resolver* dns_ares_create(grpc_resolver_args* args,
const char* default_port) {
/* Get name from args. */
const char* path = args->uri->path;
@ -378,8 +366,7 @@ static grpc_resolver* dns_ares_create(grpc_exec_ctx* exec_ctx,
arg, (grpc_integer_options){false, false, true});
r->interested_parties = grpc_pollset_set_create();
if (args->pollset_set != nullptr) {
grpc_pollset_set_add_pollset_set(exec_ctx, r->interested_parties,
args->pollset_set);
grpc_pollset_set_add_pollset_set(r->interested_parties, args->pollset_set);
}
grpc_backoff_init(
&r->backoff_state, GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS * 1000,
@ -404,9 +391,8 @@ static void dns_ares_factory_ref(grpc_resolver_factory* factory) {}
static void dns_ares_factory_unref(grpc_resolver_factory* factory) {}
static grpc_resolver* dns_factory_create_resolver(
grpc_exec_ctx* exec_ctx, grpc_resolver_factory* factory,
grpc_resolver_args* args) {
return dns_ares_create(exec_ctx, args, "https");
grpc_resolver_factory* factory, grpc_resolver_args* args) {
return dns_ares_create(args, "https");
}
static char* dns_ares_factory_get_default_host_name(

@ -28,8 +28,7 @@ typedef struct grpc_ares_ev_driver grpc_ares_ev_driver;
/* Start \a ev_driver. It will keep working until all IO on its ares_channel is
done, or grpc_ares_ev_driver_destroy() is called. It may notify the callbacks
bound to its ares_channel when necessary. */
void grpc_ares_ev_driver_start(grpc_exec_ctx* exec_ctx,
grpc_ares_ev_driver* ev_driver);
void grpc_ares_ev_driver_start(grpc_ares_ev_driver* ev_driver);
/* Returns the ares_channel owned by \a ev_driver. To bind a c-ares query to
\a ev_driver, use the ares_channel owned by \a ev_driver as the arg of the
@ -47,8 +46,7 @@ grpc_error* grpc_ares_ev_driver_create(grpc_ares_ev_driver** ev_driver,
void grpc_ares_ev_driver_destroy(grpc_ares_ev_driver* ev_driver);
/* Shutdown all the grpc_fds used by \a ev_driver */
void grpc_ares_ev_driver_shutdown(grpc_exec_ctx* exec_ctx,
grpc_ares_ev_driver* ev_driver);
void grpc_ares_ev_driver_shutdown(grpc_ares_ev_driver* ev_driver);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H \
*/

@ -77,8 +77,7 @@ struct grpc_ares_ev_driver {
bool shutting_down;
};
static void grpc_ares_notify_on_event_locked(grpc_exec_ctx* exec_ctx,
grpc_ares_ev_driver* ev_driver);
static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver);
static grpc_ares_ev_driver* grpc_ares_ev_driver_ref(
grpc_ares_ev_driver* ev_driver) {
@ -98,7 +97,7 @@ static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) {
}
}
static void fd_node_destroy(grpc_exec_ctx* exec_ctx, fd_node* fdn) {
static void fd_node_destroy(fd_node* fdn) {
gpr_log(GPR_DEBUG, "delete fd: %d", grpc_fd_wrapped_fd(fdn->fd));
GPR_ASSERT(!fdn->readable_registered);
GPR_ASSERT(!fdn->writable_registered);
@ -106,21 +105,20 @@ static void fd_node_destroy(grpc_exec_ctx* exec_ctx, fd_node* fdn) {
/* c-ares library has closed the fd inside grpc_fd. This fd may be picked up
immediately by another thread, and should not be closed by the following
grpc_fd_orphan. */
grpc_fd_orphan(exec_ctx, fdn->fd, nullptr, nullptr, true /* already_closed */,
grpc_fd_orphan(fdn->fd, nullptr, nullptr, true /* already_closed */,
"c-ares query finished");
gpr_free(fdn);
}
static void fd_node_shutdown(grpc_exec_ctx* exec_ctx, fd_node* fdn) {
static void fd_node_shutdown(fd_node* fdn) {
gpr_mu_lock(&fdn->mu);
fdn->shutting_down = true;
if (!fdn->readable_registered && !fdn->writable_registered) {
gpr_mu_unlock(&fdn->mu);
fd_node_destroy(exec_ctx, fdn);
fd_node_destroy(fdn);
} else {
grpc_fd_shutdown(
exec_ctx, fdn->fd,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("c-ares fd shutdown"));
fdn->fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING("c-ares fd shutdown"));
gpr_mu_unlock(&fdn->mu);
}
}
@ -160,15 +158,13 @@ void grpc_ares_ev_driver_destroy(grpc_ares_ev_driver* ev_driver) {
grpc_ares_ev_driver_unref(ev_driver);
}
void grpc_ares_ev_driver_shutdown(grpc_exec_ctx* exec_ctx,
grpc_ares_ev_driver* ev_driver) {
void grpc_ares_ev_driver_shutdown(grpc_ares_ev_driver* ev_driver) {
gpr_mu_lock(&ev_driver->mu);
ev_driver->shutting_down = true;
fd_node* fn = ev_driver->fds;
while (fn != nullptr) {
grpc_fd_shutdown(
exec_ctx, fn->fd,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("grpc_ares_ev_driver_shutdown"));
grpc_fd_shutdown(fn->fd, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"grpc_ares_ev_driver_shutdown"));
fn = fn->next;
}
gpr_mu_unlock(&ev_driver->mu);
@ -199,8 +195,7 @@ static bool grpc_ares_is_fd_still_readable(grpc_ares_ev_driver* ev_driver,
return ioctl(fd, FIONREAD, &bytes_available) == 0 && bytes_available > 0;
}
static void on_readable_cb(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void on_readable_cb(void* arg, grpc_error* error) {
fd_node* fdn = (fd_node*)arg;
grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
gpr_mu_lock(&fdn->mu);
@ -208,7 +203,7 @@ static void on_readable_cb(grpc_exec_ctx* exec_ctx, void* arg,
fdn->readable_registered = false;
if (fdn->shutting_down && !fdn->writable_registered) {
gpr_mu_unlock(&fdn->mu);
fd_node_destroy(exec_ctx, fdn);
fd_node_destroy(fdn);
grpc_ares_ev_driver_unref(ev_driver);
return;
}
@ -229,13 +224,12 @@ static void on_readable_cb(grpc_exec_ctx* exec_ctx, void* arg,
ares_cancel(ev_driver->channel);
}
gpr_mu_lock(&ev_driver->mu);
grpc_ares_notify_on_event_locked(exec_ctx, ev_driver);
grpc_ares_notify_on_event_locked(ev_driver);
gpr_mu_unlock(&ev_driver->mu);
grpc_ares_ev_driver_unref(ev_driver);
}
static void on_writable_cb(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void on_writable_cb(void* arg, grpc_error* error) {
fd_node* fdn = (fd_node*)arg;
grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
gpr_mu_lock(&fdn->mu);
@ -243,7 +237,7 @@ static void on_writable_cb(grpc_exec_ctx* exec_ctx, void* arg,
fdn->writable_registered = false;
if (fdn->shutting_down && !fdn->readable_registered) {
gpr_mu_unlock(&fdn->mu);
fd_node_destroy(exec_ctx, fdn);
fd_node_destroy(fdn);
grpc_ares_ev_driver_unref(ev_driver);
return;
}
@ -262,7 +256,7 @@ static void on_writable_cb(grpc_exec_ctx* exec_ctx, void* arg,
ares_cancel(ev_driver->channel);
}
gpr_mu_lock(&ev_driver->mu);
grpc_ares_notify_on_event_locked(exec_ctx, ev_driver);
grpc_ares_notify_on_event_locked(ev_driver);
gpr_mu_unlock(&ev_driver->mu);
grpc_ares_ev_driver_unref(ev_driver);
}
@ -273,8 +267,7 @@ ares_channel* grpc_ares_ev_driver_get_channel(grpc_ares_ev_driver* ev_driver) {
// Get the file descriptors used by the ev_driver's ares channel, register
// driver_closure with these filedescriptors.
static void grpc_ares_notify_on_event_locked(grpc_exec_ctx* exec_ctx,
grpc_ares_ev_driver* ev_driver) {
static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
fd_node* new_list = nullptr;
if (!ev_driver->shutting_down) {
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
@ -300,7 +293,7 @@ static void grpc_ares_notify_on_event_locked(grpc_exec_ctx* exec_ctx,
grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_INIT(&fdn->write_closure, on_writable_cb, fdn,
grpc_schedule_on_exec_ctx);
grpc_pollset_set_add_fd(exec_ctx, ev_driver->pollset_set, fdn->fd);
grpc_pollset_set_add_fd(ev_driver->pollset_set, fdn->fd);
gpr_free(fd_name);
}
fdn->next = new_list;
@ -312,7 +305,7 @@ static void grpc_ares_notify_on_event_locked(grpc_exec_ctx* exec_ctx,
!fdn->readable_registered) {
grpc_ares_ev_driver_ref(ev_driver);
gpr_log(GPR_DEBUG, "notify read on: %d", grpc_fd_wrapped_fd(fdn->fd));
grpc_fd_notify_on_read(exec_ctx, fdn->fd, &fdn->read_closure);
grpc_fd_notify_on_read(fdn->fd, &fdn->read_closure);
fdn->readable_registered = true;
}
// Register write_closure if the socket is writable and write_closure
@ -322,7 +315,7 @@ static void grpc_ares_notify_on_event_locked(grpc_exec_ctx* exec_ctx,
gpr_log(GPR_DEBUG, "notify write on: %d",
grpc_fd_wrapped_fd(fdn->fd));
grpc_ares_ev_driver_ref(ev_driver);
grpc_fd_notify_on_write(exec_ctx, fdn->fd, &fdn->write_closure);
grpc_fd_notify_on_write(fdn->fd, &fdn->write_closure);
fdn->writable_registered = true;
}
gpr_mu_unlock(&fdn->mu);
@ -335,7 +328,7 @@ static void grpc_ares_notify_on_event_locked(grpc_exec_ctx* exec_ctx,
while (ev_driver->fds != nullptr) {
fd_node* cur = ev_driver->fds;
ev_driver->fds = ev_driver->fds->next;
fd_node_shutdown(exec_ctx, cur);
fd_node_shutdown(cur);
}
ev_driver->fds = new_list;
// If the ev driver has no working fd, all the tasks are done.
@ -345,12 +338,11 @@ static void grpc_ares_notify_on_event_locked(grpc_exec_ctx* exec_ctx,
}
}
void grpc_ares_ev_driver_start(grpc_exec_ctx* exec_ctx,
grpc_ares_ev_driver* ev_driver) {
void grpc_ares_ev_driver_start(grpc_ares_ev_driver* ev_driver) {
gpr_mu_lock(&ev_driver->mu);
if (!ev_driver->working) {
ev_driver->working = true;
grpc_ares_notify_on_event_locked(exec_ctx, ev_driver);
grpc_ares_notify_on_event_locked(ev_driver);
}
gpr_mu_unlock(&ev_driver->mu);
}

@ -96,24 +96,12 @@ static void grpc_ares_request_ref(grpc_ares_request* r) {
gpr_ref(&r->pending_queries);
}
static void grpc_ares_request_unref(grpc_exec_ctx* exec_ctx,
grpc_ares_request* r) {
static void grpc_ares_request_unref(grpc_ares_request* r) {
/* If there are no pending queries, invoke on_done callback and destroy the
request */
if (gpr_unref(&r->pending_queries)) {
/* TODO(zyc): Sort results with RFC6724 before invoking on_done. */
if (exec_ctx == nullptr) {
/* A new exec_ctx is created here, as the c-ares interface does not
provide one in ares_host_callback. It's safe to schedule on_done with
the newly created exec_ctx, since the caller has been warned not to
acquire locks in on_done. ares_dns_resolver is using combiner to
protect resources needed by on_done. */
grpc_exec_ctx new_exec_ctx = GRPC_EXEC_CTX_INIT;
GRPC_CLOSURE_SCHED(&new_exec_ctx, r->on_done, r->error);
grpc_exec_ctx_finish(&new_exec_ctx);
} else {
GRPC_CLOSURE_SCHED(exec_ctx, r->on_done, r->error);
}
GRPC_CLOSURE_SCHED(r->on_done, r->error);
gpr_mu_destroy(&r->mu);
grpc_ares_ev_driver_destroy(r->ev_driver);
gpr_free(r);
@ -133,9 +121,8 @@ static grpc_ares_hostbyname_request* create_hostbyname_request(
return hr;
}
static void destroy_hostbyname_request(grpc_exec_ctx* exec_ctx,
grpc_ares_hostbyname_request* hr) {
grpc_ares_request_unref(exec_ctx, hr->parent_request);
static void destroy_hostbyname_request(grpc_ares_hostbyname_request* hr) {
grpc_ares_request_unref(hr->parent_request);
gpr_free(hr->host);
gpr_free(hr);
}
@ -220,13 +207,13 @@ static void on_hostbyname_done_cb(void* arg, int status, int timeouts,
}
}
gpr_mu_unlock(&r->mu);
destroy_hostbyname_request(nullptr, hr);
destroy_hostbyname_request(hr);
}
static void on_srv_query_done_cb(void* arg, int status, int timeouts,
unsigned char* abuf, int alen) {
grpc_ares_request* r = (grpc_ares_request*)arg;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_core::ExecCtx exec_ctx;
gpr_log(GPR_DEBUG, "on_query_srv_done_cb");
if (status == ARES_SUCCESS) {
gpr_log(GPR_DEBUG, "on_query_srv_done_cb ARES_SUCCESS");
@ -246,7 +233,7 @@ static void on_srv_query_done_cb(void* arg, int status, int timeouts,
r, srv_it->host, htons(srv_it->port), true /* is_balancer */);
ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_cb,
hr);
grpc_ares_ev_driver_start(&exec_ctx, r->ev_driver);
grpc_ares_ev_driver_start(r->ev_driver);
}
}
if (reply != nullptr) {
@ -264,8 +251,7 @@ static void on_srv_query_done_cb(void* arg, int status, int timeouts,
r->error = grpc_error_add_child(error, r->error);
}
}
grpc_ares_request_unref(&exec_ctx, r);
grpc_exec_ctx_finish(&exec_ctx);
grpc_ares_request_unref(r);
}
static const char g_service_config_attribute_prefix[] = "grpc_config=";
@ -323,14 +309,13 @@ fail:
}
done:
gpr_mu_unlock(&r->mu);
grpc_ares_request_unref(nullptr, r);
grpc_ares_request_unref(r);
}
static grpc_ares_request* grpc_dns_lookup_ares_impl(
grpc_exec_ctx* exec_ctx, const char* dns_server, const char* name,
const char* default_port, grpc_pollset_set* interested_parties,
grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb,
char** service_config_json) {
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json) {
grpc_error* error = GRPC_ERROR_NONE;
grpc_ares_hostbyname_request* hr = nullptr;
grpc_ares_request* r = nullptr;
@ -437,28 +422,28 @@ static grpc_ares_request* grpc_dns_lookup_ares_impl(
gpr_free(config_name);
}
/* TODO(zyc): Handle CNAME records here. */
grpc_ares_ev_driver_start(exec_ctx, r->ev_driver);
grpc_ares_request_unref(exec_ctx, r);
grpc_ares_ev_driver_start(r->ev_driver);
grpc_ares_request_unref(r);
gpr_free(host);
gpr_free(port);
return r;
error_cleanup:
GRPC_CLOSURE_SCHED(exec_ctx, on_done, error);
GRPC_CLOSURE_SCHED(on_done, error);
gpr_free(host);
gpr_free(port);
return nullptr;
}
grpc_ares_request* (*grpc_dns_lookup_ares)(
grpc_exec_ctx* exec_ctx, const char* dns_server, const char* name,
const char* default_port, grpc_pollset_set* interested_parties,
grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb,
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
grpc_lb_addresses** addrs, bool check_grpclb,
char** service_config_json) = grpc_dns_lookup_ares_impl;
void grpc_cancel_ares_request(grpc_exec_ctx* exec_ctx, grpc_ares_request* r) {
void grpc_cancel_ares_request(grpc_ares_request* r) {
if (grpc_dns_lookup_ares == grpc_dns_lookup_ares_impl) {
grpc_ares_ev_driver_shutdown(exec_ctx, r->ev_driver);
grpc_ares_ev_driver_shutdown(r->ev_driver);
}
}
@ -501,8 +486,7 @@ typedef struct grpc_resolve_address_ares_request {
grpc_closure on_dns_lookup_done;
} grpc_resolve_address_ares_request;
static void on_dns_lookup_done_cb(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void on_dns_lookup_done_cb(void* arg, grpc_error* error) {
grpc_resolve_address_ares_request* r =
(grpc_resolve_address_ares_request*)arg;
grpc_resolved_addresses** resolved_addresses = r->addrs_out;
@ -520,14 +504,12 @@ static void on_dns_lookup_done_cb(grpc_exec_ctx* exec_ctx, void* arg,
&r->lb_addrs->addresses[i].address, sizeof(grpc_resolved_address));
}
}
GRPC_CLOSURE_SCHED(exec_ctx, r->on_resolve_address_done,
GRPC_ERROR_REF(error));
grpc_lb_addresses_destroy(exec_ctx, r->lb_addrs);
GRPC_CLOSURE_SCHED(r->on_resolve_address_done, GRPC_ERROR_REF(error));
grpc_lb_addresses_destroy(r->lb_addrs);
gpr_free(r);
}
static void grpc_resolve_address_ares_impl(grpc_exec_ctx* exec_ctx,
const char* name,
static void grpc_resolve_address_ares_impl(const char* name,
const char* default_port,
grpc_pollset_set* interested_parties,
grpc_closure* on_done,
@ -539,14 +521,14 @@ static void grpc_resolve_address_ares_impl(grpc_exec_ctx* exec_ctx,
r->on_resolve_address_done = on_done;
GRPC_CLOSURE_INIT(&r->on_dns_lookup_done, on_dns_lookup_done_cb, r,
grpc_schedule_on_exec_ctx);
grpc_dns_lookup_ares(exec_ctx, nullptr /* dns_server */, name, default_port,
grpc_dns_lookup_ares(nullptr /* dns_server */, name, default_port,
interested_parties, &r->on_dns_lookup_done, &r->lb_addrs,
false /* check_grpclb */,
nullptr /* service_config_json */);
}
void (*grpc_resolve_address_ares)(
grpc_exec_ctx* exec_ctx, const char* name, const char* default_port,
const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
grpc_resolved_addresses** addrs) = grpc_resolve_address_ares_impl;

@ -32,8 +32,7 @@ typedef struct grpc_ares_request grpc_ares_request;
must be called at least once before this function. \a on_done may be
called directly in this function without being scheduled with \a exec_ctx,
so it must not try to acquire locks that are being held by the caller. */
extern void (*grpc_resolve_address_ares)(grpc_exec_ctx* exec_ctx,
const char* name,
extern void (*grpc_resolve_address_ares)(const char* name,
const char* default_port,
grpc_pollset_set* interested_parties,
grpc_closure* on_done,
@ -47,14 +46,13 @@ extern void (*grpc_resolve_address_ares)(grpc_exec_ctx* exec_ctx,
scheduled with \a exec_ctx, so it must not try to acquire locks that are
being held by the caller. */
extern grpc_ares_request* (*grpc_dns_lookup_ares)(
grpc_exec_ctx* exec_ctx, const char* dns_server, const char* name,
const char* default_port, grpc_pollset_set* interested_parties,
grpc_closure* on_done, grpc_lb_addresses** addresses, bool check_grpclb,
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
grpc_lb_addresses** addresses, bool check_grpclb,
char** service_config_json);
/* Cancel the pending grpc_ares_request \a request */
void grpc_cancel_ares_request(grpc_exec_ctx* exec_ctx,
grpc_ares_request* request);
void grpc_cancel_ares_request(grpc_ares_request* request);
/* Initialize gRPC ares wrapper. Must be called at least once before
grpc_resolve_address_ares(). */

@ -26,34 +26,32 @@ struct grpc_ares_request {
};
static grpc_ares_request* grpc_dns_lookup_ares_impl(
grpc_exec_ctx* exec_ctx, const char* dns_server, const char* name,
const char* default_port, grpc_pollset_set* interested_parties,
grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb,
char** service_config_json) {
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json) {
return NULL;
}
grpc_ares_request* (*grpc_dns_lookup_ares)(
grpc_exec_ctx* exec_ctx, const char* dns_server, const char* name,
const char* default_port, grpc_pollset_set* interested_parties,
grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb,
const char* dns_server, const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
grpc_lb_addresses** addrs, bool check_grpclb,
char** service_config_json) = grpc_dns_lookup_ares_impl;
void grpc_cancel_ares_request(grpc_exec_ctx* exec_ctx, grpc_ares_request* r) {}
void grpc_cancel_ares_request(grpc_ares_request* r) {}
grpc_error* grpc_ares_init(void) { return GRPC_ERROR_NONE; }
void grpc_ares_cleanup(void) {}
static void grpc_resolve_address_ares_impl(grpc_exec_ctx* exec_ctx,
const char* name,
static void grpc_resolve_address_ares_impl(const char* name,
const char* default_port,
grpc_pollset_set* interested_parties,
grpc_closure* on_done,
grpc_resolved_addresses** addrs) {}
void (*grpc_resolve_address_ares)(
grpc_exec_ctx* exec_ctx, const char* name, const char* default_port,
const char* name, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
grpc_resolved_addresses** addrs) = grpc_resolve_address_ares_impl;

@ -76,49 +76,42 @@ typedef struct {
grpc_resolved_addresses* addresses;
} dns_resolver;
static void dns_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* r);
static void dns_destroy(grpc_resolver* r);
static void dns_start_resolving_locked(grpc_exec_ctx* exec_ctx,
dns_resolver* r);
static void dns_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx,
dns_resolver* r);
static void dns_start_resolving_locked(dns_resolver* r);
static void dns_maybe_finish_next_locked(dns_resolver* r);
static void dns_shutdown_locked(grpc_exec_ctx* exec_ctx, grpc_resolver* r);
static void dns_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* r);
static void dns_next_locked(grpc_exec_ctx* exec_ctx, grpc_resolver* r,
grpc_channel_args** target_result,
static void dns_shutdown_locked(grpc_resolver* r);
static void dns_channel_saw_error_locked(grpc_resolver* r);
static void dns_next_locked(grpc_resolver* r, grpc_channel_args** target_result,
grpc_closure* on_complete);
static const grpc_resolver_vtable dns_resolver_vtable = {
dns_destroy, dns_shutdown_locked, dns_channel_saw_error_locked,
dns_next_locked};
static void dns_shutdown_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver) {
static void dns_shutdown_locked(grpc_resolver* resolver) {
dns_resolver* r = (dns_resolver*)resolver;
if (r->have_retry_timer) {
grpc_timer_cancel(exec_ctx, &r->retry_timer);
grpc_timer_cancel(&r->retry_timer);
}
if (r->next_completion != nullptr) {
*r->target_result = nullptr;
GRPC_CLOSURE_SCHED(
exec_ctx, r->next_completion,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver Shutdown"));
GRPC_CLOSURE_SCHED(r->next_completion, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Resolver Shutdown"));
r->next_completion = nullptr;
}
}
static void dns_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver) {
static void dns_channel_saw_error_locked(grpc_resolver* resolver) {
dns_resolver* r = (dns_resolver*)resolver;
if (!r->resolving) {
grpc_backoff_reset(&r->backoff_state);
dns_start_resolving_locked(exec_ctx, r);
dns_start_resolving_locked(r);
}
}
static void dns_next_locked(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver,
static void dns_next_locked(grpc_resolver* resolver,
grpc_channel_args** target_result,
grpc_closure* on_complete) {
dns_resolver* r = (dns_resolver*)resolver;
@ -127,28 +120,26 @@ static void dns_next_locked(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver,
r->target_result = target_result;
if (r->resolved_version == 0 && !r->resolving) {
grpc_backoff_reset(&r->backoff_state);
dns_start_resolving_locked(exec_ctx, r);
dns_start_resolving_locked(r);
} else {
dns_maybe_finish_next_locked(exec_ctx, r);
dns_maybe_finish_next_locked(r);
}
}
static void dns_on_retry_timer_locked(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void dns_on_retry_timer_locked(void* arg, grpc_error* error) {
dns_resolver* r = (dns_resolver*)arg;
r->have_retry_timer = false;
if (error == GRPC_ERROR_NONE) {
if (!r->resolving) {
dns_start_resolving_locked(exec_ctx, r);
dns_start_resolving_locked(r);
}
}
GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "retry-timer");
GRPC_RESOLVER_UNREF(&r->base, "retry-timer");
}
static void dns_on_resolved_locked(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void dns_on_resolved_locked(void* arg, grpc_error* error) {
dns_resolver* r = (dns_resolver*)arg;
grpc_channel_args* result = nullptr;
GPR_ASSERT(r->resolving);
@ -168,11 +159,11 @@ static void dns_on_resolved_locked(grpc_exec_ctx* exec_ctx, void* arg,
grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses);
result = grpc_channel_args_copy_and_add(r->channel_args, &new_arg, 1);
grpc_resolved_addresses_destroy(r->addresses);
grpc_lb_addresses_destroy(exec_ctx, addresses);
grpc_lb_addresses_destroy(addresses);
} else {
grpc_millis next_try =
grpc_backoff_step(exec_ctx, &r->backoff_state).next_attempt_start_time;
grpc_millis timeout = next_try - grpc_exec_ctx_now(exec_ctx);
grpc_backoff_step(&r->backoff_state).next_attempt_start_time;
grpc_millis timeout = next_try - grpc_core::ExecCtx::Get()->Now();
gpr_log(GPR_INFO, "dns resolution failed (will retry): %s",
grpc_error_string(error));
GPR_ASSERT(!r->have_retry_timer);
@ -185,59 +176,56 @@ static void dns_on_resolved_locked(grpc_exec_ctx* exec_ctx, void* arg,
}
GRPC_CLOSURE_INIT(&r->on_retry, dns_on_retry_timer_locked, r,
grpc_combiner_scheduler(r->base.combiner));
grpc_timer_init(exec_ctx, &r->retry_timer, next_try, &r->on_retry);
grpc_timer_init(&r->retry_timer, next_try, &r->on_retry);
}
if (r->resolved_result != nullptr) {
grpc_channel_args_destroy(exec_ctx, r->resolved_result);
grpc_channel_args_destroy(r->resolved_result);
}
r->resolved_result = result;
r->resolved_version++;
dns_maybe_finish_next_locked(exec_ctx, r);
dns_maybe_finish_next_locked(r);
GRPC_ERROR_UNREF(error);
GRPC_RESOLVER_UNREF(exec_ctx, &r->base, "dns-resolving");
GRPC_RESOLVER_UNREF(&r->base, "dns-resolving");
}
static void dns_start_resolving_locked(grpc_exec_ctx* exec_ctx,
dns_resolver* r) {
static void dns_start_resolving_locked(dns_resolver* r) {
GRPC_RESOLVER_REF(&r->base, "dns-resolving");
GPR_ASSERT(!r->resolving);
r->resolving = true;
r->addresses = nullptr;
grpc_resolve_address(
exec_ctx, r->name_to_resolve, r->default_port, r->interested_parties,
r->name_to_resolve, r->default_port, r->interested_parties,
GRPC_CLOSURE_CREATE(dns_on_resolved_locked, r,
grpc_combiner_scheduler(r->base.combiner)),
&r->addresses);
}
static void dns_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx,
dns_resolver* r) {
static void dns_maybe_finish_next_locked(dns_resolver* r) {
if (r->next_completion != nullptr &&
r->resolved_version != r->published_version) {
*r->target_result = r->resolved_result == nullptr
? nullptr
: grpc_channel_args_copy(r->resolved_result);
GRPC_CLOSURE_SCHED(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(r->next_completion, GRPC_ERROR_NONE);
r->next_completion = nullptr;
r->published_version = r->resolved_version;
}
}
static void dns_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* gr) {
static void dns_destroy(grpc_resolver* gr) {
dns_resolver* r = (dns_resolver*)gr;
if (r->resolved_result != nullptr) {
grpc_channel_args_destroy(exec_ctx, r->resolved_result);
grpc_channel_args_destroy(r->resolved_result);
}
grpc_pollset_set_destroy(exec_ctx, r->interested_parties);
grpc_pollset_set_destroy(r->interested_parties);
gpr_free(r->name_to_resolve);
gpr_free(r->default_port);
grpc_channel_args_destroy(exec_ctx, r->channel_args);
grpc_channel_args_destroy(r->channel_args);
gpr_free(r);
}
static grpc_resolver* dns_create(grpc_exec_ctx* exec_ctx,
grpc_resolver_args* args,
static grpc_resolver* dns_create(grpc_resolver_args* args,
const char* default_port) {
if (0 != strcmp(args->uri->authority, "")) {
gpr_log(GPR_ERROR, "authority based dns uri's not supported");
@ -254,8 +242,7 @@ static grpc_resolver* dns_create(grpc_exec_ctx* exec_ctx,
r->channel_args = grpc_channel_args_copy(args->args);
r->interested_parties = grpc_pollset_set_create();
if (args->pollset_set != nullptr) {
grpc_pollset_set_add_pollset_set(exec_ctx, r->interested_parties,
args->pollset_set);
grpc_pollset_set_add_pollset_set(r->interested_parties, args->pollset_set);
}
grpc_backoff_init(
&r->backoff_state, GRPC_DNS_INITIAL_CONNECT_BACKOFF_SECONDS * 1000,
@ -274,9 +261,8 @@ static void dns_factory_ref(grpc_resolver_factory* factory) {}
static void dns_factory_unref(grpc_resolver_factory* factory) {}
static grpc_resolver* dns_factory_create_resolver(
grpc_exec_ctx* exec_ctx, grpc_resolver_factory* factory,
grpc_resolver_args* args) {
return dns_create(exec_ctx, args, "https");
grpc_resolver_factory* factory, grpc_resolver_args* args) {
return dns_create(args, "https");
}
static char* dns_factory_get_default_host_name(grpc_resolver_factory* factory,

@ -67,57 +67,52 @@ typedef struct {
grpc_channel_args** target_result;
} fake_resolver;
static void fake_resolver_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* gr) {
static void fake_resolver_destroy(grpc_resolver* gr) {
fake_resolver* r = (fake_resolver*)gr;
grpc_channel_args_destroy(exec_ctx, r->next_results);
grpc_channel_args_destroy(exec_ctx, r->results_upon_error);
grpc_channel_args_destroy(exec_ctx, r->channel_args);
grpc_channel_args_destroy(r->next_results);
grpc_channel_args_destroy(r->results_upon_error);
grpc_channel_args_destroy(r->channel_args);
gpr_free(r);
}
static void fake_resolver_shutdown_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver) {
static void fake_resolver_shutdown_locked(grpc_resolver* resolver) {
fake_resolver* r = (fake_resolver*)resolver;
if (r->next_completion != nullptr) {
*r->target_result = nullptr;
GRPC_CLOSURE_SCHED(
exec_ctx, r->next_completion,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver Shutdown"));
GRPC_CLOSURE_SCHED(r->next_completion, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Resolver Shutdown"));
r->next_completion = nullptr;
}
}
static void fake_resolver_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx,
fake_resolver* r) {
static void fake_resolver_maybe_finish_next_locked(fake_resolver* r) {
if (r->next_completion != nullptr && r->next_results != nullptr) {
*r->target_result =
grpc_channel_args_union(r->next_results, r->channel_args);
grpc_channel_args_destroy(exec_ctx, r->next_results);
grpc_channel_args_destroy(r->next_results);
r->next_results = nullptr;
GRPC_CLOSURE_SCHED(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(r->next_completion, GRPC_ERROR_NONE);
r->next_completion = nullptr;
}
}
static void fake_resolver_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver) {
static void fake_resolver_channel_saw_error_locked(grpc_resolver* resolver) {
fake_resolver* r = (fake_resolver*)resolver;
if (r->next_results == nullptr && r->results_upon_error != nullptr) {
// Pretend we re-resolved.
r->next_results = grpc_channel_args_copy(r->results_upon_error);
}
fake_resolver_maybe_finish_next_locked(exec_ctx, r);
fake_resolver_maybe_finish_next_locked(r);
}
static void fake_resolver_next_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver,
static void fake_resolver_next_locked(grpc_resolver* resolver,
grpc_channel_args** target_result,
grpc_closure* on_complete) {
fake_resolver* r = (fake_resolver*)resolver;
GPR_ASSERT(!r->next_completion);
r->next_completion = on_complete;
r->target_result = target_result;
fake_resolver_maybe_finish_next_locked(exec_ctx, r);
fake_resolver_maybe_finish_next_locked(r);
}
static const grpc_resolver_vtable fake_resolver_vtable = {
@ -157,33 +152,31 @@ typedef struct set_response_closure_arg {
grpc_channel_args* next_response;
} set_response_closure_arg;
static void set_response_closure_fn(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void set_response_closure_fn(void* arg, grpc_error* error) {
set_response_closure_arg* closure_arg = (set_response_closure_arg*)arg;
grpc_fake_resolver_response_generator* generator = closure_arg->generator;
fake_resolver* r = generator->resolver;
if (r->next_results != nullptr) {
grpc_channel_args_destroy(exec_ctx, r->next_results);
grpc_channel_args_destroy(r->next_results);
}
r->next_results = closure_arg->next_response;
if (r->results_upon_error != nullptr) {
grpc_channel_args_destroy(exec_ctx, r->results_upon_error);
grpc_channel_args_destroy(r->results_upon_error);
}
r->results_upon_error = grpc_channel_args_copy(closure_arg->next_response);
gpr_free(closure_arg);
fake_resolver_maybe_finish_next_locked(exec_ctx, r);
fake_resolver_maybe_finish_next_locked(r);
}
void grpc_fake_resolver_response_generator_set_response(
grpc_exec_ctx* exec_ctx, grpc_fake_resolver_response_generator* generator,
grpc_fake_resolver_response_generator* generator,
grpc_channel_args* next_response) {
GPR_ASSERT(generator->resolver != nullptr);
set_response_closure_arg* closure_arg =
(set_response_closure_arg*)gpr_zalloc(sizeof(*closure_arg));
closure_arg->generator = generator;
closure_arg->next_response = grpc_channel_args_copy(next_response);
GRPC_CLOSURE_SCHED(exec_ctx,
GRPC_CLOSURE_INIT(&closure_arg->set_response_closure,
GRPC_CLOSURE_SCHED(GRPC_CLOSURE_INIT(&closure_arg->set_response_closure,
set_response_closure_fn, closure_arg,
grpc_combiner_scheduler(
generator->resolver->base.combiner)),
@ -195,7 +188,7 @@ static void* response_generator_arg_copy(void* p) {
(grpc_fake_resolver_response_generator*)p);
}
static void response_generator_arg_destroy(grpc_exec_ctx* exec_ctx, void* p) {
static void response_generator_arg_destroy(void* p) {
grpc_fake_resolver_response_generator_unref(
(grpc_fake_resolver_response_generator*)p);
}
@ -232,8 +225,7 @@ static void fake_resolver_factory_ref(grpc_resolver_factory* factory) {}
static void fake_resolver_factory_unref(grpc_resolver_factory* factory) {}
static grpc_resolver* fake_resolver_create(grpc_exec_ctx* exec_ctx,
grpc_resolver_factory* factory,
static grpc_resolver* fake_resolver_create(grpc_resolver_factory* factory,
grpc_resolver_args* args) {
fake_resolver* r = (fake_resolver*)gpr_zalloc(sizeof(*r));
r->channel_args = grpc_channel_args_copy(args->args);

@ -39,7 +39,7 @@ grpc_fake_resolver_response_generator_create();
// Instruct the fake resolver associated with the \a response_generator instance
// to trigger a new resolution for \a uri and \a args.
void grpc_fake_resolver_response_generator_set_response(
grpc_exec_ctx* exec_ctx, grpc_fake_resolver_response_generator* generator,
grpc_fake_resolver_response_generator* generator,
grpc_channel_args* next_response);
// Return a \a grpc_arg for a \a grpc_fake_resolver_response_generator instance.

@ -52,15 +52,13 @@ typedef struct {
grpc_channel_args** target_result;
} sockaddr_resolver;
static void sockaddr_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* r);
static void sockaddr_destroy(grpc_resolver* r);
static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx,
sockaddr_resolver* r);
static void sockaddr_maybe_finish_next_locked(sockaddr_resolver* r);
static void sockaddr_shutdown_locked(grpc_exec_ctx* exec_ctx, grpc_resolver* r);
static void sockaddr_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* r);
static void sockaddr_next_locked(grpc_exec_ctx* exec_ctx, grpc_resolver* r,
static void sockaddr_shutdown_locked(grpc_resolver* r);
static void sockaddr_channel_saw_error_locked(grpc_resolver* r);
static void sockaddr_next_locked(grpc_resolver* r,
grpc_channel_args** target_result,
grpc_closure* on_complete);
@ -68,52 +66,47 @@ static const grpc_resolver_vtable sockaddr_resolver_vtable = {
sockaddr_destroy, sockaddr_shutdown_locked,
sockaddr_channel_saw_error_locked, sockaddr_next_locked};
static void sockaddr_shutdown_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver) {
static void sockaddr_shutdown_locked(grpc_resolver* resolver) {
sockaddr_resolver* r = (sockaddr_resolver*)resolver;
if (r->next_completion != nullptr) {
*r->target_result = nullptr;
GRPC_CLOSURE_SCHED(
exec_ctx, r->next_completion,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Resolver Shutdown"));
GRPC_CLOSURE_SCHED(r->next_completion, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Resolver Shutdown"));
r->next_completion = nullptr;
}
}
static void sockaddr_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver) {
static void sockaddr_channel_saw_error_locked(grpc_resolver* resolver) {
sockaddr_resolver* r = (sockaddr_resolver*)resolver;
r->published = false;
sockaddr_maybe_finish_next_locked(exec_ctx, r);
sockaddr_maybe_finish_next_locked(r);
}
static void sockaddr_next_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver,
static void sockaddr_next_locked(grpc_resolver* resolver,
grpc_channel_args** target_result,
grpc_closure* on_complete) {
sockaddr_resolver* r = (sockaddr_resolver*)resolver;
GPR_ASSERT(!r->next_completion);
r->next_completion = on_complete;
r->target_result = target_result;
sockaddr_maybe_finish_next_locked(exec_ctx, r);
sockaddr_maybe_finish_next_locked(r);
}
static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx,
sockaddr_resolver* r) {
static void sockaddr_maybe_finish_next_locked(sockaddr_resolver* r) {
if (r->next_completion != nullptr && !r->published) {
r->published = true;
grpc_arg arg = grpc_lb_addresses_create_channel_arg(r->addresses);
*r->target_result =
grpc_channel_args_copy_and_add(r->channel_args, &arg, 1);
GRPC_CLOSURE_SCHED(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
GRPC_CLOSURE_SCHED(r->next_completion, GRPC_ERROR_NONE);
r->next_completion = nullptr;
}
}
static void sockaddr_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* gr) {
static void sockaddr_destroy(grpc_resolver* gr) {
sockaddr_resolver* r = (sockaddr_resolver*)gr;
grpc_lb_addresses_destroy(exec_ctx, r->addresses);
grpc_channel_args_destroy(exec_ctx, r->channel_args);
grpc_lb_addresses_destroy(r->addresses);
grpc_channel_args_destroy(r->channel_args);
gpr_free(r);
}
@ -142,8 +135,7 @@ char* unix_get_default_authority(grpc_resolver_factory* factory,
static void do_nothing(void* ignored) {}
static grpc_resolver* sockaddr_create(grpc_exec_ctx* exec_ctx,
grpc_resolver_args* args,
static grpc_resolver* sockaddr_create(grpc_resolver_args* args,
bool parse(const grpc_uri* uri,
grpc_resolved_address* dst)) {
if (0 != strcmp(args->uri->authority, "")) {
@ -170,10 +162,10 @@ static grpc_resolver* sockaddr_create(grpc_exec_ctx* exec_ctx,
gpr_free(part_str);
if (errors_found) break;
}
grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts);
grpc_slice_unref_internal(exec_ctx, path_slice);
grpc_slice_buffer_destroy_internal(&path_parts);
grpc_slice_unref_internal(path_slice);
if (errors_found) {
grpc_lb_addresses_destroy(exec_ctx, addresses);
grpc_lb_addresses_destroy(addresses);
return nullptr;
}
/* Instantiate resolver. */
@ -195,9 +187,8 @@ static void sockaddr_factory_unref(grpc_resolver_factory* factory) {}
#define DECL_FACTORY(name) \
static grpc_resolver* name##_factory_create_resolver( \
grpc_exec_ctx* exec_ctx, grpc_resolver_factory* factory, \
grpc_resolver_args* args) { \
return sockaddr_create(exec_ctx, args, grpc_parse_##name); \
grpc_resolver_factory* factory, grpc_resolver_args* args) { \
return sockaddr_create(args, grpc_parse_##name); \
} \
static const grpc_resolver_factory_vtable name##_factory_vtable = { \
sockaddr_factory_ref, sockaddr_factory_unref, \

@ -28,10 +28,9 @@ void grpc_resolver_factory_unref(grpc_resolver_factory* factory) {
/** Create a resolver instance for a name */
grpc_resolver* grpc_resolver_factory_create_resolver(
grpc_exec_ctx* exec_ctx, grpc_resolver_factory* factory,
grpc_resolver_args* args) {
grpc_resolver_factory* factory, grpc_resolver_args* args) {
if (factory == nullptr) return nullptr;
return factory->vtable->create_resolver(exec_ctx, factory, args);
return factory->vtable->create_resolver(factory, args);
}
char* grpc_resolver_factory_get_default_authority(

@ -43,8 +43,7 @@ struct grpc_resolver_factory_vtable {
void (*unref)(grpc_resolver_factory* factory);
/** Implementation of grpc_resolver_factory_create_resolver */
grpc_resolver* (*create_resolver)(grpc_exec_ctx* exec_ctx,
grpc_resolver_factory* factory,
grpc_resolver* (*create_resolver)(grpc_resolver_factory* factory,
grpc_resolver_args* args);
/** Implementation of grpc_resolver_factory_get_default_authority */
@ -59,8 +58,7 @@ void grpc_resolver_factory_unref(grpc_resolver_factory* resolver);
/** Create a resolver instance for a name */
grpc_resolver* grpc_resolver_factory_create_resolver(
grpc_exec_ctx* exec_ctx, grpc_resolver_factory* factory,
grpc_resolver_args* args);
grpc_resolver_factory* factory, grpc_resolver_args* args);
/** Return a (freshly allocated with gpr_malloc) string representing
the default authority to use for this scheme. */

@ -92,23 +92,22 @@ static grpc_resolver_factory* lookup_factory_by_uri(grpc_uri* uri) {
return lookup_factory(uri->scheme);
}
static grpc_resolver_factory* resolve_factory(grpc_exec_ctx* exec_ctx,
const char* target,
static grpc_resolver_factory* resolve_factory(const char* target,
grpc_uri** uri,
char** canonical_target) {
grpc_resolver_factory* factory = nullptr;
GPR_ASSERT(uri != nullptr);
*uri = grpc_uri_parse(exec_ctx, target, 1);
*uri = grpc_uri_parse(target, 1);
factory = lookup_factory_by_uri(*uri);
if (factory == nullptr) {
grpc_uri_destroy(*uri);
gpr_asprintf(canonical_target, "%s%s", g_default_resolver_prefix, target);
*uri = grpc_uri_parse(exec_ctx, *canonical_target, 1);
*uri = grpc_uri_parse(*canonical_target, 1);
factory = lookup_factory_by_uri(*uri);
if (factory == nullptr) {
grpc_uri_destroy(grpc_uri_parse(exec_ctx, target, 0));
grpc_uri_destroy(grpc_uri_parse(exec_ctx, *canonical_target, 0));
grpc_uri_destroy(grpc_uri_parse(target, 0));
grpc_uri_destroy(grpc_uri_parse(*canonical_target, 0));
gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target,
*canonical_target);
}
@ -116,14 +115,14 @@ static grpc_resolver_factory* resolve_factory(grpc_exec_ctx* exec_ctx,
return factory;
}
grpc_resolver* grpc_resolver_create(grpc_exec_ctx* exec_ctx, const char* target,
grpc_resolver* grpc_resolver_create(const char* target,
const grpc_channel_args* args,
grpc_pollset_set* pollset_set,
grpc_combiner* combiner) {
grpc_uri* uri = nullptr;
char* canonical_target = nullptr;
grpc_resolver_factory* factory =
resolve_factory(exec_ctx, target, &uri, &canonical_target);
resolve_factory(target, &uri, &canonical_target);
grpc_resolver* resolver;
grpc_resolver_args resolver_args;
memset(&resolver_args, 0, sizeof(resolver_args));
@ -131,29 +130,27 @@ grpc_resolver* grpc_resolver_create(grpc_exec_ctx* exec_ctx, const char* target,
resolver_args.args = args;
resolver_args.pollset_set = pollset_set;
resolver_args.combiner = combiner;
resolver =
grpc_resolver_factory_create_resolver(exec_ctx, factory, &resolver_args);
resolver = grpc_resolver_factory_create_resolver(factory, &resolver_args);
grpc_uri_destroy(uri);
gpr_free(canonical_target);
return resolver;
}
char* grpc_get_default_authority(grpc_exec_ctx* exec_ctx, const char* target) {
char* grpc_get_default_authority(const char* target) {
grpc_uri* uri = nullptr;
char* canonical_target = nullptr;
grpc_resolver_factory* factory =
resolve_factory(exec_ctx, target, &uri, &canonical_target);
resolve_factory(target, &uri, &canonical_target);
char* authority = grpc_resolver_factory_get_default_authority(factory, uri);
grpc_uri_destroy(uri);
gpr_free(canonical_target);
return authority;
}
char* grpc_resolver_factory_add_default_prefix_if_needed(
grpc_exec_ctx* exec_ctx, const char* target) {
char* grpc_resolver_factory_add_default_prefix_if_needed(const char* target) {
grpc_uri* uri = nullptr;
char* canonical_target = nullptr;
resolve_factory(exec_ctx, target, &uri, &canonical_target);
resolve_factory(target, &uri, &canonical_target);
grpc_uri_destroy(uri);
return canonical_target == nullptr ? gpr_strdup(target) : canonical_target;
}

@ -48,7 +48,7 @@ void grpc_register_resolver_type(grpc_resolver_factory* factory);
(typically the set of arguments passed in from the client API).
\a pollset_set is used to drive IO in the name resolution process, it
should not be NULL. */
grpc_resolver* grpc_resolver_create(grpc_exec_ctx* exec_ctx, const char* target,
grpc_resolver* grpc_resolver_create(const char* target,
const grpc_channel_args* args,
grpc_pollset_set* pollset_set,
grpc_combiner* combiner);
@ -59,11 +59,10 @@ grpc_resolver_factory* grpc_resolver_factory_lookup(const char* name);
/** Given a target, return a (freshly allocated with gpr_malloc) string
representing the default authority to pass from a client. */
char* grpc_get_default_authority(grpc_exec_ctx* exec_ctx, const char* target);
char* grpc_get_default_authority(const char* target);
/** Returns a newly allocated string containing \a target, adding the
default prefix if needed. */
char* grpc_resolver_factory_add_default_prefix_if_needed(
grpc_exec_ctx* exec_ctx, const char* target);
char* grpc_resolver_factory_add_default_prefix_if_needed(const char* target);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_REGISTRY_H */

@ -139,8 +139,7 @@ struct grpc_subchannel_call {
#define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \
(((grpc_subchannel_call*)(callstack)) - 1)
static void subchannel_connected(grpc_exec_ctx* exec_ctx, void* subchannel,
grpc_error* error);
static void subchannel_connected(void* subchannel, grpc_error* error);
#ifndef NDEBUG
#define REF_REASON reason
@ -157,10 +156,9 @@ static void subchannel_connected(grpc_exec_ctx* exec_ctx, void* subchannel,
* connection implementation
*/
static void connection_destroy(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void connection_destroy(void* arg, grpc_error* error) {
grpc_connected_subchannel* c = (grpc_connected_subchannel*)arg;
grpc_channel_stack_destroy(exec_ctx, CHANNEL_STACK_FROM_CONNECTION(c));
grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CONNECTION(c));
gpr_free(c);
}
@ -170,26 +168,23 @@ grpc_connected_subchannel* grpc_connected_subchannel_ref(
return c;
}
void grpc_connected_subchannel_unref(grpc_exec_ctx* exec_ctx,
grpc_connected_subchannel* c
GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
GRPC_CHANNEL_STACK_UNREF(exec_ctx, CHANNEL_STACK_FROM_CONNECTION(c),
REF_REASON);
void grpc_connected_subchannel_unref(
grpc_connected_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
GRPC_CHANNEL_STACK_UNREF(CHANNEL_STACK_FROM_CONNECTION(c), REF_REASON);
}
/*
* grpc_subchannel implementation
*/
static void subchannel_destroy(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void subchannel_destroy(void* arg, grpc_error* error) {
grpc_subchannel* c = (grpc_subchannel*)arg;
gpr_free((void*)c->filters);
grpc_channel_args_destroy(exec_ctx, c->args);
grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
grpc_connector_unref(exec_ctx, c->connector);
grpc_pollset_set_destroy(exec_ctx, c->pollset_set);
grpc_subchannel_key_destroy(exec_ctx, c->key);
grpc_channel_args_destroy(c->args);
grpc_connectivity_state_destroy(&c->state_tracker);
grpc_connector_unref(c->connector);
grpc_pollset_set_destroy(c->pollset_set);
grpc_subchannel_key_destroy(c->key);
gpr_mu_destroy(&c->mu);
gpr_free(c);
}
@ -241,59 +236,54 @@ grpc_subchannel* grpc_subchannel_ref_from_weak_ref(
}
}
static void disconnect(grpc_exec_ctx* exec_ctx, grpc_subchannel* c) {
static void disconnect(grpc_subchannel* c) {
grpc_connected_subchannel* con;
grpc_subchannel_index_unregister(exec_ctx, c->key, c);
grpc_subchannel_index_unregister(c->key, c);
gpr_mu_lock(&c->mu);
GPR_ASSERT(!c->disconnected);
c->disconnected = true;
grpc_connector_shutdown(
exec_ctx, c->connector,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Subchannel disconnected"));
grpc_connector_shutdown(c->connector, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Subchannel disconnected"));
con = GET_CONNECTED_SUBCHANNEL(c, no_barrier);
if (con != nullptr) {
GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, con, "connection");
GRPC_CONNECTED_SUBCHANNEL_UNREF(con, "connection");
gpr_atm_no_barrier_store(&c->connected_subchannel, (gpr_atm)0xdeadbeef);
}
gpr_mu_unlock(&c->mu);
}
void grpc_subchannel_unref(grpc_exec_ctx* exec_ctx,
grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
void grpc_subchannel_unref(grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
gpr_atm old_refs;
// add a weak ref and subtract a strong ref (atomically)
old_refs = ref_mutate(c, (gpr_atm)1 - (gpr_atm)(1 << INTERNAL_REF_BITS),
1 REF_MUTATE_PURPOSE("STRONG_UNREF"));
if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) {
disconnect(exec_ctx, c);
disconnect(c);
}
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "strong-unref");
GRPC_SUBCHANNEL_WEAK_UNREF(c, "strong-unref");
}
void grpc_subchannel_weak_unref(grpc_exec_ctx* exec_ctx,
grpc_subchannel* c
GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
void grpc_subchannel_weak_unref(
grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
gpr_atm old_refs;
old_refs = ref_mutate(c, -(gpr_atm)1, 1 REF_MUTATE_PURPOSE("WEAK_UNREF"));
if (old_refs == 1) {
GRPC_CLOSURE_SCHED(
exec_ctx,
GRPC_CLOSURE_CREATE(subchannel_destroy, c, grpc_schedule_on_exec_ctx),
GRPC_ERROR_NONE);
}
}
grpc_subchannel* grpc_subchannel_create(grpc_exec_ctx* exec_ctx,
grpc_connector* connector,
grpc_subchannel* grpc_subchannel_create(grpc_connector* connector,
const grpc_subchannel_args* args) {
grpc_subchannel_key* key = grpc_subchannel_key_create(args);
grpc_subchannel* c = grpc_subchannel_index_find(exec_ctx, key);
grpc_subchannel* c = grpc_subchannel_index_find(key);
if (c) {
grpc_subchannel_key_destroy(exec_ctx, key);
grpc_subchannel_key_destroy(key);
return c;
}
GRPC_STATS_INC_CLIENT_SUBCHANNELS_CREATED(exec_ctx);
GRPC_STATS_INC_CLIENT_SUBCHANNELS_CREATED();
c = (grpc_subchannel*)gpr_zalloc(sizeof(*c));
c->key = key;
gpr_atm_no_barrier_store(&c->ref_pair, 1 << INTERNAL_REF_BITS);
@ -311,10 +301,10 @@ grpc_subchannel* grpc_subchannel_create(grpc_exec_ctx* exec_ctx,
c->pollset_set = grpc_pollset_set_create();
grpc_resolved_address* addr =
(grpc_resolved_address*)gpr_malloc(sizeof(*addr));
grpc_get_subchannel_address_arg(exec_ctx, args->args, addr);
grpc_get_subchannel_address_arg(args->args, addr);
grpc_resolved_address* new_address = nullptr;
grpc_channel_args* new_args = nullptr;
if (grpc_proxy_mappers_map_address(exec_ctx, addr, args->args, &new_address,
if (grpc_proxy_mappers_map_address(addr, args->args, &new_address,
&new_args)) {
GPR_ASSERT(new_address != nullptr);
gpr_free(addr);
@ -327,7 +317,7 @@ grpc_subchannel* grpc_subchannel_create(grpc_exec_ctx* exec_ctx,
new_args != nullptr ? new_args : args->args, keys_to_remove,
GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1);
gpr_free(new_arg.value.string);
if (new_args != nullptr) grpc_channel_args_destroy(exec_ctx, new_args);
if (new_args != nullptr) grpc_channel_args_destroy(new_args);
c->root_external_state_watcher.next = c->root_external_state_watcher.prev =
&c->root_external_state_watcher;
GRPC_CLOSURE_INIT(&c->connected, subchannel_connected, c,
@ -373,21 +363,19 @@ grpc_subchannel* grpc_subchannel_create(grpc_exec_ctx* exec_ctx,
min_backoff_ms, max_backoff_ms);
gpr_mu_init(&c->mu);
return grpc_subchannel_index_register(exec_ctx, key, c);
return grpc_subchannel_index_register(key, c);
}
static void continue_connect_locked(grpc_exec_ctx* exec_ctx,
grpc_subchannel* c) {
static void continue_connect_locked(grpc_subchannel* c) {
grpc_connect_in_args args;
args.interested_parties = c->pollset_set;
args.deadline = c->backoff_result.current_deadline;
args.channel_args = c->args;
grpc_connectivity_state_set(exec_ctx, &c->state_tracker,
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
"state_change");
grpc_connector_connect(exec_ctx, c->connector, &args, &c->connecting_result,
grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING,
GRPC_ERROR_NONE, "state_change");
grpc_connector_connect(c->connector, &args, &c->connecting_result,
&c->connected);
}
@ -400,24 +388,23 @@ grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel* c,
return state;
}
static void on_external_state_watcher_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void on_external_state_watcher_done(void* arg, grpc_error* error) {
external_state_watcher* w = (external_state_watcher*)arg;
grpc_closure* follow_up = w->notify;
if (w->pollset_set != nullptr) {
grpc_pollset_set_del_pollset_set(exec_ctx, w->subchannel->pollset_set,
grpc_pollset_set_del_pollset_set(w->subchannel->pollset_set,
w->pollset_set);
}
gpr_mu_lock(&w->subchannel->mu);
w->next->prev = w->prev;
w->prev->next = w->next;
gpr_mu_unlock(&w->subchannel->mu);
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, w->subchannel, "external_state_watcher");
GRPC_SUBCHANNEL_WEAK_UNREF(w->subchannel, "external_state_watcher");
gpr_free(w);
GRPC_CLOSURE_RUN(exec_ctx, follow_up, GRPC_ERROR_REF(error));
GRPC_CLOSURE_RUN(follow_up, GRPC_ERROR_REF(error));
}
static void on_alarm(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
static void on_alarm(void* arg, grpc_error* error) {
grpc_subchannel* c = (grpc_subchannel*)arg;
gpr_mu_lock(&c->mu);
c->have_alarm = false;
@ -429,18 +416,17 @@ static void on_alarm(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
}
if (error == GRPC_ERROR_NONE) {
gpr_log(GPR_INFO, "Failed to connect to channel, retrying");
c->backoff_result = grpc_backoff_step(exec_ctx, &c->backoff_state);
continue_connect_locked(exec_ctx, c);
c->backoff_result = grpc_backoff_step(&c->backoff_state);
continue_connect_locked(c);
gpr_mu_unlock(&c->mu);
} else {
gpr_mu_unlock(&c->mu);
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
}
GRPC_ERROR_UNREF(error);
}
static void maybe_start_connecting_locked(grpc_exec_ctx* exec_ctx,
grpc_subchannel* c) {
static void maybe_start_connecting_locked(grpc_subchannel* c) {
if (c->disconnected) {
/* Don't try to connect if we're already disconnected */
return;
@ -466,28 +452,28 @@ static void maybe_start_connecting_locked(grpc_exec_ctx* exec_ctx,
if (!c->backoff_begun) {
c->backoff_begun = true;
c->backoff_result = grpc_backoff_begin(exec_ctx, &c->backoff_state);
continue_connect_locked(exec_ctx, c);
c->backoff_result = grpc_backoff_begin(&c->backoff_state);
continue_connect_locked(c);
} else {
GPR_ASSERT(!c->have_alarm);
c->have_alarm = true;
const grpc_millis time_til_next =
c->backoff_result.next_attempt_start_time - grpc_exec_ctx_now(exec_ctx);
c->backoff_result.next_attempt_start_time -
grpc_core::ExecCtx::Get()->Now();
if (time_til_next <= 0) {
gpr_log(GPR_INFO, "Retry immediately");
} else {
gpr_log(GPR_INFO, "Retry in %" PRIdPTR " milliseconds", time_til_next);
}
GRPC_CLOSURE_INIT(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx);
grpc_timer_init(exec_ctx, &c->alarm,
c->backoff_result.next_attempt_start_time, &c->on_alarm);
grpc_timer_init(&c->alarm, c->backoff_result.next_attempt_start_time,
&c->on_alarm);
}
}
void grpc_subchannel_notify_on_state_change(
grpc_exec_ctx* exec_ctx, grpc_subchannel* c,
grpc_pollset_set* interested_parties, grpc_connectivity_state* state,
grpc_closure* notify) {
grpc_subchannel* c, grpc_pollset_set* interested_parties,
grpc_connectivity_state* state, grpc_closure* notify) {
external_state_watcher* w;
if (state == nullptr) {
@ -495,8 +481,8 @@ void grpc_subchannel_notify_on_state_change(
for (w = c->root_external_state_watcher.next;
w != &c->root_external_state_watcher; w = w->next) {
if (w->notify == notify) {
grpc_connectivity_state_notify_on_state_change(
exec_ctx, &c->state_tracker, nullptr, &w->closure);
grpc_connectivity_state_notify_on_state_change(&c->state_tracker,
nullptr, &w->closure);
}
}
gpr_mu_unlock(&c->mu);
@ -508,31 +494,28 @@ void grpc_subchannel_notify_on_state_change(
GRPC_CLOSURE_INIT(&w->closure, on_external_state_watcher_done, w,
grpc_schedule_on_exec_ctx);
if (interested_parties != nullptr) {
grpc_pollset_set_add_pollset_set(exec_ctx, c->pollset_set,
interested_parties);
grpc_pollset_set_add_pollset_set(c->pollset_set, interested_parties);
}
GRPC_SUBCHANNEL_WEAK_REF(c, "external_state_watcher");
gpr_mu_lock(&c->mu);
w->next = &c->root_external_state_watcher;
w->prev = w->next->prev;
w->next->prev = w->prev->next = w;
grpc_connectivity_state_notify_on_state_change(exec_ctx, &c->state_tracker,
state, &w->closure);
maybe_start_connecting_locked(exec_ctx, c);
grpc_connectivity_state_notify_on_state_change(&c->state_tracker, state,
&w->closure);
maybe_start_connecting_locked(c);
gpr_mu_unlock(&c->mu);
}
}
void grpc_connected_subchannel_process_transport_op(
grpc_exec_ctx* exec_ctx, grpc_connected_subchannel* con,
grpc_transport_op* op) {
grpc_connected_subchannel* con, grpc_transport_op* op) {
grpc_channel_stack* channel_stack = CHANNEL_STACK_FROM_CONNECTION(con);
grpc_channel_element* top_elem = grpc_channel_stack_element(channel_stack, 0);
top_elem->filter->start_transport_op(exec_ctx, top_elem, op);
top_elem->filter->start_transport_op(top_elem, op);
}
static void subchannel_on_child_state_changed(grpc_exec_ctx* exec_ctx, void* p,
grpc_error* error) {
static void subchannel_on_child_state_changed(void* p, grpc_error* error) {
state_watcher* sw = (state_watcher*)p;
grpc_subchannel* c = sw->subchannel;
gpr_mu* mu = &c->mu;
@ -544,24 +527,22 @@ static void subchannel_on_child_state_changed(grpc_exec_ctx* exec_ctx, void* p,
/* any errors on a subchannel ==> we're done, create a new one */
sw->connectivity_state = GRPC_CHANNEL_SHUTDOWN;
}
grpc_connectivity_state_set(exec_ctx, &c->state_tracker,
sw->connectivity_state, GRPC_ERROR_REF(error),
"reflect_child");
grpc_connectivity_state_set(&c->state_tracker, sw->connectivity_state,
GRPC_ERROR_REF(error), "reflect_child");
if (sw->connectivity_state != GRPC_CHANNEL_SHUTDOWN) {
grpc_connected_subchannel_notify_on_state_change(
exec_ctx, GET_CONNECTED_SUBCHANNEL(c, no_barrier), nullptr,
GET_CONNECTED_SUBCHANNEL(c, no_barrier), nullptr,
&sw->connectivity_state, &sw->closure);
GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
sw = nullptr;
}
gpr_mu_unlock(mu);
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "state_watcher");
GRPC_SUBCHANNEL_WEAK_UNREF(c, "state_watcher");
gpr_free(sw);
}
static void connected_subchannel_state_op(grpc_exec_ctx* exec_ctx,
grpc_connected_subchannel* con,
static void connected_subchannel_state_op(grpc_connected_subchannel* con,
grpc_pollset_set* interested_parties,
grpc_connectivity_state* state,
grpc_closure* closure) {
@ -571,29 +552,27 @@ static void connected_subchannel_state_op(grpc_exec_ctx* exec_ctx,
op->on_connectivity_state_change = closure;
op->bind_pollset_set = interested_parties;
elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(con), 0);
elem->filter->start_transport_op(exec_ctx, elem, op);
elem->filter->start_transport_op(elem, op);
}
void grpc_connected_subchannel_notify_on_state_change(
grpc_exec_ctx* exec_ctx, grpc_connected_subchannel* con,
grpc_pollset_set* interested_parties, grpc_connectivity_state* state,
grpc_closure* closure) {
connected_subchannel_state_op(exec_ctx, con, interested_parties, state,
closure);
grpc_connected_subchannel* con, grpc_pollset_set* interested_parties,
grpc_connectivity_state* state, grpc_closure* closure) {
connected_subchannel_state_op(con, interested_parties, state, closure);
}
void grpc_connected_subchannel_ping(grpc_exec_ctx* exec_ctx,
grpc_connected_subchannel* con,
grpc_closure* closure) {
void grpc_connected_subchannel_ping(grpc_connected_subchannel* con,
grpc_closure* on_initiate,
grpc_closure* on_ack) {
grpc_transport_op* op = grpc_make_transport_op(nullptr);
grpc_channel_element* elem;
op->send_ping = closure;
op->send_ping.on_initiate = on_initiate;
op->send_ping.on_ack = on_ack;
elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(con), 0);
elem->filter->start_transport_op(exec_ctx, elem, op);
elem->filter->start_transport_op(elem, op);
}
static bool publish_transport_locked(grpc_exec_ctx* exec_ctx,
grpc_subchannel* c) {
static bool publish_transport_locked(grpc_subchannel* c) {
grpc_connected_subchannel* con;
grpc_channel_stack* stk;
state_watcher* sw_subchannel;
@ -601,19 +580,18 @@ static bool publish_transport_locked(grpc_exec_ctx* exec_ctx,
/* construct channel stack */
grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create();
grpc_channel_stack_builder_set_channel_arguments(
exec_ctx, builder, c->connecting_result.channel_args);
builder, c->connecting_result.channel_args);
grpc_channel_stack_builder_set_transport(builder,
c->connecting_result.transport);
if (!grpc_channel_init_create_stack(exec_ctx, builder,
GRPC_CLIENT_SUBCHANNEL)) {
grpc_channel_stack_builder_destroy(exec_ctx, builder);
if (!grpc_channel_init_create_stack(builder, GRPC_CLIENT_SUBCHANNEL)) {
grpc_channel_stack_builder_destroy(builder);
return false;
}
grpc_error* error = grpc_channel_stack_builder_finish(
exec_ctx, builder, 0, 1, connection_destroy, nullptr, (void**)&con);
builder, 0, 1, connection_destroy, nullptr, (void**)&con);
if (error != GRPC_ERROR_NONE) {
grpc_transport_destroy(exec_ctx, c->connecting_result.transport);
grpc_transport_destroy(c->connecting_result.transport);
gpr_log(GPR_ERROR, "error initializing subchannel stack: %s",
grpc_error_string(error));
GRPC_ERROR_UNREF(error);
@ -631,7 +609,7 @@ static bool publish_transport_locked(grpc_exec_ctx* exec_ctx,
if (c->disconnected) {
gpr_free(sw_subchannel);
grpc_channel_stack_destroy(exec_ctx, stk);
grpc_channel_stack_destroy(stk);
gpr_free(con);
return false;
}
@ -647,19 +625,18 @@ static bool publish_transport_locked(grpc_exec_ctx* exec_ctx,
/* setup subchannel watching connected subchannel for changes; subchannel
ref for connecting is donated to the state watcher */
GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher");
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
grpc_connected_subchannel_notify_on_state_change(
exec_ctx, con, c->pollset_set, &sw_subchannel->connectivity_state,
con, c->pollset_set, &sw_subchannel->connectivity_state,
&sw_subchannel->closure);
/* signal completion */
grpc_connectivity_state_set(exec_ctx, &c->state_tracker, GRPC_CHANNEL_READY,
grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "connected");
return true;
}
static void subchannel_connected(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
static void subchannel_connected(void* arg, grpc_error* error) {
grpc_subchannel* c = (grpc_subchannel*)arg;
grpc_channel_args* delete_channel_args = c->connecting_result.channel_args;
@ -667,13 +644,13 @@ static void subchannel_connected(grpc_exec_ctx* exec_ctx, void* arg,
gpr_mu_lock(&c->mu);
c->connecting = false;
if (c->connecting_result.transport != nullptr &&
publish_transport_locked(exec_ctx, c)) {
publish_transport_locked(c)) {
/* do nothing, transport was published */
} else if (c->disconnected) {
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
} else {
grpc_connectivity_state_set(
exec_ctx, &c->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
&c->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Connect Failed", &error, 1),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
@ -682,27 +659,26 @@ static void subchannel_connected(grpc_exec_ctx* exec_ctx, void* arg,
const char* errmsg = grpc_error_string(error);
gpr_log(GPR_INFO, "Connect failed: %s", errmsg);
maybe_start_connecting_locked(exec_ctx, c);
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
maybe_start_connecting_locked(c);
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
}
gpr_mu_unlock(&c->mu);
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connected");
grpc_channel_args_destroy(exec_ctx, delete_channel_args);
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connected");
grpc_channel_args_destroy(delete_channel_args);
}
/*
* grpc_subchannel_call implementation
*/
static void subchannel_call_destroy(grpc_exec_ctx* exec_ctx, void* call,
grpc_error* error) {
static void subchannel_call_destroy(void* call, grpc_error* error) {
grpc_subchannel_call* c = (grpc_subchannel_call*)call;
GPR_ASSERT(c->schedule_closure_after_destroy != nullptr);
GPR_TIMER_BEGIN("grpc_subchannel_call_unref.destroy", 0);
grpc_connected_subchannel* connection = c->connection;
grpc_call_stack_destroy(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c), nullptr,
grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(c), nullptr,
c->schedule_closure_after_destroy);
GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, connection, "subchannel_call");
GRPC_CONNECTED_SUBCHANNEL_UNREF(connection, "subchannel_call");
GPR_TIMER_END("grpc_subchannel_call_unref.destroy", 0);
}
@ -718,20 +694,18 @@ void grpc_subchannel_call_ref(
GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON);
}
void grpc_subchannel_call_unref(grpc_exec_ctx* exec_ctx,
grpc_subchannel_call* c
GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
GRPC_CALL_STACK_UNREF(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON);
void grpc_subchannel_call_unref(
grpc_subchannel_call* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON);
}
void grpc_subchannel_call_process_op(grpc_exec_ctx* exec_ctx,
grpc_subchannel_call* call,
void grpc_subchannel_call_process_op(grpc_subchannel_call* call,
grpc_transport_stream_op_batch* batch) {
GPR_TIMER_BEGIN("grpc_subchannel_call_process_op", 0);
grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call);
grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0);
GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch);
top_elem->filter->start_transport_stream_op_batch(exec_ctx, top_elem, batch);
top_elem->filter->start_transport_stream_op_batch(top_elem, batch);
GPR_TIMER_END("grpc_subchannel_call_process_op", 0);
}
@ -746,7 +720,7 @@ const grpc_subchannel_key* grpc_subchannel_get_key(
}
grpc_error* grpc_connected_subchannel_create_call(
grpc_exec_ctx* exec_ctx, grpc_connected_subchannel* con,
grpc_connected_subchannel* con,
const grpc_connected_subchannel_call_args* args,
grpc_subchannel_call** call) {
grpc_channel_stack* chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
@ -764,14 +738,14 @@ grpc_error* grpc_connected_subchannel_create_call(
args->arena, /* arena */
args->call_combiner /* call_combiner */
};
grpc_error* error = grpc_call_stack_init(
exec_ctx, chanstk, 1, subchannel_call_destroy, *call, &call_args);
grpc_error* error = grpc_call_stack_init(chanstk, 1, subchannel_call_destroy,
*call, &call_args);
if (error != GRPC_ERROR_NONE) {
const char* error_string = grpc_error_string(error);
gpr_log(GPR_ERROR, "error: %s", error_string);
return error;
}
grpc_call_stack_set_pollset_or_pollset_set(exec_ctx, callstk, args->pollent);
grpc_call_stack_set_pollset_or_pollset_set(callstk, args->pollent);
return GRPC_ERROR_NONE;
}
@ -780,21 +754,20 @@ grpc_call_stack* grpc_subchannel_call_get_call_stack(
return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
}
static void grpc_uri_to_sockaddr(grpc_exec_ctx* exec_ctx, const char* uri_str,
static void grpc_uri_to_sockaddr(const char* uri_str,
grpc_resolved_address* addr) {
grpc_uri* uri = grpc_uri_parse(exec_ctx, uri_str, 0 /* suppress_errors */);
grpc_uri* uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */);
GPR_ASSERT(uri != nullptr);
if (!grpc_parse_uri(uri, addr)) memset(addr, 0, sizeof(*addr));
grpc_uri_destroy(uri);
}
void grpc_get_subchannel_address_arg(grpc_exec_ctx* exec_ctx,
const grpc_channel_args* args,
void grpc_get_subchannel_address_arg(const grpc_channel_args* args,
grpc_resolved_address* addr) {
const char* addr_uri_str = grpc_get_subchannel_address_uri_arg(args);
memset(addr, 0, sizeof(*addr));
if (*addr_uri_str != '\0') {
grpc_uri_to_sockaddr(exec_ctx, addr_uri_str, addr);
grpc_uri_to_sockaddr(addr_uri_str, addr);
}
}

@ -42,36 +42,34 @@ typedef struct grpc_subchannel_key grpc_subchannel_key;
grpc_subchannel_ref((p), __FILE__, __LINE__, (r))
#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \
grpc_subchannel_ref_from_weak_ref((p), __FILE__, __LINE__, (r))
#define GRPC_SUBCHANNEL_UNREF(cl, p, r) \
grpc_subchannel_unref((cl), (p), __FILE__, __LINE__, (r))
#define GRPC_SUBCHANNEL_UNREF(p, r) \
grpc_subchannel_unref((p), __FILE__, __LINE__, (r))
#define GRPC_SUBCHANNEL_WEAK_REF(p, r) \
grpc_subchannel_weak_ref((p), __FILE__, __LINE__, (r))
#define GRPC_SUBCHANNEL_WEAK_UNREF(cl, p, r) \
grpc_subchannel_weak_unref((cl), (p), __FILE__, __LINE__, (r))
#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) \
grpc_subchannel_weak_unref((p), __FILE__, __LINE__, (r))
#define GRPC_CONNECTED_SUBCHANNEL_REF(p, r) \
grpc_connected_subchannel_ref((p), __FILE__, __LINE__, (r))
#define GRPC_CONNECTED_SUBCHANNEL_UNREF(cl, p, r) \
grpc_connected_subchannel_unref((cl), (p), __FILE__, __LINE__, (r))
#define GRPC_CONNECTED_SUBCHANNEL_UNREF(p, r) \
grpc_connected_subchannel_unref((p), __FILE__, __LINE__, (r))
#define GRPC_SUBCHANNEL_CALL_REF(p, r) \
grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r))
#define GRPC_SUBCHANNEL_CALL_UNREF(cl, p, r) \
grpc_subchannel_call_unref((cl), (p), __FILE__, __LINE__, (r))
#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) \
grpc_subchannel_call_unref((p), __FILE__, __LINE__, (r))
#define GRPC_SUBCHANNEL_REF_EXTRA_ARGS \
, const char *file, int line, const char *reason
#else
#define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p))
#define GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(p, r) \
grpc_subchannel_ref_from_weak_ref((p))
#define GRPC_SUBCHANNEL_UNREF(cl, p, r) grpc_subchannel_unref((cl), (p))
#define GRPC_SUBCHANNEL_UNREF(p, r) grpc_subchannel_unref((p))
#define GRPC_SUBCHANNEL_WEAK_REF(p, r) grpc_subchannel_weak_ref((p))
#define GRPC_SUBCHANNEL_WEAK_UNREF(cl, p, r) \
grpc_subchannel_weak_unref((cl), (p))
#define GRPC_SUBCHANNEL_WEAK_UNREF(p, r) grpc_subchannel_weak_unref((p))
#define GRPC_CONNECTED_SUBCHANNEL_REF(p, r) grpc_connected_subchannel_ref((p))
#define GRPC_CONNECTED_SUBCHANNEL_UNREF(cl, p, r) \
grpc_connected_subchannel_unref((cl), (p))
#define GRPC_CONNECTED_SUBCHANNEL_UNREF(p, r) \
grpc_connected_subchannel_unref((p))
#define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p))
#define GRPC_SUBCHANNEL_CALL_UNREF(cl, p, r) \
grpc_subchannel_call_unref((cl), (p))
#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) grpc_subchannel_call_unref((p))
#define GRPC_SUBCHANNEL_REF_EXTRA_ARGS
#endif
@ -79,24 +77,20 @@ grpc_subchannel* grpc_subchannel_ref(
grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
grpc_subchannel* grpc_subchannel_ref_from_weak_ref(
grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
void grpc_subchannel_unref(grpc_exec_ctx* exec_ctx,
grpc_subchannel* channel
GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
void grpc_subchannel_unref(
grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
grpc_subchannel* grpc_subchannel_weak_ref(
grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
void grpc_subchannel_weak_unref(grpc_exec_ctx* exec_ctx,
grpc_subchannel* channel
GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
void grpc_subchannel_weak_unref(
grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
grpc_connected_subchannel* grpc_connected_subchannel_ref(
grpc_connected_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
void grpc_connected_subchannel_unref(grpc_exec_ctx* exec_ctx,
grpc_connected_subchannel* channel
GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
void grpc_connected_subchannel_unref(
grpc_connected_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
void grpc_subchannel_call_ref(
grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
void grpc_subchannel_call_unref(grpc_exec_ctx* exec_ctx,
grpc_subchannel_call* call
GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
void grpc_subchannel_call_unref(
grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
/** construct a subchannel call */
typedef struct {
@ -110,14 +104,13 @@ typedef struct {
} grpc_connected_subchannel_call_args;
grpc_error* grpc_connected_subchannel_create_call(
grpc_exec_ctx* exec_ctx, grpc_connected_subchannel* connected_subchannel,
grpc_connected_subchannel* connected_subchannel,
const grpc_connected_subchannel_call_args* args,
grpc_subchannel_call** subchannel_call);
/** process a transport level op */
void grpc_connected_subchannel_process_transport_op(
grpc_exec_ctx* exec_ctx, grpc_connected_subchannel* subchannel,
grpc_transport_op* op);
grpc_connected_subchannel* subchannel, grpc_transport_op* op);
/** poll the current connectivity state of a channel */
grpc_connectivity_state grpc_subchannel_check_connectivity(
@ -126,16 +119,14 @@ grpc_connectivity_state grpc_subchannel_check_connectivity(
/** Calls notify when the connectivity state of a channel becomes different
from *state. Updates *state with the new state of the channel. */
void grpc_subchannel_notify_on_state_change(
grpc_exec_ctx* exec_ctx, grpc_subchannel* channel,
grpc_pollset_set* interested_parties, grpc_connectivity_state* state,
grpc_closure* notify);
grpc_subchannel* channel, grpc_pollset_set* interested_parties,
grpc_connectivity_state* state, grpc_closure* notify);
void grpc_connected_subchannel_notify_on_state_change(
grpc_exec_ctx* exec_ctx, grpc_connected_subchannel* channel,
grpc_pollset_set* interested_parties, grpc_connectivity_state* state,
grpc_closure* notify);
void grpc_connected_subchannel_ping(grpc_exec_ctx* exec_ctx,
grpc_connected_subchannel* channel,
grpc_closure* notify);
grpc_connected_subchannel* channel, grpc_pollset_set* interested_parties,
grpc_connectivity_state* state, grpc_closure* notify);
void grpc_connected_subchannel_ping(grpc_connected_subchannel* channel,
grpc_closure* on_initiate,
grpc_closure* on_ack);
/** retrieve the grpc_connected_subchannel - or NULL if called before
the subchannel becomes connected */
@ -147,8 +138,7 @@ const grpc_subchannel_key* grpc_subchannel_get_key(
const grpc_subchannel* subchannel);
/** continue processing a transport op */
void grpc_subchannel_call_process_op(grpc_exec_ctx* exec_ctx,
grpc_subchannel_call* subchannel_call,
void grpc_subchannel_call_process_op(grpc_subchannel_call* subchannel_call,
grpc_transport_stream_op_batch* op);
/** Must be called once per call. Sets the 'then_schedule_closure' argument for
@ -172,13 +162,11 @@ struct grpc_subchannel_args {
};
/** create a subchannel given a connector */
grpc_subchannel* grpc_subchannel_create(grpc_exec_ctx* exec_ctx,
grpc_connector* connector,
grpc_subchannel* grpc_subchannel_create(grpc_connector* connector,
const grpc_subchannel_args* args);
/// Sets \a addr from \a args.
void grpc_get_subchannel_address_arg(grpc_exec_ctx* exec_ctx,
const grpc_channel_args* args,
void grpc_get_subchannel_address_arg(const grpc_channel_args* args,
grpc_resolved_address* addr);
/// Returns the URI string for the address to connect to.

@ -81,16 +81,14 @@ int grpc_subchannel_key_compare(const grpc_subchannel_key* a,
return grpc_channel_args_compare(a->args.args, b->args.args);
}
void grpc_subchannel_key_destroy(grpc_exec_ctx* exec_ctx,
grpc_subchannel_key* k) {
void grpc_subchannel_key_destroy(grpc_subchannel_key* k) {
gpr_free((grpc_channel_args*)k->args.filters);
grpc_channel_args_destroy(exec_ctx, (grpc_channel_args*)k->args.args);
grpc_channel_args_destroy((grpc_channel_args*)k->args.args);
gpr_free(k);
}
static void sck_avl_destroy(void* p, void* user_data) {
grpc_exec_ctx* exec_ctx = (grpc_exec_ctx*)user_data;
grpc_subchannel_key_destroy(exec_ctx, (grpc_subchannel_key*)p);
grpc_subchannel_key_destroy((grpc_subchannel_key*)p);
}
static void* sck_avl_copy(void* p, void* unused) {
@ -103,8 +101,7 @@ static long sck_avl_compare(void* a, void* b, void* unused) {
}
static void scv_avl_destroy(void* p, void* user_data) {
grpc_exec_ctx* exec_ctx = (grpc_exec_ctx*)user_data;
GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, (grpc_subchannel*)p, "subchannel_index");
GRPC_SUBCHANNEL_WEAK_UNREF((grpc_subchannel*)p, "subchannel_index");
}
static void* scv_avl_copy(void* p, void* unused) {
@ -135,32 +132,29 @@ void grpc_subchannel_index_shutdown(void) {
void grpc_subchannel_index_unref(void) {
if (gpr_unref(&g_refcount)) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_mu_destroy(&g_mu);
gpr_avl_unref(g_subchannel_index, &exec_ctx);
grpc_exec_ctx_finish(&exec_ctx);
gpr_avl_unref(g_subchannel_index, grpc_core::ExecCtx::Get());
}
}
void grpc_subchannel_index_ref(void) { gpr_ref_non_zero(&g_refcount); }
grpc_subchannel* grpc_subchannel_index_find(grpc_exec_ctx* exec_ctx,
grpc_subchannel_key* key) {
grpc_subchannel* grpc_subchannel_index_find(grpc_subchannel_key* key) {
// Lock, and take a reference to the subchannel index.
// We don't need to do the search under a lock as avl's are immutable.
gpr_mu_lock(&g_mu);
gpr_avl index = gpr_avl_ref(g_subchannel_index, exec_ctx);
gpr_avl index = gpr_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get());
gpr_mu_unlock(&g_mu);
grpc_subchannel* c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(
(grpc_subchannel*)gpr_avl_get(index, key, exec_ctx), "index_find");
gpr_avl_unref(index, exec_ctx);
(grpc_subchannel*)gpr_avl_get(index, key, grpc_core::ExecCtx::Get()),
"index_find");
gpr_avl_unref(index, grpc_core::ExecCtx::Get());
return c;
}
grpc_subchannel* grpc_subchannel_index_register(grpc_exec_ctx* exec_ctx,
grpc_subchannel_key* key,
grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key,
grpc_subchannel* constructed) {
grpc_subchannel* c = nullptr;
bool need_to_unref_constructed = false;
@ -171,11 +165,11 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_exec_ctx* exec_ctx,
// Compare and swap loop:
// - take a reference to the current index
gpr_mu_lock(&g_mu);
gpr_avl index = gpr_avl_ref(g_subchannel_index, exec_ctx);
gpr_avl index = gpr_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get());
gpr_mu_unlock(&g_mu);
// - Check to see if a subchannel already exists
c = (grpc_subchannel*)gpr_avl_get(index, key, exec_ctx);
c = (grpc_subchannel*)gpr_avl_get(index, key, grpc_core::ExecCtx::Get());
if (c != nullptr) {
c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "index_register");
}
@ -184,9 +178,11 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_exec_ctx* exec_ctx,
need_to_unref_constructed = true;
} else {
// no -> update the avl and compare/swap
gpr_avl updated = gpr_avl_add(
gpr_avl_ref(index, exec_ctx), subchannel_key_copy(key),
GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"), exec_ctx);
gpr_avl updated =
gpr_avl_add(gpr_avl_ref(index, grpc_core::ExecCtx::Get()),
subchannel_key_copy(key),
GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"),
grpc_core::ExecCtx::Get());
// it may happen (but it's expected to be unlikely)
// that some other thread has changed the index:
@ -198,41 +194,42 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_exec_ctx* exec_ctx,
}
gpr_mu_unlock(&g_mu);
gpr_avl_unref(updated, exec_ctx);
gpr_avl_unref(updated, grpc_core::ExecCtx::Get());
}
gpr_avl_unref(index, exec_ctx);
gpr_avl_unref(index, grpc_core::ExecCtx::Get());
}
if (need_to_unref_constructed) {
GRPC_SUBCHANNEL_UNREF(exec_ctx, constructed, "index_register");
GRPC_SUBCHANNEL_UNREF(constructed, "index_register");
}
return c;
}
void grpc_subchannel_index_unregister(grpc_exec_ctx* exec_ctx,
grpc_subchannel_key* key,
void grpc_subchannel_index_unregister(grpc_subchannel_key* key,
grpc_subchannel* constructed) {
bool done = false;
while (!done) {
// Compare and swap loop:
// - take a reference to the current index
gpr_mu_lock(&g_mu);
gpr_avl index = gpr_avl_ref(g_subchannel_index, exec_ctx);
gpr_avl index = gpr_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get());
gpr_mu_unlock(&g_mu);
// Check to see if this key still refers to the previously
// registered subchannel
grpc_subchannel* c = (grpc_subchannel*)gpr_avl_get(index, key, exec_ctx);
grpc_subchannel* c =
(grpc_subchannel*)gpr_avl_get(index, key, grpc_core::ExecCtx::Get());
if (c != constructed) {
gpr_avl_unref(index, exec_ctx);
gpr_avl_unref(index, grpc_core::ExecCtx::Get());
break;
}
// compare and swap the update (some other thread may have
// mutated the index behind us)
gpr_avl updated =
gpr_avl_remove(gpr_avl_ref(index, exec_ctx), key, exec_ctx);
gpr_avl_remove(gpr_avl_ref(index, grpc_core::ExecCtx::Get()), key,
grpc_core::ExecCtx::Get());
gpr_mu_lock(&g_mu);
if (index.root == g_subchannel_index.root) {
@ -241,8 +238,8 @@ void grpc_subchannel_index_unregister(grpc_exec_ctx* exec_ctx,
}
gpr_mu_unlock(&g_mu);
gpr_avl_unref(updated, exec_ctx);
gpr_avl_unref(index, exec_ctx);
gpr_avl_unref(updated, grpc_core::ExecCtx::Get());
gpr_avl_unref(index, grpc_core::ExecCtx::Get());
}
}

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

Loading…
Cancel
Save