Merge branch 'master' into kerrick-lyft-patch-1

pull/15859/head
Kerrick Staley 7 years ago
commit f44f0bc592
  1. 8
      .gitmodules
  2. 1
      BUILD
  3. 4
      BUILDING.md
  4. 39
      CMakeLists.txt
  5. 6
      CONTRIBUTING.md
  6. 110
      Makefile
  7. 52
      build.yaml
  8. 17
      gRPC-C++.podspec
  9. 11
      gRPC-Core.podspec
  10. 4
      grpc.gemspec
  11. 26
      grpc.gyp
  12. 1
      include/grpc/module.modulemap
  13. 4
      package.xml
  14. 10
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
  15. 11
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
  16. 5
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
  17. 43
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
  18. 4
      src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
  19. 25
      src/core/ext/filters/client_channel/subchannel.cc
  20. 46
      src/core/lib/channel/channel_stack.cc
  21. 5
      src/core/lib/channel/channelz.cc
  22. 28
      src/core/lib/gpr/alloc.h
  23. 16
      src/core/lib/gpr/arena.cc
  24. 2
      src/core/lib/gprpp/thd_posix.cc
  25. 97
      src/core/lib/iomgr/ev_epollex_linux.cc
  26. 2
      src/core/lib/iomgr/iomgr.cc
  27. 5
      src/core/lib/iomgr/iomgr.h
  28. 1
      src/core/lib/iomgr/timer_manager.cc
  29. 8
      src/core/lib/security/context/security_context.cc
  30. 5
      src/core/lib/security/context/security_context.h
  31. 9
      src/core/lib/security/transport/server_auth_filter.cc
  32. 13
      src/core/lib/surface/call.cc
  33. 2
      src/core/lib/surface/call.h
  34. 3
      src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
  35. 48
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
  36. 4
      src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h
  37. 23
      src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
  38. 9
      src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h
  39. 15
      src/objective-c/GRPCClient/GRPCCall+ChannelArg.h
  40. 15
      src/objective-c/GRPCClient/GRPCCall+ChannelArg.m
  41. 5
      src/objective-c/GRPCClient/private/GRPCHost.h
  42. 15
      src/objective-c/GRPCClient/private/GRPCHost.m
  43. 92
      src/objective-c/NetworkTransitionBehavior.md
  44. 32
      src/objective-c/README-CFSTREAM.md
  45. 43
      src/objective-c/tests/GRPCClientTests.m
  46. 15
      templates/Makefile.template
  47. 10
      templates/gRPC-C++.podspec.template
  48. 19
      test/build/no-c++14-compat.cc
  49. 19
      test/build/no-maybe-uninitialized.c
  50. 19
      test/build/no-unused-but-set-variable.c
  51. 21
      test/core/iomgr/BUILD
  52. 115
      test/core/iomgr/ev_epollex_linux_test.cc
  53. 1
      test/core/surface/public_headers_must_be_c89.c
  54. 26
      test/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_test.cc
  55. 41
      test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc
  56. 46
      test/cpp/naming/cancel_ares_query_test.cc
  57. 1
      third_party/libcxx
  58. 1
      third_party/libcxxabi
  59. 1
      tools/doxygen/Doxyfile.c++
  60. 2
      tools/doxygen/Doxyfile.c++.internal
  61. 1
      tools/doxygen/Doxyfile.core
  62. 4
      tools/doxygen/Doxyfile.core.internal
  63. 2
      tools/internal_ci/linux/grpc_asan_on_foundry.sh
  64. 2
      tools/internal_ci/linux/grpc_ubsan_on_foundry.sh
  65. 19
      tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh
  66. 68
      tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh
  67. 15
      tools/interop_matrix/client_matrix.py
  68. 39
      tools/run_tests/generated/sources_and_headers.json
  69. 20
      tools/run_tests/generated/tests.json
  70. 16
      tools/run_tests/sanity/check_submodules.sh

8
.gitmodules vendored

@ -34,3 +34,11 @@
[submodule "third_party/abseil-cpp"]
path = third_party/abseil-cpp
url = https://github.com/abseil/abseil-cpp
[submodule "third_party/libcxxabi"]
path = third_party/libcxxabi
url = https://github.com/llvm-mirror/libcxxabi.git
branch = release_60
[submodule "third_party/libcxx"]
path = third_party/libcxx
url = https://github.com/llvm-mirror/libcxx.git
branch = release_60

