aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD4
-rw-r--r--CMakeLists.txt33
-rw-r--r--Makefile44
-rw-r--r--bazel/grpc_deps.bzl8
-rw-r--r--build.yaml16
-rw-r--r--config.m42
-rw-r--r--config.w322
-rw-r--r--doc/environment_variables.md1
-rw-r--r--gRPC-C++.podspec4
-rw-r--r--gRPC-Core.podspec6
-rw-r--r--grpc.gemspec4
-rw-r--r--grpc.gyp2
-rw-r--r--package.xml4
-rw-r--r--src/core/ext/filters/client_channel/client_channel.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.h4
-rw-r--r--src/core/ext/filters/client_channel/resolver.h4
-rw-r--r--src/core/ext/filters/client_channel/subchannel.cc2
-rw-r--r--src/core/ext/filters/http/client_authority_filter.cc7
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.cc10
-rw-r--r--src/core/ext/transport/cronet/transport/cronet_transport.cc2
-rw-r--r--src/core/lib/channel/channel_stack.cc5
-rw-r--r--src/core/lib/channel/channel_stack_builder.cc3
-rw-r--r--src/core/lib/channel/channel_stack_builder.h2
-rw-r--r--src/core/lib/debug/stats.h7
-rw-r--r--src/core/lib/debug/stats_data.cc5
-rw-r--r--src/core/lib/debug/stats_data.h120
-rw-r--r--src/core/lib/debug/stats_data.yaml6
-rw-r--r--src/core/lib/debug/stats_data_bq_schema.sql2
-rw-r--r--src/core/lib/gpr/fork.cc78
-rw-r--r--src/core/lib/gpr/fork.h35
-rw-r--r--src/core/lib/gprpp/fork.cc260
-rw-r--r--src/core/lib/gprpp/fork.h79
-rw-r--r--src/core/lib/gprpp/memory.h11
-rw-r--r--src/core/lib/gprpp/orphanable.h8
-rw-r--r--src/core/lib/gprpp/ref_counted.h8
-rw-r--r--src/core/lib/gprpp/thd.h3
-rw-r--r--src/core/lib/gprpp/thd_posix.cc57
-rw-r--r--src/core/lib/gprpp/thd_windows.cc7
-rw-r--r--src/core/lib/iomgr/combiner.cc19
-rw-r--r--src/core/lib/iomgr/ev_epollex_linux.cc48
-rw-r--r--src/core/lib/iomgr/exec_ctx.h53
-rw-r--r--src/core/lib/iomgr/fork_posix.cc47
-rw-r--r--src/core/lib/iomgr/resource_quota.cc2
-rw-r--r--src/core/lib/iomgr/tcp_client_posix.cc3
-rw-r--r--src/core/lib/iomgr/tcp_custom.cc2
-rw-r--r--src/core/lib/iomgr/tcp_posix.cc4
-rw-r--r--src/core/lib/iomgr/tcp_server_posix.cc10
-rw-r--r--src/core/lib/security/security_connector/alts_security_connector.cc3
-rw-r--r--src/core/lib/security/security_connector/security_connector.cc7
-rw-r--r--src/core/lib/surface/call.cc8
-rw-r--r--src/core/lib/surface/init.cc9
-rw-r--r--src/core/lib/transport/byte_stream.cc2
-rw-r--r--src/objective-c/GRPCClient/private/GRPCChannel.m1
-rw-r--r--src/objective-c/GRPCClient/private/GRPCHost.m3
-rw-r--r--src/objective-c/GRPCClient/private/NSDictionary+GRPC.m2
-rw-r--r--src/objective-c/GRPCClient/private/NSError+GRPC.m2
-rw-r--r--src/php/ext/grpc/byte_buffer.c12
-rw-r--r--src/php/ext/grpc/call.c15
-rw-r--r--src/php/ext/grpc/call.h10
-rw-r--r--src/php/ext/grpc/call_credentials.c16
-rw-r--r--src/php/ext/grpc/call_credentials.h10
-rw-r--r--src/php/ext/grpc/channel.c13
-rw-r--r--src/php/ext/grpc/channel.h9
-rw-r--r--src/php/ext/grpc/channel_credentials.c17
-rw-r--r--src/php/ext/grpc/channel_credentials.h10
-rw-r--r--src/php/ext/grpc/completion_queue.c2
-rw-r--r--src/php/ext/grpc/php_grpc.c11
-rw-r--r--src/php/ext/grpc/php_grpc.h18
-rw-r--r--src/php/ext/grpc/server.c16
-rw-r--r--src/php/ext/grpc/server.h9
-rw-r--r--src/php/ext/grpc/server_credentials.c13
-rw-r--r--src/php/ext/grpc/server_credentials.h2
-rw-r--r--src/php/ext/grpc/timeval.c14
-rw-r--r--src/php/ext/grpc/timeval.h10
-rw-r--r--src/php/lib/Grpc/BaseStub.php24
-rw-r--r--src/php/lib/Grpc/Interceptor.php4
-rw-r--r--src/php/lib/Grpc/Internal/InterceptorChannel.php6
-rw-r--r--src/php/tests/unit_tests/InterceptorTest.php6
-rw-r--r--src/proto/grpc/lb/v1/load_balancer.proto6
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py2
-rw-r--r--templates/Makefile.template6
-rw-r--r--templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template3
-rw-r--r--test/core/debug/stats_test.cc5
-rw-r--r--test/core/end2end/tests/simple_request.cc2
-rw-r--r--test/core/gprpp/BUILD10
-rw-r--r--test/core/gprpp/fork_test.cc135
-rw-r--r--tools/bazel.rc3
-rwxr-xr-xtools/codegen/core/gen_stats_data.py9
-rw-r--r--tools/dockerfile/test/multilang_jessie_x64/Dockerfile3
-rw-r--r--tools/doxygen/Doxyfile.c++.internal2
-rw-r--r--tools/doxygen/Doxyfile.core.internal4
-rw-r--r--tools/internal_ci/linux/grpc_ubsan_on_foundry.sh4
-rw-r--r--tools/run_tests/generated/sources_and_headers.json21
-rw-r--r--tools/run_tests/generated/tests.json20
-rwxr-xr-xtools/run_tests/helper_scripts/build_python.sh5
-rw-r--r--tools/run_tests/performance/massage_qps_stats.py4
-rw-r--r--tools/run_tests/performance/scenario_result_schema.json20
-rwxr-xr-xtools/run_tests/sanity/core_banned_functions.py51
98 files changed, 1108 insertions, 536 deletions
diff --git a/BUILD b/BUILD
index c35a7d65e1..4c99052e05 100644
--- a/BUILD
+++ b/BUILD
@@ -512,7 +512,6 @@ grpc_cc_library(
"src/core/lib/gpr/env_linux.cc",
"src/core/lib/gpr/env_posix.cc",
"src/core/lib/gpr/env_windows.cc",
- "src/core/lib/gpr/fork.cc",
"src/core/lib/gpr/host_port.cc",
"src/core/lib/gpr/log.cc",
"src/core/lib/gpr/log_android.cc",
@@ -537,6 +536,7 @@ grpc_cc_library(
"src/core/lib/gpr/tmpfile_posix.cc",
"src/core/lib/gpr/tmpfile_windows.cc",
"src/core/lib/gpr/wrap_memcpy.cc",
+ "src/core/lib/gprpp/fork.cc",
"src/core/lib/gprpp/thd_posix.cc",
"src/core/lib/gprpp/thd_windows.cc",
"src/core/lib/profiling/basic_timers.cc",
@@ -545,7 +545,6 @@ grpc_cc_library(
hdrs = [
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
- "src/core/lib/gpr/fork.h",
"src/core/lib/gpr/host_port.h",
"src/core/lib/gpr/mpscq.h",
"src/core/lib/gpr/murmur_hash.h",
@@ -560,6 +559,7 @@ grpc_cc_library(
"src/core/lib/gpr/tmpfile.h",
"src/core/lib/gpr/useful.h",
"src/core/lib/gprpp/abstract.h",
+ "src/core/lib/gprpp/fork.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/memory.h",
"src/core/lib/gprpp/thd.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 93f51e79eb..f53f4e384c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -264,6 +264,9 @@ endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c fling_test)
endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC)
+add_dependencies(buildtests_c fork_test)
+endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c goaway_server_test)
endif()
@@ -760,7 +763,6 @@ add_library(gpr
src/core/lib/gpr/env_linux.cc
src/core/lib/gpr/env_posix.cc
src/core/lib/gpr/env_windows.cc
- src/core/lib/gpr/fork.cc
src/core/lib/gpr/host_port.cc
src/core/lib/gpr/log.cc
src/core/lib/gpr/log_android.cc
@@ -785,6 +787,7 @@ add_library(gpr
src/core/lib/gpr/tmpfile_posix.cc
src/core/lib/gpr/tmpfile_windows.cc
src/core/lib/gpr/wrap_memcpy.cc
+ src/core/lib/gprpp/fork.cc
src/core/lib/gprpp/thd_posix.cc
src/core/lib/gprpp/thd_windows.cc
src/core/lib/profiling/basic_timers.cc
@@ -6415,6 +6418,34 @@ target_link_libraries(fling_test
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC)
+
+add_executable(fork_test
+ test/core/gprpp/fork_test.cc
+)
+
+
+target_include_directories(fork_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}
+)
+
+target_link_libraries(fork_test
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ gpr_test_util
+ gpr
+)
+
+endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(goaway_server_test
diff --git a/Makefile b/Makefile
index ba765f0af6..d1f71d765b 100644
--- a/Makefile
+++ b/Makefile
@@ -993,6 +993,7 @@ fling_client: $(BINDIR)/$(CONFIG)/fling_client
fling_server: $(BINDIR)/$(CONFIG)/fling_server
fling_stream_test: $(BINDIR)/$(CONFIG)/fling_stream_test
fling_test: $(BINDIR)/$(CONFIG)/fling_test
+fork_test: $(BINDIR)/$(CONFIG)/fork_test
goaway_server_test: $(BINDIR)/$(CONFIG)/goaway_server_test
gpr_cpu_test: $(BINDIR)/$(CONFIG)/gpr_cpu_test
gpr_env_test: $(BINDIR)/$(CONFIG)/gpr_env_test
@@ -1435,6 +1436,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/fling_server \
$(BINDIR)/$(CONFIG)/fling_stream_test \
$(BINDIR)/$(CONFIG)/fling_test \
+ $(BINDIR)/$(CONFIG)/fork_test \
$(BINDIR)/$(CONFIG)/goaway_server_test \
$(BINDIR)/$(CONFIG)/gpr_cpu_test \
$(BINDIR)/$(CONFIG)/gpr_env_test \
@@ -1954,6 +1956,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/fling_stream_test || ( echo test fling_stream_test failed ; exit 1 )
$(E) "[RUN] Testing fling_test"
$(Q) $(BINDIR)/$(CONFIG)/fling_test || ( echo test fling_test failed ; exit 1 )
+ $(E) "[RUN] Testing fork_test"
+ $(Q) $(BINDIR)/$(CONFIG)/fork_test || ( echo test fork_test failed ; exit 1 )
$(E) "[RUN] Testing goaway_server_test"
$(Q) $(BINDIR)/$(CONFIG)/goaway_server_test || ( echo test goaway_server_test failed ; exit 1 )
$(E) "[RUN] Testing gpr_cpu_test"
@@ -3091,7 +3095,7 @@ PUBLIC_HEADERS_C += \
LIBADDRESS_SORTING_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBADDRESS_SORTING_SRC))))
-$(LIBDIR)/$(CONFIG)/libaddress_sorting.a: $(ZLIB_DEP) $(CARES_DEP) $(LIBADDRESS_SORTING_OBJS)
+$(LIBDIR)/$(CONFIG)/libaddress_sorting.a: $(LIBADDRESS_SORTING_OBJS)
$(E) "[AR] Creating $@"
$(Q) mkdir -p `dirname $@`
$(Q) rm -f $(LIBDIR)/$(CONFIG)/libaddress_sorting.a
@@ -3176,7 +3180,6 @@ LIBGPR_SRC = \
src/core/lib/gpr/env_linux.cc \
src/core/lib/gpr/env_posix.cc \
src/core/lib/gpr/env_windows.cc \
- src/core/lib/gpr/fork.cc \
src/core/lib/gpr/host_port.cc \
src/core/lib/gpr/log.cc \
src/core/lib/gpr/log_android.cc \
@@ -3201,6 +3204,7 @@ LIBGPR_SRC = \
src/core/lib/gpr/tmpfile_posix.cc \
src/core/lib/gpr/tmpfile_windows.cc \
src/core/lib/gpr/wrap_memcpy.cc \
+ src/core/lib/gprpp/fork.cc \
src/core/lib/gprpp/thd_posix.cc \
src/core/lib/gprpp/thd_windows.cc \
src/core/lib/profiling/basic_timers.cc \
@@ -9745,7 +9749,7 @@ LIBZ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBZ_
$(LIBZ_OBJS): CFLAGS += -Wno-sign-conversion -Wno-conversion -Wno-unused-value -Wno-implicit-function-declaration -Wno-implicit-fallthrough $(W_NO_SHIFT_NEGATIVE_VALUE) -fvisibility=hidden
-$(LIBDIR)/$(CONFIG)/libz.a: $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(LIBZ_OBJS)
+$(LIBDIR)/$(CONFIG)/libz.a: $(LIBZ_OBJS)
$(E) "[AR] Creating $@"
$(Q) mkdir -p `dirname $@`
$(Q) rm -f $(LIBDIR)/$(CONFIG)/libz.a
@@ -9820,7 +9824,7 @@ LIBARES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LI
$(LIBARES_OBJS): CPPFLAGS += -Ithird_party/cares -Ithird_party/cares/cares -fvisibility=hidden -D_GNU_SOURCE $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) $(if $(subst FreeBSD,,$(SYSTEM)),,-Ithird_party/cares/config_freebsd) $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) $(if $(subst OpenBSD,,$(SYSTEM)),,-Ithird_party/cares/config_openbsd) -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,)
$(LIBARES_OBJS): CFLAGS += -Wno-sign-conversion $(if $(subst Darwin,,$(SYSTEM)),,-Wno-shorten-64-to-32) $(if $(subst MINGW32,,$(SYSTEM)),-Wno-invalid-source-encoding,)
-$(LIBDIR)/$(CONFIG)/libares.a: $(ZLIB_DEP) $(ADDRESS_SORTING_DEP) $(LIBARES_OBJS)
+$(LIBDIR)/$(CONFIG)/libares.a: $(LIBARES_OBJS)
$(E) "[AR] Creating $@"
$(Q) mkdir -p `dirname $@`
$(Q) rm -f $(LIBDIR)/$(CONFIG)/libares.a
@@ -11293,6 +11297,38 @@ endif
endif
+FORK_TEST_SRC = \
+ test/core/gprpp/fork_test.cc \
+
+FORK_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(FORK_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/fork_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/fork_test: $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LD) $(LDFLAGS) $(FORK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fork_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/gprpp/fork_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_fork_test: $(FORK_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(FORK_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
GOAWAY_SERVER_TEST_SRC = \
test/core/end2end/goaway_server_test.cc \
diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl
index 1e3d83d06a..53073941f3 100644
--- a/bazel/grpc_deps.bzl
+++ b/bazel/grpc_deps.bzl
@@ -130,12 +130,12 @@ def grpc_deps():
if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules():
native.http_archive(
name = "com_github_bazelbuild_bazeltoolchains",
- strip_prefix = "bazel-toolchains-44200e0c026d86c53470d107b3697a3e46469c43",
+ strip_prefix = "bazel-toolchains-09c850dbb8e785ded3d23a7003e9a0168fe1fb2f",
urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/44200e0c026d86c53470d107b3697a3e46469c43.tar.gz",
- "https://github.com/bazelbuild/bazel-toolchains/archive/44200e0c026d86c53470d107b3697a3e46469c43.tar.gz",
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/09c850dbb8e785ded3d23a7003e9a0168fe1fb2f.tar.gz",
+ "https://github.com/bazelbuild/bazel-toolchains/archive/09c850dbb8e785ded3d23a7003e9a0168fe1fb2f.tar.gz",
],
- sha256 = "699b55a6916c687f4b7dc092dbbf5f64672cde0dc965f79717735ec4e5416556",
+ sha256 = "08e521cf2d0998e3d27a16c2e2542ebf4d3857b3ddadcfd145d128140754d7bd",
)
# TODO: move some dependencies from "grpc_deps" here?
diff --git a/build.yaml b/build.yaml
index 1bc2adbb8c..f4812aa538 100644
--- a/build.yaml
+++ b/build.yaml
@@ -123,7 +123,6 @@ filegroups:
- src/core/lib/gpr/env_linux.cc
- src/core/lib/gpr/env_posix.cc
- src/core/lib/gpr/env_windows.cc
- - src/core/lib/gpr/fork.cc
- src/core/lib/gpr/host_port.cc
- src/core/lib/gpr/log.cc
- src/core/lib/gpr/log_android.cc
@@ -148,6 +147,7 @@ filegroups:
- src/core/lib/gpr/tmpfile_posix.cc
- src/core/lib/gpr/tmpfile_windows.cc
- src/core/lib/gpr/wrap_memcpy.cc
+ - src/core/lib/gprpp/fork.cc
- src/core/lib/gprpp/thd_posix.cc
- src/core/lib/gprpp/thd_windows.cc
- src/core/lib/profiling/basic_timers.cc
@@ -176,7 +176,6 @@ filegroups:
headers:
- src/core/lib/gpr/arena.h
- src/core/lib/gpr/env.h
- - src/core/lib/gpr/fork.h
- src/core/lib/gpr/host_port.h
- src/core/lib/gpr/mpscq.h
- src/core/lib/gpr/murmur_hash.h
@@ -194,6 +193,7 @@ filegroups:
- src/core/lib/gprpp/atomic.h
- src/core/lib/gprpp/atomic_with_atm.h
- src/core/lib/gprpp/atomic_with_std.h
+ - src/core/lib/gprpp/fork.h
- src/core/lib/gprpp/manual_constructor.h
- src/core/lib/gprpp/memory.h
- src/core/lib/gprpp/thd.h
@@ -2387,6 +2387,18 @@ targets:
- mac
- linux
- posix
+- name: fork_test
+ build: test
+ language: c
+ src:
+ - test/core/gprpp/fork_test.cc
+ deps:
+ - gpr_test_util
+ - gpr
+ platforms:
+ - mac
+ - linux
+ uses_polling: false
- name: goaway_server_test
cpu_cost: 0.1
build: test
diff --git a/config.m4 b/config.m4
index ee2aca4fa5..3acc72eaa1 100644
--- a/config.m4
+++ b/config.m4
@@ -53,7 +53,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/gpr/env_linux.cc \
src/core/lib/gpr/env_posix.cc \
src/core/lib/gpr/env_windows.cc \
- src/core/lib/gpr/fork.cc \
src/core/lib/gpr/host_port.cc \
src/core/lib/gpr/log.cc \
src/core/lib/gpr/log_android.cc \
@@ -78,6 +77,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/gpr/tmpfile_posix.cc \
src/core/lib/gpr/tmpfile_windows.cc \
src/core/lib/gpr/wrap_memcpy.cc \
+ src/core/lib/gprpp/fork.cc \
src/core/lib/gprpp/thd_posix.cc \
src/core/lib/gprpp/thd_windows.cc \
src/core/lib/profiling/basic_timers.cc \
diff --git a/config.w32 b/config.w32
index abca8e22f2..d1a595026f 100644
--- a/config.w32
+++ b/config.w32
@@ -29,7 +29,6 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\gpr\\env_linux.cc " +
"src\\core\\lib\\gpr\\env_posix.cc " +
"src\\core\\lib\\gpr\\env_windows.cc " +
- "src\\core\\lib\\gpr\\fork.cc " +
"src\\core\\lib\\gpr\\host_port.cc " +
"src\\core\\lib\\gpr\\log.cc " +
"src\\core\\lib\\gpr\\log_android.cc " +
@@ -54,6 +53,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\gpr\\tmpfile_posix.cc " +
"src\\core\\lib\\gpr\\tmpfile_windows.cc " +
"src\\core\\lib\\gpr\\wrap_memcpy.cc " +
+ "src\\core\\lib\\gprpp\\fork.cc " +
"src\\core\\lib\\gprpp\\thd_posix.cc " +
"src\\core\\lib\\gprpp\\thd_windows.cc " +
"src\\core\\lib\\profiling\\basic_timers.cc " +
diff --git a/doc/environment_variables.md b/doc/environment_variables.md
index 6911e22c4a..15752ae865 100644
--- a/doc/environment_variables.md
+++ b/doc/environment_variables.md
@@ -47,7 +47,6 @@ some configuration as environment variables that can be set.
- combiner - traces combiner lock state
- compression - traces compression operations
- connectivity_state - traces connectivity state changes to channels
- - channel_stack_builder - traces information about channel stacks being built
- executor - traces grpc's internal thread pool ('the executor')
- fd_trace - traces fd create(), shutdown() and close() calls for channel fds.
Also traces epoll fd create()/close() calls in epollex polling engine
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index 29b79e0b01..0b15bb8532 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -214,7 +214,6 @@ Pod::Spec.new do |s|
'src/cpp/codegen/codegen_init.cc',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
- 'src/core/lib/gpr/fork.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
'src/core/lib/gpr/murmur_hash.h',
@@ -232,6 +231,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/atomic_with_atm.h',
'src/core/lib/gprpp/atomic_with_std.h',
+ 'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/memory.h',
'src/core/lib/gprpp/thd.h',
@@ -504,7 +504,6 @@ Pod::Spec.new do |s|
'src/cpp/thread_manager/thread_manager.h',
'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
- 'src/core/lib/gpr/fork.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
'src/core/lib/gpr/murmur_hash.h',
@@ -522,6 +521,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/atomic_with_atm.h',
'src/core/lib/gprpp/atomic_with_std.h',
+ 'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/memory.h',
'src/core/lib/gprpp/thd.h',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index ce6ff76806..89cc95fccd 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -185,7 +185,6 @@ Pod::Spec.new do |s|
# To save you from scrolling, this is the last part of the podspec.
ss.source_files = 'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
- 'src/core/lib/gpr/fork.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
'src/core/lib/gpr/murmur_hash.h',
@@ -203,6 +202,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/atomic_with_atm.h',
'src/core/lib/gprpp/atomic_with_std.h',
+ 'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/memory.h',
'src/core/lib/gprpp/thd.h',
@@ -217,7 +217,6 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/env_linux.cc',
'src/core/lib/gpr/env_posix.cc',
'src/core/lib/gpr/env_windows.cc',
- 'src/core/lib/gpr/fork.cc',
'src/core/lib/gpr/host_port.cc',
'src/core/lib/gpr/log.cc',
'src/core/lib/gpr/log_android.cc',
@@ -242,6 +241,7 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/tmpfile_posix.cc',
'src/core/lib/gpr/tmpfile_windows.cc',
'src/core/lib/gpr/wrap_memcpy.cc',
+ 'src/core/lib/gprpp/fork.cc',
'src/core/lib/gprpp/thd_posix.cc',
'src/core/lib/gprpp/thd_windows.cc',
'src/core/lib/profiling/basic_timers.cc',
@@ -802,7 +802,6 @@ Pod::Spec.new do |s|
ss.private_header_files = 'src/core/lib/gpr/arena.h',
'src/core/lib/gpr/env.h',
- 'src/core/lib/gpr/fork.h',
'src/core/lib/gpr/host_port.h',
'src/core/lib/gpr/mpscq.h',
'src/core/lib/gpr/murmur_hash.h',
@@ -820,6 +819,7 @@ Pod::Spec.new do |s|
'src/core/lib/gprpp/atomic.h',
'src/core/lib/gprpp/atomic_with_atm.h',
'src/core/lib/gprpp/atomic_with_std.h',
+ 'src/core/lib/gprpp/fork.h',
'src/core/lib/gprpp/manual_constructor.h',
'src/core/lib/gprpp/memory.h',
'src/core/lib/gprpp/thd.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 2a66801e34..80422ac670 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -81,7 +81,6 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/impl/codegen/sync_windows.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/fork.h )
s.files += %w( src/core/lib/gpr/host_port.h )
s.files += %w( src/core/lib/gpr/mpscq.h )
s.files += %w( src/core/lib/gpr/murmur_hash.h )
@@ -99,6 +98,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gprpp/atomic.h )
s.files += %w( src/core/lib/gprpp/atomic_with_atm.h )
s.files += %w( src/core/lib/gprpp/atomic_with_std.h )
+ s.files += %w( src/core/lib/gprpp/fork.h )
s.files += %w( src/core/lib/gprpp/manual_constructor.h )
s.files += %w( src/core/lib/gprpp/memory.h )
s.files += %w( src/core/lib/gprpp/thd.h )
@@ -113,7 +113,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/env_linux.cc )
s.files += %w( src/core/lib/gpr/env_posix.cc )
s.files += %w( src/core/lib/gpr/env_windows.cc )
- s.files += %w( src/core/lib/gpr/fork.cc )
s.files += %w( src/core/lib/gpr/host_port.cc )
s.files += %w( src/core/lib/gpr/log.cc )
s.files += %w( src/core/lib/gpr/log_android.cc )
@@ -138,6 +137,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/tmpfile_posix.cc )
s.files += %w( src/core/lib/gpr/tmpfile_windows.cc )
s.files += %w( src/core/lib/gpr/wrap_memcpy.cc )
+ s.files += %w( src/core/lib/gprpp/fork.cc )
s.files += %w( src/core/lib/gprpp/thd_posix.cc )
s.files += %w( src/core/lib/gprpp/thd_windows.cc )
s.files += %w( src/core/lib/profiling/basic_timers.cc )
diff --git a/grpc.gyp b/grpc.gyp
index 5726719521..0d03a66b75 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -194,7 +194,6 @@
'src/core/lib/gpr/env_linux.cc',
'src/core/lib/gpr/env_posix.cc',
'src/core/lib/gpr/env_windows.cc',
- 'src/core/lib/gpr/fork.cc',
'src/core/lib/gpr/host_port.cc',
'src/core/lib/gpr/log.cc',
'src/core/lib/gpr/log_android.cc',
@@ -219,6 +218,7 @@
'src/core/lib/gpr/tmpfile_posix.cc',
'src/core/lib/gpr/tmpfile_windows.cc',
'src/core/lib/gpr/wrap_memcpy.cc',
+ 'src/core/lib/gprpp/fork.cc',
'src/core/lib/gprpp/thd_posix.cc',
'src/core/lib/gprpp/thd_windows.cc',
'src/core/lib/profiling/basic_timers.cc',
diff --git a/package.xml b/package.xml
index ac9b520fb7..4e8d514883 100644
--- a/package.xml
+++ b/package.xml
@@ -88,7 +88,6 @@
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.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/fork.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/host_port.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/mpscq.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/murmur_hash.h" role="src" />
@@ -106,6 +105,7 @@
<file baseinstalldir="/" name="src/core/lib/gprpp/atomic.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/atomic_with_atm.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/atomic_with_std.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/fork.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/manual_constructor.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/memory.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/thd.h" role="src" />
@@ -120,7 +120,6 @@
<file baseinstalldir="/" name="src/core/lib/gpr/env_linux.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/env_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/env_windows.cc" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr/fork.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/host_port.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/log.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/log_android.cc" role="src" />
@@ -145,6 +144,7 @@
<file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/tmpfile_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/wrap_memcpy.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gprpp/fork.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/thd_posix.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/gprpp/thd_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/basic_timers.cc" role="src" />
diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc
index 3813190794..fa0c280f80 100644
--- a/src/core/ext/filters/client_channel/client_channel.cc
+++ b/src/core/ext/filters/client_channel/client_channel.cc
@@ -3242,7 +3242,7 @@ static void on_external_watch_complete_locked(void* arg, grpc_error* error) {
"external_connectivity_watcher");
external_connectivity_watcher_list_remove(w->chand, w);
gpr_free(w);
- GRPC_CLOSURE_RUN(follow_up, GRPC_ERROR_REF(error));
+ GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error));
}
static void watch_connectivity_state_locked(void* arg,
diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h
index 454e00a690..dab4466b21 100644
--- a/src/core/ext/filters/client_channel/lb_policy.h
+++ b/src/core/ext/filters/client_channel/lb_policy.h
@@ -162,9 +162,7 @@ class LoadBalancingPolicy
GRPC_ABSTRACT_BASE_CLASS
protected:
- // So Delete() can access our protected dtor.
- template <typename T>
- friend void Delete(T*);
+ GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
explicit LoadBalancingPolicy(const Args& args);
virtual ~LoadBalancingPolicy();
diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h
index 02380314dd..c7e37e4468 100644
--- a/src/core/ext/filters/client_channel/resolver.h
+++ b/src/core/ext/filters/client_channel/resolver.h
@@ -105,9 +105,7 @@ class Resolver : public InternallyRefCountedWithTracing<Resolver> {
GRPC_ABSTRACT_BASE_CLASS
protected:
- // So Delete() can access our protected dtor.
- template <typename T>
- friend void Delete(T*);
+ GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
/// Does NOT take ownership of the reference to \a combiner.
// TODO(roth): Once we have a C++-like interface for combiners, this
diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc
index 140441da10..ad6b6dd192 100644
--- a/src/core/ext/filters/client_channel/subchannel.cc
+++ b/src/core/ext/filters/client_channel/subchannel.cc
@@ -408,7 +408,7 @@ static void on_external_state_watcher_done(void* arg, grpc_error* error) {
gpr_mu_unlock(&w->subchannel->mu);
GRPC_SUBCHANNEL_WEAK_UNREF(w->subchannel, "external_state_watcher");
gpr_free(w);
- GRPC_CLOSURE_RUN(follow_up, GRPC_ERROR_REF(error));
+ GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error));
}
static void on_alarm(void* arg, grpc_error* error) {
diff --git a/src/core/ext/filters/http/client_authority_filter.cc b/src/core/ext/filters/http/client_authority_filter.cc
index 1f57ab5ce6..63b9150aec 100644
--- a/src/core/ext/filters/http/client_authority_filter.cc
+++ b/src/core/ext/filters/http/client_authority_filter.cc
@@ -59,8 +59,9 @@ void authority_start_transport_stream_op_batch(
initial_metadata->idx.named.authority == nullptr) {
grpc_error* error = grpc_metadata_batch_add_head(
initial_metadata, &calld->authority_storage,
- grpc_mdelem_from_slices(GRPC_MDSTR_AUTHORITY,
- grpc_slice_ref(chand->default_authority)));
+ grpc_mdelem_from_slices(
+ GRPC_MDSTR_AUTHORITY,
+ grpc_slice_ref_internal(chand->default_authority)));
if (error != GRPC_ERROR_NONE) {
grpc_transport_stream_op_batch_finish_with_failure(batch, error,
calld->call_combiner);
@@ -110,7 +111,7 @@ grpc_error* init_channel_elem(grpc_channel_element* elem,
/* Destructor for channel data */
void destroy_channel_elem(grpc_channel_element* elem) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
- grpc_slice_unref(chand->default_authority);
+ grpc_slice_unref_internal(chand->default_authority);
}
} // namespace
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index 7ff7cabfbd..cc4a823798 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -1684,16 +1684,16 @@ static void send_ping_locked(grpc_chttp2_transport* t,
*/
static void send_keepalive_ping_locked(grpc_chttp2_transport* t) {
if (t->closed_with_error != GRPC_ERROR_NONE) {
- GRPC_CLOSURE_SCHED(&t->start_keepalive_ping_locked,
- GRPC_ERROR_REF(t->closed_with_error));
- GRPC_CLOSURE_SCHED(&t->finish_keepalive_ping_locked,
- GRPC_ERROR_REF(t->closed_with_error));
+ GRPC_CLOSURE_RUN(&t->start_keepalive_ping_locked,
+ GRPC_ERROR_REF(t->closed_with_error));
+ GRPC_CLOSURE_RUN(&t->finish_keepalive_ping_locked,
+ GRPC_ERROR_REF(t->closed_with_error));
return;
}
grpc_chttp2_ping_queue* pq = &t->ping_queue;
if (!grpc_closure_list_empty(pq->lists[GRPC_CHTTP2_PCL_INFLIGHT])) {
/* There is a ping in flight. Add yourself to the inflight closure list. */
- GRPC_CLOSURE_SCHED(&t->start_keepalive_ping_locked, GRPC_ERROR_NONE);
+ GRPC_CLOSURE_RUN(&t->start_keepalive_ping_locked, GRPC_ERROR_NONE);
grpc_closure_list_append(&pq->lists[GRPC_CHTTP2_PCL_INFLIGHT],
&t->finish_keepalive_ping_locked, GRPC_ERROR_NONE);
return;
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc
index 0b88ff7afe..420c2d13e1 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.cc
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc
@@ -736,7 +736,7 @@ static void convert_metadata_to_cronet_headers(
if (grpc_is_binary_header(GRPC_MDKEY(mdelem))) {
grpc_slice wire_value = grpc_chttp2_base64_encode(GRPC_MDVALUE(mdelem));
value = grpc_slice_to_c_string(wire_value);
- grpc_slice_unref(wire_value);
+ grpc_slice_unref_internal(wire_value);
} else {
value = grpc_slice_to_c_string(GRPC_MDVALUE(mdelem));
}
diff --git a/src/core/lib/channel/channel_stack.cc b/src/core/lib/channel/channel_stack.cc
index a9459b150d..ef6482cb7f 100644
--- a/src/core/lib/channel/channel_stack.cc
+++ b/src/core/lib/channel/channel_stack.cc
@@ -193,18 +193,13 @@ void grpc_call_stack_set_pollset_or_pollset_set(grpc_call_stack* call_stack,
grpc_polling_entity* pollent) {
size_t count = call_stack->count;
grpc_call_element* call_elems;
- char* user_data;
size_t i;
call_elems = CALL_ELEMS_FROM_STACK(call_stack);
- user_data = (reinterpret_cast<char*>(call_elems)) +
- ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element));
/* init per-filter data */
for (i = 0; i < count; i++) {
call_elems[i].filter->set_pollset_or_pollset_set(&call_elems[i], pollent);
- user_data +=
- ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data);
}
}
diff --git a/src/core/lib/channel/channel_stack_builder.cc b/src/core/lib/channel/channel_stack_builder.cc
index 8a72449034..df5a783631 100644
--- a/src/core/lib/channel/channel_stack_builder.cc
+++ b/src/core/lib/channel/channel_stack_builder.cc
@@ -25,9 +25,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
-grpc_core::TraceFlag grpc_trace_channel_stack_builder(false,
- "channel_stack_builder");
-
typedef struct filter_node {
struct filter_node* next;
struct filter_node* prev;
diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h
index c9a170bc88..9196de9378 100644
--- a/src/core/lib/channel/channel_stack_builder.h
+++ b/src/core/lib/channel/channel_stack_builder.h
@@ -155,6 +155,4 @@ grpc_error* grpc_channel_stack_builder_finish(
/// Destroy the builder without creating a channel stack
void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder* builder);
-extern grpc_core::TraceFlag grpc_trace_channel_stack_builder;
-
#endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H */
diff --git a/src/core/lib/debug/stats.h b/src/core/lib/debug/stats.h
index 749665262a..9e88ad7000 100644
--- a/src/core/lib/debug/stats.h
+++ b/src/core/lib/debug/stats.h
@@ -35,6 +35,9 @@ extern grpc_stats_data* grpc_stats_per_cpu_storage;
#define GRPC_THREAD_STATS_DATA() \
(&grpc_stats_per_cpu_storage[grpc_core::ExecCtx::Get()->starting_cpu()])
+/* Only collect stats if GRPC_COLLECT_STATS is defined or it is a debug build.
+ */
+#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG)
#define GRPC_STATS_INC_COUNTER(ctr) \
(gpr_atm_no_barrier_fetch_add(&GRPC_THREAD_STATS_DATA()->counters[(ctr)], 1))
@@ -42,6 +45,10 @@ extern grpc_stats_data* grpc_stats_per_cpu_storage;
(gpr_atm_no_barrier_fetch_add( \
&GRPC_THREAD_STATS_DATA()->histograms[histogram##_FIRST_SLOT + (index)], \
1))
+#else /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */
+#define GRPC_STATS_INC_COUNTER(ctr)
+#define GRPC_STATS_INC_HISTOGRAM(histogram, index)
+#endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */
void grpc_stats_init(void);
void grpc_stats_shutdown(void);
diff --git a/src/core/lib/debug/stats_data.cc b/src/core/lib/debug/stats_data.cc
index 309ece94bb..f8c27db0a8 100644
--- a/src/core/lib/debug/stats_data.cc
+++ b/src/core/lib/debug/stats_data.cc
@@ -40,6 +40,8 @@ const char* grpc_stats_counter_name[GRPC_STATS_COUNTER_COUNT] = {
"pollset_kick_wakeup_fd",
"pollset_kick_wakeup_cv",
"pollset_kick_own_thread",
+ "syscall_epoll_ctl",
+ "pollset_fd_cache_hits",
"histogram_slow_lookups",
"syscall_write",
"syscall_read",
@@ -144,6 +146,9 @@ const char* grpc_stats_counter_doc[GRPC_STATS_COUNTER_COUNT] = {
"polling wakeup (only valid for epoll1 right now)",
"How many times could a polling wakeup be satisfied by keeping the waking "
"thread awake? (only valid for epoll1 right now)",
+ "Number of epoll_ctl calls made (only valid for epollex right now)",
+ "Number of epoll_ctl calls skipped because the fd was cached as already "
+ "being added. (only valid for epollex right now)",
"Number of times histogram increments went through the slow (binary "
"search) path",
"Number of write syscalls (or equivalent - eg sendmsg) made by this "
diff --git a/src/core/lib/debug/stats_data.h b/src/core/lib/debug/stats_data.h
index da1266ad73..1f3861f494 100644
--- a/src/core/lib/debug/stats_data.h
+++ b/src/core/lib/debug/stats_data.h
@@ -41,6 +41,8 @@ typedef enum {
GRPC_STATS_COUNTER_POLLSET_KICK_WAKEUP_FD,
GRPC_STATS_COUNTER_POLLSET_KICK_WAKEUP_CV,
GRPC_STATS_COUNTER_POLLSET_KICK_OWN_THREAD,
+ GRPC_STATS_COUNTER_SYSCALL_EPOLL_CTL,
+ GRPC_STATS_COUNTER_POLLSET_FD_CACHE_HITS,
GRPC_STATS_COUNTER_HISTOGRAM_SLOW_LOOKUPS,
GRPC_STATS_COUNTER_SYSCALL_WRITE,
GRPC_STATS_COUNTER_SYSCALL_READ,
@@ -174,6 +176,7 @@ typedef enum {
GRPC_STATS_HISTOGRAM_SERVER_CQS_CHECKED_BUCKETS = 8,
GRPC_STATS_HISTOGRAM_BUCKETS = 840
} grpc_stats_histogram_constants;
+#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG)
#define GRPC_STATS_INC_CLIENT_CALLS_CREATED() \
GRPC_STATS_INC_COUNTER(GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED)
#define GRPC_STATS_INC_SERVER_CALLS_CREATED() \
@@ -202,6 +205,10 @@ typedef enum {
GRPC_STATS_INC_COUNTER(GRPC_STATS_COUNTER_POLLSET_KICK_WAKEUP_CV)
#define GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD() \
GRPC_STATS_INC_COUNTER(GRPC_STATS_COUNTER_POLLSET_KICK_OWN_THREAD)
+#define GRPC_STATS_INC_SYSCALL_EPOLL_CTL() \
+ GRPC_STATS_INC_COUNTER(GRPC_STATS_COUNTER_SYSCALL_EPOLL_CTL)
+#define GRPC_STATS_INC_POLLSET_FD_CACHE_HITS() \
+ GRPC_STATS_INC_COUNTER(GRPC_STATS_COUNTER_POLLSET_FD_CACHE_HITS)
#define GRPC_STATS_INC_HISTOGRAM_SLOW_LOOKUPS() \
GRPC_STATS_INC_COUNTER(GRPC_STATS_COUNTER_HISTOGRAM_SLOW_LOOKUPS)
#define GRPC_STATS_INC_SYSCALL_WRITE() \
@@ -427,6 +434,119 @@ void grpc_stats_inc_http2_send_flowctl_per_write(int x);
#define GRPC_STATS_INC_SERVER_CQS_CHECKED(value) \
grpc_stats_inc_server_cqs_checked((int)(value))
void grpc_stats_inc_server_cqs_checked(int x);
+#else
+#define GRPC_STATS_INC_CLIENT_CALLS_CREATED()
+#define GRPC_STATS_INC_SERVER_CALLS_CREATED()
+#define GRPC_STATS_INC_CQS_CREATED()
+#define GRPC_STATS_INC_CLIENT_CHANNELS_CREATED()
+#define GRPC_STATS_INC_CLIENT_SUBCHANNELS_CREATED()
+#define GRPC_STATS_INC_SERVER_CHANNELS_CREATED()
+#define GRPC_STATS_INC_SYSCALL_POLL()
+#define GRPC_STATS_INC_SYSCALL_WAIT()
+#define GRPC_STATS_INC_POLLSET_KICK()
+#define GRPC_STATS_INC_POLLSET_KICKED_WITHOUT_POLLER()
+#define GRPC_STATS_INC_POLLSET_KICKED_AGAIN()
+#define GRPC_STATS_INC_POLLSET_KICK_WAKEUP_FD()
+#define GRPC_STATS_INC_POLLSET_KICK_WAKEUP_CV()
+#define GRPC_STATS_INC_POLLSET_KICK_OWN_THREAD()
+#define GRPC_STATS_INC_SYSCALL_EPOLL_CTL()
+#define GRPC_STATS_INC_POLLSET_FD_CACHE_HITS()
+#define GRPC_STATS_INC_HISTOGRAM_SLOW_LOOKUPS()
+#define GRPC_STATS_INC_SYSCALL_WRITE()
+#define GRPC_STATS_INC_SYSCALL_READ()
+#define GRPC_STATS_INC_TCP_BACKUP_POLLERS_CREATED()
+#define GRPC_STATS_INC_TCP_BACKUP_POLLER_POLLS()
+#define GRPC_STATS_INC_HTTP2_OP_BATCHES()
+#define GRPC_STATS_INC_HTTP2_OP_CANCEL()
+#define GRPC_STATS_INC_HTTP2_OP_SEND_INITIAL_METADATA()
+#define GRPC_STATS_INC_HTTP2_OP_SEND_MESSAGE()
+#define GRPC_STATS_INC_HTTP2_OP_SEND_TRAILING_METADATA()
+#define GRPC_STATS_INC_HTTP2_OP_RECV_INITIAL_METADATA()
+#define GRPC_STATS_INC_HTTP2_OP_RECV_MESSAGE()
+#define GRPC_STATS_INC_HTTP2_OP_RECV_TRAILING_METADATA()
+#define GRPC_STATS_INC_HTTP2_SETTINGS_WRITES()
+#define GRPC_STATS_INC_HTTP2_PINGS_SENT()
+#define GRPC_STATS_INC_HTTP2_WRITES_BEGUN()
+#define GRPC_STATS_INC_HTTP2_WRITES_OFFLOADED()
+#define GRPC_STATS_INC_HTTP2_WRITES_CONTINUED()
+#define GRPC_STATS_INC_HTTP2_PARTIAL_WRITES()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_INITIAL_WRITE()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_START_NEW_STREAM()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_SEND_MESSAGE()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_SEND_INITIAL_METADATA()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_SEND_TRAILING_METADATA()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_RETRY_SEND_PING()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_CONTINUE_PINGS()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_GOAWAY_SENT()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_RST_STREAM()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_CLOSE_FROM_API()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_STREAM_FLOW_CONTROL()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_TRANSPORT_FLOW_CONTROL()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_SEND_SETTINGS()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_BDP_ESTIMATOR_PING()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_FLOW_CONTROL_UNSTALLED_BY_SETTING()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_FLOW_CONTROL_UNSTALLED_BY_UPDATE()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_APPLICATION_PING()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_KEEPALIVE_PING()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_TRANSPORT_FLOW_CONTROL_UNSTALLED()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_PING_RESPONSE()
+#define GRPC_STATS_INC_HTTP2_INITIATE_WRITE_DUE_TO_FORCE_RST_STREAM()
+#define GRPC_STATS_INC_HTTP2_SPURIOUS_WRITES_BEGUN()
+#define GRPC_STATS_INC_HPACK_RECV_INDEXED()
+#define GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX()
+#define GRPC_STATS_INC_HPACK_RECV_LITHDR_INCIDX_V()
+#define GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX()
+#define GRPC_STATS_INC_HPACK_RECV_LITHDR_NOTIDX_V()
+#define GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX()
+#define GRPC_STATS_INC_HPACK_RECV_LITHDR_NVRIDX_V()
+#define GRPC_STATS_INC_HPACK_RECV_UNCOMPRESSED()
+#define GRPC_STATS_INC_HPACK_RECV_HUFFMAN()
+#define GRPC_STATS_INC_HPACK_RECV_BINARY()
+#define GRPC_STATS_INC_HPACK_RECV_BINARY_BASE64()
+#define GRPC_STATS_INC_HPACK_SEND_INDEXED()
+#define GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX()
+#define GRPC_STATS_INC_HPACK_SEND_LITHDR_INCIDX_V()
+#define GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX()
+#define GRPC_STATS_INC_HPACK_SEND_LITHDR_NOTIDX_V()
+#define GRPC_STATS_INC_HPACK_SEND_LITHDR_NVRIDX()
+#define GRPC_STATS_INC_HPACK_SEND_LITHDR_NVRIDX_V()
+#define GRPC_STATS_INC_HPACK_SEND_UNCOMPRESSED()
+#define GRPC_STATS_INC_HPACK_SEND_HUFFMAN()
+#define GRPC_STATS_INC_HPACK_SEND_BINARY()
+#define GRPC_STATS_INC_HPACK_SEND_BINARY_BASE64()
+#define GRPC_STATS_INC_COMBINER_LOCKS_INITIATED()
+#define GRPC_STATS_INC_COMBINER_LOCKS_SCHEDULED_ITEMS()
+#define GRPC_STATS_INC_COMBINER_LOCKS_SCHEDULED_FINAL_ITEMS()
+#define GRPC_STATS_INC_COMBINER_LOCKS_OFFLOADED()
+#define GRPC_STATS_INC_CALL_COMBINER_LOCKS_INITIATED()
+#define GRPC_STATS_INC_CALL_COMBINER_LOCKS_SCHEDULED_ITEMS()
+#define GRPC_STATS_INC_CALL_COMBINER_SET_NOTIFY_ON_CANCEL()
+#define GRPC_STATS_INC_CALL_COMBINER_CANCELLED()
+#define GRPC_STATS_INC_EXECUTOR_SCHEDULED_SHORT_ITEMS()
+#define GRPC_STATS_INC_EXECUTOR_SCHEDULED_LONG_ITEMS()
+#define GRPC_STATS_INC_EXECUTOR_SCHEDULED_TO_SELF()
+#define GRPC_STATS_INC_EXECUTOR_WAKEUP_INITIATED()
+#define GRPC_STATS_INC_EXECUTOR_QUEUE_DRAINED()
+#define GRPC_STATS_INC_EXECUTOR_PUSH_RETRIES()
+#define GRPC_STATS_INC_SERVER_REQUESTED_CALLS()
+#define GRPC_STATS_INC_SERVER_SLOWPATH_REQUESTS_QUEUED()
+#define GRPC_STATS_INC_CQ_EV_QUEUE_TRYLOCK_FAILURES()
+#define GRPC_STATS_INC_CQ_EV_QUEUE_TRYLOCK_SUCCESSES()
+#define GRPC_STATS_INC_CQ_EV_QUEUE_TRANSIENT_POP_FAILURES()
+#define GRPC_STATS_INC_CALL_INITIAL_SIZE(value)
+#define GRPC_STATS_INC_POLL_EVENTS_RETURNED(value)
+#define GRPC_STATS_INC_TCP_WRITE_SIZE(value)
+#define GRPC_STATS_INC_TCP_WRITE_IOV_SIZE(value)
+#define GRPC_STATS_INC_TCP_READ_SIZE(value)
+#define GRPC_STATS_INC_TCP_READ_OFFER(value)
+#define GRPC_STATS_INC_TCP_READ_OFFER_IOV_SIZE(value)
+#define GRPC_STATS_INC_HTTP2_SEND_MESSAGE_SIZE(value)
+#define GRPC_STATS_INC_HTTP2_SEND_INITIAL_METADATA_PER_WRITE(value)
+#define GRPC_STATS_INC_HTTP2_SEND_MESSAGE_PER_WRITE(value)
+#define GRPC_STATS_INC_HTTP2_SEND_TRAILING_METADATA_PER_WRITE(value)
+#define GRPC_STATS_INC_HTTP2_SEND_FLOWCTL_PER_WRITE(value)
+#define GRPC_STATS_INC_SERVER_CQS_CHECKED(value)
+#endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */
extern const int grpc_stats_histo_buckets[13];
extern const int grpc_stats_histo_start[13];
extern const int* const grpc_stats_histo_bucket_boundaries[13];
diff --git a/src/core/lib/debug/stats_data.yaml b/src/core/lib/debug/stats_data.yaml
index af4553028e..775b09df74 100644
--- a/src/core/lib/debug/stats_data.yaml
+++ b/src/core/lib/debug/stats_data.yaml
@@ -63,6 +63,12 @@
doc: How many times could a polling wakeup be satisfied by keeping the waking
thread awake?
(only valid for epoll1 right now)
+# polling
+- counter: syscall_epoll_ctl
+ doc: Number of epoll_ctl calls made (only valid for epollex right now)
+- counter: pollset_fd_cache_hits
+ doc: Number of epoll_ctl calls skipped because the fd was cached as
+ already being added. (only valid for epollex right now)
# stats system
- counter: histogram_slow_lookups
doc: Number of times histogram increments went through the slow
diff --git a/src/core/lib/debug/stats_data_bq_schema.sql b/src/core/lib/debug/stats_data_bq_schema.sql
index 04b6d471f6..7d1ab1dae9 100644
--- a/src/core/lib/debug/stats_data_bq_schema.sql
+++ b/src/core/lib/debug/stats_data_bq_schema.sql
@@ -12,6 +12,8 @@ pollset_kicked_again_per_iteration:FLOAT,
pollset_kick_wakeup_fd_per_iteration:FLOAT,
pollset_kick_wakeup_cv_per_iteration:FLOAT,
pollset_kick_own_thread_per_iteration:FLOAT,
+syscall_epoll_ctl_per_iteration:FLOAT,
+pollset_fd_cache_hits_per_iteration:FLOAT,
histogram_slow_lookups_per_iteration:FLOAT,
syscall_write_per_iteration:FLOAT,
syscall_read_per_iteration:FLOAT,
diff --git a/src/core/lib/gpr/fork.cc b/src/core/lib/gpr/fork.cc
deleted file mode 100644
index 812522b058..0000000000
--- a/src/core/lib/gpr/fork.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#include <grpc/support/port_platform.h>
-
-#include "src/core/lib/gpr/fork.h"
-
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-
-#include "src/core/lib/gpr/env.h"
-#include "src/core/lib/gpr/useful.h"
-
-/*
- * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK
- * AROUND VERY SPECIFIC USE CASES.
- */
-
-static int override_fork_support_enabled = -1;
-static int fork_support_enabled;
-
-void grpc_fork_support_init() {
-#ifdef GRPC_ENABLE_FORK_SUPPORT
- fork_support_enabled = 1;
-#else
- fork_support_enabled = 0;
-#endif
- bool env_var_set = false;
- char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT");
- if (env != nullptr) {
- static const char* truthy[] = {"yes", "Yes", "YES", "true",
- "True", "TRUE", "1"};
- static const char* falsey[] = {"no", "No", "NO", "false",
- "False", "FALSE", "0"};
- for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) {
- if (0 == strcmp(env, truthy[i])) {
- fork_support_enabled = 1;
- env_var_set = true;
- break;
- }
- }
- if (!env_var_set) {
- for (size_t i = 0; i < GPR_ARRAY_SIZE(falsey); i++) {
- if (0 == strcmp(env, falsey[i])) {
- fork_support_enabled = 0;
- env_var_set = true;
- break;
- }
- }
- }
- gpr_free(env);
- }
- if (override_fork_support_enabled != -1) {
- fork_support_enabled = override_fork_support_enabled;
- }
-}
-
-int grpc_fork_support_enabled() { return fork_support_enabled; }
-
-void grpc_enable_fork_support(int enable) {
- override_fork_support_enabled = enable;
-}
diff --git a/src/core/lib/gpr/fork.h b/src/core/lib/gpr/fork.h
deleted file mode 100644
index 94c61bb836..0000000000
--- a/src/core/lib/gpr/fork.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *
- * 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.
- *
- */
-
-#ifndef GRPC_CORE_LIB_GPR_FORK_H
-#define GRPC_CORE_LIB_GPR_FORK_H
-
-/*
- * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK
- * AROUND VERY SPECIFIC USE CASES.
- */
-
-void grpc_fork_support_init(void);
-
-int grpc_fork_support_enabled(void);
-
-// Test only: Must be called before grpc_init(), and overrides
-// environment variables/compile flags
-void grpc_enable_fork_support(int enable);
-
-#endif /* GRPC_CORE_LIB_GPR_FORK_H */
diff --git a/src/core/lib/gprpp/fork.cc b/src/core/lib/gprpp/fork.cc
new file mode 100644
index 0000000000..f6d9a87d2c
--- /dev/null
+++ b/src/core/lib/gprpp/fork.cc
@@ -0,0 +1,260 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/gprpp/fork.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/memory.h"
+
+/*
+ * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK
+ * AROUND VERY SPECIFIC USE CASES.
+ */
+
+namespace grpc_core {
+namespace internal {
+// The exec_ctx_count has 2 modes, blocked and unblocked.
+// When unblocked, the count is 2-indexed; exec_ctx_count=2 indicates
+// 0 active ExecCtxs, exex_ctx_count=3 indicates 1 active ExecCtxs...
+
+// When blocked, the exec_ctx_count is 0-indexed. Note that ExecCtx
+// creation can only be blocked if there is exactly 1 outstanding ExecCtx,
+// meaning that BLOCKED and UNBLOCKED counts partition the integers
+#define UNBLOCKED(n) (n + 2)
+#define BLOCKED(n) (n)
+
+class ExecCtxState {
+ public:
+ ExecCtxState() : fork_complete_(true) {
+ gpr_mu_init(&mu_);
+ gpr_cv_init(&cv_);
+ gpr_atm_no_barrier_store(&count_, UNBLOCKED(0));
+ }
+
+ void IncExecCtxCount() {
+ gpr_atm count = gpr_atm_no_barrier_load(&count_);
+ while (true) {
+ if (count <= BLOCKED(1)) {
+ // This only occurs if we are trying to fork. Wait until the fork()
+ // operation completes before allowing new ExecCtxs.
+ gpr_mu_lock(&mu_);
+ if (gpr_atm_no_barrier_load(&count_) <= BLOCKED(1)) {
+ while (!fork_complete_) {
+ gpr_cv_wait(&cv_, &mu_, gpr_inf_future(GPR_CLOCK_REALTIME));
+ }
+ }
+ gpr_mu_unlock(&mu_);
+ } else if (gpr_atm_no_barrier_cas(&count_, count, count + 1)) {
+ break;
+ }
+ count = gpr_atm_no_barrier_load(&count_);
+ }
+ }
+
+ void DecExecCtxCount() { gpr_atm_no_barrier_fetch_add(&count_, -1); }
+
+ bool BlockExecCtx() {
+ // Assumes there is an active ExecCtx when this function is called
+ if (gpr_atm_no_barrier_cas(&count_, UNBLOCKED(1), BLOCKED(1))) {
+ gpr_mu_lock(&mu_);
+ fork_complete_ = false;
+ gpr_mu_unlock(&mu_);
+ return true;
+ }
+ return false;
+ }
+
+ void AllowExecCtx() {
+ gpr_mu_lock(&mu_);
+ gpr_atm_no_barrier_store(&count_, UNBLOCKED(0));
+ fork_complete_ = true;
+ gpr_cv_broadcast(&cv_);
+ gpr_mu_unlock(&mu_);
+ }
+
+ ~ExecCtxState() {
+ gpr_mu_destroy(&mu_);
+ gpr_cv_destroy(&cv_);
+ }
+
+ private:
+ bool fork_complete_;
+ gpr_mu mu_;
+ gpr_cv cv_;
+ gpr_atm count_;
+};
+
+class ThreadState {
+ public:
+ ThreadState() : awaiting_threads_(false), threads_done_(false), count_(0) {
+ gpr_mu_init(&mu_);
+ gpr_cv_init(&cv_);
+ }
+
+ void IncThreadCount() {
+ gpr_mu_lock(&mu_);
+ count_++;
+ gpr_mu_unlock(&mu_);
+ }
+
+ void DecThreadCount() {
+ gpr_mu_lock(&mu_);
+ count_--;
+ if (awaiting_threads_ && count_ == 0) {
+ threads_done_ = true;
+ gpr_cv_signal(&cv_);
+ }
+ gpr_mu_unlock(&mu_);
+ }
+ void AwaitThreads() {
+ gpr_mu_lock(&mu_);
+ awaiting_threads_ = true;
+ threads_done_ = (count_ == 0);
+ while (!threads_done_) {
+ gpr_cv_wait(&cv_, &mu_, gpr_inf_future(GPR_CLOCK_REALTIME));
+ }
+ awaiting_threads_ = true;
+ gpr_mu_unlock(&mu_);
+ }
+
+ ~ThreadState() {
+ gpr_mu_destroy(&mu_);
+ gpr_cv_destroy(&cv_);
+ }
+
+ private:
+ bool awaiting_threads_;
+ bool threads_done_;
+ gpr_mu mu_;
+ gpr_cv cv_;
+ int count_;
+};
+
+} // namespace
+
+void Fork::GlobalInit() {
+ if (!overrideEnabled_) {
+#ifdef GRPC_ENABLE_FORK_SUPPORT
+ supportEnabled_ = true;
+#else
+ supportEnabled_ = false;
+#endif
+ bool env_var_set = false;
+ char* env = gpr_getenv("GRPC_ENABLE_FORK_SUPPORT");
+ if (env != nullptr) {
+ static const char* truthy[] = {"yes", "Yes", "YES", "true",
+ "True", "TRUE", "1"};
+ static const char* falsey[] = {"no", "No", "NO", "false",
+ "False", "FALSE", "0"};
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(truthy); i++) {
+ if (0 == strcmp(env, truthy[i])) {
+ supportEnabled_ = true;
+ env_var_set = true;
+ break;
+ }
+ }
+ if (!env_var_set) {
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(falsey); i++) {
+ if (0 == strcmp(env, falsey[i])) {
+ supportEnabled_ = false;
+ env_var_set = true;
+ break;
+ }
+ }
+ }
+ gpr_free(env);
+ }
+ }
+ if (supportEnabled_) {
+ execCtxState_ = grpc_core::New<internal::ExecCtxState>();
+ threadState_ = grpc_core::New<internal::ThreadState>();
+ }
+}
+
+void Fork::GlobalShutdown() {
+ if (supportEnabled_) {
+ grpc_core::Delete(execCtxState_);
+ grpc_core::Delete(threadState_);
+ }
+}
+
+bool Fork::Enabled() { return supportEnabled_; }
+
+// Testing Only
+void Fork::Enable(bool enable) {
+ overrideEnabled_ = true;
+ supportEnabled_ = enable;
+}
+
+void Fork::IncExecCtxCount() {
+ if (supportEnabled_) {
+ execCtxState_->IncExecCtxCount();
+ }
+}
+
+void Fork::DecExecCtxCount() {
+ if (supportEnabled_) {
+ execCtxState_->DecExecCtxCount();
+ }
+}
+
+bool Fork::BlockExecCtx() {
+ if (supportEnabled_) {
+ return execCtxState_->BlockExecCtx();
+ }
+ return false;
+}
+
+void Fork::AllowExecCtx() {
+ if (supportEnabled_) {
+ execCtxState_->AllowExecCtx();
+ }
+}
+
+void Fork::IncThreadCount() {
+ if (supportEnabled_) {
+ threadState_->IncThreadCount();
+ }
+}
+
+void Fork::DecThreadCount() {
+ if (supportEnabled_) {
+ threadState_->DecThreadCount();
+ }
+}
+void Fork::AwaitThreads() {
+ if (supportEnabled_) {
+ threadState_->AwaitThreads();
+ }
+}
+
+internal::ExecCtxState* Fork::execCtxState_ = nullptr;
+internal::ThreadState* Fork::threadState_ = nullptr;
+bool Fork::supportEnabled_ = false;
+bool Fork::overrideEnabled_ = false;
+
+} // namespace grpc_core
diff --git a/src/core/lib/gprpp/fork.h b/src/core/lib/gprpp/fork.h
new file mode 100644
index 0000000000..123e22c4c6
--- /dev/null
+++ b/src/core/lib/gprpp/fork.h
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_GPRPP_FORK_H
+#define GRPC_CORE_LIB_GPRPP_FORK_H
+
+/*
+ * NOTE: FORKING IS NOT GENERALLY SUPPORTED, THIS IS ONLY INTENDED TO WORK
+ * AROUND VERY SPECIFIC USE CASES.
+ */
+
+namespace grpc_core {
+
+namespace internal {
+class ExecCtxState;
+class ThreadState;
+} // namespace internal
+
+class Fork {
+ public:
+ static void GlobalInit();
+ static void GlobalShutdown();
+
+ // Returns true if fork suppport is enabled, false otherwise
+ static bool Enabled();
+
+ // Increment the count of active ExecCtxs.
+ // Will block until a pending fork is complete if one is in progress.
+ static void IncExecCtxCount();
+
+ // Decrement the count of active ExecCtxs
+ static void DecExecCtxCount();
+
+ // Check if there is a single active ExecCtx
+ // (the one used to invoke this function). If there are more,
+ // return false. Otherwise, return true and block creation of
+ // more ExecCtx s until AlloWExecCtx() is called
+ //
+ static bool BlockExecCtx();
+ static void AllowExecCtx();
+
+ // Increment the count of active threads.
+ static void IncThreadCount();
+
+ // Decrement the count of active threads.
+ static void DecThreadCount();
+
+ // Await all core threads to be joined.
+ static void AwaitThreads();
+
+ // Test only: overrides environment variables/compile flags
+ // Must be called before grpc_init()
+ static void Enable(bool enable);
+
+ private:
+ static internal::ExecCtxState* execCtxState_;
+ static internal::ThreadState* threadState_;
+ static bool supportEnabled_;
+ static bool overrideEnabled_;
+};
+
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_GPRPP_FORK_H */
diff --git a/src/core/lib/gprpp/memory.h b/src/core/lib/gprpp/memory.h
index ba2f546675..1354109bf3 100644
--- a/src/core/lib/gprpp/memory.h
+++ b/src/core/lib/gprpp/memory.h
@@ -27,6 +27,17 @@
#include <memory>
#include <utility>
+// Add this to a class that want to use Delete(), but has a private or
+// protected destructor.
+#define GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE \
+ template <typename T> \
+ friend void Delete(T*);
+// Add this to a class that want to use New(), but has a private or
+// protected constructor.
+#define GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW \
+ template <typename T, typename... Args> \
+ friend T* New(Args&&...);
+
namespace grpc_core {
// The alignment of memory returned by gpr_malloc().
diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h
index 73a73995c7..d0ec9b6461 100644
--- a/src/core/lib/gprpp/orphanable.h
+++ b/src/core/lib/gprpp/orphanable.h
@@ -83,9 +83,7 @@ class InternallyRefCounted : public Orphanable {
GRPC_ABSTRACT_BASE_CLASS
protected:
- // Allow Delete() to access destructor.
- template <typename T>
- friend void Delete(T*);
+ GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
// Allow RefCountedPtr<> to access Unref() and IncrementRefCount().
friend class RefCountedPtr<Child>;
@@ -128,9 +126,7 @@ class InternallyRefCountedWithTracing : public Orphanable {
GRPC_ABSTRACT_BASE_CLASS
protected:
- // Allow Delete() to access destructor.
- template <typename T>
- friend void Delete(T*);
+ GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
// Allow RefCountedPtr<> to access Unref() and IncrementRefCount().
friend class RefCountedPtr<Child>;
diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h
index c67e3f315c..ddac5bd475 100644
--- a/src/core/lib/gprpp/ref_counted.h
+++ b/src/core/lib/gprpp/ref_counted.h
@@ -65,9 +65,7 @@ class RefCounted {
GRPC_ABSTRACT_BASE_CLASS
protected:
- // Allow Delete() to access destructor.
- template <typename T>
- friend void Delete(T*);
+ GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
RefCounted() { gpr_ref_init(&refs_, 1); }
@@ -135,9 +133,7 @@ class RefCountedWithTracing {
GRPC_ABSTRACT_BASE_CLASS
protected:
- // Allow Delete() to access destructor.
- template <typename T>
- friend void Delete(T*);
+ GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
RefCountedWithTracing()
: RefCountedWithTracing(static_cast<TraceFlag*>(nullptr)) {}
diff --git a/src/core/lib/gprpp/thd.h b/src/core/lib/gprpp/thd.h
index 05c7ded45f..caf0652c1a 100644
--- a/src/core/lib/gprpp/thd.h
+++ b/src/core/lib/gprpp/thd.h
@@ -111,9 +111,6 @@ class Thread {
}
};
- static void Init();
- static bool AwaitAll(gpr_timespec deadline);
-
private:
Thread(const Thread&) = delete;
Thread& operator=(const Thread&) = delete;
diff --git a/src/core/lib/gprpp/thd_posix.cc b/src/core/lib/gprpp/thd_posix.cc
index 2f6c2edcae..533c07e7d8 100644
--- a/src/core/lib/gprpp/thd_posix.cc
+++ b/src/core/lib/gprpp/thd_posix.cc
@@ -32,17 +32,12 @@
#include <stdlib.h>
#include <string.h>
-#include "src/core/lib/gpr/fork.h"
#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/fork.h"
#include "src/core/lib/gprpp/memory.h"
namespace grpc_core {
namespace {
-gpr_mu g_mu;
-gpr_cv g_cv;
-int g_thread_count;
-int g_awaiting_threads;
-
class ThreadInternalsPosix;
struct thd_arg {
ThreadInternalsPosix* thread;
@@ -68,7 +63,7 @@ class ThreadInternalsPosix
info->body = thd_body;
info->arg = arg;
info->name = thd_name;
- inc_thd_count();
+ grpc_core::Fork::IncThreadCount();
GPR_ASSERT(pthread_attr_init(&attr) == 0);
GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) ==
@@ -103,7 +98,7 @@ class ThreadInternalsPosix
gpr_mu_unlock(&arg.thread->mu_);
(*arg.body)(arg.arg);
- dec_thd_count();
+ grpc_core::Fork::DecThreadCount();
return nullptr;
},
info) == 0);
@@ -113,7 +108,7 @@ class ThreadInternalsPosix
if (!success) {
/* don't use gpr_free, as this was allocated using malloc (see above) */
free(info);
- dec_thd_count();
+ grpc_core::Fork::DecThreadCount();
}
};
@@ -132,29 +127,6 @@ class ThreadInternalsPosix
void Join() override { pthread_join(pthread_id_, nullptr); }
private:
- /*****************************************
- * Only used when fork support is enabled
- */
-
- static void inc_thd_count() {
- if (grpc_fork_support_enabled()) {
- gpr_mu_lock(&g_mu);
- g_thread_count++;
- gpr_mu_unlock(&g_mu);
- }
- }
-
- static void dec_thd_count() {
- if (grpc_fork_support_enabled()) {
- gpr_mu_lock(&g_mu);
- g_thread_count--;
- if (g_awaiting_threads && g_thread_count == 0) {
- gpr_cv_signal(&g_cv);
- }
- gpr_mu_unlock(&g_mu);
- }
- }
-
gpr_mu mu_;
gpr_cv ready_;
bool started_;
@@ -180,27 +152,6 @@ Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg,
*success = outcome;
}
}
-
-void Thread::Init() {
- gpr_mu_init(&g_mu);
- gpr_cv_init(&g_cv);
- g_thread_count = 0;
- g_awaiting_threads = 0;
-}
-
-bool Thread::AwaitAll(gpr_timespec deadline) {
- gpr_mu_lock(&g_mu);
- g_awaiting_threads = 1;
- int res = 0;
- while ((g_thread_count > 0) &&
- (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0)) {
- res = gpr_cv_wait(&g_cv, &g_mu, deadline);
- }
- g_awaiting_threads = 0;
- gpr_mu_unlock(&g_mu);
- return res == 0;
-}
-
} // namespace grpc_core
// The following is in the external namespace as it is exposed as C89 API
diff --git a/src/core/lib/gprpp/thd_windows.cc b/src/core/lib/gprpp/thd_windows.cc
index 59ea02f3d2..71584fd358 100644
--- a/src/core/lib/gprpp/thd_windows.cc
+++ b/src/core/lib/gprpp/thd_windows.cc
@@ -131,13 +131,6 @@ class ThreadInternalsWindows
namespace grpc_core {
-void Thread::Init() {}
-
-bool Thread::AwaitAll(gpr_timespec deadline) {
- // TODO: Consider adding this if needed
- return false;
-}
-
Thread::Thread(const char* thd_name, void (*thd_body)(void* arg), void* arg,
bool* success) {
bool outcome = false;
diff --git a/src/core/lib/iomgr/combiner.cc b/src/core/lib/iomgr/combiner.cc
index 9429842eb8..6789e4d12d 100644
--- a/src/core/lib/iomgr/combiner.cc
+++ b/src/core/lib/iomgr/combiner.cc
@@ -63,11 +63,12 @@ struct grpc_combiner {
gpr_refcount refs;
};
+static void combiner_run(grpc_closure* closure, grpc_error* error);
static void combiner_exec(grpc_closure* closure, grpc_error* error);
static void combiner_finally_exec(grpc_closure* closure, grpc_error* error);
static const grpc_closure_scheduler_vtable scheduler = {
- combiner_exec, combiner_exec, "combiner:immediately"};
+ combiner_run, combiner_exec, "combiner:immediately"};
static const grpc_closure_scheduler_vtable finally_scheduler = {
combiner_finally_exec, combiner_finally_exec, "combiner:finally"};
@@ -343,6 +344,22 @@ static void combiner_finally_exec(grpc_closure* closure, grpc_error* error) {
grpc_closure_list_append(&lock->final_list, closure, error);
}
+static void combiner_run(grpc_closure* closure, grpc_error* error) {
+ grpc_combiner* lock = COMBINER_FROM_CLOSURE_SCHEDULER(closure, scheduler);
+#ifndef NDEBUG
+ closure->scheduled = false;
+ GRPC_COMBINER_TRACE(gpr_log(
+ GPR_DEBUG,
+ "Combiner:%p grpc_combiner_run closure:%p created [%s:%d] run [%s:%d]",
+ lock, closure, closure->file_created, closure->line_created,
+ closure->file_initiated, closure->line_initiated));
+#endif
+ GPR_ASSERT(grpc_core::ExecCtx::Get()->combiner_data()->active_combiner ==
+ lock);
+ closure->cb(closure->cb_arg, error);
+ GRPC_ERROR_UNREF(error);
+}
+
static void enqueue_finally(void* closure, grpc_error* error) {
combiner_finally_exec(static_cast<grpc_closure*>(closure),
GRPC_ERROR_REF(error));
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index 98369ddd6e..4c6cff7fe2 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -63,6 +63,7 @@
// a keepalive ping timeout issue. We may want to revert https://github
// .com/grpc/grpc/pull/14943 once we figure out the root cause.
#define MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL 16
+#define MAX_PROBE_EPOLL_FDS 32
grpc_core::DebugOnlyTraceFlag grpc_trace_pollable_refcount(false,
"pollable_refcount");
@@ -75,6 +76,12 @@ typedef enum { PO_MULTI, PO_FD, PO_EMPTY } pollable_type;
typedef struct pollable pollable;
+typedef struct cached_fd {
+ intptr_t salt;
+ int fd;
+ uint64_t last_used;
+} cached_fd;
+
/// A pollable is something that can be polled: it has an epoll set to poll on,
/// and a wakeup fd for kicks
/// There are three broad types:
@@ -103,6 +110,11 @@ struct pollable {
int event_cursor;
int event_count;
struct epoll_event events[MAX_EPOLL_EVENTS];
+
+ // Maintain a LRU-eviction cache of fds in this pollable
+ cached_fd fd_cache[MAX_PROBE_EPOLL_FDS];
+ int fd_cache_size;
+ uint64_t fd_cache_counter;
};
static const char* pollable_type_string(pollable_type t) {
@@ -145,8 +157,11 @@ static void pollable_unref(pollable* p, int line, const char* reason);
* Fd Declarations
*/
+static gpr_atm g_fd_salt;
+
struct grpc_fd {
int fd;
+ intptr_t salt;
/* refst format:
bit 0 : 1=Active / 0=Orphaned
bits 1-n : refcount
@@ -354,6 +369,7 @@ static grpc_fd* fd_create(int fd, const char* name) {
new_fd->pollable_obj = nullptr;
gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
new_fd->fd = fd;
+ new_fd->salt = gpr_atm_no_barrier_fetch_add(&g_fd_salt, 1);
new_fd->read_closure->InitEvent();
new_fd->write_closure->InitEvent();
gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
@@ -484,6 +500,8 @@ static grpc_error* pollable_create(pollable_type type, pollable** p) {
(*p)->root_worker = nullptr;
(*p)->event_cursor = 0;
(*p)->event_count = 0;
+ (*p)->fd_cache_size = 0;
+ (*p)->fd_cache_counter = 0;
return GRPC_ERROR_NONE;
}
@@ -524,7 +542,36 @@ static grpc_error* pollable_add_fd(pollable* p, grpc_fd* fd) {
grpc_error* error = GRPC_ERROR_NONE;
static const char* err_desc = "pollable_add_fd";
const int epfd = p->epfd;
+ gpr_mu_lock(&p->mu);
+ p->fd_cache_counter++;
+ // Handle the case of overflow for our cache counter by
+ // reseting the recency-counter on all cache objects
+ if (p->fd_cache_counter == 0) {
+ for (int i = 0; i < p->fd_cache_size; i++) {
+ p->fd_cache[i].last_used = 0;
+ }
+ }
+ int lru_idx = 0;
+ for (int i = 0; i < p->fd_cache_size; i++) {
+ if (p->fd_cache[i].fd == fd->fd && p->fd_cache[i].salt == fd->salt) {
+ GRPC_STATS_INC_POLLSET_FD_CACHE_HITS();
+ p->fd_cache[i].last_used = p->fd_cache_counter;
+ gpr_mu_unlock(&p->mu);
+ return GRPC_ERROR_NONE;
+ } else if (p->fd_cache[i].last_used < p->fd_cache[lru_idx].last_used) {
+ lru_idx = i;
+ }
+ }
+ // Add to cache
+ if (p->fd_cache_size < MAX_PROBE_EPOLL_FDS) {
+ lru_idx = p->fd_cache_size;
+ p->fd_cache_size++;
+ }
+ p->fd_cache[lru_idx].fd = fd->fd;
+ p->fd_cache[lru_idx].salt = fd->salt;
+ p->fd_cache[lru_idx].last_used = p->fd_cache_counter;
+ gpr_mu_unlock(&p->mu);
if (grpc_polling_trace.enabled()) {
gpr_log(GPR_INFO, "add fd %p (%d) to pollable %p", fd, fd->fd, p);
}
@@ -533,6 +580,7 @@ static grpc_error* pollable_add_fd(pollable* p, grpc_fd* fd) {
ev_fd.events =
static_cast<uint32_t>(EPOLLET | EPOLLIN | EPOLLOUT | EPOLLEXCLUSIVE);
ev_fd.data.ptr = fd;
+ GRPC_STATS_INC_SYSCALL_EPOLL_CTL();
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd->fd, &ev_fd) != 0) {
switch (errno) {
case EEXIST:
diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h
index 72d0ae58c1..8823dc4b51 100644
--- a/src/core/lib/iomgr/exec_ctx.h
+++ b/src/core/lib/iomgr/exec_ctx.h
@@ -26,6 +26,7 @@
#include <grpc/support/log.h>
#include "src/core/lib/gpr/tls.h"
+#include "src/core/lib/gprpp/fork.h"
#include "src/core/lib/iomgr/closure.h"
typedef gpr_atm grpc_millis;
@@ -79,30 +80,41 @@ namespace grpc_core {
* - Exactly one instance of ExecCtx must be created per thread. Instances must
* always be called exec_ctx.
* - Do not pass exec_ctx as a parameter to a function. Always access it using
- * grpc_core::ExecCtx::Get()
+ * grpc_core::ExecCtx::Get().
*/
class ExecCtx {
public:
/** Default Constructor */
- ExecCtx() : flags_(GRPC_EXEC_CTX_FLAG_IS_FINISHED) { Set(this); }
+ ExecCtx() : flags_(GRPC_EXEC_CTX_FLAG_IS_FINISHED) {
+ grpc_core::Fork::IncExecCtxCount();
+ Set(this);
+ }
/** Parameterised Constructor */
- ExecCtx(uintptr_t fl) : flags_(fl) { Set(this); }
+ ExecCtx(uintptr_t fl) : flags_(fl) {
+ grpc_core::Fork::IncExecCtxCount();
+ Set(this);
+ }
/** Destructor */
virtual ~ExecCtx() {
flags_ |= GRPC_EXEC_CTX_FLAG_IS_FINISHED;
Flush();
Set(last_exec_ctx_);
+ grpc_core::Fork::DecExecCtxCount();
}
/** Disallow copy and assignment operators */
ExecCtx(const ExecCtx&) = delete;
ExecCtx& operator=(const ExecCtx&) = delete;
- /** Return starting_cpu */
+ /** Return starting_cpu. This is only required for stats collection and is
+ * hence only defined if GRPC_COLLECT_STATS is enabled.
+ */
+#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG)
unsigned starting_cpu() const { return starting_cpu_; }
+#endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */
struct CombinerData {
/* currently active combiner: updated only via combiner.c */
@@ -128,12 +140,14 @@ class ExecCtx {
/** Flush any work that has been enqueued onto this grpc_exec_ctx.
* Caller must guarantee that no interfering locks are held.
- * Returns true if work was performed, false otherwise. */
+ * Returns true if work was performed, false otherwise.
+ */
bool Flush();
/** Returns true if we'd like to leave this execution context as soon as
-possible: useful for deciding whether to do something more or not depending
-on outside context */
+ * possible: useful for deciding whether to do something more or not
+ * depending on outside context.
+ */
bool IsReadyToFinish() {
if ((flags_ & GRPC_EXEC_CTX_FLAG_IS_FINISHED) == 0) {
if (CheckReadyToFinish()) {
@@ -147,12 +161,14 @@ on outside context */
}
/** Returns the stored current time relative to start if valid,
- * otherwise refreshes the stored time, sets it valid and returns the new
- * value */
+ * otherwise refreshes the stored time, sets it valid and returns the new
+ * value.
+ */
grpc_millis Now();
/** Invalidates the stored time value. A new time value will be set on calling
- * Now() */
+ * Now().
+ */
void InvalidateNow() { now_is_valid_ = false; }
/** To be used only by shutdown code in iomgr */
@@ -162,20 +178,20 @@ on outside context */
}
/** To be used only for testing.
- * Sets the now value
+ * Sets the now value.
*/
void TestOnlySetNow(grpc_millis new_val) {
now_ = new_val;
now_is_valid_ = true;
}
- /** Global initialization for ExecCtx. Called by iomgr */
+ /** Global initialization for ExecCtx. Called by iomgr. */
static void GlobalInit(void);
- /** Global shutdown for ExecCtx. Called by iomgr */
+ /** Global shutdown for ExecCtx. Called by iomgr. */
static void GlobalShutdown(void) { gpr_tls_destroy(&exec_ctx_); }
- /** Gets pointer to current exec_ctx */
+ /** Gets pointer to current exec_ctx. */
static ExecCtx* Get() {
return reinterpret_cast<ExecCtx*>(gpr_tls_get(&exec_ctx_));
}
@@ -185,19 +201,22 @@ on outside context */
}
protected:
- /** Check if ready to finish */
+ /** Check if ready to finish. */
virtual bool CheckReadyToFinish() { return false; }
- /** Disallow delete on ExecCtx */
+ /** Disallow delete on ExecCtx. */
static void operator delete(void* p) { abort(); }
private:
- /** Set exec_ctx_ to exec_ctx */
+ /** Set exec_ctx_ to exec_ctx. */
grpc_closure_list closure_list_ = GRPC_CLOSURE_LIST_INIT;
CombinerData combiner_data_ = {nullptr, nullptr};
uintptr_t flags_;
+
+#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG)
unsigned starting_cpu_ = gpr_cpu_current_cpu();
+#endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */
bool now_is_valid_ = false;
grpc_millis now_ = 0;
diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc
index 6c506eb5c9..b37384b8db 100644
--- a/src/core/lib/iomgr/fork_posix.cc
+++ b/src/core/lib/iomgr/fork_posix.cc
@@ -28,7 +28,7 @@
#include <grpc/support/log.h>
#include "src/core/lib/gpr/env.h"
-#include "src/core/lib/gpr/fork.h"
+#include "src/core/lib/gprpp/fork.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/executor.h"
@@ -41,46 +41,59 @@
* AROUND VERY SPECIFIC USE CASES.
*/
+namespace {
+bool skipped_handler = true;
+bool registered_handlers = false;
+} // namespace
+
void grpc_prefork() {
- if (!grpc_fork_support_enabled()) {
+ grpc_core::ExecCtx exec_ctx;
+ skipped_handler = true;
+ if (!grpc_is_initialized()) {
+ return;
+ }
+ if (!grpc_core::Fork::Enabled()) {
gpr_log(GPR_ERROR,
"Fork support not enabled; try running with the "
"environment variable GRPC_ENABLE_FORK_SUPPORT=1");
return;
}
- if (grpc_is_initialized()) {
- grpc_core::ExecCtx exec_ctx;
- grpc_timer_manager_set_threading(false);
- grpc_executor_set_threading(false);
- grpc_core::ExecCtx::Get()->Flush();
- if (!grpc_core::Thread::AwaitAll(
- gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_seconds(3, GPR_TIMESPAN)))) {
- gpr_log(GPR_ERROR, "gRPC thread still active! Cannot fork!");
- }
+ if (!grpc_core::Fork::BlockExecCtx()) {
+ gpr_log(GPR_INFO,
+ "Other threads are currently calling into gRPC, skipping fork() "
+ "handlers");
+ return;
}
+ grpc_timer_manager_set_threading(false);
+ grpc_executor_set_threading(false);
+ grpc_core::ExecCtx::Get()->Flush();
+ grpc_core::Fork::AwaitThreads();
+ skipped_handler = false;
}
void grpc_postfork_parent() {
- if (grpc_is_initialized()) {
- grpc_timer_manager_set_threading(true);
+ if (!skipped_handler) {
+ grpc_core::Fork::AllowExecCtx();
grpc_core::ExecCtx exec_ctx;
+ grpc_timer_manager_set_threading(true);
grpc_executor_set_threading(true);
}
}
void grpc_postfork_child() {
- if (grpc_is_initialized()) {
- grpc_timer_manager_set_threading(true);
+ if (!skipped_handler) {
+ grpc_core::Fork::AllowExecCtx();
grpc_core::ExecCtx exec_ctx;
+ grpc_timer_manager_set_threading(true);
grpc_executor_set_threading(true);
}
}
void grpc_fork_handlers_auto_register() {
- if (grpc_fork_support_enabled()) {
+ if (grpc_core::Fork::Enabled() & !registered_handlers) {
#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK
pthread_atfork(grpc_prefork, grpc_postfork_parent, grpc_postfork_child);
+ registered_handlers = true;
#endif // GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK
}
}
diff --git a/src/core/lib/iomgr/resource_quota.cc b/src/core/lib/iomgr/resource_quota.cc
index 8cf4fe9928..539bc120ce 100644
--- a/src/core/lib/iomgr/resource_quota.cc
+++ b/src/core/lib/iomgr/resource_quota.cc
@@ -386,7 +386,7 @@ static bool rq_reclaim(grpc_resource_quota* resource_quota, bool destructive) {
resource_quota->debug_only_last_reclaimer_resource_user = resource_user;
resource_quota->debug_only_last_initiated_reclaimer = c;
resource_user->reclaimers[destructive] = nullptr;
- GRPC_CLOSURE_RUN(c, GRPC_ERROR_NONE);
+ GRPC_CLOSURE_SCHED(c, GRPC_ERROR_NONE);
return true;
}
diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc
index 6144d389f7..900c056575 100644
--- a/src/core/lib/iomgr/tcp_client_posix.cc
+++ b/src/core/lib/iomgr/tcp_client_posix.cc
@@ -45,6 +45,7 @@
#include "src/core/lib/iomgr/tcp_posix.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
+#include "src/core/lib/slice/slice_internal.h"
extern grpc_core::TraceFlag grpc_tcp_trace;
@@ -233,7 +234,7 @@ finish:
error = grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS,
addr_str_slice /* takes ownership */);
} else {
- grpc_slice_unref(addr_str_slice);
+ grpc_slice_unref_internal(addr_str_slice);
}
if (done) {
// This is safe even outside the lock, because "done", the sentinel, is
diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc
index b3b2934014..990e8d632b 100644
--- a/src/core/lib/iomgr/tcp_custom.cc
+++ b/src/core/lib/iomgr/tcp_custom.cc
@@ -141,7 +141,7 @@ static void call_read_cb(custom_tcp_endpoint* tcp, grpc_error* error) {
TCP_UNREF(tcp, "read");
tcp->read_slices = nullptr;
tcp->read_cb = nullptr;
- GRPC_CLOSURE_RUN(cb, error);
+ GRPC_CLOSURE_SCHED(cb, error);
}
static void custom_read_callback(grpc_custom_socket* socket, size_t nread,
diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc
index 153be05e83..b79ffe20f1 100644
--- a/src/core/lib/iomgr/tcp_posix.cc
+++ b/src/core/lib/iomgr/tcp_posix.cc
@@ -366,7 +366,7 @@ static void call_read_cb(grpc_tcp* tcp, grpc_error* error) {
tcp->read_cb = nullptr;
tcp->incoming_buffer = nullptr;
- GRPC_CLOSURE_RUN(cb, error);
+ GRPC_CLOSURE_SCHED(cb, error);
}
#define MAX_READ_IOVEC 4
@@ -629,7 +629,7 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) {
gpr_log(GPR_INFO, "write: %s", str);
}
- GRPC_CLOSURE_RUN(cb, error);
+ GRPC_CLOSURE_SCHED(cb, error);
TCP_UNREF(tcp, "write");
}
}
diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc
index 153ac63424..484d2b6077 100644
--- a/src/core/lib/iomgr/tcp_server_posix.cc
+++ b/src/core/lib/iomgr/tcp_server_posix.cc
@@ -187,11 +187,6 @@ static void on_read(void* arg, grpc_error* err) {
goto error;
}
- read_notifier_pollset =
- sp->server->pollsets[static_cast<size_t>(gpr_atm_no_barrier_fetch_add(
- &sp->server->next_pollset_to_assign, 1)) %
- sp->server->pollset_count];
-
/* loop until accept4 returns EAGAIN, and then re-arm notification */
for (;;) {
grpc_resolved_address addr;
@@ -233,6 +228,11 @@ static void on_read(void* arg, grpc_error* err) {
grpc_fd* fdobj = grpc_fd_create(fd, name);
+ read_notifier_pollset =
+ sp->server->pollsets[static_cast<size_t>(gpr_atm_no_barrier_fetch_add(
+ &sp->server->next_pollset_to_assign, 1)) %
+ sp->server->pollset_count];
+
grpc_pollset_add_fd(read_notifier_pollset, fdobj);
// Create acceptor.
diff --git a/src/core/lib/security/security_connector/alts_security_connector.cc b/src/core/lib/security/security_connector/alts_security_connector.cc
index 5ff7d7938b..35a787871a 100644
--- a/src/core/lib/security/security_connector/alts_security_connector.cc
+++ b/src/core/lib/security/security_connector/alts_security_connector.cc
@@ -30,6 +30,7 @@
#include "src/core/lib/security/credentials/alts/alts_credentials.h"
#include "src/core/lib/security/transport/security_handshaker.h"
+#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/transport.h"
#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h"
@@ -133,7 +134,7 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer(
rpc_versions_prop->value.data, rpc_versions_prop->value.length);
bool decode_result =
grpc_gcp_rpc_protocol_versions_decode(slice, &peer_versions);
- grpc_slice_unref(slice);
+ grpc_slice_unref_internal(slice);
if (!decode_result) {
gpr_log(GPR_ERROR, "Invalid peer rpc protocol versions.");
return GRPC_SECURITY_ERROR;
diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc
index a30696703f..b54a7643e4 100644
--- a/src/core/lib/security/security_connector/security_connector.cc
+++ b/src/core/lib/security/security_connector/security_connector.cc
@@ -69,8 +69,11 @@ void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) {
/* Defines the cipher suites that we accept by default. All these cipher suites
are compliant with HTTP2. */
-#define GRPC_SSL_CIPHER_SUITES \
- "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384"
+#define GRPC_SSL_CIPHER_SUITES \
+ "ECDHE-ECDSA-AES128-GCM-SHA256:" \
+ "ECDHE-ECDSA-AES256-GCM-SHA384:" \
+ "ECDHE-RSA-AES128-GCM-SHA256:" \
+ "ECDHE-RSA-AES256-GCM-SHA384"
static gpr_once cipher_suites_once = GPR_ONCE_INIT;
static const char* cipher_suites = nullptr;
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index da488034ca..7ed1696f80 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -1259,8 +1259,12 @@ static void post_batch_completion(batch_control* bctl) {
if (bctl->completion_data.notify_tag.is_closure) {
/* unrefs bctl->error */
bctl->call = nullptr;
- GRPC_CLOSURE_RUN((grpc_closure*)bctl->completion_data.notify_tag.tag,
- error);
+ /* This closure may be meant to be run within some combiner. Since we aren't
+ * running in any combiner here, we need to use GRPC_CLOSURE_SCHED instead
+ * of GRPC_CLOSURE_RUN.
+ */
+ GRPC_CLOSURE_SCHED((grpc_closure*)bctl->completion_data.notify_tag.tag,
+ error);
GRPC_CALL_INTERNAL_UNREF(call, "completion");
} else {
/* unrefs bctl->error */
diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc
index bd436d6857..a14f77e346 100644
--- a/src/core/lib/surface/init.cc
+++ b/src/core/lib/surface/init.cc
@@ -32,8 +32,7 @@
#include "src/core/lib/channel/handshaker_registry.h"
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/debug/trace.h"
-#include "src/core/lib/gpr/fork.h"
-#include "src/core/lib/gprpp/thd.h"
+#include "src/core/lib/gprpp/fork.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/call_combiner.h"
#include "src/core/lib/iomgr/combiner.h"
@@ -65,12 +64,10 @@ static int g_initializations;
static void do_basic_init(void) {
gpr_log_verbosity_init();
- grpc_fork_support_init();
gpr_mu_init(&g_init_mu);
grpc_register_built_in_plugins();
grpc_cq_global_init();
g_initializations = 0;
- grpc_fork_handlers_auto_register();
}
static bool append_filter(grpc_channel_stack_builder* builder, void* arg) {
@@ -123,8 +120,9 @@ void grpc_init(void) {
gpr_mu_lock(&g_init_mu);
if (++g_initializations == 1) {
+ grpc_core::Fork::GlobalInit();
+ grpc_fork_handlers_auto_register();
gpr_time_init();
- grpc_core::Thread::Init();
grpc_stats_init();
grpc_slice_intern_init();
grpc_mdctx_global_init();
@@ -180,6 +178,7 @@ void grpc_shutdown(void) {
grpc_slice_intern_shutdown();
grpc_channel_trace_registry_shutdown();
grpc_stats_shutdown();
+ grpc_core::Fork::GlobalShutdown();
}
grpc_core::ExecCtx::GlobalShutdown();
}
diff --git a/src/core/lib/transport/byte_stream.cc b/src/core/lib/transport/byte_stream.cc
index cb15a71a91..16b85ca0db 100644
--- a/src/core/lib/transport/byte_stream.cc
+++ b/src/core/lib/transport/byte_stream.cc
@@ -45,7 +45,7 @@ SliceBufferByteStream::SliceBufferByteStream(grpc_slice_buffer* slice_buffer,
SliceBufferByteStream::~SliceBufferByteStream() {}
void SliceBufferByteStream::Orphan() {
- grpc_slice_buffer_destroy(&backing_buffer_);
+ grpc_slice_buffer_destroy_internal(&backing_buffer_);
GRPC_ERROR_UNREF(shutdown_error_);
// Note: We do not actually delete the object here, since
// SliceBufferByteStream is usually allocated as part of a larger
diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m
index a49a489ea8..b1f6ea270e 100644
--- a/src/objective-c/GRPCClient/private/GRPCChannel.m
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.m
@@ -56,6 +56,7 @@ static void FreeChannelArgs(grpc_channel_args *channel_args) {
gpr_free(arg->value.string);
}
}
+ gpr_free(channel_args->args);
gpr_free(channel_args);
}
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m
index bfb1fd352c..c3ea9afc37 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.m
+++ b/src/objective-c/GRPCClient/private/GRPCHost.m
@@ -50,6 +50,7 @@ static NSMutableDictionary *kHostCache;
if (_channelCreds != nil) {
grpc_channel_credentials_release(_channelCreds);
}
+ [GRPCConnectivityMonitor unregisterObserver:self];
}
// Default initializer.
@@ -278,7 +279,7 @@ static NSMutableDictionary *kHostCache;
// and Cellular data, so that a new call will use a new channel. Otherwise, a new call will still
// use the cached channel which is no longer available and will cause gRPC to hang.
- (void)connectivityChange:(NSNotification *)note {
- [GRPCHost flushChannelCache];
+ [self disconnect];
}
@end
diff --git a/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m b/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
index af1ce0bf23..730a1436e4 100644
--- a/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
+++ b/src/objective-c/GRPCClient/private/NSDictionary+GRPC.m
@@ -54,7 +54,7 @@
+ (instancetype)grpc_stringFromMetadataValue:(grpc_metadata *)metadata {
return [[self alloc] initWithBytes:GRPC_SLICE_START_PTR(metadata->value)
length:GRPC_SLICE_LENGTH(metadata->value)
- encoding:NSASCIIStringEncoding];
+ encoding:NSUTF8StringEncoding];
}
// Precondition: This object contains only ASCII characters.
diff --git a/src/objective-c/GRPCClient/private/NSError+GRPC.m b/src/objective-c/GRPCClient/private/NSError+GRPC.m
index 74cfa943cc..c2e65e4d8a 100644
--- a/src/objective-c/GRPCClient/private/NSError+GRPC.m
+++ b/src/objective-c/GRPCClient/private/NSError+GRPC.m
@@ -27,7 +27,7 @@ NSString *const kGRPCErrorDomain = @"io.grpc";
if (statusCode == GRPC_STATUS_OK) {
return nil;
}
- NSString *message = [NSString stringWithCString:details encoding:NSASCIIStringEncoding];
+ NSString *message = [NSString stringWithCString:details encoding:NSUTF8StringEncoding];
return [NSError errorWithDomain:kGRPCErrorDomain
code:statusCode
userInfo:@{NSLocalizedDescriptionKey : message}];
diff --git a/src/php/ext/grpc/byte_buffer.c b/src/php/ext/grpc/byte_buffer.c
index 810cc81151..474b7a694b 100644
--- a/src/php/ext/grpc/byte_buffer.c
+++ b/src/php/ext/grpc/byte_buffer.c
@@ -16,23 +16,11 @@
*
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
-#include <ext/spl/spl_exceptions.h>
-#include "php_grpc.h"
-
-#include <string.h>
#include "byte_buffer.h"
-#include <grpc/grpc.h>
#include <grpc/byte_buffer_reader.h>
-#include <grpc/slice.h>
grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length) {
grpc_slice slice = grpc_slice_from_copied_buffer(string, length);
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index 4a647ec7c2..9a1dcb640b 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -18,25 +18,12 @@
#include "call.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
#include <ext/spl/spl_exceptions.h>
-#include "php_grpc.h"
-#include "call_credentials.h"
-
#include <zend_exceptions.h>
-#include <zend_hash.h>
-
-#include <stdbool.h>
#include <grpc/support/alloc.h>
-#include <grpc/grpc.h>
+#include "call_credentials.h"
#include "completion_queue.h"
#include "timeval.h"
#include "channel.h"
diff --git a/src/php/ext/grpc/call.h b/src/php/ext/grpc/call.h
index bb73354c42..c07fb9ba69 100644
--- a/src/php/ext/grpc/call.h
+++ b/src/php/ext/grpc/call.h
@@ -19,17 +19,9 @@
#ifndef NET_GRPC_PHP_GRPC_CALL_H_
#define NET_GRPC_PHP_GRPC_CALL_H_
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
#include "php_grpc.h"
-#include "channel.h"
-#include <grpc/grpc.h>
+#include "channel.h"
/* Class entry for the Call PHP class */
extern zend_class_entry *grpc_ce_call;
diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c
index d96dc7f3b7..12dcd46b21 100644
--- a/src/php/ext/grpc/call_credentials.c
+++ b/src/php/ext/grpc/call_credentials.c
@@ -16,28 +16,16 @@
*
*/
-#include "channel_credentials.h"
#include "call_credentials.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
#include <ext/spl/spl_exceptions.h>
-#include "php_grpc.h"
-#include "call.h"
-
#include <zend_exceptions.h>
-#include <zend_hash.h>
-#include <grpc/grpc.h>
-#include <grpc/grpc_security.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+#include "call.h"
+
zend_class_entry *grpc_ce_call_credentials;
#if PHP_MAJOR_VERSION >= 7
static zend_object_handlers call_credentials_ce_handlers;
diff --git a/src/php/ext/grpc/call_credentials.h b/src/php/ext/grpc/call_credentials.h
index 663cc6858d..1db90b96b2 100644
--- a/src/php/ext/grpc/call_credentials.h
+++ b/src/php/ext/grpc/call_credentials.h
@@ -19,17 +19,9 @@
#ifndef NET_GRPC_PHP_GRPC_CALL_CREDENTIALS_H_
#define NET_GRPC_PHP_GRPC_CALL_CREDENTIALS_H_
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
#include "php_grpc.h"
-#include "grpc/grpc.h"
-#include "grpc/grpc_security.h"
+#include <grpc/grpc_security.h>
/* Class entry for the CallCredentials PHP class */
extern zend_class_entry *grpc_ce_call_credentials;
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index 6f3acc7afb..dc17e05310 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -18,13 +18,6 @@
#include "channel.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
#include <ext/standard/php_var.h>
#include <ext/standard/sha1.h>
#if PHP_MAJOR_VERSION < 7
@@ -33,19 +26,13 @@
#include <zend_smart_str.h>
#endif
#include <ext/spl/spl_exceptions.h>
-#include "php_grpc.h"
-
#include <zend_exceptions.h>
-#include <stdbool.h>
-
-#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
#include "completion_queue.h"
#include "channel_credentials.h"
-#include "server.h"
#include "timeval.h"
zend_class_entry *grpc_ce_channel;
diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h
index 7aad59abe5..c0bd8c7daa 100644
--- a/src/php/ext/grpc/channel.h
+++ b/src/php/ext/grpc/channel.h
@@ -19,17 +19,8 @@
#ifndef NET_GRPC_PHP_GRPC_CHANNEL_H_
#define NET_GRPC_PHP_GRPC_CHANNEL_H_
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
#include "php_grpc.h"
-#include <grpc/grpc.h>
-
/* Class entry for the PHP Channel class */
extern zend_class_entry *grpc_ce_channel;
diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c
index 624d7cc75c..8bda64cf41 100644
--- a/src/php/ext/grpc/channel_credentials.c
+++ b/src/php/ext/grpc/channel_credentials.c
@@ -17,27 +17,16 @@
*/
#include "channel_credentials.h"
-#include "call_credentials.h"
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
#include <ext/standard/sha1.h>
#include <ext/spl/spl_exceptions.h>
-#include "channel.h"
-#include "php_grpc.h"
-
#include <zend_exceptions.h>
-#include <zend_hash.h>
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
-#include <grpc/grpc.h>
-#include <grpc/grpc_security.h>
+
+#include "call_credentials.h"
+#include "channel.h"
zend_class_entry *grpc_ce_channel_credentials;
#if PHP_MAJOR_VERSION >= 7
diff --git a/src/php/ext/grpc/channel_credentials.h b/src/php/ext/grpc/channel_credentials.h
index 357d732642..ef312be13f 100644
--- a/src/php/ext/grpc/channel_credentials.h
+++ b/src/php/ext/grpc/channel_credentials.h
@@ -19,17 +19,9 @@
#ifndef NET_GRPC_PHP_GRPC_CHANNEL_CREDENTIALS_H_
#define NET_GRPC_PHP_GRPC_CHANNEL_CREDENTIALS_H_
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
#include "php_grpc.h"
-#include "grpc/grpc.h"
-#include "grpc/grpc_security.h"
+#include <grpc/grpc_security.h>
/* Class entry for the ChannelCredentials PHP class */
extern zend_class_entry *grpc_ce_channel_credentials;
diff --git a/src/php/ext/grpc/completion_queue.c b/src/php/ext/grpc/completion_queue.c
index f54089b3a0..e7a2fa6d2a 100644
--- a/src/php/ext/grpc/completion_queue.c
+++ b/src/php/ext/grpc/completion_queue.c
@@ -18,8 +18,6 @@
#include "completion_queue.h"
-#include <php.h>
-
grpc_completion_queue *completion_queue;
void grpc_php_init_completion_queue(TSRMLS_D) {
diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c
index 1dd1f4fe50..fabd98975d 100644
--- a/src/php/ext/grpc/php_grpc.c
+++ b/src/php/ext/grpc/php_grpc.c
@@ -16,6 +16,8 @@
*
*/
+#include "php_grpc.h"
+
#include "call.h"
#include "channel.h"
#include "server.h"
@@ -25,15 +27,6 @@
#include "server_credentials.h"
#include "completion_queue.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
-#include "php_grpc.h"
-
ZEND_DECLARE_MODULE_GLOBALS(grpc)
static PHP_GINIT_FUNCTION(grpc);
HashTable grpc_persistent_list;
diff --git a/src/php/ext/grpc/php_grpc.h b/src/php/ext/grpc/php_grpc.h
index e30f011c39..ecf5ebaa05 100644
--- a/src/php/ext/grpc/php_grpc.h
+++ b/src/php/ext/grpc/php_grpc.h
@@ -20,8 +20,21 @@
#ifndef PHP_GRPC_H
#define PHP_GRPC_H
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdbool.h>
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
+
+#include <grpc/grpc.h>
+
+#include "php7_wrapper.h"
+#include "version.h"
+
extern zend_module_entry grpc_module_entry;
#define phpext_grpc_ptr &grpc_module_entry
@@ -37,11 +50,6 @@ extern zend_module_entry grpc_module_entry;
#include "TSRM.h"
#endif
-#include "php.h"
-#include "php7_wrapper.h"
-#include "grpc/grpc.h"
-#include "version.h"
-
/* These are all function declarations */
/* Code that runs at module initialization */
PHP_MINIT_FUNCTION(grpc);
diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c
index 292d512e37..ece7b0048a 100644
--- a/src/php/ext/grpc/server.c
+++ b/src/php/ext/grpc/server.c
@@ -16,29 +16,17 @@
*
*/
-#include "call.h"
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "server.h"
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
#include <ext/spl/spl_exceptions.h>
-#include "php_grpc.h"
-
#include <zend_exceptions.h>
-#include <stdbool.h>
-
-#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpc/slice.h>
#include <grpc/support/alloc.h>
+#include "call.h"
#include "completion_queue.h"
-#include "server.h"
#include "channel.h"
#include "server_credentials.h"
#include "timeval.h"
diff --git a/src/php/ext/grpc/server.h b/src/php/ext/grpc/server.h
index 366f5d05a4..ca70589cfa 100644
--- a/src/php/ext/grpc/server.h
+++ b/src/php/ext/grpc/server.h
@@ -19,17 +19,8 @@
#ifndef NET_GRPC_PHP_GRPC_SERVER_H_
#define NET_GRPC_PHP_GRPC_SERVER_H_
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
#include "php_grpc.h"
-#include <grpc/grpc.h>
-
/* Class entry for the Server PHP class */
extern zend_class_entry *grpc_ce_server;
diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c
index 212486e2e1..d143217f04 100644
--- a/src/php/ext/grpc/server_credentials.c
+++ b/src/php/ext/grpc/server_credentials.c
@@ -18,21 +18,8 @@
#include "server_credentials.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
#include <ext/spl/spl_exceptions.h>
-#include "php_grpc.h"
-
#include <zend_exceptions.h>
-#include <zend_hash.h>
-
-#include <grpc/grpc.h>
-#include <grpc/grpc_security.h>
zend_class_entry *grpc_ce_server_credentials;
#if PHP_MAJOR_VERSION >= 7
diff --git a/src/php/ext/grpc/server_credentials.h b/src/php/ext/grpc/server_credentials.h
index 310c28db76..68e505ca1e 100644
--- a/src/php/ext/grpc/server_credentials.h
+++ b/src/php/ext/grpc/server_credentials.h
@@ -26,9 +26,9 @@
#include <php.h>
#include <php_ini.h>
#include <ext/standard/info.h>
+
#include "php_grpc.h"
-#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
/* Class entry for the Server_Credentials PHP class */
diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c
index 7280dde30b..77a5ffa256 100644
--- a/src/php/ext/grpc/timeval.c
+++ b/src/php/ext/grpc/timeval.c
@@ -18,23 +18,9 @@
#include "timeval.h"
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
#include <ext/spl/spl_exceptions.h>
-#include "php_grpc.h"
-
#include <zend_exceptions.h>
-#include <stdbool.h>
-
-#include <grpc/grpc.h>
-#include <grpc/support/time.h>
-
zend_class_entry *grpc_ce_timeval;
#if PHP_MAJOR_VERSION >= 7
static zend_object_handlers timeval_ce_handlers;
diff --git a/src/php/ext/grpc/timeval.h b/src/php/ext/grpc/timeval.h
index f4d267f907..23f5c1e971 100644
--- a/src/php/ext/grpc/timeval.h
+++ b/src/php/ext/grpc/timeval.h
@@ -19,18 +19,8 @@
#ifndef NET_GRPC_PHP_GRPC_TIMEVAL_H_
#define NET_GRPC_PHP_GRPC_TIMEVAL_H_
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
#include "php_grpc.h"
-#include <grpc/grpc.h>
-#include <grpc/support/time.h>
-
/* Class entry for the Timeval PHP Class */
extern zend_class_entry *grpc_ce_timeval;
diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index 7860233ca2..b9c50b1da6 100644
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -60,7 +60,7 @@ class BaseStub
}
if ($channel) {
if (!is_a($channel, 'Grpc\Channel') &&
- !is_a($channel, 'Grpc\InterceptorChannel')) {
+ !is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
throw new \Exception('The channel argument is not a Channel object '.
'or an InterceptorChannel object created by '.
'Interceptor::intercept($channel, Interceptor|Interceptor[] $interceptors)');
@@ -69,6 +69,18 @@ class BaseStub
return;
}
+ $this->channel = static::getDefaultChannel($hostname, $opts);
+ }
+
+ /**
+ * Creates and returns the default Channel
+ *
+ * @param array $opts Channel constructor options
+ *
+ * @return Channel The channel
+ */
+ public static function getDefaultChannel($hostname, array $opts)
+ {
$package_config = json_decode(
file_get_contents(dirname(__FILE__).'/../../composer.json'),
true
@@ -85,7 +97,7 @@ class BaseStub
'required. Please see one of the '.
'ChannelCredentials::create methods');
}
- $this->channel = new Channel($hostname, $opts);
+ return new Channel($hostname, $opts);
}
/**
@@ -365,7 +377,7 @@ class BaseStub
*/
private function _UnaryUnaryCallFactory($channel, $deserialize)
{
- if (is_a($channel, 'Grpc\InterceptorChannel')) {
+ if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
return function ($method,
$argument,
array $metadata = [],
@@ -392,7 +404,7 @@ class BaseStub
*/
private function _UnaryStreamCallFactory($channel, $deserialize)
{
- if (is_a($channel, 'Grpc\InterceptorChannel')) {
+ if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
return function ($method,
$argument,
array $metadata = [],
@@ -419,7 +431,7 @@ class BaseStub
*/
private function _StreamUnaryCallFactory($channel, $deserialize)
{
- if (is_a($channel, 'Grpc\InterceptorChannel')) {
+ if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
return function ($method,
array $metadata = [],
array $options = []) use ($channel, $deserialize) {
@@ -444,7 +456,7 @@ class BaseStub
*/
private function _StreamStreamCallFactory($channel, $deserialize)
{
- if (is_a($channel, 'Grpc\InterceptorChannel')) {
+ if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
return function ($method,
array $metadata = [],
array $options = []) use ($channel, $deserialize) {
diff --git a/src/php/lib/Grpc/Interceptor.php b/src/php/lib/Grpc/Interceptor.php
index 9c1b5616f2..e1b97f2a84 100644
--- a/src/php/lib/Grpc/Interceptor.php
+++ b/src/php/lib/Grpc/Interceptor.php
@@ -75,10 +75,10 @@ class Interceptor
{
if (is_array($interceptors)) {
for ($i = count($interceptors) - 1; $i >= 0; $i--) {
- $channel = new InterceptorChannel($channel, $interceptors[$i]);
+ $channel = new Internal\InterceptorChannel($channel, $interceptors[$i]);
}
} else {
- $channel = new InterceptorChannel($channel, $interceptors);
+ $channel = new Internal\InterceptorChannel($channel, $interceptors);
}
return $channel;
}
diff --git a/src/php/lib/Grpc/Internal/InterceptorChannel.php b/src/php/lib/Grpc/Internal/InterceptorChannel.php
index 9ac05748f3..2f85c35fe0 100644
--- a/src/php/lib/Grpc/Internal/InterceptorChannel.php
+++ b/src/php/lib/Grpc/Internal/InterceptorChannel.php
@@ -17,12 +17,12 @@
*
*/
-namespace Grpc;
+namespace Grpc\Internal;
/**
* This is a PRIVATE API and can change without notice.
*/
-class InterceptorChannel
+class InterceptorChannel extends \Grpc\Channel
{
private $next = null;
private $interceptor;
@@ -35,7 +35,7 @@ class InterceptorChannel
public function __construct($channel, $interceptor)
{
if (!is_a($channel, 'Grpc\Channel') &&
- !is_a($channel, 'Grpc\InterceptorChannel')) {
+ !is_a($channel, 'Grpc\Internal\InterceptorChannel')) {
throw new \Exception('The channel argument is not a Channel object '.
'or an InterceptorChannel object created by '.
'Interceptor::intercept($channel, Interceptor|Interceptor[] $interceptors)');
diff --git a/src/php/tests/unit_tests/InterceptorTest.php b/src/php/tests/unit_tests/InterceptorTest.php
index 08f5abbb21..11c5b4325a 100644
--- a/src/php/tests/unit_tests/InterceptorTest.php
+++ b/src/php/tests/unit_tests/InterceptorTest.php
@@ -58,7 +58,7 @@ class InterceptorClient extends Grpc\BaseStub
/**
* A simple RPC.
- * @param \Routeguide\Point $argument input argument
+ * @param SimpleRequest $argument input argument
* @param array $metadata metadata
* @param array $options call options
*/
@@ -221,15 +221,11 @@ class InterceptorTest extends PHPUnit_Framework_TestCase
$req_text = 'client_request';
$channel_matadata_interceptor = new ChangeMetadataInterceptor();
$intercept_channel = Grpc\Interceptor::intercept($this->channel, $channel_matadata_interceptor);
- echo "create Client\n";
$client = new InterceptorClient('localhost:'.$this->port, [
'credentials' => Grpc\ChannelCredentials::createInsecure(),
], $intercept_channel);
- echo "create Call\n";
$req = new SimpleRequest($req_text);
- echo "Call created\n";
$unary_call = $client->UnaryCall($req);
- echo "start call\n";
$event = $this->server->requestCall();
$this->assertSame('/dummy_method', $event->method);
$this->assertSame(['interceptor_from_unary_request'], $event->metadata['foo']);
diff --git a/src/proto/grpc/lb/v1/load_balancer.proto b/src/proto/grpc/lb/v1/load_balancer.proto
index 75c916defa..3e0a4b2c97 100644
--- a/src/proto/grpc/lb/v1/load_balancer.proto
+++ b/src/proto/grpc/lb/v1/load_balancer.proto
@@ -62,8 +62,10 @@ message LoadBalanceRequest {
}
message InitialLoadBalanceRequest {
- // Name of load balanced service (IE, balancer.service.com)
- // length should be less than 256 bytes.
+ // The name of the load balanced service (e.g., balancer.service.com). The max
+ // length of the name is 256 bytes.
+ // The name might include a port number. How to handle the port number is up
+ // to the balancer.
string name = 1;
}
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 699d504c12..bf6c2534a8 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -28,7 +28,6 @@ CORE_SOURCE_FILES = [
'src/core/lib/gpr/env_linux.cc',
'src/core/lib/gpr/env_posix.cc',
'src/core/lib/gpr/env_windows.cc',
- 'src/core/lib/gpr/fork.cc',
'src/core/lib/gpr/host_port.cc',
'src/core/lib/gpr/log.cc',
'src/core/lib/gpr/log_android.cc',
@@ -53,6 +52,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/gpr/tmpfile_posix.cc',
'src/core/lib/gpr/tmpfile_windows.cc',
'src/core/lib/gpr/wrap_memcpy.cc',
+ 'src/core/lib/gprpp/fork.cc',
'src/core/lib/gprpp/thd_posix.cc',
'src/core/lib/gprpp/thd_windows.cc',
'src/core/lib/profiling/basic_timers.cc',
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 354f2a2f40..901dbfc9c8 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -1503,13 +1503,9 @@
% endif
$(LIBDIR)/$(CONFIG)/lib${lib.name}.a: \
- % if lib.name != 'z':
+ % if lib.name not in ['z', 'ares', 'address_sorting']:
$(ZLIB_DEP) \
- % endif
- % if lib.name != 'ares':
$(CARES_DEP) \
- % endif
- % if lib.name != 'address_sorting':
$(ADDRESS_SORTING_DEP) \
% endif
% endif
diff --git a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
index 672e9fbb5c..ac687b710f 100644
--- a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
@@ -33,6 +33,9 @@
RUN pip install coverage
ENV PATH ~/.local/bin:$PATH
+ # Install Mako to generate files in grpc/grpc-node
+ RUN pip install Mako
+
<%include file="../../run_tests_addons.include"/>
# Define the default command.
CMD ["bash"]
diff --git a/test/core/debug/stats_test.cc b/test/core/debug/stats_test.cc
index 949a88f8f0..aeb13655bf 100644
--- a/test/core/debug/stats_test.cc
+++ b/test/core/debug/stats_test.cc
@@ -142,9 +142,14 @@ INSTANTIATE_TEST_CASE_P(HistogramTestCases, HistogramTest,
} // namespace grpc
int main(int argc, char** argv) {
+/* Only run this test if GRPC_COLLECT_STATS is defined or if it is a debug
+ * build.
+ */
+#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG)
::testing::InitGoogleTest(&argc, argv);
grpc_init();
int ret = RUN_ALL_TESTS();
grpc_shutdown();
return ret;
+#endif
}
diff --git a/test/core/end2end/tests/simple_request.cc b/test/core/end2end/tests/simple_request.cc
index 2d6ccad0ec..941d9ae319 100644
--- a/test/core/end2end/tests/simple_request.cc
+++ b/test/core/end2end/tests/simple_request.cc
@@ -235,12 +235,14 @@ static void simple_request_body(grpc_end2end_test_config config,
if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) {
expected_calls *= 2;
}
+#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG)
GPR_ASSERT(after->counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] -
before->counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] ==
expected_calls);
GPR_ASSERT(after->counters[GRPC_STATS_COUNTER_SERVER_CALLS_CREATED] -
before->counters[GRPC_STATS_COUNTER_SERVER_CALLS_CREATED] ==
expected_calls);
+#endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */
gpr_free(before);
gpr_free(after);
}
diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD
index a8a5739552..e7232d9df8 100644
--- a/test/core/gprpp/BUILD
+++ b/test/core/gprpp/BUILD
@@ -19,6 +19,16 @@ licenses(["notice"]) # Apache v2
grpc_package(name = "test/core/gprpp")
grpc_cc_test(
+ name = "fork_test",
+ srcs = ["fork_test.cc"],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//test/core/util:gpr_test_util",
+ ],
+)
+
+grpc_cc_test(
name = "manual_constructor_test",
srcs = ["manual_constructor_test.cc"],
language = "C++",
diff --git a/test/core/gprpp/fork_test.cc b/test/core/gprpp/fork_test.cc
new file mode 100644
index 0000000000..05820eb885
--- /dev/null
+++ b/test/core/gprpp/fork_test.cc
@@ -0,0 +1,135 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "src/core/lib/gprpp/fork.h"
+
+#include "src/core/lib/gprpp/thd.h"
+#include "test/core/util/test_config.h"
+
+static void test_init() {
+ GPR_ASSERT(!grpc_core::Fork::Enabled());
+
+ // Default fork support (disabled)
+ grpc_core::Fork::GlobalInit();
+ GPR_ASSERT(!grpc_core::Fork::Enabled());
+ grpc_core::Fork::GlobalShutdown();
+
+ // Explicitly disabled fork support
+ grpc_core::Fork::Enable(false);
+ grpc_core::Fork::GlobalInit();
+ GPR_ASSERT(!grpc_core::Fork::Enabled());
+ grpc_core::Fork::GlobalShutdown();
+
+ // Explicitly enabled fork support
+ grpc_core::Fork::Enable(true);
+ grpc_core::Fork::GlobalInit();
+ GPR_ASSERT(grpc_core::Fork::Enabled());
+ grpc_core::Fork::GlobalShutdown();
+}
+
+#define THREAD_DELAY_MS 3000
+#define THREAD_DELAY_EPSILON 500
+#define CONCURRENT_TEST_THREADS 100
+
+static void sleeping_thd(void* arg) {
+ int64_t sleep_ms = (int64_t)arg;
+ gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_millis(sleep_ms, GPR_TIMESPAN)));
+}
+
+static void test_thd_count() {
+ // Test no active threads
+ grpc_core::Fork::Enable(true);
+ grpc_core::Fork::GlobalInit();
+ grpc_core::Fork::AwaitThreads();
+ grpc_core::Fork::GlobalShutdown();
+
+ grpc_core::Fork::Enable(true);
+ grpc_core::Fork::GlobalInit();
+ grpc_core::Thread thds[CONCURRENT_TEST_THREADS];
+ gpr_timespec est_end_time =
+ gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_millis(THREAD_DELAY_MS, GPR_TIMESPAN));
+ gpr_timespec tolerance =
+ gpr_time_from_millis(THREAD_DELAY_EPSILON, GPR_TIMESPAN);
+ for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) {
+ intptr_t sleep_time_ms =
+ (i * THREAD_DELAY_MS) / (CONCURRENT_TEST_THREADS - 1);
+ thds[i] =
+ grpc_core::Thread("grpc_fork_test", sleeping_thd, (void*)sleep_time_ms);
+ thds[i].Start();
+ }
+ grpc_core::Fork::AwaitThreads();
+ gpr_timespec end_time = gpr_now(GPR_CLOCK_REALTIME);
+ for (auto& thd : thds) {
+ thd.Join();
+ }
+ GPR_ASSERT(gpr_time_similar(end_time, est_end_time, tolerance));
+ grpc_core::Fork::GlobalShutdown();
+}
+
+static void exec_ctx_thread(void* arg) {
+ bool* exec_ctx_created = (bool*)arg;
+ grpc_core::Fork::IncExecCtxCount();
+ *exec_ctx_created = true;
+}
+
+static void test_exec_count() {
+ grpc_core::Fork::Enable(true);
+ grpc_core::Fork::GlobalInit();
+
+ grpc_core::Fork::IncExecCtxCount();
+ GPR_ASSERT(grpc_core::Fork::BlockExecCtx());
+ grpc_core::Fork::DecExecCtxCount();
+ grpc_core::Fork::AllowExecCtx();
+
+ grpc_core::Fork::IncExecCtxCount();
+ grpc_core::Fork::IncExecCtxCount();
+ GPR_ASSERT(!grpc_core::Fork::BlockExecCtx());
+ grpc_core::Fork::DecExecCtxCount();
+ grpc_core::Fork::DecExecCtxCount();
+
+ grpc_core::Fork::IncExecCtxCount();
+ GPR_ASSERT(grpc_core::Fork::BlockExecCtx());
+ grpc_core::Fork::DecExecCtxCount();
+ grpc_core::Fork::AllowExecCtx();
+
+ // Test that block_exec_ctx() blocks grpc_core::Fork::IncExecCtxCount
+ bool exec_ctx_created = false;
+ grpc_core::Thread thd =
+ grpc_core::Thread("grpc_fork_test", exec_ctx_thread, &exec_ctx_created);
+ grpc_core::Fork::IncExecCtxCount();
+ GPR_ASSERT(grpc_core::Fork::BlockExecCtx());
+ grpc_core::Fork::DecExecCtxCount();
+ thd.Start();
+ gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_seconds(1, GPR_TIMESPAN)));
+ GPR_ASSERT(!exec_ctx_created);
+ grpc_core::Fork::AllowExecCtx();
+ thd.Join(); // This ensure that the call got un-blocked
+ grpc_core::Fork::GlobalShutdown();
+}
+
+int main(int argc, char* argv[]) {
+ grpc_test_init(argc, argv);
+ test_init();
+ test_thd_count();
+ test_exec_count();
+
+ return 0;
+}
diff --git a/tools/bazel.rc b/tools/bazel.rc
index ed9169fc79..19e7921ca9 100644
--- a/tools/bazel.rc
+++ b/tools/bazel.rc
@@ -1,6 +1,7 @@
build --client_env=CC=clang
build --copt -DGRPC_BAZEL_BUILD
-build --copt -Wframe-larger-than=16384
+
+build:opt --copt -Wframe-larger-than=16384
build:asan --strip=never
build:asan --copt -fsanitize-coverage=edge
diff --git a/tools/codegen/core/gen_stats_data.py b/tools/codegen/core/gen_stats_data.py
index 3ebd00d049..33faeafc16 100755
--- a/tools/codegen/core/gen_stats_data.py
+++ b/tools/codegen/core/gen_stats_data.py
@@ -265,6 +265,7 @@ with open('src/core/lib/debug/stats_data.h', 'w') as H:
print >> H, " GRPC_STATS_HISTOGRAM_BUCKETS = %d" % first_slot
print >> H, "} grpc_stats_histogram_constants;"
+ print >> H, "#if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG)"
for ctr in inst_map['Counter']:
print >> H, ("#define GRPC_STATS_INC_%s() " +
"GRPC_STATS_INC_COUNTER(GRPC_STATS_COUNTER_%s)") % (
@@ -274,6 +275,14 @@ with open('src/core/lib/debug/stats_data.h', 'w') as H:
histogram.name.upper(), histogram.name.lower())
print >> H, "void grpc_stats_inc_%s(int x);" % histogram.name.lower()
+ print >> H, "#else"
+ for ctr in inst_map['Counter']:
+ print >> H, ("#define GRPC_STATS_INC_%s() ") % (ctr.name.upper())
+ for histogram in inst_map['Histogram']:
+ print >> H, "#define GRPC_STATS_INC_%s(value)" % (
+ histogram.name.upper())
+ print >> H, "#endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */"
+
for i, tbl in enumerate(static_tables):
print >> H, "extern const %s grpc_stats_table_%d[%d];" % (tbl[0], i,
len(tbl[1]))
diff --git a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
index e22484fbcd..40e13c385e 100644
--- a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
@@ -152,6 +152,9 @@ RUN python3.4 -m pip install virtualenv
RUN pip install coverage
ENV PATH ~/.local/bin:$PATH
+# Install Mako to generate files in grpc/grpc-node
+RUN pip install Mako
+
# Prepare ccache
RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
RUN ln -s /usr/bin/ccache /usr/local/bin/g++
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 7c6b75d8ed..37a936b7cd 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -1031,7 +1031,6 @@ src/core/lib/debug/stats_data.h \
src/core/lib/debug/trace.h \
src/core/lib/gpr/arena.h \
src/core/lib/gpr/env.h \
-src/core/lib/gpr/fork.h \
src/core/lib/gpr/host_port.h \
src/core/lib/gpr/mpscq.h \
src/core/lib/gpr/murmur_hash.h \
@@ -1050,6 +1049,7 @@ src/core/lib/gprpp/atomic.h \
src/core/lib/gprpp/atomic_with_atm.h \
src/core/lib/gprpp/atomic_with_std.h \
src/core/lib/gprpp/debug_location.h \
+src/core/lib/gprpp/fork.h \
src/core/lib/gprpp/inlined_vector.h \
src/core/lib/gprpp/manual_constructor.h \
src/core/lib/gprpp/memory.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 2d1541279e..6ae1c490a6 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1083,8 +1083,6 @@ src/core/lib/gpr/env.h \
src/core/lib/gpr/env_linux.cc \
src/core/lib/gpr/env_posix.cc \
src/core/lib/gpr/env_windows.cc \
-src/core/lib/gpr/fork.cc \
-src/core/lib/gpr/fork.h \
src/core/lib/gpr/host_port.cc \
src/core/lib/gpr/host_port.h \
src/core/lib/gpr/log.cc \
@@ -1128,6 +1126,8 @@ src/core/lib/gprpp/atomic.h \
src/core/lib/gprpp/atomic_with_atm.h \
src/core/lib/gprpp/atomic_with_std.h \
src/core/lib/gprpp/debug_location.h \
+src/core/lib/gprpp/fork.cc \
+src/core/lib/gprpp/fork.h \
src/core/lib/gprpp/inlined_vector.h \
src/core/lib/gprpp/manual_constructor.h \
src/core/lib/gprpp/memory.h \
diff --git a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh
index 0f71ff27cf..5c0e2df09d 100644
--- a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh
+++ b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh
@@ -50,13 +50,13 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc
--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-debian8@sha256:b2d946c1ddc20af250fe85cf98bd648ac5519131659f7c36e64184b433175a33" }' \
+ --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/cloud-marketplace/google/rbe-debian8@sha256:1ede2a929b44d629ec5abe86eee6d7ffea1d5a4d247489a8867d46cfde3e38bd" }' \
--define GRPC_PORT_ISOLATED_RUNTIME=1 \
--copt=-gmlt \
--strip=never \
--copt=-fsanitize=undefined \
--linkopt=-fsanitize=undefined \
- --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/debian8_clang/0.3.0/bazel_0.10.0/ubsan:ubsan_experimental_toolchain \
+ --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/debian8_clang/0.3.0/bazel_0.12.0/ubsan:toolchain \
-- //test/... || FAILED="true"
# Sleep to let ResultStore finish writing results before querying
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 4f0fc1d30d..d7dc75b80e 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -605,6 +605,21 @@
{
"deps": [
"gpr",
+ "gpr_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c",
+ "name": "fork_test",
+ "src": [
+ "test/core/gprpp/fork_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
"gpr_test_util",
"grpc",
"grpc_test_util"
@@ -9012,7 +9027,6 @@
"src/core/lib/gpr/env_linux.cc",
"src/core/lib/gpr/env_posix.cc",
"src/core/lib/gpr/env_windows.cc",
- "src/core/lib/gpr/fork.cc",
"src/core/lib/gpr/host_port.cc",
"src/core/lib/gpr/log.cc",
"src/core/lib/gpr/log_android.cc",
@@ -9037,6 +9051,7 @@
"src/core/lib/gpr/tmpfile_posix.cc",
"src/core/lib/gpr/tmpfile_windows.cc",
"src/core/lib/gpr/wrap_memcpy.cc",
+ "src/core/lib/gprpp/fork.cc",
"src/core/lib/gprpp/thd_posix.cc",
"src/core/lib/gprpp/thd_windows.cc",
"src/core/lib/profiling/basic_timers.cc",
@@ -9069,7 +9084,6 @@
"include/grpc/support/time.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
- "src/core/lib/gpr/fork.h",
"src/core/lib/gpr/host_port.h",
"src/core/lib/gpr/mpscq.h",
"src/core/lib/gpr/murmur_hash.h",
@@ -9087,6 +9101,7 @@
"src/core/lib/gprpp/atomic.h",
"src/core/lib/gprpp/atomic_with_atm.h",
"src/core/lib/gprpp/atomic_with_std.h",
+ "src/core/lib/gprpp/fork.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/memory.h",
"src/core/lib/gprpp/thd.h",
@@ -9115,7 +9130,6 @@
"include/grpc/support/time.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
- "src/core/lib/gpr/fork.h",
"src/core/lib/gpr/host_port.h",
"src/core/lib/gpr/mpscq.h",
"src/core/lib/gpr/murmur_hash.h",
@@ -9133,6 +9147,7 @@
"src/core/lib/gprpp/atomic.h",
"src/core/lib/gprpp/atomic_with_atm.h",
"src/core/lib/gprpp/atomic_with_std.h",
+ "src/core/lib/gprpp/fork.h",
"src/core/lib/gprpp/manual_constructor.h",
"src/core/lib/gprpp/memory.h",
"src/core/lib/gprpp/thd.h",
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 701f44fb92..461323380d 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -724,6 +724,26 @@
"benchmark": false,
"ci_platforms": [
"linux",
+ "mac"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": false,
+ "language": "c",
+ "name": "fork_test",
+ "platforms": [
+ "linux",
+ "mac"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
"mac",
"posix"
],
diff --git a/tools/run_tests/helper_scripts/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh
index c2a506afd8..6990244e51 100755
--- a/tools/run_tests/helper_scripts/build_python.sh
+++ b/tools/run_tests/helper_scripts/build_python.sh
@@ -129,7 +129,7 @@ fi
############################
# Instantiate the virtualenv from the Python version passed in.
-$PYTHON -m pip install virtualenv
+$PYTHON -m pip install --user virtualenv
$PYTHON -m virtualenv "$VENV"
VENV_PYTHON=$(script_realpath "$VENV/$VENV_RELATIVE_PYTHON")
@@ -150,7 +150,8 @@ pip_install_dir() {
case "$VENV" in
*gevent*)
- $VENV_PYTHON -m pip install gevent
+ # TODO(https://github.com/grpc/grpc/issues/15411) unpin this
+ $VENV_PYTHON -m pip install gevent==1.3.b1
;;
esac
diff --git a/tools/run_tests/performance/massage_qps_stats.py b/tools/run_tests/performance/massage_qps_stats.py
index 790202c43e..4056991d23 100644
--- a/tools/run_tests/performance/massage_qps_stats.py
+++ b/tools/run_tests/performance/massage_qps_stats.py
@@ -57,6 +57,10 @@ def massage_qps_stats(scenario_result):
stats[
"core_pollset_kick_own_thread"] = massage_qps_stats_helpers.counter(
core_stats, "pollset_kick_own_thread")
+ stats["core_syscall_epoll_ctl"] = massage_qps_stats_helpers.counter(
+ core_stats, "syscall_epoll_ctl")
+ stats["core_pollset_fd_cache_hits"] = massage_qps_stats_helpers.counter(
+ core_stats, "pollset_fd_cache_hits")
stats[
"core_histogram_slow_lookups"] = massage_qps_stats_helpers.counter(
core_stats, "histogram_slow_lookups")
diff --git a/tools/run_tests/performance/scenario_result_schema.json b/tools/run_tests/performance/scenario_result_schema.json
index b00c2eed16..8b8ebb9b4c 100644
--- a/tools/run_tests/performance/scenario_result_schema.json
+++ b/tools/run_tests/performance/scenario_result_schema.json
@@ -182,6 +182,16 @@
},
{
"mode": "NULLABLE",
+ "name": "core_syscall_epoll_ctl",
+ "type": "INTEGER"
+ },
+ {
+ "mode": "NULLABLE",
+ "name": "core_pollset_fd_cache_hits",
+ "type": "INTEGER"
+ },
+ {
+ "mode": "NULLABLE",
"name": "core_histogram_slow_lookups",
"type": "INTEGER"
},
@@ -1014,6 +1024,16 @@
},
{
"mode": "NULLABLE",
+ "name": "core_syscall_epoll_ctl",
+ "type": "INTEGER"
+ },
+ {
+ "mode": "NULLABLE",
+ "name": "core_pollset_fd_cache_hits",
+ "type": "INTEGER"
+ },
+ {
+ "mode": "NULLABLE",
"name": "core_histogram_slow_lookups",
"type": "INTEGER"
},
diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py
index 989990542e..1d3f2eba8a 100755
--- a/tools/run_tests/sanity/core_banned_functions.py
+++ b/tools/run_tests/sanity/core_banned_functions.py
@@ -23,35 +23,39 @@ os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
# map of banned function signature to whitelist
BANNED_EXCEPT = {
- 'grpc_resource_quota_ref(': ['src/core/lib/iomgr/resource_quota.c'],
- 'grpc_resource_quota_unref(': ['src/core/lib/iomgr/resource_quota.c'],
- 'grpc_slice_buffer_destroy(': ['src/core/lib/slice/slice_buffer.c'],
- 'grpc_slice_buffer_reset_and_unref(': ['src/core/lib/slice/slice_buffer.c'],
- 'grpc_slice_ref(': ['src/core/lib/slice/slice.c'],
- 'grpc_slice_unref(': ['src/core/lib/slice/slice.c'],
- 'grpc_error_create(': ['src/core/lib/iomgr/error.c'],
- 'grpc_error_ref(': ['src/core/lib/iomgr/error.c'],
- 'grpc_error_unref(': ['src/core/lib/iomgr/error.c'],
- 'grpc_os_error(': ['src/core/lib/iomgr/error.c'],
- 'grpc_wsa_error(': ['src/core/lib/iomgr/error.c'],
- 'grpc_log_if_error(': ['src/core/lib/iomgr/error.c'],
- 'grpc_slice_malloc(': ['src/core/lib/slice/slice.c'],
- 'grpc_closure_create(': ['src/core/lib/iomgr/closure.c'],
- 'grpc_closure_init(': ['src/core/lib/iomgr/closure.c'],
- 'grpc_closure_sched(': ['src/core/lib/iomgr/closure.c'],
- 'grpc_closure_run(': ['src/core/lib/iomgr/closure.c'],
- 'grpc_closure_list_sched(': ['src/core/lib/iomgr/closure.c'],
+ 'grpc_resource_quota_ref(': ['src/core/lib/iomgr/resource_quota.cc'],
+ 'grpc_resource_quota_unref(': ['src/core/lib/iomgr/resource_quota.cc'],
+ 'grpc_slice_buffer_destroy(': ['src/core/lib/slice/slice_buffer.cc'],
+ 'grpc_slice_buffer_reset_and_unref(':
+ ['src/core/lib/slice/slice_buffer.cc'],
+ 'grpc_slice_ref(': ['src/core/lib/slice/slice.cc'],
+ 'grpc_slice_unref(': ['src/core/lib/slice/slice.cc'],
+ 'grpc_error_create(': ['src/core/lib/iomgr/error.cc'],
+ 'grpc_error_ref(': ['src/core/lib/iomgr/error.cc'],
+ 'grpc_error_unref(': ['src/core/lib/iomgr/error.cc'],
+ 'grpc_os_error(': ['src/core/lib/iomgr/error.cc'],
+ 'grpc_wsa_error(': ['src/core/lib/iomgr/error.cc'],
+ 'grpc_log_if_error(': ['src/core/lib/iomgr/error.cc'],
+ 'grpc_slice_malloc(': ['src/core/lib/slice/slice.cc'],
+ 'grpc_closure_create(': ['src/core/lib/iomgr/closure.cc'],
+ 'grpc_closure_init(': ['src/core/lib/iomgr/closure.cc'],
+ 'grpc_closure_sched(': ['src/core/lib/iomgr/closure.cc'],
+ 'grpc_closure_run(': ['src/core/lib/iomgr/closure.cc'],
+ 'grpc_closure_list_sched(': ['src/core/lib/iomgr/closure.cc'],
'gpr_getenv_silent(': [
- 'src/core/lib/gpr/log.c', 'src/core/lib/gpr/env_linux.c',
- 'src/core/lib/gpr/env_posix.c', 'src/core/lib/gpr/env_windows.c'
+ 'src/core/lib/gpr/log.cc', 'src/core/lib/gpr/env_linux.cc',
+ 'src/core/lib/gpr/env_posix.cc', 'src/core/lib/gpr/env_windows.cc'
],
}
errors = 0
+num_files = 0
for root, dirs, files in os.walk('src/core'):
+ if root.startswith('src/core/tsi'): continue
for filename in files:
+ num_files += 1
path = os.path.join(root, filename)
- if os.path.splitext(path)[1] != '.c': continue
+ if os.path.splitext(path)[1] != '.cc': continue
with open(path) as f:
text = f.read()
for banned, exceptions in BANNED_EXCEPT.items():
@@ -61,3 +65,8 @@ for root, dirs, files in os.walk('src/core'):
errors += 1
assert errors == 0
+# This check comes about from this issue:
+# https://github.com/grpc/grpc/issues/15381
+# Basically, a change rendered this script useless and we did not realize it.
+# This dumb check ensures that this type of issue doesn't occur again.
+assert num_files > 300 # we definitely have more than 300 files