|  | @@ -144,6 +144,7 @@ struct grpc_server {
 | 
	
		
			
				|  |  |    requested_call_array requested_calls;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    gpr_uint8 shutdown;
 | 
	
		
			
				|  |  | +  gpr_uint8 shutdown_published;
 | 
	
		
			
				|  |  |    size_t num_shutdown_tags;
 | 
	
		
			
				|  |  |    shutdown_tag *shutdown_tags;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -389,7 +390,8 @@ static int num_listeners(grpc_server *server) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void maybe_finish_shutdown(grpc_server *server) {
 | 
	
		
			
				|  |  |    size_t i;
 | 
	
		
			
				|  |  | -  if (server->shutdown && server->lists[ALL_CALLS] == NULL && server->listeners_destroyed == num_listeners(server)) {
 | 
	
		
			
				|  |  | +  if (server->shutdown && !server->shutdown_published && server->lists[ALL_CALLS] == NULL && server->listeners_destroyed == num_listeners(server)) {
 | 
	
		
			
				|  |  | +    server->shutdown_published = 1;
 | 
	
		
			
				|  |  |      for (i = 0; i < server->num_shutdown_tags; i++) {
 | 
	
		
			
				|  |  |        grpc_cq_end_op(server->shutdown_tags[i].cq, server->shutdown_tags[i].tag,
 | 
	
		
			
				|  |  |                       NULL, 1);
 | 
	
	
		
			
				|  | @@ -456,8 +458,9 @@ static void server_on_recv(void *ptr, int success) {
 | 
	
		
			
				|  |  |          calld->state = ZOMBIED;
 | 
	
		
			
				|  |  |          grpc_iomgr_add_callback(kill_zombie, elem);
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  | -      call_list_remove(calld, ALL_CALLS);
 | 
	
		
			
				|  |  | -      maybe_finish_shutdown(chand->server);
 | 
	
		
			
				|  |  | +      if (call_list_remove(calld, ALL_CALLS)) {
 | 
	
		
			
				|  |  | +        maybe_finish_shutdown(chand->server);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  |        gpr_mu_unlock(&chand->server->mu);
 | 
	
		
			
				|  |  |        break;
 | 
	
		
			
				|  |  |    }
 | 
	
	
		
			
				|  | @@ -822,9 +825,7 @@ void grpc_server_shutdown_and_notify(grpc_server *server,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    /* lock, and gather up some stuff to do */
 | 
	
		
			
				|  |  |    gpr_mu_lock(&server->mu);
 | 
	
		
			
				|  |  | -  for (i = 0; i < server->cq_count; i++) {
 | 
	
		
			
				|  |  | -    grpc_cq_begin_op(server->cqs[i], NULL);
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +  grpc_cq_begin_op(cq, NULL);
 | 
	
		
			
				|  |  |    server->shutdown_tags =
 | 
	
		
			
				|  |  |        gpr_realloc(server->shutdown_tags,
 | 
	
		
			
				|  |  |                    sizeof(void *) * (server->num_shutdown_tags + 1));
 |