@ -540,6 +540,7 @@ grpc_cc_library(
"src/core/lib/profiling/stap_timers.cc",
],
hdrs = [
"src/core/lib/gpr/alloc.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
"src/core/lib/gpr/host_port.h",

@ -112,9 +112,11 @@ From the grpc repository root
## bazel
See [Installing Bazel](https://docs.bazel.build/versions/master/install.html) for instructions how to install bazel on your system.
From the grpc repository root
```
bazel build :all
$ bazel build :all
```
## cmake: Windows, Using Visual Studio 2015 or 2017 (can only build with OPENSSL_NO_ASM).

@ -246,6 +246,9 @@ endif()
add_dependencies(buildtests_c endpoint_pair_test)
add_dependencies(buildtests_c error_test)
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c ev_epollex_linux_test)
endif()
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c ev_epollsig_linux_test)
endif()
add_dependencies(buildtests_c fake_resolver_test)
@ -1301,6 +1304,7 @@ foreach(_hdr
include/grpc/grpc.h
include/grpc/grpc_posix.h
include/grpc/grpc_security_constants.h
include/grpc/load_reporting.h
include/grpc/slice.h
include/grpc/slice_buffer.h
include/grpc/status.h
@ -2603,6 +2607,7 @@ foreach(_hdr
include/grpc/grpc.h
include/grpc/grpc_posix.h
include/grpc/grpc_security_constants.h
include/grpc/load_reporting.h
include/grpc/slice.h
include/grpc/slice_buffer.h
include/grpc/status.h
@ -2919,6 +2924,7 @@ foreach(_hdr
include/grpc/grpc.h
include/grpc/grpc_posix.h
include/grpc/grpc_security_constants.h
include/grpc/load_reporting.h
include/grpc/slice.h
include/grpc/slice_buffer.h
include/grpc/status.h
@ -3482,6 +3488,7 @@ foreach(_hdr
include/grpc/grpc.h
include/grpc/grpc_posix.h
include/grpc/grpc_security_constants.h
include/grpc/load_reporting.h
include/grpc/slice.h
include/grpc/slice_buffer.h
include/grpc/status.h
@ -4381,6 +4388,7 @@ foreach(_hdr
include/grpc/grpc.h
include/grpc/grpc_posix.h
include/grpc/grpc_security_constants.h
include/grpc/load_reporting.h
include/grpc/slice.h
include/grpc/slice_buffer.h
include/grpc/status.h
@ -6186,6 +6194,37 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX)
add_executable(ev_epollex_linux_test
test/core/iomgr/ev_epollex_linux_test.cc
)
target_include_directories(ev_epollex_linux_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(ev_epollex_linux_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr_test_util
gpr
)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX)
add_executable(ev_epollsig_linux_test
test/core/iomgr/ev_epollsig_linux_test.cc
)

@ -24,9 +24,9 @@ script that unifies the experience of building and testing gRPC in different
languages and on different platforms is provided.
To build gRPC in the language of choice (e.g. `c++`, `csharp`, `php`, `python`, `ruby`, ...)
- Prepare you development environment based on language-specific instructions in `src/YOUR-LANGUAGE` directory.
- Prepare your development environment based on language-specific instructions in `src/YOUR-LANGUAGE` directory.
- The language-specific instructions might involve installing C/C++ prerequisites listed in
[Building gRPC C++: Prerequisites](BUILDING.md#pre-requisites) as gRPC implementations
[Building gRPC C++: Prerequisites](BUILDING.md#pre-requisites). This is because gRPC implementations
in this repository are using the native gRPC "core" library internally.
- Run
```
@ -38,7 +38,7 @@ To build gRPC in the language of choice (e.g. `c++`, `csharp`, `php`, `python`,
```
You can also run `python tools/run_tests/run_tests.py --help` to discover useful command line flags supported. For more details,
see [tools/run_tests](tools/run_tests) where you will also find guidance on how to run various other test suites (e.g. interop tests, benchmarks)
see [tools/run_tests](tools/run_tests) where you will also find guidance on how to run various other test suites (e.g. interop tests, benchmarks).
## Generated project files

@ -300,6 +300,12 @@ else
TMPOUT = `mktemp /tmp/test-out-XXXXXX`
endif
CHECK_NO_CXX14_COMPAT_WORKS_CMD = $(CC) -std=c++11 -Werror -Wno-c++14-compat -o $(TMPOUT) -c test/build/no-c++14-compat.cc
HAS_WORKING_NO_CXX14_COMPAT = $(shell $(CHECK_NO_CXX14_COMPAT_WORKS_CMD) 2> /dev/null && echo true || echo false)
ifeq ($(HAS_WORKING_NO_CXX14_COMPAT),true)
W_NO_CXX14_COMPAT=-Wno-c++14-compat
endif
CHECK_SHADOW_WORKS_CMD = $(CC) -std=c99 -Werror -Wshadow -o $(TMPOUT) -c test/build/shadow.c
HAS_WORKING_SHADOW = $(shell $(CHECK_SHADOW_WORKS_CMD) 2> /dev/null && echo true || echo false)
ifeq ($(HAS_WORKING_SHADOW),true)
@ -318,6 +324,18 @@ ifeq ($(HAS_WORKING_NO_SHIFT_NEGATIVE_VALUE),true)
W_NO_SHIFT_NEGATIVE_VALUE=-Wno-shift-negative-value
NO_W_NO_SHIFT_NEGATIVE_VALUE=-Wshift-negative-value
endif
CHECK_NO_UNUSED_BUT_SET_VARIABLE_WORKS_CMD = $(CC) -std=c99 -Werror -Wno-unused-but-set-variable -o $(TMPOUT) -c test/build/no-unused-but-set-variable.c
HAS_WORKING_NO_UNUSED_BUT_SET_VARIABLE = $(shell $(CHECK_NO_UNUSED_BUT_SET_VARIABLE_WORKS_CMD) 2> /dev/null && echo true || echo false)
ifeq ($(HAS_WORKING_NO_UNUSED_BUT_SET_VARIABLE),true)
W_NO_UNUSED_BUT_SET_VARIABLE=-Wno-unused-but-set-variable
NO_W_NO_UNUSED_BUT_SET_VARIABLE=-Wunused-but-set-variable
endif
CHECK_NO_MAYBE_UNINITIALIZED_WORKS_CMD = $(CC) -std=c99 -Werror -Wno-maybe-uninitialized -o $(TMPOUT) -c test/build/no-maybe-uninitialized.c
HAS_WORKING_NO_MAYBE_UNINITIALIZED = $(shell $(CHECK_NO_MAYBE_UNINITIALIZED_WORKS_CMD) 2> /dev/null && echo true || echo false)
ifeq ($(HAS_WORKING_NO_MAYBE_UNINITIALIZED),true)
W_NO_MAYBE_UNINITIALIZED=-Wno-maybe-uninitialized
NO_W_NO_MAYBE_UNINITIALIZED=-Wmaybe-uninitialized
endif
# The HOST compiler settings are used to compile the protoc plugins.
# In most cases, you won't have to change anything, but if you are
@ -968,6 +986,7 @@ dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test
dualstack_socket_test: $(BINDIR)/$(CONFIG)/dualstack_socket_test
endpoint_pair_test: $(BINDIR)/$(CONFIG)/endpoint_pair_test
error_test: $(BINDIR)/$(CONFIG)/error_test
ev_epollex_linux_test: $(BINDIR)/$(CONFIG)/ev_epollex_linux_test
ev_epollsig_linux_test: $(BINDIR)/$(CONFIG)/ev_epollsig_linux_test
fake_resolver_test: $(BINDIR)/$(CONFIG)/fake_resolver_test
fake_transport_security_test: $(BINDIR)/$(CONFIG)/fake_transport_security_test
@ -1371,7 +1390,7 @@ plugins: $(PROTOC_PLUGINS)
privatelibs: privatelibs_c privatelibs_cxx
privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a
privatelibs_c: $(LIBDIR)/$(CONFIG)/libalts_test_util.a $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libares.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a
pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc
pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc
@ -1413,6 +1432,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/dualstack_socket_test \
$(BINDIR)/$(CONFIG)/endpoint_pair_test \
$(BINDIR)/$(CONFIG)/error_test \
$(BINDIR)/$(CONFIG)/ev_epollex_linux_test \
$(BINDIR)/$(CONFIG)/ev_epollsig_linux_test \
$(BINDIR)/$(CONFIG)/fake_resolver_test \
$(BINDIR)/$(CONFIG)/fake_transport_security_test \
@ -1934,6 +1954,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/endpoint_pair_test || ( echo test endpoint_pair_test failed ; exit 1 )
$(E) "[RUN] Testing error_test"
$(Q) $(BINDIR)/$(CONFIG)/error_test || ( echo test error_test failed ; exit 1 )
$(E) "[RUN] Testing ev_epollex_linux_test"
$(Q) $(BINDIR)/$(CONFIG)/ev_epollex_linux_test || ( echo test ev_epollex_linux_test failed ; exit 1 )
$(E) "[RUN] Testing ev_epollsig_linux_test"
$(Q) $(BINDIR)/$(CONFIG)/ev_epollsig_linux_test || ( echo test ev_epollsig_linux_test failed ; exit 1 )
$(E) "[RUN] Testing fake_resolver_test"
@ -2855,6 +2877,11 @@ $(OBJDIR)/$(CONFIG)/%.o : %.cc
$(Q) mkdir -p `dirname $@`
$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
$(OBJDIR)/$(CONFIG)/%.o : %.cpp
$(E) "[CXX] Compiling $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
install: install_c install_cxx install-plugins install-certs
install_c: install-headers_c install-static_c install-shared_c
@ -3169,6 +3196,50 @@ endif
endif
LIBCXXABI_SRC = \
third_party/libcxxabi/src/abort_message.cpp \
third_party/libcxxabi/src/cxa_aux_runtime.cpp \
third_party/libcxxabi/src/cxa_default_handlers.cpp \
third_party/libcxxabi/src/cxa_demangle.cpp \
third_party/libcxxabi/src/cxa_exception_storage.cpp \
third_party/libcxxabi/src/cxa_guard.cpp \
third_party/libcxxabi/src/cxa_handlers.cpp \
third_party/libcxxabi/src/cxa_noexception.cpp \
third_party/libcxxabi/src/cxa_thread_atexit.cpp \
third_party/libcxxabi/src/cxa_unexpected.cpp \
third_party/libcxxabi/src/cxa_vector.cpp \
third_party/libcxxabi/src/cxa_virtual.cpp \
third_party/libcxxabi/src/fallback_malloc.cpp \
third_party/libcxxabi/src/private_typeinfo.cpp \
third_party/libcxxabi/src/stdlib_exception.cpp \
third_party/libcxxabi/src/stdlib_new_delete.cpp \
third_party/libcxxabi/src/stdlib_stdexcept.cpp \
third_party/libcxxabi/src/stdlib_typeinfo.cpp \
PUBLIC_HEADERS_C += \
LIBCXXABI_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBCXXABI_SRC))))
$(LIBCXXABI_OBJS): CPPFLAGS += -D_LIBCPP_DISABLE_EXTERN_TEMPLATE -D_LIBCXXABI_BUILDING_LIBRARY -D_LIBCXXABI_NO_EXCEPTIONS -Ithird_party/libcxxabi/include -nostdinc++ -Ithird_party/libcxx/include $(W_NO_UNUSED_BUT_SET_VARIABLE) $(W_NO_MAYBE_UNINITIALIZED) -fvisibility=hidden
$(LIBCXXABI_OBJS): CXXFLAGS += $(W_NO_CXX14_COMPAT)
$(LIBDIR)/$(CONFIG)/libcxxabi.a: $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(LIBCXXABI_OBJS)
$(E) "[AR] Creating $@"
$(Q) mkdir -p `dirname $@`
$(Q) rm -f $(LIBDIR)/$(CONFIG)/libcxxabi.a
$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libcxxabi.a $(LIBCXXABI_OBJS)
ifeq ($(SYSTEM),Darwin)
$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libcxxabi.a
endif
ifneq ($(NO_DEPS),true)
-include $(LIBCXXABI_OBJS:.o=.dep)
endif
LIBGPR_SRC = \
src/core/lib/gpr/alloc.cc \
src/core/lib/gpr/arena.cc \
@ -3640,6 +3711,7 @@ PUBLIC_HEADERS_C += \
include/grpc/grpc.h \
include/grpc/grpc_posix.h \
include/grpc/grpc_security_constants.h \
include/grpc/load_reporting.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \
@ -4909,6 +4981,7 @@ PUBLIC_HEADERS_C += \
include/grpc/grpc.h \
include/grpc/grpc_posix.h \
include/grpc/grpc_security_constants.h \
include/grpc/load_reporting.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \
@ -5204,6 +5277,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/grpc.h \
include/grpc/grpc_posix.h \
include/grpc/grpc_security_constants.h \
include/grpc/load_reporting.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \
@ -5774,6 +5848,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/grpc.h \
include/grpc/grpc_posix.h \
include/grpc/grpc_security_constants.h \
include/grpc/load_reporting.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \
@ -6633,6 +6708,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/grpc.h \
include/grpc/grpc_posix.h \
include/grpc/grpc_security_constants.h \
include/grpc/load_reporting.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \
@ -10998,6 +11074,38 @@ endif
endif
EV_EPOLLEX_LINUX_TEST_SRC = \
test/core/iomgr/ev_epollex_linux_test.cc \
EV_EPOLLEX_LINUX_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(EV_EPOLLEX_LINUX_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/ev_epollex_linux_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(EV_EPOLLEX_LINUX_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/ev_epollex_linux_test
endif
$(OBJDIR)/$(CONFIG)/test/core/iomgr/ev_epollex_linux_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_ev_epollex_linux_test: $(EV_EPOLLEX_LINUX_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(EV_EPOLLEX_LINUX_TEST_OBJS:.o=.dep)
endif
endif
EV_EPOLLSIG_LINUX_TEST_SRC = \
test/core/iomgr/ev_epollsig_linux_test.cc \

@ -173,6 +173,7 @@ filegroups:
- include/grpc/support/thd_id.h
- include/grpc/support/time.h
headers:
- src/core/lib/gpr/alloc.h
- src/core/lib/gpr/arena.h
- src/core/lib/gpr/env.h
- src/core/lib/gpr/host_port.h
@ -393,6 +394,7 @@ filegroups:
- include/grpc/grpc.h
- include/grpc/grpc_posix.h
- include/grpc/grpc_security_constants.h
- include/grpc/load_reporting.h
- include/grpc/slice.h
- include/grpc/slice_buffer.h
- include/grpc/status.h
@ -645,6 +647,8 @@ filegroups:
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
src:
- src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
@ -668,6 +672,8 @@ filegroups:
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
src:
- src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
@ -1367,6 +1373,32 @@ libs:
deps:
- grpc
secure: true
- name: cxxabi
build: private
language: c
src:
- third_party/libcxxabi/src/abort_message.cpp
- third_party/libcxxabi/src/cxa_aux_runtime.cpp
- third_party/libcxxabi/src/cxa_default_handlers.cpp
- third_party/libcxxabi/src/cxa_demangle.cpp
- third_party/libcxxabi/src/cxa_exception_storage.cpp
- third_party/libcxxabi/src/cxa_guard.cpp
- third_party/libcxxabi/src/cxa_handlers.cpp
- third_party/libcxxabi/src/cxa_noexception.cpp
- third_party/libcxxabi/src/cxa_thread_atexit.cpp
- third_party/libcxxabi/src/cxa_unexpected.cpp
- third_party/libcxxabi/src/cxa_vector.cpp
- third_party/libcxxabi/src/cxa_virtual.cpp
- third_party/libcxxabi/src/fallback_malloc.cpp
- third_party/libcxxabi/src/private_typeinfo.cpp
- third_party/libcxxabi/src/stdlib_exception.cpp
- third_party/libcxxabi/src/stdlib_new_delete.cpp
- third_party/libcxxabi/src/stdlib_stdexcept.cpp
- third_party/libcxxabi/src/stdlib_typeinfo.cpp
build_system:
- Makefile
defaults: cxxabi
secure: false
- name: gpr
build: all
language: c
@ -2260,6 +2292,21 @@ targets:
- gpr_test_util
- gpr
uses_polling: false
- name: ev_epollex_linux_test
cpu_cost: 3
build: test
language: c
src:
- test/core/iomgr/ev_epollex_linux_test.cc
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
exclude_iomgrs:
- uv
platforms:
- linux
- name: ev_epollsig_linux_test
cpu_cost: 3
build: test
@ -5645,6 +5692,11 @@ defaults:
CPPFLAGS: -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM
-D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX
CXXFLAGS: -fno-rtti -fno-exceptions
cxxabi:
CPPFLAGS: -D_LIBCPP_DISABLE_EXTERN_TEMPLATE -D_LIBCXXABI_BUILDING_LIBRARY -D_LIBCXXABI_NO_EXCEPTIONS
-Ithird_party/libcxxabi/include -nostdinc++ -Ithird_party/libcxx/include $(W_NO_UNUSED_BUT_SET_VARIABLE)
$(W_NO_MAYBE_UNINITIALIZED) -fvisibility=hidden
CXXFLAGS: $(W_NO_CXX14_COMPAT)
global:
COREFLAGS: -fno-rtti -fno-exceptions
CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1

@ -24,7 +24,7 @@ Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
# version = '1.14.0-dev'
version = '0.0.2'
version = '0.0.3'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
@ -212,6 +212,7 @@ Pod::Spec.new do |s|
'src/cpp/util/string_ref.cc',
'src/cpp/util/time_cc.cc',
'src/cpp/codegen/codegen_init.cc',
'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/host_port.h',
@ -479,6 +480,8 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
@ -501,6 +504,7 @@ Pod::Spec.new do |s|
'src/cpp/server/health/health.pb.h',
'src/cpp/server/thread_pool_interface.h',
'src/cpp/thread_manager/thread_manager.h',
'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/host_port.h',
@ -662,6 +666,17 @@ Pod::Spec.new do |s|
'src/core/ext/transport/inproc/inproc_transport.h'
end
s.subspec 'Protobuf' do |ss|
ss.header_mappings_dir = 'include/grpcpp'
ss.dependency "#{s.name}/Interface", version
ss.source_files = 'include/grpcpp/impl/codegen/proto_buffer_reader.h',
'include/grpcpp/impl/codegen/proto_buffer_writer.h',
'include/grpcpp/impl/codegen/proto_utils.h',
'include/grpcpp/impl/codegen/config_protobuf.h',
'include/grpcpp/impl/codegen/config_protobuf.h'
end
s.prepare_command = <<-END_OF_COMMAND
find src/cpp/ -type f ! -path '*.grpc_back' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(pb(_.*)?\\.h)";#include <nanopb/\\1>;g'
find src/cpp/ -type f -path '*.grpc_back' -print0 | xargs -0 rm

@ -168,6 +168,7 @@ Pod::Spec.new do |s|
'include/grpc/grpc.h',
'include/grpc/grpc_posix.h',
'include/grpc/grpc_security_constants.h',
'include/grpc/load_reporting.h',
'include/grpc/slice.h',
'include/grpc/slice_buffer.h',
'include/grpc/status.h',
@ -182,7 +183,8 @@ Pod::Spec.new do |s|
ss.dependency 'nanopb', '~> 0.3'
# To save you from scrolling, this is the last part of the podspec.
ss.source_files = 'src/core/lib/gpr/arena.h',
ss.source_files = 'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
@ -488,6 +490,8 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',
@ -800,7 +804,8 @@ Pod::Spec.new do |s|
'src/core/ext/filters/workarounds/workaround_utils.cc',
'src/core/plugin_registry/grpc_plugin_registry.cc'
ss.private_header_files = 'src/core/lib/gpr/arena.h',
ss.private_header_files = 'src/core/lib/gpr/alloc.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
@ -1067,6 +1072,8 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h',

@ -81,6 +81,7 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/impl/codegen/sync_generic.h )
s.files += %w( include/grpc/impl/codegen/sync_posix.h )
s.files += %w( include/grpc/impl/codegen/sync_windows.h )
s.files += %w( src/core/lib/gpr/alloc.h )
s.files += %w( src/core/lib/gpr/arena.h )
s.files += %w( src/core/lib/gpr/env.h )
s.files += %w( src/core/lib/gpr/host_port.h )
@ -173,6 +174,7 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/grpc.h )
s.files += %w( include/grpc/grpc_posix.h )
s.files += %w( include/grpc/grpc_security_constants.h )
s.files += %w( include/grpc/load_reporting.h )
s.files += %w( include/grpc/slice.h )
s.files += %w( include/grpc/slice_buffer.h )
s.files += %w( include/grpc/status.h )
@ -425,6 +427,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h )

@ -185,6 +185,32 @@
'test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc',
],
},
{
'target_name': 'cxxabi',
'type': 'static_library',
'dependencies': [
],
'sources': [
'third_party/libcxxabi/src/abort_message.cpp',
'third_party/libcxxabi/src/cxa_aux_runtime.cpp',
'third_party/libcxxabi/src/cxa_default_handlers.cpp',
'third_party/libcxxabi/src/cxa_demangle.cpp',
'third_party/libcxxabi/src/cxa_exception_storage.cpp',
'third_party/libcxxabi/src/cxa_guard.cpp',
'third_party/libcxxabi/src/cxa_handlers.cpp',
'third_party/libcxxabi/src/cxa_noexception.cpp',
'third_party/libcxxabi/src/cxa_thread_atexit.cpp',
'third_party/libcxxabi/src/cxa_unexpected.cpp',
'third_party/libcxxabi/src/cxa_vector.cpp',
'third_party/libcxxabi/src/cxa_virtual.cpp',
'third_party/libcxxabi/src/fallback_malloc.cpp',
'third_party/libcxxabi/src/private_typeinfo.cpp',
'third_party/libcxxabi/src/stdlib_exception.cpp',
'third_party/libcxxabi/src/stdlib_new_delete.cpp',
'third_party/libcxxabi/src/stdlib_stdexcept.cpp',
'third_party/libcxxabi/src/stdlib_typeinfo.cpp',
],
},
{
'target_name': 'gpr',
'type': 'static_library',

@ -43,6 +43,7 @@ framework module grpc {
header "grpc.h"
header "grpc_posix.h"
header "grpc_security_constants.h"
header "load_reporting.h"
header "slice.h"
header "slice_buffer.h"
header "status.h"

@ -86,6 +86,7 @@
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_generic.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/alloc.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/arena.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/env.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/host_port.h" role="src" />
@ -178,6 +179,7 @@
<file baseinstalldir="/" name="include/grpc/grpc.h" role="src" />
<file baseinstalldir="/" name="include/grpc/grpc_posix.h" role="src" />
<file baseinstalldir="/" name="include/grpc/grpc_security_constants.h" role="src" />
<file baseinstalldir="/" name="include/grpc/load_reporting.h" role="src" />
<file baseinstalldir="/" name="include/grpc/slice.h" role="src" />
<file baseinstalldir="/" name="include/grpc/slice_buffer.h" role="src" />
<file baseinstalldir="/" name="include/grpc/status.h" role="src" />
@ -430,6 +432,8 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" role="src" />

@ -74,6 +74,8 @@ struct grpc_ares_ev_driver {
bool working;
/** is this event driver being shut down */
bool shutting_down;
/** request object that's using this ev driver */
grpc_ares_request* request;
};
static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver);
@ -92,6 +94,7 @@ static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) {
GPR_ASSERT(ev_driver->fds == nullptr);
GRPC_COMBINER_UNREF(ev_driver->combiner, "free ares event driver");
ares_destroy(ev_driver->channel);
grpc_ares_complete_request_locked(ev_driver->request);
gpr_free(ev_driver);
}
}
@ -115,7 +118,8 @@ static void fd_node_shutdown_locked(fd_node* fdn, const char* reason) {
grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
grpc_pollset_set* pollset_set,
grpc_combiner* combiner) {
grpc_combiner* combiner,
grpc_ares_request* request) {
*ev_driver = static_cast<grpc_ares_ev_driver*>(
gpr_malloc(sizeof(grpc_ares_ev_driver)));
ares_options opts;
@ -139,10 +143,12 @@ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
(*ev_driver)->fds = nullptr;
(*ev_driver)->working = false;
(*ev_driver)->shutting_down = false;
(*ev_driver)->request = request;
return GRPC_ERROR_NONE;
}
void grpc_ares_ev_driver_destroy_locked(grpc_ares_ev_driver* ev_driver) {
void grpc_ares_ev_driver_on_queries_complete_locked(
grpc_ares_ev_driver* ev_driver) {
// We mark the event driver as being shut down. If the event driver
// is working, grpc_ares_notify_on_event_locked will shut down the
// fds; if it's not working, there are no fds to shut down.

@ -22,6 +22,7 @@
#include <grpc/support/port_platform.h>
#include <ares.h>
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/lib/gprpp/abstract.h"
#include "src/core/lib/iomgr/pollset_set.h"
@ -42,12 +43,12 @@ ares_channel* grpc_ares_ev_driver_get_channel_locked(
created successfully. */
grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
grpc_pollset_set* pollset_set,
grpc_combiner* combiner);
grpc_combiner* combiner,
grpc_ares_request* request);
/* Destroys \a ev_driver asynchronously. Pending lookups made on \a ev_driver
will be cancelled and their on_done callbacks will be invoked with a status
of ARES_ECANCELLED. */
void grpc_ares_ev_driver_destroy_locked(grpc_ares_ev_driver* ev_driver);
/* Called back when all DNS lookups have completed. */
void grpc_ares_ev_driver_on_queries_complete_locked(
grpc_ares_ev_driver* ev_driver);
/* Shutdown all the grpc_fds used by \a ev_driver */
void grpc_ares_ev_driver_shutdown_locked(grpc_ares_ev_driver* ev_driver);

@ -44,11 +44,13 @@ class GrpcPolledFdPosix : public GrpcPolledFd {
: as_(as) {
gpr_asprintf(&name_, "c-ares fd: %d", (int)as);
fd_ = grpc_fd_create((int)as, name_, false);
grpc_pollset_set_add_fd(driver_pollset_set, fd_);
driver_pollset_set_ = driver_pollset_set;
grpc_pollset_set_add_fd(driver_pollset_set_, fd_);
}
~GrpcPolledFdPosix() {
gpr_free(name_);
grpc_pollset_set_del_fd(driver_pollset_set_, fd_);
/* c-ares library will close 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. */
@ -81,6 +83,7 @@ class GrpcPolledFdPosix : public GrpcPolledFd {
char* name_;
ares_socket_t as_;
grpc_fd* fd_;
grpc_pollset_set* driver_pollset_set_;
};
GrpcPolledFd* NewGrpcPolledFdLocked(ares_socket_t as,

@ -63,7 +63,7 @@ struct grpc_ares_request {
/** the evernt driver used by this request */
grpc_ares_ev_driver* ev_driver;
/** number of ongoing queries */
gpr_refcount pending_queries;
size_t pending_queries;
/** is there at least one successful query, set in on_done_cb */
bool success;
@ -145,21 +145,25 @@ void grpc_cares_wrapper_test_only_address_sorting_sort(
}
static void grpc_ares_request_ref_locked(grpc_ares_request* r) {
gpr_ref(&r->pending_queries);
r->pending_queries++;
}
static void grpc_ares_request_unref_locked(grpc_ares_request* r) {
/* If there are no pending queries, invoke on_done callback and destroy the
r->pending_queries--;
if (r->pending_queries == 0u) {
grpc_ares_ev_driver_on_queries_complete_locked(r->ev_driver);
}
}
void grpc_ares_complete_request_locked(grpc_ares_request* r) {
/* Invoke on_done callback and destroy the
request */
if (gpr_unref(&r->pending_queries)) {
grpc_lb_addresses* lb_addrs = *(r->lb_addrs_out);
if (lb_addrs != nullptr) {
grpc_cares_wrapper_address_sorting_sort(lb_addrs);
}
GRPC_CLOSURE_SCHED(r->on_done, r->error);
grpc_ares_ev_driver_destroy_locked(r->ev_driver);
gpr_free(r);
grpc_lb_addresses* lb_addrs = *(r->lb_addrs_out);
if (lb_addrs != nullptr) {
grpc_cares_wrapper_address_sorting_sort(lb_addrs);
}
GRPC_CLOSURE_SCHED(r->on_done, r->error);
gpr_free(r);
}
static grpc_ares_hostbyname_request* create_hostbyname_request_locked(
@ -399,20 +403,18 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
}
port = gpr_strdup(default_port);
}
grpc_ares_ev_driver* ev_driver;
error = grpc_ares_ev_driver_create_locked(&ev_driver, interested_parties,
combiner);
if (error != GRPC_ERROR_NONE) goto error_cleanup;
r = static_cast<grpc_ares_request*>(gpr_zalloc(sizeof(grpc_ares_request)));
r->ev_driver = ev_driver;
r->ev_driver = nullptr;
r->on_done = on_done;
r->lb_addrs_out = addrs;
r->service_config_json_out = service_config_json;
r->success = false;
r->error = GRPC_ERROR_NONE;
r->pending_queries = 0;
error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties,
combiner, r);
if (error != GRPC_ERROR_NONE) goto error_cleanup;
channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver);
// If dns_server is specified, use it.
if (dns_server != nullptr) {
gpr_log(GPR_INFO, "Using DNS server %s", dns_server);
@ -437,7 +439,6 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
error = grpc_error_set_str(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("cannot parse authority"),
GRPC_ERROR_STR_TARGET_ADDRESS, grpc_slice_from_copied_string(name));
gpr_free(r);
goto error_cleanup;
}
int status = ares_set_servers_ports(*channel, &r->dns_server_addr);
@ -447,11 +448,10 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
ares_strerror(status));
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg);
gpr_free(error_msg);
gpr_free(r);
goto error_cleanup;
}
}
gpr_ref_init(&r->pending_queries, 1);
r->pending_queries = 1;
if (grpc_ipv6_loopback_available()) {
hr = create_hostbyname_request_locked(r, host, strhtons(port),
false /* is_balancer */);
@ -487,6 +487,7 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
error_cleanup:
GRPC_CLOSURE_SCHED(on_done, error);
gpr_free(r);
gpr_free(host);
gpr_free(port);
return nullptr;

@ -66,6 +66,10 @@ grpc_error* grpc_ares_init(void);
it has been called the same number of times as grpc_ares_init(). */
void grpc_ares_cleanup(void);
/** Schedules the desired callback for request completion
* and destroys the grpc_ares_request */
void grpc_ares_complete_request_locked(grpc_ares_request* request);
/* Exposed only for testing */
void grpc_cares_wrapper_test_only_address_sorting_sort(
grpc_lb_addresses* lb_addrs);

@ -38,6 +38,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/gpr/alloc.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
@ -140,9 +141,13 @@ struct grpc_subchannel_call {
grpc_closure* schedule_closure_after_destroy;
};
#define SUBCHANNEL_CALL_TO_CALL_STACK(call) ((grpc_call_stack*)((call) + 1))
#define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \
(((grpc_subchannel_call*)(callstack)) - 1)
#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \
(grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
sizeof(grpc_subchannel_call)))
#define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \
(grpc_subchannel_call*)(((char*)(call_stack)) - \
GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
sizeof(grpc_subchannel_call)))
static void on_subchannel_connected(void* subchannel, grpc_error* error);
@ -783,9 +788,17 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate,
grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args,
grpc_subchannel_call** call) {
*call = static_cast<grpc_subchannel_call*>(gpr_arena_alloc(
args.arena, sizeof(grpc_subchannel_call) +
channel_stack_->call_stack_size + args.parent_data_size));
size_t allocation_size =
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call));
if (args.parent_data_size > 0) {
allocation_size +=
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) +
args.parent_data_size;
} else {
allocation_size += channel_stack_->call_stack_size;
}
*call = static_cast<grpc_subchannel_call*>(
gpr_arena_alloc(args.arena, allocation_size));
grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
RefCountedPtr<ConnectedSubchannel> connection =
Ref(DEBUG_LOCATION, "subchannel_call");

