|
|
@ -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)); |
|
|
|