diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h index cf1118a003c..8ddab0d3810 100644 --- a/src/core/lib/iomgr/exec_ctx.h +++ b/src/core/lib/iomgr/exec_ctx.h @@ -45,6 +45,9 @@ typedef struct grpc_combiner grpc_combiner; /* The exec_ctx's thread is (potentially) owned by a call or channel: care should be given to not delete said call/channel from this exec_ctx */ #define GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP 2 +/* This exec ctx was initialized by an internal thread, and should not + be counted by fork handlers */ +#define GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD 4 extern grpc_closure_scheduler* grpc_schedule_on_exec_ctx; @@ -93,7 +96,9 @@ class ExecCtx { /** Parameterised Constructor */ ExecCtx(uintptr_t fl) : flags_(fl) { - grpc_core::Fork::IncExecCtxCount(); + if (!(GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags_)) { + grpc_core::Fork::IncExecCtxCount(); + } Set(this); } @@ -102,7 +107,9 @@ class ExecCtx { flags_ |= GRPC_EXEC_CTX_FLAG_IS_FINISHED; Flush(); Set(last_exec_ctx_); - grpc_core::Fork::DecExecCtxCount(); + if (!(GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags_)) { + grpc_core::Fork::DecExecCtxCount(); + } } /** Disallow copy and assignment operators */ diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc index f19f8cf20d5..db4b45d1a98 100644 --- a/src/core/lib/iomgr/executor.cc +++ b/src/core/lib/iomgr/executor.cc @@ -145,7 +145,7 @@ static void executor_thread(void* arg) { thread_state* ts = static_cast(arg); gpr_tls_set(&g_this_thread_state, (intptr_t)ts); - grpc_core::ExecCtx exec_ctx(0); + grpc_core::ExecCtx exec_ctx(GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD); size_t subtract_depth = 0; for (;;) { diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index 9fdae17909c..55be919bbb0 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -265,7 +265,7 @@ static void timer_thread_cleanup(completed_thread* ct) { static void timer_thread(void* completed_thread_ptr) { // this threads exec_ctx: we try to run things through to completion here // since it's easy to spin up new threads - grpc_core::ExecCtx exec_ctx(0); + grpc_core::ExecCtx exec_ctx(GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD); timer_main_loop(); timer_thread_cleanup(static_cast(completed_thread_ptr));