@ -21,6 +21,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/alloc.h"
#include <stdlib.h>
#include <string.h>
@ -43,16 +44,12 @@ grpc_core::TraceFlag grpc_trace_channel(false, "channel");
per-filter memory, aligned to GPR_MAX_ALIGNMENT
} */
/* Given a size, round up to the next multiple of sizeof(void*) */
#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
(((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u))
size_t grpc_channel_stack_size(const grpc_channel_filter** filters,
size_t filter_count) {
/* always need the header, and size for the channel elements */
size_t size =
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)) +
ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element));
size_t size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)) +
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filter_count *
sizeof(grpc_channel_element));
size_t i;
GPR_ASSERT((GPR_MAX_ALIGNMENT & (GPR_MAX_ALIGNMENT - 1)) == 0 &&
@ -60,19 +57,19 @@ size_t grpc_channel_stack_size(const grpc_channel_filter** filters,
/* add the size for each filter */
for (i = 0; i < filter_count; i++) {
size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
size += GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
}
return size;
}
#define CHANNEL_ELEMS_FROM_STACK(stk) \
((grpc_channel_element*)((char*)(stk) + ROUND_UP_TO_ALIGNMENT_SIZE( \
#define CHANNEL_ELEMS_FROM_STACK(stk) \
((grpc_channel_element*)((char*)(stk) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
sizeof(grpc_channel_stack))))
#define CALL_ELEMS_FROM_STACK(stk) \
((grpc_call_element*)((char*)(stk) + \
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack))))
#define CALL_ELEMS_FROM_STACK(stk) \
((grpc_call_element*)((char*)(stk) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
sizeof(grpc_call_stack))))
grpc_channel_element* grpc_channel_stack_element(
grpc_channel_stack* channel_stack, size_t index) {
@ -95,8 +92,8 @@ grpc_error* grpc_channel_stack_init(
const grpc_channel_args* channel_args, grpc_transport* optional_transport,
const char* name, grpc_channel_stack* stack) {
size_t call_size =
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) +
ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element));
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) +
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element));
grpc_channel_element* elems;
grpc_channel_element_args args;
char* user_data;
@ -106,9 +103,9 @@ grpc_error* grpc_channel_stack_init(
GRPC_STREAM_REF_INIT(&stack->refcount, initial_refs, destroy, destroy_arg,
name);
elems = CHANNEL_ELEMS_FROM_STACK(stack);
user_data =
(reinterpret_cast<char*>(elems)) +
ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element));
user_data = (reinterpret_cast<char*>(elems)) +
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filter_count *
sizeof(grpc_channel_element));
/* init per-filter data */
grpc_error* first_error = GRPC_ERROR_NONE;
@ -128,8 +125,9 @@ grpc_error* grpc_channel_stack_init(
GRPC_ERROR_UNREF(error);
}
}
user_data += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
call_size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data);
user_data +=
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
call_size += GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data);
}
GPR_ASSERT(user_data > (char*)stack);
@ -166,7 +164,7 @@ grpc_error* grpc_call_stack_init(grpc_channel_stack* channel_stack,
destroy_arg, "CALL_STACK");
call_elems = CALL_ELEMS_FROM_STACK(elem_args->call_stack);
user_data = (reinterpret_cast<char*>(call_elems)) +
ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element));
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element));
/* init per-filter data */
grpc_error* first_error = GRPC_ERROR_NONE;
@ -184,7 +182,7 @@ grpc_error* grpc_call_stack_init(grpc_channel_stack* channel_stack,
}
}
user_data +=
ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data);
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data);
}
return first_error;
}
@ -243,11 +241,11 @@ grpc_channel_stack* grpc_channel_stack_from_top_element(
grpc_channel_element* elem) {
return reinterpret_cast<grpc_channel_stack*>(
reinterpret_cast<char*>(elem) -
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)));
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)));
}
grpc_call_stack* grpc_call_stack_from_top_element(grpc_call_element* elem) {
return reinterpret_cast<grpc_call_stack*>(
reinterpret_cast<char*>(elem) -
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)));
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)));
}

@ -113,7 +113,10 @@ grpc_connectivity_state ChannelNode::GetConnectivityState() {
if (channel_ == nullptr) {
return GRPC_CHANNEL_SHUTDOWN;
} else {
return grpc_channel_check_connectivity_state(channel_, false);
// TODO(ncteisen): re-enable this once we have cleaned up all of the
// internal dependency issues.
// return grpc_channel_check_connectivity_state(channel_, false);
return GRPC_CHANNEL_IDLE;
}
}

