| 
					
				 | 
			
			
				@@ -124,7 +124,7 @@ static grpc_error* non_polling_poller_work(grpc_pollset* pollset, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   while (!npp->shutdown && !w.kicked && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          !gpr_cv_wait(&w.cv, &npp->mu, deadline_ts)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grpc_exec_ctx_invalidate_now(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ExecCtx::Get()->InvalidateNow(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (&w == npp->root) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     npp->root = w.next; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (&w == npp->root) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -371,7 +371,6 @@ int grpc_completion_queue_thread_local_cache_flush(grpc_completion_queue* cq, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       gpr_mu_unlock(cq->mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       GRPC_CQ_INTERNAL_UNREF(cq, "shutting_down"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    grpc_exec_ctx_finish(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_tls_set(&g_cached_event, (intptr_t)0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_tls_set(&g_cached_cq, (intptr_t)0); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -412,8 +411,6 @@ static grpc_cq_completion* cq_event_queue_pop(grpc_cq_event_queue* q) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GRPC_STATS_INC_CQ_EV_QUEUE_TRYLOCK_FAILURES(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grpc_exec_ctx_finish(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     gpr_atm_no_barrier_fetch_add(&q->num_queue_items, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -445,7 +442,6 @@ grpc_completion_queue* grpc_completion_queue_create_internal( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   ExecCtx _local_exec_ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GRPC_STATS_INC_CQS_CREATED(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grpc_exec_ctx_finish(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   cq = (grpc_completion_queue*)gpr_zalloc(sizeof(grpc_completion_queue) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                           vtable->data_size + 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -639,9 +635,9 @@ static void cq_end_op_for_next(grpc_completion_queue* cq, void* tag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        error != GRPC_ERROR_NONE)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const char* errmsg = grpc_error_string(error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GRPC_API_TRACE( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        "cq_end_op_for_next(=%p, cq=%p, tag=%p, error=%s, " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        "cq_end_op_for_next(cq=%p, tag=%p, error=%s, " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         "done=%p, done_arg=%p, storage=%p)", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        7, (exec_ctx, cq, tag, errmsg, done, done_arg, storage)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        6, (cq, tag, errmsg, done, done_arg, storage)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (GRPC_TRACER_ON(grpc_trace_operation_failures) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         error != GRPC_ERROR_NONE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -726,9 +722,9 @@ static void cq_end_op_for_pluck(grpc_completion_queue* cq, void* tag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        error != GRPC_ERROR_NONE)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const char* errmsg = grpc_error_string(error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GRPC_API_TRACE( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        "cq_end_op_for_pluck(=%p, cq=%p, tag=%p, error=%s, " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        "cq_end_op_for_pluck(cq=%p, tag=%p, error=%s, " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         "done=%p, done_arg=%p, storage=%p)", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        7, (exec_ctx, cq, tag, errmsg, done, done_arg, storage)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        6, (cq, tag, errmsg, done, done_arg, storage)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (GRPC_TRACER_ON(grpc_trace_operation_failures) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         error != GRPC_ERROR_NONE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -794,31 +790,40 @@ typedef struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   bool first_loop; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } cq_is_finished_arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static bool cq_is_next_finished(void* arg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  cq_is_finished_arg* a = (cq_is_finished_arg*)arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grpc_completion_queue* cq = a->cq; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  cq_next_data* cqd = (cq_next_data*)DATA_FROM_CQ(cq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  GPR_ASSERT(a->stolen_completion == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class ExecCtxNext : public ExecCtx { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ExecCtxNext(void* arg) : ExecCtx(0), check_ready_to_finish_arg_(arg) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gpr_atm current_last_seen_things_queued_ever = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      gpr_atm_no_barrier_load(&cqd->things_queued_ever); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  bool CheckReadyToFinish() override { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cq_is_finished_arg* a = (cq_is_finished_arg*)check_ready_to_finish_arg_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_completion_queue* cq = a->cq; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cq_next_data* cqd = (cq_next_data*)DATA_FROM_CQ(cq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GPR_ASSERT(a->stolen_completion == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    a->last_seen_things_queued_ever = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_atm current_last_seen_things_queued_ever = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         gpr_atm_no_barrier_load(&cqd->things_queued_ever); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /* Pop a cq_completion from the queue. Returns NULL if the queue is empty 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * might return NULL in some cases even if the queue is not empty; but 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * that 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * is ok and doesn't affect correctness. Might effect the tail latencies a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * bit) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    a->stolen_completion = cq_event_queue_pop(&cqd->queue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (a->stolen_completion != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (current_last_seen_things_queued_ever != 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        a->last_seen_things_queued_ever) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      a->last_seen_things_queued_ever = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          gpr_atm_no_barrier_load(&cqd->things_queued_ever); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      /* Pop a cq_completion from the queue. Returns NULL if the queue is empty 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * might return NULL in some cases even if the queue is not empty; but 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * that 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * is ok and doesn't affect correctness. Might effect the tail latencies a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * bit) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      a->stolen_completion = cq_event_queue_pop(&cqd->queue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (a->stolen_completion != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return !a->first_loop && a->deadline < ExecCtx::Get()->Now(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return !a->first_loop && a->deadline < grpc_exec_ctx_now(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ private: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  void* check_ready_to_finish_arg_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #ifndef NDEBUG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void dump_pending_tags(grpc_completion_queue* cq) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -873,7 +878,7 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       NULL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       NULL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       true}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ExecCtx _local_exec_ctx(0, cq_is_next_finished, &is_finished_arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ExecCtxNext _local_exec_ctx(&is_finished_arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (;;) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_millis iteration_deadline = deadline_millis; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -923,7 +928,8 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!is_finished_arg.first_loop && grpc_exec_ctx_now() >= deadline_millis) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!is_finished_arg.first_loop && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ExecCtx::Get()->Now() >= deadline_millis) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       memset(&ret, 0, sizeof(ret)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       ret.type = GRPC_QUEUE_TIMEOUT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       dump_pending_tags(cq); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -959,7 +965,7 @@ static grpc_event cq_next(grpc_completion_queue* cq, gpr_timespec deadline, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, &ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GRPC_CQ_INTERNAL_UNREF(cq, "next"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grpc_exec_ctx_finish(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_ASSERT(is_finished_arg.stolen_completion == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_TIMER_END("grpc_completion_queue_next", 0); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1039,37 +1045,46 @@ static void del_plucker(grpc_completion_queue* cq, void* tag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_UNREACHABLE_CODE(return ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static bool cq_is_pluck_finished(void* arg) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  cq_is_finished_arg* a = (cq_is_finished_arg*)arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grpc_completion_queue* cq = a->cq; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  cq_pluck_data* cqd = (cq_pluck_data*)DATA_FROM_CQ(cq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class ExecCtxPluck : public ExecCtx { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ExecCtxPluck(void* arg) : ExecCtx(0), check_ready_to_finish_arg_(arg) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  GPR_ASSERT(a->stolen_completion == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gpr_atm current_last_seen_things_queued_ever = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      gpr_atm_no_barrier_load(&cqd->things_queued_ever); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    gpr_mu_lock(cq->mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    a->last_seen_things_queued_ever = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  bool CheckReadyToFinish() override { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cq_is_finished_arg* a = (cq_is_finished_arg*)check_ready_to_finish_arg_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_completion_queue* cq = a->cq; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cq_pluck_data* cqd = (cq_pluck_data*)DATA_FROM_CQ(cq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GPR_ASSERT(a->stolen_completion == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_atm current_last_seen_things_queued_ever = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         gpr_atm_no_barrier_load(&cqd->things_queued_ever); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    grpc_cq_completion* c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    grpc_cq_completion* prev = &cqd->completed_head; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    while ((c = (grpc_cq_completion*)(prev->next & ~(uintptr_t)1)) != 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           &cqd->completed_head) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (c->tag == a->tag) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (c == cqd->completed_tail) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          cqd->completed_tail = prev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (current_last_seen_things_queued_ever != 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        a->last_seen_things_queued_ever) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_mu_lock(cq->mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      a->last_seen_things_queued_ever = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          gpr_atm_no_barrier_load(&cqd->things_queued_ever); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_cq_completion* c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_cq_completion* prev = &cqd->completed_head; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while ((c = (grpc_cq_completion*)(prev->next & ~(uintptr_t)1)) != 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             &cqd->completed_head) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (c->tag == a->tag) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (c == cqd->completed_tail) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cqd->completed_tail = prev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          gpr_mu_unlock(cq->mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          a->stolen_completion = c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        gpr_mu_unlock(cq->mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        a->stolen_completion = c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        prev = c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      prev = c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      gpr_mu_unlock(cq->mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    gpr_mu_unlock(cq->mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return !a->first_loop && a->deadline < ExecCtx::Get()->Now(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return !a->first_loop && a->deadline < grpc_exec_ctx_now(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ private: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  void* check_ready_to_finish_arg_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            gpr_timespec deadline, void* reserved) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1106,7 +1121,7 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       NULL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       tag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       true}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ExecCtx _local_exec_ctx(0, cq_is_pluck_finished, &is_finished_arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ExecCtxPluck _local_exec_ctx(&is_finished_arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   for (;;) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (is_finished_arg.stolen_completion != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       gpr_mu_unlock(cq->mu); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1153,7 +1168,8 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       dump_pending_tags(cq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!is_finished_arg.first_loop && grpc_exec_ctx_now() >= deadline_millis) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!is_finished_arg.first_loop && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ExecCtx::Get()->Now() >= deadline_millis) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       del_plucker(cq, tag, &worker); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       gpr_mu_unlock(cq->mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       memset(&ret, 0, sizeof(ret)); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1182,7 +1198,7 @@ static grpc_event cq_pluck(grpc_completion_queue* cq, void* tag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 done: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, &ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GRPC_CQ_INTERNAL_UNREF(cq, "pluck"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grpc_exec_ctx_finish(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_ASSERT(is_finished_arg.stolen_completion == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_TIMER_END("grpc_completion_queue_pluck", 0); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1238,7 +1254,7 @@ void grpc_completion_queue_shutdown(grpc_completion_queue* cq) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_TIMER_BEGIN("grpc_completion_queue_shutdown", 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GRPC_API_TRACE("grpc_completion_queue_shutdown(cq=%p)", 1, (cq)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   cq->vtable->shutdown(cq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grpc_exec_ctx_finish(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_TIMER_END("grpc_completion_queue_shutdown", 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1249,7 +1265,7 @@ void grpc_completion_queue_destroy(grpc_completion_queue* cq) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   ExecCtx _local_exec_ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GRPC_CQ_INTERNAL_UNREF(cq, "destroy"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grpc_exec_ctx_finish(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GPR_TIMER_END("grpc_completion_queue_destroy", 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |