Merge branch 'master' into kerrick-lyft-patch-1
diff --git a/.gitmodules b/.gitmodules
index 52db29b..afde4d3 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -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
diff --git a/BUILD b/BUILD
index dca9c87..8ce67e6 100644
--- a/BUILD
+++ b/BUILD
@@ -540,6 +540,7 @@
"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",
diff --git a/BUILDING.md b/BUILDING.md
index e1d63a7..e408402 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -112,9 +112,11 @@
## 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).
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 34adc3e..4443539 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -246,6 +246,9 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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
)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index abd7a5e..e8582d9 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -24,9 +24,9 @@
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 @@
```
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
diff --git a/Makefile b/Makefile
index d0a4329..d90755b 100644
--- a/Makefile
+++ b/Makefile
@@ -300,6 +300,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
+
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 @@
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 @@
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 @@
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 @@
$(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 @@
$(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 @@
$(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
+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 @@
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 @@
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 @@
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 @@
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 @@
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
+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 \
diff --git a/build.yaml b/build.yaml
index 05ea972..3fa8366 100644
--- a/build.yaml
+++ b/build.yaml
@@ -173,6 +173,7 @@
- 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 @@
- 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 @@
- 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 @@
- 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 @@
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 @@
- 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 @@
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
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index 7eb7abe..ce8cc06 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -24,7 +24,7 @@
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 @@
'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 @@
'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 @@
'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 @@
'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
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 11988ef..4006889 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -168,6 +168,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',
@@ -182,7 +183,8 @@
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 @@
'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 @@
'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 @@
'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',
diff --git a/grpc.gemspec b/grpc.gemspec
index 30bb522..21bd8e0 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -81,6 +81,7 @@
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 @@
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 @@
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 )
diff --git a/grpc.gyp b/grpc.gyp
index b0421ae..fcb5a3f 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -186,6 +186,32 @@
],
},
{
+ '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',
'dependencies': [
diff --git a/include/grpc/module.modulemap b/include/grpc/module.modulemap
index 755b6e7..e0d5404 100644
--- a/include/grpc/module.modulemap
+++ b/include/grpc/module.modulemap
@@ -43,6 +43,7 @@
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"
diff --git a/package.xml b/package.xml
index cd5a2a0..bab3bc1 100644
--- a/package.xml
+++ b/package.xml
@@ -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" />
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
index 06a6e85..c886795 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
@@ -74,6 +74,8 @@
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 @@
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 @@
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 @@
(*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.
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
index 7002c8f..2c9db71 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
@@ -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 @@
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);
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
index 5db832b..fffe9ed 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
@@ -44,11 +44,13 @@
: 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 @@
char* name_;
ares_socket_t as_;
grpc_fd* fd_;
+ grpc_pollset_set* driver_pollset_set_;
};
GrpcPolledFd* NewGrpcPolledFdLocked(ares_socket_t as,
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
index 471de58..497ad99 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
@@ -63,7 +63,7 @@
/** 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,23 +145,27 @@
}
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
- 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);
+ 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 */
+ 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(
grpc_ares_request* parent_request, char* host, uint16_t port,
bool is_balancer) {
@@ -399,20 +403,18 @@
}
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 @@
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 @@
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 @@
error_cleanup:
GRPC_CLOSURE_SCHED(on_done, error);
+ gpr_free(r);
gpr_free(host);
gpr_free(port);
return nullptr;
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
index 9e93d0c..ce26f5d 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
@@ -66,6 +66,10 @@
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);
diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc
index f010002..8ab3fe4 100644
--- a/src/core/ext/filters/client_channel/subchannel.cc
+++ b/src/core/ext/filters/client_channel/subchannel.cc
@@ -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 @@
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 @@
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");
diff --git a/src/core/lib/channel/channel_stack.cc b/src/core/lib/channel/channel_stack.cc
index ef6482c..056fcd9 100644
--- a/src/core/lib/channel/channel_stack.cc
+++ b/src/core/lib/channel/channel_stack.cc
@@ -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 @@
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 @@
/* 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 @@
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_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_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 @@
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 @@
}
}
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_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)));
}
diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc
index 3550fc0..a49271c 100644
--- a/src/core/lib/channel/channelz.cc
+++ b/src/core/lib/channel/channelz.cc
@@ -113,7 +113,10 @@
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;
}
}
diff --git a/src/core/lib/gpr/alloc.h b/src/core/lib/gpr/alloc.h
new file mode 100644
index 0000000..762b51b
--- /dev/null
+++ b/src/core/lib/gpr/alloc.h
@@ -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 */
diff --git a/src/core/lib/gpr/arena.cc b/src/core/lib/gpr/arena.cc
index b02c5b9..141de69 100644
--- a/src/core/lib/gpr/arena.cc
+++ b/src/core/lib/gpr/arena.cc
@@ -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 @@
// 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 @@
}
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 @@
}
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 @@
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 @@
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;
}
diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc
index 533c07e..2751b22 100644
--- a/src/core/lib/gprpp/thd_posix.cc
+++ b/src/core/lib/gprpp/thd_posix.cc
@@ -105,7 +105,7 @@
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();
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index a9b2adf..5ffabdc 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -104,8 +104,10 @@
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 @@
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 @@
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 @@
}
#endif
gpr_free(fd_name);
+
+ new_fd->track_err = track_err;
return new_fd;
}
@@ -446,6 +472,17 @@
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 @@
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 @@
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 @@
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_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 @@
}
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 @@
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 @@
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 @@
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;
diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc
index 468814e..46afda1 100644
--- a/src/core/lib/iomgr/iomgr.cc
+++ b/src/core/lib/iomgr/iomgr.cc
@@ -70,6 +70,8 @@
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) {
diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h
index e6d66e5..537ef8a 100644
--- a/src/core/lib/iomgr/iomgr.h
+++ b/src/core/lib/iomgr/iomgr.h
@@ -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 @@
* 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 */
diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc
index 55be919..26de216 100644
--- a/src/core/lib/iomgr/timer_manager.cc
+++ b/src/core/lib/iomgr/timer_manager.cc
@@ -277,7 +277,6 @@
g_threaded = true;
start_timer_thread_and_unlock();
} else {
- g_threaded = false;
gpr_mu_unlock(&g_mu);
}
}
diff --git a/src/core/lib/security/context/security_context.cc b/src/core/lib/security/context/security_context.cc
index 14051a3..dbf6e39 100644
--- a/src/core/lib/security/context/security_context.cc
+++ b/src/core/lib/security/context/security_context.cc
@@ -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 @@
}
/* --- 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 @@
if (c->extension.instance != nullptr && c->extension.destroy != nullptr) {
c->extension.destroy(c->extension.instance);
}
- gpr_free(ctx);
}
/* --- grpc_auth_context --- */
diff --git a/src/core/lib/security/context/security_context.h b/src/core/lib/security/context/security_context.h
index e782e4f..1e98d16 100644
--- a/src/core/lib/security/context/security_context.h
+++ b/src/core/lib/security/context/security_context.h
@@ -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 @@
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 --- */
diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc
index a560a4a..2dbefdf 100644
--- a/src/core/lib/security/transport/server_auth_filter.cc
+++ b/src/core/lib/security/transport/server_auth_filter.cc
@@ -44,7 +44,6 @@
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 @@
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 @@
// 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);
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index 556eb23..88e015c 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -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 @@
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_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 @@
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);
}
diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h
index e000f13..b3b0605 100644
--- a/src/core/lib/surface/call.h
+++ b/src/core/lib/surface/call.h
@@ -71,6 +71,8 @@
#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,
diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
index 9676085..06b9998 100644
--- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
+++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
@@ -127,7 +127,8 @@
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");
}
diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
index 7ba03eb..54e59a6 100644
--- a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
+++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc
@@ -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 @@
"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 @@
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 @@
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. */
diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h
index 8d68b27..5456d34 100644
--- a/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h
+++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h
@@ -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 \
*/
diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc b/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
index 6082137..58aba9b 100644
--- a/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
+++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc
@@ -110,7 +110,7 @@
*/
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 @@
: 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 @@
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 @@
/* 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;
diff --git a/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h b/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h
index 71e953c..515c27e 100644
--- a/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h
+++ b/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h
@@ -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 \
*/
diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h
index c05ba54..803f19d 100644
--- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h
+++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h
@@ -55,4 +55,19 @@
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
diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m
index 8f9c1b9..0e631fb 100644
--- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m
+++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m
@@ -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
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h
index d9916d9..291b07d 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.h
+++ b/src/objective-c/GRPCClient/private/GRPCHost.h
@@ -38,6 +38,11 @@
@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: */
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m
index 3489899..2e9f9f2 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.m
+++ b/src/objective-c/GRPCClient/private/GRPCHost.m
@@ -85,6 +85,7 @@
_secure = YES;
kHostCache[address] = self;
_compressAlgorithm = GRPC_COMPRESS_NONE;
+ _retryEnabled = YES;
}
#ifndef GRPC_CFSTREAM
[GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)];
@@ -240,6 +241,20 @@
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;
}
diff --git a/src/objective-c/NetworkTransitionBehavior.md b/src/objective-c/NetworkTransitionBehavior.md
new file mode 100644
index 0000000..51b1e47
--- /dev/null
+++ b/src/objective-c/NetworkTransitionBehavior.md
@@ -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).
+
diff --git a/src/objective-c/README-CFSTREAM.md b/src/objective-c/README-CFSTREAM.md
new file mode 100644
index 0000000..0b5215a
--- /dev/null
+++ b/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.
diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m
index d918656..2a16980 100644
--- a/src/objective-c/tests/GRPCClientTests.m
+++ b/src/objective-c/tests/GRPCClientTests.m
@@ -548,4 +548,47 @@
[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
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 4a04af1..628056e 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -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
diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template
index 2853bb6..cff252b 100644
--- a/templates/gRPC-C++.podspec.template
+++ b/templates/gRPC-C++.podspec.template
@@ -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
diff --git a/test/build/no-c++14-compat.cc b/test/build/no-c++14-compat.cc
new file mode 100644
index 0000000..0c1771c
--- /dev/null
+++ b/test/build/no-c++14-compat.cc
@@ -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) {}
diff --git a/test/build/no-maybe-uninitialized.c b/test/build/no-maybe-uninitialized.c
new file mode 100644
index 0000000..0c1771c
--- /dev/null
+++ b/test/build/no-maybe-uninitialized.c
@@ -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) {}
diff --git a/test/build/no-unused-but-set-variable.c b/test/build/no-unused-but-set-variable.c
new file mode 100644
index 0000000..0c1771c
--- /dev/null
+++ b/test/build/no-unused-but-set-variable.c
@@ -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) {}
diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD
index bbf0815..cc1b6ae 100644
--- a/test/core/iomgr/BUILD
+++ b/test/core/iomgr/BUILD
@@ -18,7 +18,10 @@
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",
@@ -73,15 +76,27 @@
)
grpc_cc_test(
- name = "ev_epollsig_linux_test",
- srcs = ["ev_epollsig_linux_test.cc"],
+ 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",
+ ],
)
grpc_cc_test(
@@ -221,13 +236,13 @@
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(
diff --git a/test/core/iomgr/ev_epollex_linux_test.cc b/test/core/iomgr/ev_epollex_linux_test.cc
new file mode 100644
index 0000000..08d1e68
--- /dev/null
+++ b/test/core/iomgr/ev_epollex_linux_test.cc
@@ -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
diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index bad28fe..2908306 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -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>
diff --git a/test/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_test.cc b/test/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_test.cc
index b763f19..3ae64d6 100644
--- a/test/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_test.cc
+++ b/test/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_test.cc
@@ -109,7 +109,7 @@
}
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 @@
&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,9 +445,12 @@
}
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);
diff --git a/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc b/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc
index 32159e2..3ee8323 100644
--- a/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc
+++ b/test/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector_test.cc
@@ -100,7 +100,8 @@
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 @@
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 @@
/* --- 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;
}
diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc
index 11cdc0b..0d59bf6 100644
--- a/test/cpp/naming/cancel_ares_query_test.cc
+++ b/test/cpp/naming/cancel_ares_query_test.cc
@@ -160,10 +160,7 @@
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 @@
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,
diff --git a/third_party/libcxx b/third_party/libcxx
new file mode 160000
index 0000000..6599cac
--- /dev/null
+++ b/third_party/libcxx
@@ -0,0 +1 @@
+Subproject commit 6599cac0965be8e5a835ab7a5684bbef033d5ad0
diff --git a/third_party/libcxxabi b/third_party/libcxxabi
new file mode 160000
index 0000000..9245d48
--- /dev/null
+++ b/third_party/libcxxabi
@@ -0,0 +1 @@
+Subproject commit 9245d481eb3e890f708ff2d7dadf2a10c04748ba
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index efe59c3..3da41dc 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -900,6 +900,7 @@
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 \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 6f8a81c..b11e5ae 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -901,6 +901,7 @@
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/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 \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index f64bdfc..592c94e 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -840,6 +840,7 @@
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 \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 63da493..e602609 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -840,6 +840,7 @@
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/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.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 \
diff --git a/tools/internal_ci/linux/grpc_asan_on_foundry.sh b/tools/internal_ci/linux/grpc_asan_on_foundry.sh
index 791c56c..5099fa0 100644
--- a/tools/internal_ci/linux/grpc_asan_on_foundry.sh
+++ b/tools/internal_ci/linux/grpc_asan_on_foundry.sh
@@ -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}"
diff --git a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh
index f5c12c2..c733a0a 100644
--- a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh
+++ b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh
@@ -60,6 +60,8 @@
--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
diff --git a/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh
new file mode 100644
index 0000000..791c56c
--- /dev/null
+++ b/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh
@@ -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}"
+
diff --git a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh
new file mode 100644
index 0000000..e3db4d6
--- /dev/null
+++ b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh
@@ -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
diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py
index 1a7c24f..cc4b5fc 100644
--- a/tools/interop_matrix/client_matrix.py
+++ b/tools/interop_matrix/client_matrix.py
@@ -93,6 +93,9 @@
{
'v1.12.0': None
},
+ {
+ 'v1.13.0': None
+ },
],
'go': [
{
@@ -213,6 +216,9 @@
{
'v1.12.0': None
},
+ {
+ 'v1.13.0': None
+ },
],
'node': [
{
@@ -289,6 +295,9 @@
{
'v1.12.0': None
},
+ {
+ 'v1.13.0': None
+ },
],
'php': [
{
@@ -327,6 +336,9 @@
{
'v1.12.0': None
},
+ {
+ 'v1.13.0': None
+ },
],
'csharp': [
{
@@ -370,6 +382,9 @@
{
'v1.12.0': None
},
+ {
+ 'v1.13.0': None
+ },
],
}
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 2e3e413..9d450d6 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -459,6 +459,23 @@
"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",
+ "gpr_test_util",
+ "grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c",
"name": "ev_epollsig_linux_test",
"src": [
"test/core/iomgr/ev_epollsig_linux_test.cc"
@@ -6851,6 +6868,16 @@
"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"
],
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 6ec6dbb..094ba13 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -575,6 +575,26 @@
"flaky": false,
"gtest": false,
"language": "c",
+ "name": "ev_epollex_linux_test",
+ "platforms": [
+ "linux"
+ ],
+ "uses_polling": true
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 3,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "gtest": false,
+ "language": "c",
"name": "ev_epollsig_linux_test",
"platforms": [
"linux"
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index 6362afd..4fe1aa8 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -26,16 +26,18 @@
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)
- ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0)
- b5fbb742af122b565925987e65c08957739976a7 third_party/protobuf (v3.5.2)
- cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11)
+ 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)
- 73594cde8c9a52a102c4341c244c833aa61b9c06 third_party/bloaty
- cc4bed2d74f7c8717e31f9579214ab52a9c9c610 third_party/abseil-cpp
+ 30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e third_party/gflags (v2.2.0-5-g30dbc81)
+ ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0)
+ 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)
EOF
diff -u "$submodules" "$want_submodules"