@ -0,0 +1,28 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_CORE_LIB_GPR_ALLOC_H
#define GRPC_CORE_LIB_GPR_ALLOC_H
#include <grpc/support/port_platform.h>
/// Given a size, round up to the next multiple of sizeof(void*).
#define GPR_ROUND_UP_TO_ALIGNMENT_SIZE(x) \
(((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u))
#endif /* GRPC_CORE_LIB_GPR_ALLOC_H */

@ -26,6 +26,8 @@
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include "src/core/lib/gpr/alloc.h"
// Uncomment this to use a simple arena that simply allocates the
// requested amount of memory for each call to gpr_arena_alloc(). This
// effectively eliminates the efficiency gain of using an arena, but it
@ -74,8 +76,6 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
// arena API to C++, we should consider replacing gpr_arena_alloc() with a
// template that takes the type of the value being allocated, which
// would allow us to use the alignment actually needed by the caller.
#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
(((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u))
typedef struct zone {
size_t size_begin;
@ -95,9 +95,9 @@ static void* zalloc_aligned(size_t size) {
}
gpr_arena* gpr_arena_create(size_t initial_size) {
initial_size = ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size);
gpr_arena* a = static_cast<gpr_arena*>(zalloc_aligned(
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size));
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size));
a->initial_zone.size_end = initial_size;
return a;
}
@ -115,7 +115,7 @@ size_t gpr_arena_destroy(gpr_arena* arena) {
}
void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
size = ROUND_UP_TO_ALIGNMENT_SIZE(size);
size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size);
size_t start = static_cast<size_t>(
gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size));
zone* z = &arena->initial_zone;
@ -125,7 +125,7 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
size_t next_z_size =
static_cast<size_t>(gpr_atm_no_barrier_load(&arena->size_so_far));
next_z = static_cast<zone*>(zalloc_aligned(
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + next_z_size));
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + next_z_size));
next_z->size_begin = z->size_end;
next_z->size_end = z->size_end + next_z_size;
if (!gpr_atm_rel_cas(&z->next_atm, static_cast<gpr_atm>(NULL),
@ -143,9 +143,9 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
GPR_ASSERT(start + size <= z->size_end);
char* ptr = (z == &arena->initial_zone)
? reinterpret_cast<char*>(arena) +
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena))
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena))
: reinterpret_cast<char*>(z) +
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
return ptr + start - z->size_begin;
}

