From c7aee34c37ec794b2df356e64293ba27cde3c92a Mon Sep 17 00:00:00 2001 From: AJ Heller Date: Fri, 12 May 2023 10:30:49 -0700 Subject: [PATCH] [iomgr] Fix epoll1 engine reinitialization after grpc_shutdown (#33085) Fixes https://github.com/grpc/grpc/issues/32481. Please test this with the (excellent) repro case in https://github.com/grpc/grpc/pull/33000, and consider merging _just_ the test from that PR. Per #32481, the issue was bisected to https://github.com/grpc/grpc/pull/30101. What changed in that PR is that the epoll1 engine is only checked for availablily once per process at iomgr initialization (which as a side effect initializes the engine), but the engine was being shutdown with `grpc_shutdown` anyhow. With repeated cycles of grpc init & shutdown in the same process, the second attempt to reinit and use gRPC finds the epoll1 engine in an invalid state. --- src/core/lib/iomgr/ev_epoll1_linux.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index 83b379552af..8e88ebbb9f2 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -61,6 +61,7 @@ #include "src/core/lib/iomgr/wakeup_fd_posix.h" static grpc_wakeup_fd global_wakeup_fd; +static bool g_is_shutdown = true; //****************************************************************************** // Singleton epoll set related fields @@ -1239,6 +1240,7 @@ static void shutdown_engine(void) { gpr_mu_destroy(&fork_fd_list_mu); grpc_core::Fork::SetResetChildPollingEngineFunc(nullptr); } + g_is_shutdown = true; } static bool init_epoll1_linux(); @@ -1278,10 +1280,13 @@ const grpc_event_engine_vtable grpc_ev_epoll1_posix = { is_any_background_poller_thread, /* name = */ "epoll1", - /* check_engine_available = */ [](bool) { return init_epoll1_linux(); }, - /* init_engine = */ []() {}, + /* check_engine_available = */ + [](bool) { return init_epoll1_linux(); }, + /* init_engine = */ + []() { GPR_ASSERT(init_epoll1_linux()); }, shutdown_background_closure, - /* shutdown_engine = */ []() {}, + /* shutdown_engine = */ + []() { shutdown_engine(); }, add_closure_to_background_poller, fd_set_pre_allocated, @@ -1306,6 +1311,7 @@ static void reset_event_manager_on_fork() { // Create epoll_fd (epoll_set_init() takes care of that) to make sure epoll // support is available static bool init_epoll1_linux() { + if (!g_is_shutdown) return true; if (!grpc_has_wakeup_fd()) { gpr_log(GPR_ERROR, "Skipping epoll1 because of no wakeup fd."); return false; @@ -1328,6 +1334,7 @@ static bool init_epoll1_linux() { grpc_core::Fork::SetResetChildPollingEngineFunc( reset_event_manager_on_fork); } + g_is_shutdown = false; return true; }