Fixup windows server
diff --git a/src/core/iomgr/tcp_server_windows.c b/src/core/iomgr/tcp_server_windows.c
index 79ea223..21f19f0 100644
--- a/src/core/iomgr/tcp_server_windows.c
+++ b/src/core/iomgr/tcp_server_windows.c
@@ -75,18 +75,18 @@
   void *cb_arg;
 
   gpr_mu mu;
-  gpr_cv cv;
 
   /* active port count: how many ports are actually still listening */
   int active_ports;
-  /* number of iomgr callbacks that have been explicitly scheduled during
-   * shutdown */
-  int iomgr_callbacks_pending;
 
   /* all listening ports */
   server_port *ports;
   size_t nports;
   size_t port_capacity;
+
+  /* shutdown callback */
+  void(*shutdown_complete)(void *);
+  void *shutdown_complete_arg;
 };
 
 /* Public function. Allocates the proper data structures to hold a
@@ -94,34 +94,41 @@
 grpc_tcp_server *grpc_tcp_server_create(void) {
   grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
   gpr_mu_init(&s->mu);
-  gpr_cv_init(&s->cv);
   s->active_ports = 0;
-  s->iomgr_callbacks_pending = 0;
   s->cb = NULL;
   s->cb_arg = NULL;
   s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP);
   s->nports = 0;
   s->port_capacity = INIT_PORT_CAP;
+  s->shutdown_complete = NULL;
   return s;
 }
 
+static void dont_care_about_shutdown_completion(void *arg) {}
+
 /* Public function. Stops and destroys a grpc_tcp_server. */
 void grpc_tcp_server_destroy(grpc_tcp_server *s,
-                             void (*shutdown_done)(void *shutdown_done_arg),
-                             void *shutdown_done_arg) {
+                             void (*shutdown_complete)(void *shutdown_done_arg),
+                             void *shutdown_complete_arg) {
   size_t i;
+  int immediately_done = 0;
   gpr_mu_lock(&s->mu);
+
+  s->shutdown_complete = shutdown_complete
+    ? shutdown_complete
+    : dont_care_about_shutdown_completion;
+  s->shutdown_complete_arg = shutdown_complete_arg;
+
   /* First, shutdown all fd's. This will queue abortion calls for all
      of the pending accepts due to the normal operation mechanism. */
+  if (s->active_ports == 0) {
+    immediately_done = 1;
+  }
   for (i = 0; i < s->nports; i++) {
     server_port *sp = &s->ports[i];
     sp->shutting_down = 1;
     grpc_winsocket_shutdown(sp->socket);
   }
-  /* This happens asynchronously. Wait while that happens. */
-  while (s->active_ports || s->iomgr_callbacks_pending) {
-    gpr_cv_wait(&s->cv, &s->mu, gpr_inf_future(GPR_CLOCK_REALTIME));
-  }
   gpr_mu_unlock(&s->mu);
 
   /* Now that the accepts have been aborted, we can destroy the sockets.
@@ -134,8 +141,8 @@
   gpr_free(s->ports);
   gpr_free(s);
 
-  if (shutdown_done) {
-    shutdown_done(shutdown_done_arg);
+  if (immediately_done) {
+    s->shutdown_complete(s->shutdown_complete_arg);
   }
 }
 
@@ -188,13 +195,19 @@
 }
 
 static void decrement_active_ports_and_notify(server_port *sp) {
+  void(*notify)(void *) = NULL;
+  void *notify_arg = NULL;
   sp->shutting_down = 0;
   gpr_mu_lock(&sp->server->mu);
   GPR_ASSERT(sp->server->active_ports > 0);
   if (0 == --sp->server->active_ports) {
-    gpr_cv_broadcast(&sp->server->cv);
+    notify = sp->server->shutdown_complete;
+    notify_arg = sp->server->shutdown_complete_arg;
   }
   gpr_mu_unlock(&sp->server->mu);
+  if (notify != NULL) {
+    notify(notify_arg);
+  }
 }
 
 /* start_accept will reference that for the IOCP notification request. */
@@ -279,12 +292,6 @@
      this is necessary in the read/write case, it's useless for the accept
      case. We only need to adjust the pending callback count */
   if (!from_iocp) {
-    gpr_mu_lock(&sp->server->mu);
-    GPR_ASSERT(sp->server->iomgr_callbacks_pending > 0);
-    if (0 == --sp->server->iomgr_callbacks_pending) {
-      gpr_cv_broadcast(&sp->server->cv);
-    }
-    gpr_mu_unlock(&sp->server->mu);
     return;
   }