@ -105,7 +105,7 @@ class ThreadInternalsPosix
GPR_ASSERT(pthread_attr_destroy(&attr) == 0);
if (!success) {
if (!(*success)) {
/* don't use gpr_free, as this was allocated using malloc (see above) */
free(info);
grpc_core::Fork::DecThreadCount();

@ -104,8 +104,10 @@ struct pollable {
int epfd;
grpc_wakeup_fd wakeup;
// only for type fd... one ref to the owner fd
grpc_fd* owner_fd;
// The following are relevant only for type PO_FD
grpc_fd* owner_fd; // Set to the owner_fd if the type is PO_FD
gpr_mu owner_orphan_mu; // Synchronizes access to owner_orphaned field
bool owner_orphaned; // Is the owner fd orphaned
grpc_pollset_set* pollset_set;
pollable* next;
@ -338,21 +340,45 @@ static void ref_by(grpc_fd* fd, int n) {
GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0);
}
#ifndef NDEBUG
#define INVALIDATE_FD(fd) invalidate_fd(fd)
/* Since an fd is never really destroyed (i.e gpr_free() is not called), it is
* hard to cases where fd fields are accessed even after calling fd_destroy().
* The following invalidates fd fields to make catching such errors easier */
static void invalidate_fd(grpc_fd* fd) {
fd->fd = -1;
fd->salt = -1;
gpr_atm_no_barrier_store(&fd->refst, -1);
memset(&fd->orphan_mu, -1, sizeof(fd->orphan_mu));
memset(&fd->pollable_mu, -1, sizeof(fd->pollable_mu));
fd->pollable_obj = nullptr;
fd->on_done_closure = nullptr;
gpr_atm_no_barrier_store(&fd->read_notifier_pollset, 0);
memset(&fd->iomgr_object, -1, sizeof(fd->iomgr_object));
fd->track_err = false;
}
#else
#define INVALIDATE_FD(fd)
#endif
/* Uninitialize and add to the freelist */
static void fd_destroy(void* arg, grpc_error* error) {
grpc_fd* fd = static_cast<grpc_fd*>(arg);
/* Add the fd to the freelist */
grpc_iomgr_unregister_object(&fd->iomgr_object);
POLLABLE_UNREF(fd->pollable_obj, "fd_pollable");
gpr_mu_destroy(&fd->pollable_mu);
gpr_mu_destroy(&fd->orphan_mu);
gpr_mu_lock(&fd_freelist_mu);
fd->freelist_next = fd_freelist;
fd_freelist = fd;
fd->read_closure->DestroyEvent();
fd->write_closure->DestroyEvent();
fd->error_closure->DestroyEvent();
INVALIDATE_FD(fd);
/* Add the fd to the freelist */
gpr_mu_lock(&fd_freelist_mu);
fd->freelist_next = fd_freelist;
fd_freelist = fd;
gpr_mu_unlock(&fd_freelist_mu);
}
@ -408,20 +434,18 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
new_fd->error_closure.Init();
}
gpr_mu_init(&new_fd->pollable_mu);
gpr_mu_init(&new_fd->orphan_mu);
new_fd->pollable_obj = nullptr;
gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
new_fd->fd = fd;
new_fd->track_err = track_err;
new_fd->salt = gpr_atm_no_barrier_fetch_add(&g_fd_salt, 1);
gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
gpr_mu_init(&new_fd->orphan_mu);
gpr_mu_init(&new_fd->pollable_mu);
new_fd->pollable_obj = nullptr;
new_fd->read_closure->InitEvent();
new_fd->write_closure->InitEvent();
new_fd->error_closure->InitEvent();
gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
new_fd->freelist_next = nullptr;
new_fd->on_done_closure = nullptr;
gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
char* fd_name;
gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
@ -432,6 +456,8 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
}
#endif
gpr_free(fd_name);
new_fd->track_err = track_err;
return new_fd;
}
@ -446,6 +472,17 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
gpr_mu_lock(&fd->orphan_mu);
// Get the fd->pollable_obj and set the owner_orphaned on that pollable to
// true so that the pollable will no longer access its owner_fd field.
gpr_mu_lock(&fd->pollable_mu);
pollable* pollable_obj = fd->pollable_obj;
gpr_mu_unlock(&fd->pollable_mu);
if (pollable_obj) {
gpr_mu_lock(&pollable_obj->owner_orphan_mu);
pollable_obj->owner_orphaned = true;
}
fd->on_done_closure = on_done;
/* If release_fd is not NULL, we should be relinquishing control of the file
@ -467,6 +504,10 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
GRPC_CLOSURE_SCHED(fd->on_done_closure, GRPC_ERROR_NONE);
if (pollable_obj) {
gpr_mu_unlock(&pollable_obj->owner_orphan_mu);
}
gpr_mu_unlock(&fd->orphan_mu);
UNREF_BY(fd, 2, reason); /* Drop the reference */
@ -551,6 +592,8 @@ static grpc_error* pollable_create(pollable_type type, pollable** p) {
gpr_mu_init(&(*p)->mu);
(*p)->epfd = epfd;
(*p)->owner_fd = nullptr;
gpr_mu_init(&(*p)->owner_orphan_mu);
(*p)->owner_orphaned = false;
(*p)->pollset_set = nullptr;
(*p)->next = (*p)->prev = *p;
(*p)->root_worker = nullptr;
@ -590,6 +633,7 @@ static void pollable_unref(pollable* p, int line, const char* reason) {
GRPC_FD_TRACE("pollable_unref: Closing epfd: %d", p->epfd);
close(p->epfd);
grpc_wakeup_fd_destroy(&p->wakeup);
gpr_mu_destroy(&p->owner_orphan_mu);
gpr_free(p);
}
}
@ -846,10 +890,15 @@ static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); }
static grpc_error* fd_get_or_become_pollable(grpc_fd* fd, pollable** p) {
/* Get the pollable_obj attached to this fd. If none is attached, create a new
* pollable object (of type PO_FD), attach it to the fd and return it
*
* Note that if a pollable object is already attached to the fd, it may be of
* either PO_FD or PO_MULTI type */
static grpc_error* get_fd_pollable(grpc_fd* fd, pollable** p) {
gpr_mu_lock(&fd->pollable_mu);
grpc_error* error = GRPC_ERROR_NONE;
static const char* err_desc = "fd_get_or_become_pollable";
static const char* err_desc = "get_fd_pollable";
if (fd->pollable_obj == nullptr) {
if (append_error(&error, pollable_create(PO_FD, &fd->pollable_obj),
err_desc)) {
@ -1186,7 +1235,7 @@ static grpc_error* pollset_transition_pollable_from_empty_to_fd_locked(
}
append_error(&error, pollset_kick_all(pollset), err_desc);
POLLABLE_UNREF(pollset->active_pollable, "pollset");
append_error(&error, fd_get_or_become_pollable(fd, &pollset->active_pollable),
append_error(&error, get_fd_pollable(fd, &pollset->active_pollable),
err_desc);
return error;
}
@ -1230,9 +1279,8 @@ static grpc_error* pollset_add_fd_locked(grpc_pollset* pollset, grpc_fd* fd) {
error = pollset_transition_pollable_from_empty_to_fd_locked(pollset, fd);
break;
case PO_FD:
gpr_mu_lock(&po_at_start->owner_fd->orphan_mu);
if ((gpr_atm_no_barrier_load(&pollset->active_pollable->owner_fd->refst) &
1) == 0) {
gpr_mu_lock(&po_at_start->owner_orphan_mu);
if (po_at_start->owner_orphaned) {
error =
pollset_transition_pollable_from_empty_to_fd_locked(pollset, fd);
} else {
@ -1240,7 +1288,7 @@ static grpc_error* pollset_add_fd_locked(grpc_pollset* pollset, grpc_fd* fd) {
error =
pollset_transition_pollable_from_fd_to_multi_locked(pollset, fd);
}
gpr_mu_unlock(&po_at_start->owner_fd->orphan_mu);
gpr_mu_unlock(&po_at_start->owner_orphan_mu);
break;
case PO_MULTI:
error = pollable_add_fd(pollset->active_pollable, fd);
@ -1276,16 +1324,17 @@ static grpc_error* pollset_as_multipollable_locked(grpc_pollset* pollset,
append_error(&error, pollset_kick_all(pollset), err_desc);
break;
case PO_FD:
gpr_mu_lock(&po_at_start->owner_fd->orphan_mu);
if ((gpr_atm_no_barrier_load(&pollset->active_pollable->owner_fd->refst) &
1) == 0) {
gpr_mu_lock(&po_at_start->owner_orphan_mu);
if (po_at_start->owner_orphaned) {
// Unlock before Unref'ing the pollable
gpr_mu_unlock(&po_at_start->owner_orphan_mu);
POLLABLE_UNREF(pollset->active_pollable, "pollset");
error = pollable_create(PO_MULTI, &pollset->active_pollable);
} else {
error = pollset_transition_pollable_from_fd_to_multi_locked(pollset,
nullptr);
gpr_mu_unlock(&po_at_start->owner_orphan_mu);
}
gpr_mu_unlock(&po_at_start->owner_fd->orphan_mu);
break;
case PO_MULTI:
break;

@ -70,6 +70,8 @@ static size_t count_objects(void) {
return n;
}
size_t grpc_iomgr_count_objects_for_testing(void) { return count_objects(); }
static void dump_objects(const char* kind) {
grpc_iomgr_object* obj;
for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) {

@ -23,6 +23,8 @@
#include "src/core/lib/iomgr/port.h"
#include <stdlib.h>
/** Initializes the iomgr. */
void grpc_iomgr_init();
@ -33,4 +35,7 @@ void grpc_iomgr_start();
* exec_ctx. */
void grpc_iomgr_shutdown();
/* Exposed only for testing */
size_t grpc_iomgr_count_objects_for_testing();
#endif /* GRPC_CORE_LIB_IOMGR_IOMGR_H */

@ -277,7 +277,6 @@ static void start_threads(void) {
g_threaded = true;
start_timer_thread_and_unlock();
} else {
g_threaded = false;
gpr_mu_unlock(&g_mu);
}
}

@ -21,6 +21,7 @@
#include <string.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/arena.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/surface/api_trace.h"
@ -99,10 +100,10 @@ void grpc_client_security_context_destroy(void* ctx) {
}
/* --- grpc_server_security_context --- */
grpc_server_security_context* grpc_server_security_context_create(void) {
grpc_server_security_context* grpc_server_security_context_create(
gpr_arena* arena) {
return static_cast<grpc_server_security_context*>(
gpr_zalloc(sizeof(grpc_server_security_context)));
gpr_arena_alloc(arena, sizeof(grpc_server_security_context)));
}
void grpc_server_security_context_destroy(void* ctx) {
@ -112,7 +113,6 @@ void grpc_server_security_context_destroy(void* ctx) {
if (c->extension.instance != nullptr && c->extension.destroy != nullptr) {
c->extension.destroy(c->extension.instance);
}
gpr_free(ctx);
}
/* --- grpc_auth_context --- */

@ -26,6 +26,8 @@
extern grpc_core::DebugOnlyTraceFlag grpc_trace_auth_context_refcount;
struct gpr_arena;
/* --- grpc_auth_context ---
High level authentication context object. Can optionally be chained. */
@ -101,7 +103,8 @@ typedef struct {
grpc_security_context_extension extension;
} grpc_server_security_context;
grpc_server_security_context* grpc_server_security_context_create(void);
grpc_server_security_context* grpc_server_security_context_create(
gpr_arena* arena);
void grpc_server_security_context_destroy(void* ctx);
/* --- Channel args for auth context --- */

@ -44,7 +44,6 @@ struct call_data {
grpc_metadata_array md;
const grpc_metadata* consumed_md;
size_t num_consumed_md;
grpc_auth_context* auth_context;
grpc_closure cancel_closure;
gpr_atm state; // async_state
};
@ -178,7 +177,7 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) {
calld->md = metadata_batch_to_md_array(
batch->payload->recv_initial_metadata.recv_initial_metadata);
chand->creds->processor.process(
chand->creds->processor.state, calld->auth_context,
chand->creds->processor.state, chand->auth_context,
calld->md.metadata, calld->md.count, on_md_processing_done, elem);
return;
}
@ -214,9 +213,9 @@ static grpc_error* init_call_elem(grpc_call_element* elem,
// Create server security context. Set its auth context from channel
// data and save it in the call context.
grpc_server_security_context* server_ctx =
grpc_server_security_context_create();
server_ctx->auth_context = grpc_auth_context_create(chand->auth_context);
calld->auth_context = server_ctx->auth_context;
grpc_server_security_context_create(args->arena);
server_ctx->auth_context =
GRPC_AUTH_CONTEXT_REF(chand->auth_context, "server_auth_filter");
if (args->context[GRPC_CONTEXT_SECURITY].value != nullptr) {
args->context[GRPC_CONTEXT_SECURITY].destroy(
args->context[GRPC_CONTEXT_SECURITY].value);

@ -34,6 +34,7 @@
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/compression/algorithm_metadata.h"
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/gpr/alloc.h"
#include "src/core/lib/gpr/arena.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
@ -271,16 +272,12 @@ struct grpc_call {
grpc_core::TraceFlag grpc_call_error_trace(false, "call_error");
grpc_core::TraceFlag grpc_compression_trace(false, "compression");
/* Given a size, round up to the next multiple of sizeof(void*) */
#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \
(((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u))
#define CALL_STACK_FROM_CALL(call) \
(grpc_call_stack*)((char*)(call) + \
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)))
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)))
#define CALL_FROM_CALL_STACK(call_stack) \
(grpc_call*)(((char*)(call_stack)) - \
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)))
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)))
#define CALL_ELEM_FROM_CALL(call, idx) \
grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx)
@ -353,7 +350,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args,
GRPC_STATS_INC_CALL_INITIAL_SIZE(initial_size);
gpr_arena* arena = gpr_arena_create(initial_size);
call = static_cast<grpc_call*>(
gpr_arena_alloc(arena, ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) +
gpr_arena_alloc(arena, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) +
channel_stack->call_stack_size));
gpr_ref_init(&call->ext_ref, 1);
call->arena = arena;
@ -1113,6 +1110,8 @@ static void recv_trailing_filter(void* args, grpc_metadata_batch* b) {
publish_app_metadata(call, b, true);
}
gpr_arena* grpc_call_get_arena(grpc_call* call) { return call->arena; }
grpc_call_stack* grpc_call_get_call_stack(grpc_call* call) {
return CALL_STACK_FROM_CALL(call);
}

@ -71,6 +71,8 @@ void grpc_call_internal_unref(grpc_call* call);
#define GRPC_CALL_INTERNAL_UNREF(call, reason) grpc_call_internal_unref(call)
#endif
gpr_arena* grpc_call_get_arena(grpc_call* call);
grpc_call_stack* grpc_call_get_call_stack(grpc_call* call);
grpc_call_error grpc_call_start_batch_and_execute(grpc_call* call,

@ -127,7 +127,8 @@ static tsi_result handshaker_result_create_zero_copy_grpc_protector(
tsi_result ok = alts_zero_copy_grpc_protector_create(
reinterpret_cast<const uint8_t*>(result->key_data),
kAltsAes128GcmRekeyKeyLength, /*is_rekey=*/true, result->is_client,
/*is_integrity_only=*/false, max_output_protected_frame_size, protector);
/*is_integrity_only=*/false, /*enable_extra_copy=*/false,
max_output_protected_frame_size, protector);
if (ok != TSI_OK) {
gpr_log(GPR_ERROR, "Failed to create zero-copy grpc protector");
}

@ -23,6 +23,8 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <string.h>
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h"
@ -30,12 +32,49 @@
/* Main struct for alts_grpc_integrity_only_record_protocol. */
typedef struct alts_grpc_integrity_only_record_protocol {
alts_grpc_record_protocol base;
bool enable_extra_copy;
grpc_slice_buffer data_sb;
unsigned char* tag_buf;
} alts_grpc_integrity_only_record_protocol;
/* --- alts_grpc_record_protocol methods implementation. --- */
static tsi_result alts_grpc_integrity_only_extra_copy_protect(
alts_grpc_record_protocol* rp, grpc_slice_buffer* unprotected_slices,
grpc_slice_buffer* protected_slices) {
/* Allocates memory for protected frame. */
size_t protected_frame_size =
unprotected_slices->length + rp->header_length + rp->tag_length;
grpc_slice protected_slice = GRPC_SLICE_MALLOC(protected_frame_size);
/* Calls alts_iovec_record_protocol protect. */
char* error_details = nullptr;
iovec_t header_iovec = {GRPC_SLICE_START_PTR(protected_slice),
rp->header_length};
iovec_t tag_iovec = {GRPC_SLICE_START_PTR(protected_slice) +
rp->header_length + unprotected_slices->length,
rp->tag_length};
alts_grpc_record_protocol_convert_slice_buffer_to_iovec(rp,
unprotected_slices);
grpc_status_code status = alts_iovec_record_protocol_integrity_only_protect(
rp->iovec_rp, rp->iovec_buf, unprotected_slices->count, header_iovec,
tag_iovec, &error_details);
if (status != GRPC_STATUS_OK) {
gpr_log(GPR_ERROR, "Failed to protect, %s", error_details);
gpr_free(error_details);
return TSI_INTERNAL_ERROR;
}
/* Copies data from unprotected_slices to protected_slice. */
uint8_t* data = GRPC_SLICE_START_PTR(protected_slice) + rp->header_length;
for (size_t i = 0; i < unprotected_slices->count; i++) {
memcpy(data, GRPC_SLICE_START_PTR(unprotected_slices->slices[i]),
GRPC_SLICE_LENGTH(unprotected_slices->slices[i]));
data += GRPC_SLICE_LENGTH(unprotected_slices->slices[i]);
}
grpc_slice_buffer_add(protected_slices, protected_slice);
grpc_slice_buffer_reset_and_unref_internal(unprotected_slices);
return TSI_OK;
}
static tsi_result alts_grpc_integrity_only_protect(
alts_grpc_record_protocol* rp, grpc_slice_buffer* unprotected_slices,
grpc_slice_buffer* protected_slices) {
@ -46,6 +85,12 @@ static tsi_result alts_grpc_integrity_only_protect(
"Invalid nullptr arguments to alts_grpc_record_protocol protect.");
return TSI_INVALID_ARGUMENT;
}
alts_grpc_integrity_only_record_protocol* integrity_only_record_protocol =
reinterpret_cast<alts_grpc_integrity_only_record_protocol*>(rp);
if (integrity_only_record_protocol->enable_extra_copy) {
return alts_grpc_integrity_only_extra_copy_protect(rp, unprotected_slices,
protected_slices);
}
/* Allocates memory for header and tag slices. */
grpc_slice header_slice = GRPC_SLICE_MALLOC(rp->header_length);
grpc_slice tag_slice = GRPC_SLICE_MALLOC(rp->tag_length);
@ -152,7 +197,7 @@ static const alts_grpc_record_protocol_vtable
tsi_result alts_grpc_integrity_only_record_protocol_create(
gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
bool is_protect, alts_grpc_record_protocol** rp) {
bool is_protect, bool enable_extra_copy, alts_grpc_record_protocol** rp) {
if (crypter == nullptr || rp == nullptr) {
gpr_log(GPR_ERROR,
"Invalid nullptr arguments to alts_grpc_record_protocol create.");
@ -169,6 +214,7 @@ tsi_result alts_grpc_integrity_only_record_protocol_create(
gpr_free(impl);
return result;
}
impl->enable_extra_copy = enable_extra_copy;
/* Initializes slice buffer for data_sb. */
grpc_slice_buffer_init(&impl->data_sb);
/* Allocates tag buffer. */

@ -38,6 +38,8 @@
* be used at the client or server side.
* - is_protect: a flag indicating if the alts_grpc_record_protocol instance
* will be used for protect or unprotect.
*- enable_extra_copy: a flag indicating if the instance uses one-copy instead
* of zero-copy in the protect operation.
* - rp: an alts_grpc_record_protocol instance to be returned from
* the method.
*
@ -46,7 +48,7 @@
*/
tsi_result alts_grpc_integrity_only_record_protocol_create(
gsec_aead_crypter* crypter, size_t overflow_size, bool is_client,
bool is_protect, alts_grpc_record_protocol** rp);
bool is_protect, bool enable_extra_copy, alts_grpc_record_protocol** rp);
#endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_GRPC_INTEGRITY_ONLY_RECORD_PROTOCOL_H \
*/

@ -110,7 +110,7 @@ static bool read_frame_size(const grpc_slice_buffer* sb,
*/
static tsi_result create_alts_grpc_record_protocol(
const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
bool is_integrity_only, bool is_protect,
bool is_integrity_only, bool is_protect, bool enable_extra_copy,
alts_grpc_record_protocol** record_protocol) {
if (key == nullptr || record_protocol == nullptr) {
return TSI_INVALID_ARGUMENT;
@ -130,13 +130,13 @@ static tsi_result create_alts_grpc_record_protocol(
: kAltsRecordProtocolFrameLimit;
/* Creates alts_grpc_record_protocol with AEAD crypter ownership transferred.
*/
tsi_result result =
is_integrity_only
? alts_grpc_integrity_only_record_protocol_create(
crypter, overflow_limit, is_client, is_protect, record_protocol)
: alts_grpc_privacy_integrity_record_protocol_create(
crypter, overflow_limit, is_client, is_protect,
record_protocol);
tsi_result result = is_integrity_only
? alts_grpc_integrity_only_record_protocol_create(
crypter, overflow_limit, is_client, is_protect,
enable_extra_copy, record_protocol)
: alts_grpc_privacy_integrity_record_protocol_create(
crypter, overflow_limit, is_client, is_protect,
record_protocol);
if (result != TSI_OK) {
gsec_aead_crypter_destroy(crypter);
return result;
@ -241,7 +241,8 @@ static const tsi_zero_copy_grpc_protector_vtable
tsi_result alts_zero_copy_grpc_protector_create(
const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
bool is_integrity_only, size_t* max_protected_frame_size,
bool is_integrity_only, bool enable_extra_copy,
size_t* max_protected_frame_size,
tsi_zero_copy_grpc_protector** protector) {
if (grpc_core::ExecCtx::Get() == nullptr || key == nullptr ||
protector == nullptr) {
@ -257,11 +258,11 @@ tsi_result alts_zero_copy_grpc_protector_create(
/* Creates alts_grpc_record_protocol objects. */
tsi_result status = create_alts_grpc_record_protocol(
key, key_size, is_rekey, is_client, is_integrity_only,
/*is_protect=*/true, &impl->record_protocol);
/*is_protect=*/true, enable_extra_copy, &impl->record_protocol);
if (status == TSI_OK) {
status = create_alts_grpc_record_protocol(
key, key_size, is_rekey, is_client, is_integrity_only,
/*is_protect=*/false, &impl->unrecord_protocol);
/*is_protect=*/false, enable_extra_copy, &impl->unrecord_protocol);
if (status == TSI_OK) {
/* Sets maximum frame size. */
size_t max_protected_frame_size_to_set = kDefaultFrameLength;

@ -35,6 +35,11 @@
* server side.
* - is_integrity_only: a flag indicating if the protector instance will be
* used for integrity-only or privacy-integrity mode.
* - enable_extra_copy: a flag indicating if the protector instance does one
* extra memory copy during the protect operation for integrity_only mode.
* For the unprotect operation, it is still zero-copy. If application intends
* to modify the data buffer after the protect operation, we can turn on this
* mode to avoid integrity check failure.
* - max_protected_frame_size: an in/out parameter indicating max frame size
* to be used by the protector. If it is nullptr, the default frame size will
* be used. Otherwise, the provided frame size will be adjusted (if not
@ -45,8 +50,8 @@
*/
tsi_result alts_zero_copy_grpc_protector_create(
const uint8_t* key, size_t key_size, bool is_rekey, bool is_client,
bool is_integrity_only, size_t* max_protected_frame_size,
tsi_zero_copy_grpc_protector** protector);
bool is_integrity_only, bool enable_extra_copy,
size_t* max_protected_frame_size, tsi_zero_copy_grpc_protector** protector);
#endif /* GRPC_CORE_TSI_ALTS_ZERO_COPY_FRAME_PROTECTOR_ALTS_ZERO_COPY_GRPC_PROTECTOR_H \
*/

@ -55,4 +55,19 @@ typedef NS_ENUM(NSInteger, GRPCCompressAlgorithm) {
timeout:(int)timeout
forHost:(nonnull NSString *)host;
/** Enable/Disable automatic retry of gRPC calls on the channel. If automatic retry is enabled, the
* retry is controlled by server's service config. If automatic retry is disabled, failed calls are
* immediately returned to the application layer. */
+ (void)enableRetry:(BOOL)enabled forHost:(nonnull NSString *)host;
/** Set channel connection timeout and backoff parameters. All parameters are positive integers in
* milliseconds. Set a parameter to 0 to make gRPC use default value for that parameter.
*
* Refer to gRPC's doc at https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md for the
* details of each parameter. */
+ (void)setMinConnectTimeout:(unsigned int)timeout
initialBackoff:(unsigned int)initialBackoff
maxBackoff:(unsigned int)maxBackoff
forHost:(nonnull NSString *)host;
@end

@ -64,4 +64,19 @@
hostConfig.keepaliveTimeout = timeout;
}
+ (void)enableRetry:(BOOL)enabled forHost:(nonnull NSString *)host {
GRPCHost *hostConfig = [GRPCHost hostWithAddress:host];
hostConfig.retryEnabled = enabled;
}
+ (void)setMinConnectTimeout:(unsigned int)timeout
initialBackoff:(unsigned int)initialBackoff
maxBackoff:(unsigned int)maxBackoff
forHost:(nonnull NSString *)host {
GRPCHost *hostConfig = [GRPCHost hostWithAddress:host];
hostConfig.minConnectTimeout = timeout;
hostConfig.initialConnectBackoff = initialBackoff;
hostConfig.maxConnectBackoff = maxBackoff;
}
@end

@ -38,6 +38,11 @@ struct grpc_channel_credentials;
@property(nonatomic) int keepaliveInterval;
@property(nonatomic) int keepaliveTimeout;
@property(nonatomic) id logContext;
@property(nonatomic) BOOL retryEnabled;
@property(nonatomic) unsigned int minConnectTimeout;
@property(nonatomic) unsigned int initialConnectBackoff;
@property(nonatomic) unsigned int maxConnectBackoff;
/** The following properties should only be modified for testing: */

@ -85,6 +85,7 @@ static NSMutableDictionary *kHostCache;
_secure = YES;
kHostCache[address] = self;
_compressAlgorithm = GRPC_COMPRESS_NONE;
_retryEnabled = YES;
}
#ifndef GRPC_CFSTREAM
[GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)];
@ -240,6 +241,20 @@ static NSMutableDictionary *kHostCache;
args[@GRPC_ARG_DISABLE_CLIENT_AUTHORITY_FILTER] = [NSNumber numberWithInt:1];
}
if (_retryEnabled == NO) {
args[@GRPC_ARG_ENABLE_RETRIES] = [NSNumber numberWithInt:0];
}
if (_minConnectTimeout > 0) {
args[@GRPC_ARG_MIN_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_minConnectTimeout];
}
if (_initialConnectBackoff > 0) {
args[@GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_initialConnectBackoff];
}
if (_maxConnectBackoff > 0) {
args[@GRPC_ARG_MAX_RECONNECT_BACKOFF_MS] = [NSNumber numberWithInt:_maxConnectBackoff];
}
return args;
}

@ -0,0 +1,92 @@
# gRPC iOS Network Transition Behaviors
Network connectivity on an iOS device may transition between cellular, WIFI, or
no network connectivity. This document describes how these network changes
should be handled by gRPC and current known issues.
## Expected Network Transition Behaviors
The expected gRPC iOS channel and network transition behaviors are:
* Channel connection to a particular host is established at the time of
starting the first call to the channel and remains connected for future calls
to the same host.
* If the underlying connection to the remote host is broken, the channel is
disconnected and enters TRANSIENT\_FAILURE state.
* A channel is broken if the channel connection is no longer viable. This
happens when
* The network interface is no longer available, e.g. WiFi or cellular
interface is turned off or goes offline, airplane mode turned on, etc;
* The underlying TCP connection is no longer valid, e.g. WiFi connects to
another hotspot, cellular data switched from LTE to 4G, etc;
* A network interface more preferable by the OS is valid, e.g. WiFi gets
connected when the channel is already connected via cellular.
* A channel in TRANSIENT\_FAILURE state attempts reconnection on start of the
next call to the same host, but only after a certain backoff period (see
corresponding
[doc](https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md)).
During the backoff period, any call to the same host will wait until the
first of the following events occur:
* Connection succeeded; calls will be made using this channel;
* Conncetion failed; calls will be failed and return UNAVAILABLE status code;
* The call's deadline is reached; the call will fail and return
DEADLINE\_EXCEEDED status code.
The length of backoff period of a channel is reset whenever a connection
attempt is successful.
## Implementations
### gRPC iOS with TCP Sockets
gRPC's default implementation is to use TCP sockets for networking. It turns
out that although Apple supports this type of usage, it is [not recommended by
Apple](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/SocketsAndStreams/SocketsAndStreams.html)
and has some issues described below.
#### Issues with TCP Sockets
The TCP sockets on iOS is flawed in that it does not reflect the viability of
the channel connection. Particularly, we observed the following issues when
using TCP sockets:
* When a TCP socket connection is established on cellular data and WiFi
becomes available, the TCP socket neither return an error event nor continue
sending/receiving data on it, but still accepts write on it.
* A TCP socket does not report certain events that happen in the
background. When a TCP connection breaks in the background for the reason
like WiFi connects to another hotspot, the socket neither return an error nor
continue sending/receiving data on it, but still accepts write on it.
In both situations, the user will see the call hang for an extended period of
time before the TCP socket times out.
#### gRPC iOS library's resolution to TCP socket issues
We introduced
[`ConnectivityMonitor`](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/SocketsAndStreams/SocketsAndStreams.html)
in gRPC iOS library v0.14.0 to alleviate these issues in TCP sockets,
which changes the network transition behaviors a bit.
We classify network connectivity state of the device into three categories
based on flags obtained from `SCNetworkReachability` API:
| Reachable | ConnectionRequired | IsWWAN | **Category** |
|:---------:|:------------------:|:------:|:------------:|
| 0 | X | X | None |
| X | 1 | X | None |
| 1 | 0 | 0 | WiFi |
| 1 | 0 | 1 | Cellular |
Whenever there is a transition of network between two of these categories, all
previously existing channels are assumed to be broken and are actively
destroyed. If there is an unfinished call, the call should return with status
code `UNAVAILABLE`.
`ConnectivityMonitor` is able to detect the scenario of the first issue above
and actively destroy the channels. However, the second issue is not resolvable.
To solve that issue the best solution is to switch to CFStream implementation
which eliminates all of them.
### gRPC iOS with CFStream
gRPC iOS with CFStream implementation (introduced in v1.13.0) uses Apple's
networking API to make connections. It resolves the issues with TCP sockets
mentioned above. Users are recommended to use this implementation rather than
TCP socket implementation. The detailed behavior of streams in CFStream is not
documented by Apple, but our experiments show that it accords to the expected
behaviors. With CFStream implementation, an event is always received when the
underlying connection is no longer viable. For more detailed information and
usages of CFStream implementation, refer to the
[user guide](https://github.com/grpc/grpc/blob/master/src/objective-c/README-CFSTREAM.md).

@ -0,0 +1,32 @@
[![Cocoapods](https://img.shields.io/cocoapods/v/gRPC.svg)](https://cocoapods.org/pods/gRPC)
# gRPC Objective-C with CFStream
gRPC Objective-C library now provides the option to use Apple's CFStream API (rather than TCP
sockets) for networking. Using CFStream resolves a bunch of network connectivity transition issues
(see the [doc](https://github.com/grpc/grpc/blob/master/src/objective-c/NetworkTransitionBehavior.md)
for more information).
CFStream integration is now in experimental state. You will need explicit opt-in to use it to get
the benefits of resolving the issues above. We expect to make CFStream the default networking
interface that gRPC uses when it is ready for production.
## Usage
If you use gRPC following the instructions in
[README.md](https://github.com/grpc/grpc/blob/master/src/objective-c/README.md):
- Simply replace the
dependency on `gRPC-ProtoRPC` with `gRPC-ProtoRPC/CFStream`. The build system will take care of
everything else and switch networking to CFStream.
If your project directly depends on podspecs other than `gRPC-ProtoRPC` (e.g. `gRPC` or
`gRPC-Core`):
- Make your projects depend on subspecs corresponding to CFStream in each gRPC podspec. For
`gRPC-Core`, you will need to make sure that the completion queue you create is of type
`GRPC_CQ_NON_POLLING`. This is expected to be fixed soon so that you do not have to modify the
completion queue type.
## Notes
- Currently we do not support platforms other than iOS, although it is likely that this integration
can run on MacOS targets with Apple's compiler.
- Let us know if you meet any issue by filing issue and ping @muxi.

@ -548,4 +548,47 @@ static GRPCProtoMethod *kFullDuplexCallMethod;
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
- (void)testTimeoutBackoffWithTimeout:(double)timeout Backoff:(double)backoff {
const double maxConnectTime = timeout > backoff ? timeout : backoff;
const double kMargin = 0.1;
__weak XCTestExpectation *completion = [self expectationWithDescription:@"Timeout in a second."];
NSString *const kDummyAddress = [NSString stringWithFormat:@"8.8.8.8:1"];
GRPCCall *call = [[GRPCCall alloc] initWithHost:kDummyAddress
path:@""
requestsWriter:[GRXWriter writerWithValue:[NSData data]]];
[GRPCCall setMinConnectTimeout:timeout * 1000
initialBackoff:backoff * 1000
maxBackoff:0
forHost:kDummyAddress];
NSDate *startTime = [NSDate date];
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(id value) {
XCTAssert(NO, @"Received message. Should not reach here");
}
completionHandler:^(NSError *errorOrNil) {
XCTAssertNotNil(errorOrNil, @"Finished with no error");
// The call must fail before maxConnectTime. However there is no lower bound on the time
// taken for connection. A shorter time happens when connection is actively refused
// by 8.8.8.8:1 before maxConnectTime elapsed.
XCTAssertLessThan([[NSDate date] timeIntervalSinceDate:startTime],
maxConnectTime + kMargin);
[completion fulfill];
}];
[call startWithWriteable:responsesWriteable];
[self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil];
}
// The numbers of the following three tests are selected to be smaller than the default values of
// initial backoff (1s) and min_connect_timeout (20s), so that if they fail we know the default
// values fail to be overridden by the channel args.
- (void)testTimeoutBackoff2 {
[self testTimeoutBackoffWithTimeout:0.7 Backoff:0.3];
}
- (void)testTimeoutBackoff3 {
[self testTimeoutBackoffWithTimeout:0.3 Backoff:0.7];
}
@end

@ -37,10 +37,10 @@
# warnings we'd like, but that dont exist in all compilers
PREFERRED_WARNINGS=['shadow', 'extra-semi']
CHECK_WARNINGS=PREFERRED_WARNINGS + ['no-shift-negative-value']
CHECK_WARNINGS=PREFERRED_WARNINGS + ['no-shift-negative-value', 'no-unused-but-set-variable', 'no-maybe-uninitialized']
def warning_var(fmt, warning):
return fmt % warning.replace('-', '_').upper()
return fmt % warning.replace('-', '_').replace('+', 'X').upper()
def neg_warning(warning):
if warning[0:3] == 'no-':
@ -191,6 +191,12 @@
TMPOUT = `mktemp /tmp/test-out-XXXXXX`
endif
CHECK_NO_CXX14_COMPAT_WORKS_CMD = $(CC) -std=c++11 -Werror -Wno-c++14-compat -o $(TMPOUT) -c test/build/no-c++14-compat.cc
HAS_WORKING_NO_CXX14_COMPAT = $(shell $(CHECK_NO_CXX14_COMPAT_WORKS_CMD) 2> /dev/null && echo true || echo false)
ifeq ($(HAS_WORKING_NO_CXX14_COMPAT),true)
W_NO_CXX14_COMPAT=-Wno-c++14-compat
endif
%for warning in CHECK_WARNINGS:
${warning_var('CHECK_%s_WORKS_CMD', warning)} = $(CC) -std=c99 -Werror -W${warning} -o $(TMPOUT) -c test/build/${warning}.c
${warning_var('HAS_WORKING_%s', warning)} = $(shell $(${warning_var('CHECK_%s_WORKS_CMD', warning)}) 2> /dev/null && echo true || echo false)
@ -1271,6 +1277,11 @@
$(Q) mkdir -p `dirname $@`
$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
$(OBJDIR)/$(CONFIG)/%.o : %.cpp
$(E) "[CXX] Compiling $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
install: install_c install_cxx install-plugins install-certs
install_c: install-headers_c install-static_c install-shared_c

@ -49,6 +49,7 @@
out = grpc_lib_files(filegroups, ("grpc++_codegen_proto", "grpc++_config_proto"), ("headers", "src", "public_headers"))
excl_files = grpc_lib_files(filegroups, ("grpc++_codegen_base",), ("headers", "src", "public_headers"))
out = [file for file in out if file not in excl_files]
out = filter_grpcpp(out)
return out
def grpcpp_private_files(libs, filegroups):
@ -131,7 +132,7 @@
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
# version = '${settings.version}'
version = '0.0.2'
version = '0.0.3'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
@ -195,6 +196,13 @@
ss.private_header_files = ${ruby_multiline_list(grpcpp_private_headers(libs, filegroups), 30)}
end
s.subspec 'Protobuf' do |ss|
ss.header_mappings_dir = 'include/grpcpp'
ss.dependency "#{s.name}/Interface", version
ss.source_files = ${ruby_multiline_list(grpcpp_proto_files(filegroups), 22)}
end
s.prepare_command = <<-END_OF_COMMAND
find src/cpp/ -type f ! -path '*.grpc_back' -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include "(pb(_.*)?\\.h)";#include <nanopb/\\1>;g'
find src/cpp/ -type f -path '*.grpc_back' -print0 | xargs -0 rm

@ -0,0 +1,19 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
int main(void) {}

@ -0,0 +1,19 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
int main(void) {}

@ -0,0 +1,19 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
int main(void) {}

@ -18,7 +18,10 @@ licenses(["notice"]) # Apache v2
load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
grpc_package(name = "test/core/iomgr", visibility = "public") # Useful for third party devs to test their io manager implementation.
grpc_package(
name = "test/core/iomgr",
visibility = "public",
) # Useful for third party devs to test their io manager implementation.
grpc_cc_library(
name = "endpoint_tests",
@ -72,16 +75,28 @@ grpc_cc_test(
],
)
grpc_cc_test(
name = "ev_epollex_linux_test",
srcs = ["ev_epollex_linux_test.cc"],
language = "C++",
deps = [
"//:gpr",
"//:grpc",
"//test/core/util:gpr_test_util",
"//test/core/util:grpc_test_util",
],
)
grpc_cc_test(
name = "ev_epollsig_linux_test",
srcs = ["ev_epollsig_linux_test.cc"],
language = "C++",
deps = [
"//:gpr",
"//:grpc",
"//test/core/util:gpr_test_util",
"//test/core/util:grpc_test_util",
],
language = "C++",
)
grpc_cc_test(
@ -221,13 +236,13 @@ grpc_cc_test(
name = "tcp_server_posix_test",
srcs = ["tcp_server_posix_test.cc"],
language = "C++",
tags = ["manual"], # TODO(adelez): Remove once this works on Foundry.
deps = [
"//:gpr",
"//:grpc",
"//test/core/util:gpr_test_util",
"//test/core/util:grpc_test_util",
],
tags = ["manual"], # TODO(adelez): Remove once this works on Foundry.
)
grpc_cc_test(

@ -0,0 +1,115 @@
/*
*
* Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "src/core/lib/iomgr/port.h"
/* This test only relevant on linux systems where epoll() is available */
#if defined(GRPC_LINUX_EPOLL_CREATE1) && defined(GRPC_LINUX_EVENTFD)
#include "src/core/lib/iomgr/ev_epollex_linux.h"
#include <grpc/grpc.h>
#include <string.h>
#include <sys/eventfd.h>
#include "test/core/util/test_config.h"
static void pollset_destroy(void* ps, grpc_error* error) {
grpc_pollset_destroy(static_cast<grpc_pollset*>(ps));
gpr_free(ps);
}
// This test is added to cover the case found in bug:
// https://github.com/grpc/grpc/issues/15760
static void test_pollable_owner_fd() {
grpc_core::ExecCtx exec_ctx;
int ev_fd1;
int ev_fd2;
grpc_fd* grpc_fd1;
grpc_fd* grpc_fd2;
grpc_pollset* ps;
gpr_mu* mu;
// == Create two grpc_fds ==
// All we need is two file descriptors. Doesn't matter what type. We use
// eventfd type here for the purpose of this test
ev_fd1 = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
ev_fd2 = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
if (ev_fd1 < 0 || ev_fd2 < 0) {
gpr_log(GPR_ERROR, "Error in creating event fds for the test");
return;
}
grpc_fd1 = grpc_fd_create(ev_fd1, "epollex-test-fd1", false);
grpc_fd2 = grpc_fd_create(ev_fd2, "epollex-test-fd2", false);
grpc_core::ExecCtx::Get()->Flush();
// == Create a pollset ==
ps = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
grpc_pollset_init(ps, &mu);
grpc_core::ExecCtx::Get()->Flush();
// == Add fd1 to pollset ==
grpc_pollset_add_fd(ps, grpc_fd1);
grpc_core::ExecCtx::Get()->Flush();
// == Destroy fd1 ==
grpc_fd_orphan(grpc_fd1, nullptr, nullptr, "test fd1 orphan");
grpc_core::ExecCtx::Get()->Flush();
// = Add fd2 to pollset ==
//
// Before https://github.com/grpc/grpc/issues/15760, the following line caused
// unexpected behavior (The previous grpc_pollset_add_fd(ps, grpc_fd1) created
// an underlying structure in epollex that held a reference to grpc_fd1 which
// was being accessed here even after grpc_fd_orphan(grpc_fd1) was called
grpc_pollset_add_fd(ps, grpc_fd2);
grpc_core::ExecCtx::Get()->Flush();
// == Destroy fd2 ==
grpc_fd_orphan(grpc_fd2, nullptr, nullptr, "test fd2 orphan");
grpc_core::ExecCtx::Get()->Flush();
// == Destroy pollset
grpc_closure ps_destroy_closure;
GRPC_CLOSURE_INIT(&ps_destroy_closure, pollset_destroy, ps,
grpc_schedule_on_exec_ctx);
grpc_pollset_shutdown(ps, &ps_destroy_closure);
grpc_core::ExecCtx::Get()->Flush();
}
int main(int argc, char** argv) {
const char* poll_strategy = nullptr;
grpc_test_init(argc, argv);
grpc_init();
{
grpc_core::ExecCtx exec_ctx;
poll_strategy = grpc_get_poll_strategy_name();
if (poll_strategy != nullptr && strcmp(poll_strategy, "epollex") == 0) {
test_pollable_owner_fd();
} else {
gpr_log(GPR_INFO,
"Skipping the test. The test is only relevant for 'epollex' "
"strategy. and the current strategy is: '%s'",
poll_strategy);
}
}
grpc_shutdown();
return 0;
}
#else /* defined(GRPC_LINUX_EPOLL_CREATE1) && defined(GRPC_LINUX_EVENTFD) */
int main(int argc, char** argv) { return 0; }
#endif

@ -40,6 +40,7 @@
#include <grpc/impl/codegen/sync.h>
#include <grpc/impl/codegen/sync_custom.h>
#include <grpc/impl/codegen/sync_generic.h>
#include <grpc/load_reporting.h>
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
#include <grpc/status.h>

@ -109,7 +109,7 @@ static void alter_random_byte(grpc_slice_buffer* sb) {
}
static alts_grpc_record_protocol_test_fixture*
test_fixture_integrity_only_create(bool rekey) {
test_fixture_integrity_only_create(bool rekey, bool extra_copy) {
alts_grpc_record_protocol_test_fixture* fixture =
static_cast<alts_grpc_record_protocol_test_fixture*>(
gpr_zalloc(sizeof(alts_grpc_record_protocol_test_fixture)));
@ -124,41 +124,46 @@ test_fixture_integrity_only_create(bool rekey) {
&crypter, nullptr) == GRPC_STATUS_OK);
GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create(
crypter, 8, /*is_client=*/true, /*is_protect=*/true,
&fixture->client_protect) == TSI_OK);
extra_copy, &fixture->client_protect) == TSI_OK);
/* Create client record protocol for unprotect. */
GPR_ASSERT(gsec_aes_gcm_aead_crypter_create(
key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey,
&crypter, nullptr) == GRPC_STATUS_OK);
GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create(
crypter, 8, /*is_client=*/true, /*is_protect=*/false,
&fixture->client_unprotect) == TSI_OK);
extra_copy, &fixture->client_unprotect) == TSI_OK);
/* Create server record protocol for protect. */
GPR_ASSERT(gsec_aes_gcm_aead_crypter_create(
key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey,
&crypter, nullptr) == GRPC_STATUS_OK);
GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create(
crypter, 8, /*is_client=*/false, /*is_protect=*/true,
&fixture->server_protect) == TSI_OK);
extra_copy, &fixture->server_protect) == TSI_OK);
/* Create server record protocol for unprotect. */
GPR_ASSERT(gsec_aes_gcm_aead_crypter_create(
key, key_length, kAesGcmNonceLength, kAesGcmTagLength, rekey,
&crypter, nullptr) == GRPC_STATUS_OK);
GPR_ASSERT(alts_grpc_integrity_only_record_protocol_create(
crypter, 8, /*is_client=*/false, /*is_protect=*/false,
&fixture->server_unprotect) == TSI_OK);
extra_copy, &fixture->server_unprotect) == TSI_OK);
gpr_free(key);
return fixture;
}
static alts_grpc_record_protocol_test_fixture*
test_fixture_integrity_only_no_rekey_create() {
return test_fixture_integrity_only_create(false);
test_fixture_integrity_only_no_rekey_no_extra_copy_create() {
return test_fixture_integrity_only_create(false, false);
}
static alts_grpc_record_protocol_test_fixture*
test_fixture_integrity_only_rekey_create() {
return test_fixture_integrity_only_create(true);
return test_fixture_integrity_only_create(true, false);
}
static alts_grpc_record_protocol_test_fixture*
test_fixture_integrity_only_extra_copy_create() {
return test_fixture_integrity_only_create(false, true);
}
static alts_grpc_record_protocol_test_fixture*
@ -440,8 +445,11 @@ static void alts_grpc_record_protocol_tests(
}
int main(int argc, char** argv) {
alts_grpc_record_protocol_tests(&test_fixture_integrity_only_no_rekey_create);
alts_grpc_record_protocol_tests(
&test_fixture_integrity_only_no_rekey_no_extra_copy_create);
alts_grpc_record_protocol_tests(&test_fixture_integrity_only_rekey_create);
alts_grpc_record_protocol_tests(
&test_fixture_integrity_only_extra_copy_create);
alts_grpc_record_protocol_tests(
&test_fixture_privacy_integrity_no_rekey_create);
alts_grpc_record_protocol_tests(&test_fixture_privacy_integrity_rekey_create);

@ -100,7 +100,8 @@ static bool are_slice_buffers_equal(grpc_slice_buffer* first,
static alts_zero_copy_grpc_protector_test_fixture*
alts_zero_copy_grpc_protector_test_fixture_create(bool rekey,
bool integrity_only) {
bool integrity_only,
bool enable_extra_copy) {
alts_zero_copy_grpc_protector_test_fixture* fixture =
static_cast<alts_zero_copy_grpc_protector_test_fixture*>(
gpr_zalloc(sizeof(alts_zero_copy_grpc_protector_test_fixture)));
@ -111,10 +112,12 @@ alts_zero_copy_grpc_protector_test_fixture_create(bool rekey,
gsec_test_random_array(&key, key_length);
GPR_ASSERT(alts_zero_copy_grpc_protector_create(
key, key_length, rekey, /*is_client=*/true, integrity_only,
&max_protected_frame_size, &fixture->client) == TSI_OK);
enable_extra_copy, &max_protected_frame_size,
&fixture->client) == TSI_OK);
GPR_ASSERT(alts_zero_copy_grpc_protector_create(
key, key_length, rekey, /*is_client=*/false, integrity_only,
&max_protected_frame_size, &fixture->server) == TSI_OK);
enable_extra_copy, &max_protected_frame_size,
&fixture->server) == TSI_OK);
gpr_free(key);
grpc_core::ExecCtx::Get()->Flush();
return fixture;
@ -229,62 +232,70 @@ static void seal_unseal_large_buffer(tsi_zero_copy_grpc_protector* sender,
/* --- Test cases. --- */
static void alts_zero_copy_protector_seal_unseal_small_buffer_tests() {
static void alts_zero_copy_protector_seal_unseal_small_buffer_tests(
bool enable_extra_copy) {
alts_zero_copy_grpc_protector_test_fixture* fixture =
alts_zero_copy_grpc_protector_test_fixture_create(
/*rekey=*/false, /*integrity_only=*/true);
/*rekey=*/false, /*integrity_only=*/true, enable_extra_copy);
seal_unseal_small_buffer(fixture->client, fixture->server);
seal_unseal_small_buffer(fixture->server, fixture->client);
alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
fixture = alts_zero_copy_grpc_protector_test_fixture_create(
/*rekey=*/false, /*integrity_only=*/false);
/*rekey=*/false, /*integrity_only=*/false, enable_extra_copy);
seal_unseal_small_buffer(fixture->client, fixture->server);
seal_unseal_small_buffer(fixture->server, fixture->client);
alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
fixture = alts_zero_copy_grpc_protector_test_fixture_create(
/*rekey=*/true, /*integrity_only=*/true);
/*rekey=*/true, /*integrity_only=*/true, enable_extra_copy);
seal_unseal_small_buffer(fixture->client, fixture->server);
seal_unseal_small_buffer(fixture->server, fixture->client);
alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
fixture = alts_zero_copy_grpc_protector_test_fixture_create(
/*rekey=*/true, /*integrity_only=*/false);
/*rekey=*/true, /*integrity_only=*/false, enable_extra_copy);
seal_unseal_small_buffer(fixture->client, fixture->server);
seal_unseal_small_buffer(fixture->server, fixture->client);
alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
}
static void alts_zero_copy_protector_seal_unseal_large_buffer_tests() {
static void alts_zero_copy_protector_seal_unseal_large_buffer_tests(
bool enable_extra_copy) {
alts_zero_copy_grpc_protector_test_fixture* fixture =
alts_zero_copy_grpc_protector_test_fixture_create(
/*rekey=*/false, /*integrity_only=*/true);
/*rekey=*/false, /*integrity_only=*/true, enable_extra_copy);
seal_unseal_large_buffer(fixture->client, fixture->server);
seal_unseal_large_buffer(fixture->server, fixture->client);
alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
fixture = alts_zero_copy_grpc_protector_test_fixture_create(
/*rekey=*/false, /*integrity_only=*/false);
/*rekey=*/false, /*integrity_only=*/false, enable_extra_copy);
seal_unseal_large_buffer(fixture->client, fixture->server);
seal_unseal_large_buffer(fixture->server, fixture->client);
alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
fixture = alts_zero_copy_grpc_protector_test_fixture_create(
/*rekey=*/true, /*integrity_only=*/true);
/*rekey=*/true, /*integrity_only=*/true, enable_extra_copy);
seal_unseal_large_buffer(fixture->client, fixture->server);
seal_unseal_large_buffer(fixture->server, fixture->client);
alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
fixture = alts_zero_copy_grpc_protector_test_fixture_create(
/*rekey=*/true, /*integrity_only=*/false);
/*rekey=*/true, /*integrity_only=*/false, enable_extra_copy);
seal_unseal_large_buffer(fixture->client, fixture->server);
seal_unseal_large_buffer(fixture->server, fixture->client);
alts_zero_copy_grpc_protector_test_fixture_destroy(fixture);
}
int main(int argc, char** argv) {
alts_zero_copy_protector_seal_unseal_small_buffer_tests();
alts_zero_copy_protector_seal_unseal_large_buffer_tests();
alts_zero_copy_protector_seal_unseal_small_buffer_tests(
/*enable_extra_copy=*/false);
alts_zero_copy_protector_seal_unseal_small_buffer_tests(
/*enable_extra_copy=*/true);
alts_zero_copy_protector_seal_unseal_large_buffer_tests(
/*enable_extra_copy=*/false);
alts_zero_copy_protector_seal_unseal_large_buffer_tests(
/*enable_extra_copy=*/true);
return 0;
}

