diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 50a24163219bee7cc5f6de163da49eca48b031a4..2cfeb359fc08c2162e20f064ea65c61ffcdc56dd 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -77,6 +77,7 @@ class Server GRPC_FINAL : public GrpcLibrary,
 
   class SyncRequest;
   class AsyncRequest;
+  class ShutdownRequest;
 
   // ServerBuilder use only
   Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index d3b97489eb7d3519bf6e295324f2185927ba6777..db2ee22c9944d8ab8689365a58164f432f91de4a 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -491,7 +491,8 @@ void grpc_server_start(grpc_server *server);
    Send a GRPC_OP_COMPLETE event when there are no more calls being serviced.
    Shutdown is idempotent, and all tags will be notified at once if multiple
    grpc_server_shutdown_and_notify calls are made. */
-void grpc_server_shutdown_and_notify(grpc_server *server, void *tag);
+void grpc_server_shutdown_and_notify(grpc_server *server,
+                                     grpc_completion_queue *cq, void *tag);
 
 /* Cancel all in-progress calls. 
    Only usable after shutdown. */
diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c
index 6d49637f8e36cbe467e118c8f029f8c50ece6ff4..b48fbace315b477000ab2a07911f5f42e986e449 100644
--- a/src/core/surface/completion_queue.c
+++ b/src/core/surface/completion_queue.c
@@ -150,7 +150,6 @@ void grpc_cq_end_op(grpc_completion_queue *cc, void *tag, grpc_call *call,
                     int success) {
   event *ev;
   int shutdown = 0;
-  gpr_log(GPR_DEBUG, "end_op:%p", tag);
   gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
   ev = add_locked(cc, GRPC_OP_COMPLETE, tag, call);
   ev->base.success = success;
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 37ceca43ba467817d3c27af050f45d3040029b6e..0bf7f8331fbbfb94afda9cfd387e17f25b14e047 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -124,6 +124,11 @@ struct channel_data {
   gpr_uint32 registered_method_max_probes;
 };
 
+typedef struct shutdown_tag {
+  void *tag;
+  grpc_completion_queue *cq;
+} shutdown_tag;
+
 struct grpc_server {
   size_t channel_filter_count;
   const grpc_channel_filter **channel_filters;
@@ -140,7 +145,7 @@ struct grpc_server {
 
   gpr_uint8 shutdown;
   size_t num_shutdown_tags;
-  void **shutdown_tags;
+  shutdown_tag *shutdown_tags;
 
   call_data *lists[CALL_LIST_COUNT];
   channel_data root_channel_data;
@@ -383,13 +388,11 @@ static int num_listeners(grpc_server *server) {
 }
 
 static void maybe_finish_shutdown(grpc_server *server) {
-  size_t i, j;
+  size_t i;
   if (server->shutdown && server->lists[ALL_CALLS] == NULL && server->listeners_destroyed == num_listeners(server)) {
     for (i = 0; i < server->num_shutdown_tags; i++) {
-      for (j = 0; j < server->cq_count; j++) {
-        grpc_cq_end_op(server->cqs[j], server->shutdown_tags[i],
-                       NULL, 1);
-      }
+      grpc_cq_end_op(server->shutdown_tags[i].cq, server->shutdown_tags[i].tag,
+                     NULL, 1);
     }
   }
 }
@@ -804,7 +807,8 @@ grpc_transport_setup_result grpc_server_setup_transport(
   return result;
 }
 
-void grpc_server_shutdown_and_notify(grpc_server *server, void *shutdown_tag) {
+void grpc_server_shutdown_and_notify(grpc_server *server,
+                                     grpc_completion_queue *cq, void *tag) {
   listener *l;
   requested_call_array requested_calls;
   channel_data **channels;
@@ -814,6 +818,7 @@ void grpc_server_shutdown_and_notify(grpc_server *server, void *shutdown_tag) {
   grpc_channel_op op;
   grpc_channel_element *elem;
   registered_method *rm;
+  shutdown_tag *sdt;
 
   /* lock, and gather up some stuff to do */
   gpr_mu_lock(&server->mu);
@@ -823,7 +828,9 @@ void grpc_server_shutdown_and_notify(grpc_server *server, void *shutdown_tag) {
   server->shutdown_tags =
       gpr_realloc(server->shutdown_tags,
                   sizeof(void *) * (server->num_shutdown_tags + 1));
-  server->shutdown_tags[server->num_shutdown_tags++] = shutdown_tag;
+  sdt = &server->shutdown_tags[server->num_shutdown_tags++];
+  sdt->tag = tag;
+  sdt->cq = cq;
   if (server->shutdown) {
     gpr_mu_unlock(&server->mu);
     return;
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index e66b4ed2d8ba20eda2bbb3fcd2baab926c4dabc7..bcd631963faa161dad341df4c7967536409dcfe7 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -52,6 +52,14 @@
 
 namespace grpc {
 
+class Server::ShutdownRequest GRPC_FINAL : public CompletionQueueTag {
+ public:
+  bool FinalizeResult(void** tag, bool* status) {
+    delete this;
+    return false;
+  }
+};
+
 class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag {
  public:
   SyncRequest(RpcServiceMethod* method, void* tag)
@@ -286,7 +294,7 @@ void Server::Shutdown() {
   grpc::unique_lock<grpc::mutex> lock(mu_);
   if (started_ && !shutdown_) {
     shutdown_ = true;
-    grpc_server_shutdown(server_);
+    grpc_server_shutdown_and_notify(server_, cq_.cq(), new ShutdownRequest());
     cq_.Shutdown();
 
     // Wait for running callbacks to finish.
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index b440d738b9cef99d6675ca96bdd1a2cee703db02..3b3680794b55df9ca17f1c288fb6da85b8fe8d90 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -206,7 +206,7 @@ void test_connect(const char *server_host, const char *client_host, int port,
   grpc_completion_queue_destroy(client_cq);
 
   /* Destroy server. */
-  grpc_server_shutdown_and_notify(server, tag(1000));
+  grpc_server_shutdown_and_notify(server, server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(server);
   grpc_completion_queue_shutdown(server_cq);
diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c
index 51f311080d69be3c56221e2f634ffd31c4666969..6533b3c475932cd389fd07eb854b7660a1580ab8 100644
--- a/test/core/end2end/tests/bad_hostname.c
+++ b/test/core/end2end/tests/bad_hostname.c
@@ -76,7 +76,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c
index 539509fa8eec59b14a0b5360a2cb385cab2895fe..b1fa496d83f61458dc310cd5d1300559d72fd190 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -75,7 +75,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
index 543a70a6386b66c9203cca463893863292d7d918..09d320c21f424e728f78774568c54837c3d88d39 100644
--- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
+++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
@@ -75,7 +75,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index 61103fbc93a5a6101736c549db4eb01f12dce448..7c146566adf0e41e6845511ac96e020a24d8f0f5 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -76,7 +76,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c
index 26a8ea677f149f2ebb6e0a4dc3fb2ef35679f647..5a4e4004e55541d7ab30a7c0ad45e6773dd8d594 100644
--- a/test/core/end2end/tests/cancel_before_invoke.c
+++ b/test/core/end2end/tests/cancel_before_invoke.c
@@ -74,7 +74,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c
index 0b1fcf33b73f98872294056b3ba798d101cdcd5a..5d7d762e5fb8363dd3e0bc67d5ffe10ee22bb78f 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum.c
+++ b/test/core/end2end/tests/cancel_in_a_vacuum.c
@@ -75,7 +75,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/census_simple_request.c b/test/core/end2end/tests/census_simple_request.c
index 191b7361dc2ac424d1b8acf5bbe8331dfe60af81..e7a8c22727011ec0b01cbc3a6e60dfca88fab11f 100644
--- a/test/core/end2end/tests/census_simple_request.c
+++ b/test/core/end2end/tests/census_simple_request.c
@@ -64,7 +64,7 @@ static void *tag(gpr_intptr t) { return (void *)t; }
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c
index 5f5a4778fc59b54a25c6dc1791a822fd7fdcf011..8ba60d78e6bf5fd4c95cad542cf95fef66dd0807 100644
--- a/test/core/end2end/tests/disappearing_server.c
+++ b/test/core/end2end/tests/disappearing_server.c
@@ -136,7 +136,7 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f,
 
   /* should be able to shut down the server early
      - and still complete the request */
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
 
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
index 3b7a2b9fd0561be221a3246e453291b1603fc038..30d64d3f750cd1ea9c5700a6af5ebd3501873ffd 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
@@ -149,7 +149,7 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102)));
 
   /* shutdown and destroy the server */
-  grpc_server_shutdown_and_notify(f.server, tag(1000));
+  grpc_server_shutdown_and_notify(f.server, f.server_cq, tag(1000));
   grpc_server_cancel_all_calls(f.server);
 
   cq_expect_completion(v_server, tag(102), 1);
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_tags.c b/test/core/end2end/tests/early_server_shutdown_finishes_tags.c
index e82b33b0c2fcae6589ac0976353b287b907d7980..0c2cdb78f0cf1d95432280dec0cd0dd9285944b8 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_tags.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_tags.c
@@ -106,7 +106,7 @@ static void test_early_server_shutdown_finishes_tags(
              grpc_server_request_call(f.server, &s, &call_details,
                                       &request_metadata_recv, f.server_cq,
                                       f.server_cq, tag(101)));
-  grpc_server_shutdown_and_notify(f.server, tag(1000));
+  grpc_server_shutdown_and_notify(f.server, f.server_cq, tag(1000));
   cq_expect_completion(v_server, tag(101), 0);
   cq_expect_completion(v_server, tag(1000), 1);
   cq_verify(v_server);
diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c
index 135826f851041a02043d91802cd4a7df5c9f380b..79d19659812672de6c7be375b5dbfdf163350267 100644
--- a/test/core/end2end/tests/empty_batch.c
+++ b/test/core/end2end/tests/empty_batch.c
@@ -76,7 +76,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c
index 5baf37f5c14e5d98fa77a86042f11d8047b80bca..a1ea13afd9c746be0c61e7cfc6760d44d2936eb2 100644
--- a/test/core/end2end/tests/graceful_server_shutdown.c
+++ b/test/core/end2end/tests/graceful_server_shutdown.c
@@ -150,7 +150,7 @@ static void test_early_server_shutdown_finishes_inflight_calls(
   cq_verify(v_server);
 
   /* shutdown and destroy the server */
-  grpc_server_shutdown_and_notify(f.server, tag(0xdead));
+  grpc_server_shutdown_and_notify(f.server, f.server_cq, tag(0xdead));
   cq_verify_empty(v_server);
 
   op = ops;
diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c
index 38560447a2ac5ccc2a401860aa48fb800909ffb1..7fef85ccaa13b1ae1a2f471cce6250d7568978cd 100644
--- a/test/core/end2end/tests/invoke_large_request.c
+++ b/test/core/end2end/tests/invoke_large_request.c
@@ -72,7 +72,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c
index aac8e2ee1225ba4ecb3aa1978172ea335b322853..c3af98482853ff4aef8c41c880ad8362de98041c 100644
--- a/test/core/end2end/tests/max_concurrent_streams.c
+++ b/test/core/end2end/tests/max_concurrent_streams.c
@@ -74,7 +74,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c
index dd91e14dc6c1cdffdc542aa7facebd229a77b625..27067fdcd7247158f2f20fd08a7bd69851aff86a 100644
--- a/test/core/end2end/tests/max_message_length.c
+++ b/test/core/end2end/tests/max_message_length.c
@@ -74,7 +74,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c
index 853230a15b9e23b37b317b51e23d791c1498a55c..1f32691e63393dd9ca0fb5c9bb8aa28ff45ceb45 100644
--- a/test/core/end2end/tests/no_op.c
+++ b/test/core/end2end/tests/no_op.c
@@ -74,7 +74,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c
index 0731f3436ee23167e402019dcdc39fd3eff57456..96e265ffe18e9883d0a730ba23e3fad6e7222eea 100644
--- a/test/core/end2end/tests/ping_pong_streaming.c
+++ b/test/core/end2end/tests/ping_pong_streaming.c
@@ -74,7 +74,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c
index 03b3637e2ca83aaac6afe7c2e9f03d1bc9536ddd..41dd3e43f431a486c7b198cb1b146490ef52748a 100644
--- a/test/core/end2end/tests/registered_call.c
+++ b/test/core/end2end/tests/registered_call.c
@@ -76,7 +76,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
index 478707460e18159ea872c640052a6c7653b4c1e1..b71fd26845fc72b3696ae1771ef9c2408b9af063 100644
--- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
@@ -74,7 +74,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_metadata_and_payload.c
index 5ea26c651d0187f392d2c0f88f373e7492e82d47..884b32cb0be414ed106a70db4d726eb1f03a3e89 100644
--- a/test/core/end2end/tests/request_response_with_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_metadata_and_payload.c
@@ -74,7 +74,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/request_response_with_payload.c b/test/core/end2end/tests/request_response_with_payload.c
index 170882ec32140910b0edeac1d2955b79da1fd284..2e92fbc63730aaac9d3e93827d30ffff0b435b99 100644
--- a/test/core/end2end/tests/request_response_with_payload.c
+++ b/test/core/end2end/tests/request_response_with_payload.c
@@ -74,7 +74,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/request_response_with_payload_and_call_creds.c b/test/core/end2end/tests/request_response_with_payload_and_call_creds.c
index 77291b7e42e4649fe7c7d4684dd5b57af2d41454..c4f8979501c37ebd5f71d3972ea0454c31be2729 100644
--- a/test/core/end2end/tests/request_response_with_payload_and_call_creds.c
+++ b/test/core/end2end/tests/request_response_with_payload_and_call_creds.c
@@ -88,7 +88,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
index 4ba12e4b68f18bf3583713478bbd4a45234ac2b5..3c54881390c5316d0ad0475744bf3108143b899d 100644
--- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
@@ -74,7 +74,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/request_with_large_metadata.c b/test/core/end2end/tests/request_with_large_metadata.c
index e2d8dee7a37daaa9110b842bad9e94b08f33a231..98dab1cc24e67451f6e3c1455d0020346f3eb0bf 100644
--- a/test/core/end2end/tests/request_with_large_metadata.c
+++ b/test/core/end2end/tests/request_with_large_metadata.c
@@ -74,7 +74,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c
index cf9ccbdf6663699320f1e0b624599d8874ba0bb8..b50db5549801afb46ed1a172d59b5350e45f3af2 100644
--- a/test/core/end2end/tests/request_with_payload.c
+++ b/test/core/end2end/tests/request_with_payload.c
@@ -74,7 +74,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c
index e7321391e51736db3d3fd495a77b79be053fc8e8..7782d6bcd4460cb5c00a45ad373f8a1e88f04ce0 100644
--- a/test/core/end2end/tests/server_finishes_request.c
+++ b/test/core/end2end/tests/server_finishes_request.c
@@ -76,7 +76,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c
index a1afe4bf595adb66d55e0998dbf3c38d098af2bb..65760a1a4341c830c99a23a78e60e385a3c8ee3f 100644
--- a/test/core/end2end/tests/simple_delayed_request.c
+++ b/test/core/end2end/tests/simple_delayed_request.c
@@ -62,7 +62,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c
index 9e8c562dd3638fc06af89e86f4eb80b7dec5e39d..b6ea6a08b4827c3604d300588b069687f1267cbd 100644
--- a/test/core/end2end/tests/simple_request.c
+++ b/test/core/end2end/tests/simple_request.c
@@ -76,7 +76,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c b/test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c
index d8e18f2ef4711d1e2e42d77ddd5e7535f88dc142..dafac60558c60b43d7aec89d7230f20ef38685e5 100644
--- a/test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c
+++ b/test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c
@@ -76,7 +76,7 @@ static void drain_cq(grpc_completion_queue *cq) {
 
 static void shutdown_server(grpc_end2end_test_fixture *f) {
   if (!f->server) return;
-  grpc_server_shutdown_and_notify(f->server, tag(1000));
+  grpc_server_shutdown_and_notify(f->server, f->server_cq, tag(1000));
   GPR_ASSERT(grpc_completion_queue_pluck(f->server_cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->server);
   f->server = NULL;
diff --git a/test/core/fling/server.c b/test/core/fling/server.c
index 87254ee1dc805b255faf9eee756fb62e9ee75be0..e58d721c86c38f1ab99e2f71d306b6da61a4cfe5 100644
--- a/test/core/fling/server.c
+++ b/test/core/fling/server.c
@@ -233,7 +233,7 @@ int main(int argc, char **argv) {
   while (!shutdown_finished) {
     if (got_sigint && !shutdown_started) {
       gpr_log(GPR_INFO, "Shutting down due to SIGINT");
-      grpc_server_shutdown_and_notify(server, tag(1000));
+      grpc_server_shutdown_and_notify(server, cq, tag(1000));
       GPR_ASSERT(grpc_completion_queue_pluck(cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)).type == GRPC_OP_COMPLETE);
       grpc_completion_queue_shutdown(cq);
       shutdown_started = 1;