Defensive programming: ACEC is an optimization and not strictly needed

pull/22837/head
Vijay Pai 5 years ago
parent e9b4e168ba
commit 415b71c98d
  1. 5
      src/core/lib/iomgr/exec_ctx.h
  2. 9
      src/core/lib/surface/completion_queue.cc

@ -357,6 +357,11 @@ class ApplicationCallbackExecCtx {
/** Global shutdown for ApplicationCallbackExecCtx. Called by init. */ /** Global shutdown for ApplicationCallbackExecCtx. Called by init. */
static void GlobalShutdown(void) { gpr_tls_destroy(&callback_exec_ctx_); } static void GlobalShutdown(void) { gpr_tls_destroy(&callback_exec_ctx_); }
static bool Available() {
return reinterpret_cast<ApplicationCallbackExecCtx*>(
gpr_tls_get(&callback_exec_ctx_)) != nullptr;
}
private: private:
uintptr_t flags_{0u}; uintptr_t flags_{0u};
grpc_experimental_completion_queue_functor* head_{nullptr}; grpc_experimental_completion_queue_functor* head_{nullptr};

@ -874,8 +874,15 @@ static void cq_end_op_for_callback(
cq_finish_shutdown_callback(cq); cq_finish_shutdown_callback(cq);
} }
// If possible, schedule the callback onto an existing thread-local
// ApplicationCallbackExecCtx, which is a work queue. This is possible for:
// 1. The callback is internally-generated and there is an ACEC available
// 2. The callback is marked inlineable and there is an ACEC available
// 3. We are already running in a background poller thread (which always has
// an ACEC available at the base of the stack).
auto* functor = static_cast<grpc_experimental_completion_queue_functor*>(tag); auto* functor = static_cast<grpc_experimental_completion_queue_functor*>(tag);
if (internal || functor->inlineable || if (((internal || functor->inlineable) &&
grpc_core::ApplicationCallbackExecCtx::Available()) ||
grpc_iomgr_is_any_background_poller_thread()) { grpc_iomgr_is_any_background_poller_thread()) {
grpc_core::ApplicationCallbackExecCtx::Enqueue(functor, grpc_core::ApplicationCallbackExecCtx::Enqueue(functor,
(error == GRPC_ERROR_NONE)); (error == GRPC_ERROR_NONE));

Loading…
Cancel
Save