@ -160,10 +160,7 @@ void CheckResolverResultAssertFailureLocked(void* arg, grpc_error* error) {
gpr_mu_unlock(args->mu);
}
TEST(CancelDuringAresQuery, TestCancelActiveDNSQuery) {
grpc_core::ExecCtx exec_ctx;
ArgsStruct args;
ArgsInit(&args);
void TestCancelActiveDNSQuery(ArgsStruct* args) {
int fake_dns_port = grpc_pick_unused_port_or_die();
FakeNonResponsiveDNSServer fake_dns_server(fake_dns_port);
char* client_target;
@ -173,20 +170,47 @@ TEST(CancelDuringAresQuery, TestCancelActiveDNSQuery) {
fake_dns_port));
// create resolver and resolve
grpc_core::OrphanablePtr<grpc_core::Resolver> resolver =
grpc_core::ResolverRegistry::CreateResolver(client_target, nullptr,
args.pollset_set, args.lock);
grpc_core::ResolverRegistry::CreateResolver(
client_target, nullptr, args->pollset_set, args->lock);
gpr_free(client_target);
grpc_closure on_resolver_result_changed;
GRPC_CLOSURE_INIT(&on_resolver_result_changed,
CheckResolverResultAssertFailureLocked, (void*)&args,
grpc_combiner_scheduler(args.lock));
resolver->NextLocked(&args.channel_args, &on_resolver_result_changed);
CheckResolverResultAssertFailureLocked, (void*)args,
grpc_combiner_scheduler(args->lock));
resolver->NextLocked(&args->channel_args, &on_resolver_result_changed);
// Without resetting and causing resolver shutdown, the
// PollPollsetUntilRequestDone call should never finish.
resolver.reset();
grpc_core::ExecCtx::Get()->Flush();
PollPollsetUntilRequestDone(&args);
ArgsFinish(&args);
PollPollsetUntilRequestDone(args);
ArgsFinish(args);
}
TEST(CancelDuringAresQuery, TestCancelActiveDNSQuery) {
grpc_core::ExecCtx exec_ctx;
ArgsStruct args;
ArgsInit(&args);
TestCancelActiveDNSQuery(&args);
}
TEST(CancelDuringAresQuery, TestFdsAreDeletedFromPollsetSet) {
grpc_core::ExecCtx exec_ctx;
ArgsStruct args;
ArgsInit(&args);
// Add fake_other_pollset_set into the mix to test
// that we're explicitly deleting fd's from their pollset.
// If we aren't doing so, then the remaining presence of
// "fake_other_pollset_set" after the request is done and the resolver
// pollset set is destroyed should keep the resolver's fd alive and
// fail the test.
grpc_pollset_set* fake_other_pollset_set = grpc_pollset_set_create();
grpc_pollset_set_add_pollset_set(fake_other_pollset_set, args.pollset_set);
// Note that running the cancellation c-ares test is somewhat irrelevant for
// this test. This test only cares about what happens to fd's that c-ares
// opens.
TestCancelActiveDNSQuery(&args);
EXPECT_EQ(grpc_iomgr_count_objects_for_testing(), 0u);
grpc_pollset_set_destroy(fake_other_pollset_set);
}
TEST(CancelDuringAresQuery,

@ -0,0 +1 @@
Subproject commit 6599cac0965be8e5a835ab7a5684bbef033d5ad0

@ -0,0 +1 @@
Subproject commit 9245d481eb3e890f708ff2d7dadf2a10c04748ba

@ -900,6 +900,7 @@ include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h \
include/grpc/load_reporting.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \

@ -901,6 +901,7 @@ include/grpc/impl/codegen/sync_custom.h \
include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h \
include/grpc/load_reporting.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \
@ -1028,6 +1029,7 @@ src/core/lib/compression/stream_compression_identity.h \
src/core/lib/debug/stats.h \
src/core/lib/debug/stats_data.h \
src/core/lib/debug/trace.h \
src/core/lib/gpr/alloc.h \
src/core/lib/gpr/arena.h \
src/core/lib/gpr/env.h \
src/core/lib/gpr/host_port.h \

@ -840,6 +840,7 @@ include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h \
include/grpc/impl/codegen/sync_windows.h \
include/grpc/load_reporting.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \

@ -840,6 +840,7 @@ include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h \
include/grpc/impl/codegen/sync_windows.h \
include/grpc/load_reporting.h \
include/grpc/slice.h \
include/grpc/slice_buffer.h \
include/grpc/status.h \
@ -891,7 +892,9 @@ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \
src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h \
src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \
@ -1070,6 +1073,7 @@ src/core/lib/debug/trace.cc \
src/core/lib/debug/trace.h \
src/core/lib/gpr/README.md \
src/core/lib/gpr/alloc.cc \
src/core/lib/gpr/alloc.h \
src/core/lib/gpr/arena.cc \
src/core/lib/gpr/arena.h \
src/core/lib/gpr/atm.cc \

@ -14,6 +14,6 @@
# limitations under the License.
export UPLOAD_TEST_RESULTS=true
EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address --test_timeout=3600"
EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address --test_timeout=3600 --runs_per_test_detects_flakes --runs_per_test=2"
github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"

@ -60,6 +60,8 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc
--action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \
--extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.13.0/cpp:cc-toolchain-clang-x86_64-default \
--extra_execution_platforms=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0:rbe_ubuntu1604 \
--runs_per_test_detects_flakes \
--runs_per_test=2 \
-- //test/... || FAILED="true"
# Sleep to let ResultStore finish writing results before querying

@ -0,0 +1,19 @@
#!/usr/bin/env bash
# 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.
export UPLOAD_TEST_RESULTS=true
EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address --test_timeout=3600"
github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"

@ -0,0 +1,68 @@
#!/usr/bin/env bash
# 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.
set -ex
# A temporary solution to give Kokoro credentials.
# The file name 4321_grpc-testing-service needs to match auth_credential in
# the build config.
# TODO: Use keystore.
mkdir -p ${KOKORO_KEYSTORE_DIR}
cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
temp_dir=$(mktemp -d)
ln -f "${KOKORO_GFILE_DIR}/bazel-rc-0.14.0rc5" ${temp_dir}/bazel
chmod 755 "${KOKORO_GFILE_DIR}/bazel-rc-0.14.0rc5"
export PATH="${temp_dir}:${PATH}"
# This should show ${temp_dir}/bazel
which bazel
chmod +x "${KOKORO_GFILE_DIR}/bazel_wrapper.py"
# change to grpc repo root
cd $(dirname $0)/../../../..
source tools/internal_ci/helper_scripts/prepare_build_linux_rc
"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \
--host_jvm_args=-Dbazel.DigestFunction=SHA256 \
test --jobs="200" \
--test_timeout="3600,3600,3600,3600" \
--test_output=errors \
--verbose_failures=true \
--keep_going \
--remote_accept_cached=true \
--spawn_strategy=remote \
--remote_local_fallback=false \
--remote_timeout=3600 \
--strategy=Javac=remote \
--strategy=Closure=remote \
--genrule_strategy=remote \
--experimental_strict_action_env=true \
--experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:59bf0e191a6b5cc1ab62c2224c810681d1326bad5a27b1d36c9f40113e79da7f" }' \
--define GRPC_PORT_ISOLATED_RUNTIME=1 \
--copt=-gmlt \
--strip=never \
--copt=-fsanitize=undefined \
--linkopt=-fsanitize=undefined \
--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.13.0/ubsan:toolchain \
--action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \
--extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.13.0/cpp:cc-toolchain-clang-x86_64-default \
--extra_execution_platforms=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0:rbe_ubuntu1604 \
-- //test/... || FAILED="true"
if [ "$FAILED" != "" ]
then
exit 1
fi

