Skip to content

Commit 415b71c

Browse files
committed
Defensive programming: ACEC is an optimization and not strictly needed
1 parent e9b4e16 commit 415b71c

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

src/core/lib/iomgr/exec_ctx.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ class ApplicationCallbackExecCtx {
357357
/** Global shutdown for ApplicationCallbackExecCtx. Called by init. */
358358
static void GlobalShutdown(void) { gpr_tls_destroy(&callback_exec_ctx_); }
359359

360+
static bool Available() {
361+
return reinterpret_cast<ApplicationCallbackExecCtx*>(
362+
gpr_tls_get(&callback_exec_ctx_)) != nullptr;
363+
}
364+
360365
private:
361366
uintptr_t flags_{0u};
362367
grpc_experimental_completion_queue_functor* head_{nullptr};

src/core/lib/surface/completion_queue.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,8 +874,15 @@ static void cq_end_op_for_callback(
874874
cq_finish_shutdown_callback(cq);
875875
}
876876

877+
// If possible, schedule the callback onto an existing thread-local
878+
// ApplicationCallbackExecCtx, which is a work queue. This is possible for:
879+
// 1. The callback is internally-generated and there is an ACEC available
880+
// 2. The callback is marked inlineable and there is an ACEC available
881+
// 3. We are already running in a background poller thread (which always has
882+
// an ACEC available at the base of the stack).
877883
auto* functor = static_cast<grpc_experimental_completion_queue_functor*>(tag);
878-
if (internal || functor->inlineable ||
884+
if (((internal || functor->inlineable) &&
885+
grpc_core::ApplicationCallbackExecCtx::Available()) ||
879886
grpc_iomgr_is_any_background_poller_thread()) {
880887
grpc_core::ApplicationCallbackExecCtx::Enqueue(functor,
881888
(error == GRPC_ERROR_NONE));

0 commit comments

Comments
 (0)