@ -93,6 +93,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.12.0': None
},
{
'v1.13.0': None
},
],
'go': [
{
@ -213,6 +216,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.12.0': None
},
{
'v1.13.0': None
},
],
'node': [
{
@ -289,6 +295,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.12.0': None
},
{
'v1.13.0': None
},
],
'php': [
{
@ -327,6 +336,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.12.0': None
},
{
'v1.13.0': None
},
],
'csharp': [
{
@ -370,6 +382,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.12.0': None
},
{
'v1.13.0': None
},
],
}

@ -449,6 +449,23 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c",
"name": "ev_epollex_linux_test",
"src": [
"test/core/iomgr/ev_epollex_linux_test.cc"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
@ -6850,6 +6867,16 @@
"third_party": false,
"type": "lib"
},
{
"deps": [],
"headers": [],
"is_filegroup": false,
"language": "c",
"name": "cxxabi",
"src": [],
"third_party": false,
"type": "lib"
},
{
"deps": [
"gpr_base"
@ -9139,6 +9166,7 @@
"include/grpc/support/sync_windows.h",
"include/grpc/support/thd_id.h",
"include/grpc/support/time.h",
"src/core/lib/gpr/alloc.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
"src/core/lib/gpr/host_port.h",
@ -9185,6 +9213,7 @@
"include/grpc/support/sync_windows.h",
"include/grpc/support/thd_id.h",
"include/grpc/support/time.h",
"src/core/lib/gpr/alloc.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
"src/core/lib/gpr/host_port.h",
@ -9460,6 +9489,7 @@
"include/grpc/grpc.h",
"include/grpc/grpc_posix.h",
"include/grpc/grpc_security_constants.h",
"include/grpc/load_reporting.h",
"include/grpc/slice.h",
"include/grpc/slice_buffer.h",
"include/grpc/status.h",
@ -9609,6 +9639,7 @@
"include/grpc/grpc.h",
"include/grpc/grpc_posix.h",
"include/grpc/grpc_security_constants.h",
"include/grpc/load_reporting.h",
"include/grpc/slice.h",
"include/grpc/slice_buffer.h",
"include/grpc/status.h",
@ -9958,6 +9989,8 @@
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
],
"is_filegroup": true,
@ -9975,7 +10008,9 @@
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
],
@ -9997,6 +10032,8 @@
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
],
"is_filegroup": true,
@ -10014,7 +10051,9 @@
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
"src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
],

@ -561,6 +561,26 @@
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux"
],
"cpu_cost": 3,
"exclude_configs": [],
"exclude_iomgrs": [
"uv"
],
"flaky": false,
"gtest": false,
"language": "c",
"name": "ev_epollex_linux_test",
"platforms": [
"linux"
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,

@ -26,16 +26,18 @@ want_submodules=$(mktemp /tmp/submXXXXXX)
git submodule | awk '{ print $1 }' | sort > "$submodules"
cat << EOF | awk '{ print $1 }' | sort > "$want_submodules"
cc4bed2d74f7c8717e31f9579214ab52a9c9c610 third_party/abseil-cpp (cc4bed2)
5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8 third_party/benchmark (v1.2.0)
70ef9596bbcc11353b9bb8d4e91478694dd21439 third_party/boringssl (fips-20170615-704-g70ef9596)
dcd3e6e6ecddf059adb48fca45bc7346a108bdd9 third_party/boringssl-with-bazel (version_for_cocoapods_10.0-369-gdcd3e6e6)
30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e third_party/gflags (v2.2.0)
73594cde8c9a52a102c4341c244c833aa61b9c06 third_party/bloaty (remotes/origin/wide-14-g73594cd)
70ef9596bbcc11353b9bb8d4e91478694dd21439 third_party/boringssl (fips-20170615-704-g70ef959)
dcd3e6e6ecddf059adb48fca45bc7346a108bdd9 third_party/boringssl-with-bazel (version_for_cocoapods_10.0-369-gdcd3e6e)
3be1924221e1326df520f8498d704a5c4c8d0cce third_party/cares/cares (cares-1_13_0)
30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e third_party/gflags (v2.2.0-5-g30dbc81)
ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0)
b5fbb742af122b565925987e65c08957739976a7 third_party/protobuf (v3.5.2)
6599cac0965be8e5a835ab7a5684bbef033d5ad0 third_party/libcxx (heads/release_60)
9245d481eb3e890f708ff2d7dadf2a10c04748ba third_party/libcxxabi (heads/release_60)
b5fbb742af122b565925987e65c08957739976a7 third_party/protobuf (v3.3.1-641-gb5fbb74)
cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11)
3be1924221e1326df520f8498d704a5c4c8d0cce third_party/cares/cares (cares-1_13_0)
73594cde8c9a52a102c4341c244c833aa61b9c06 third_party/bloaty
cc4bed2d74f7c8717e31f9579214ab52a9c9c610 third_party/abseil-cpp
EOF
diff -u "$submodules" "$want_submodules"

Loading…
Cancel
Save