From 01be53d1a11c966baf1b1ce66baa60bf763bfc8b Mon Sep 17 00:00:00 2001
From: Craig Tiller <craig.tiller@gmail.com>
Date: Wed, 30 Sep 2015 08:36:03 -0700
Subject: [PATCH] Add a facility to flush iocp at iomgr shutdown

---
 src/core/iomgr/iocp_windows.c   | 12 +++++++++---
 src/core/iomgr/iocp_windows.h   |  1 +
 src/core/iomgr/iomgr.c          |  2 ++
 src/core/iomgr/iomgr_internal.h |  3 +++
 src/core/iomgr/iomgr_posix.c    |  3 +++
 src/core/iomgr/iomgr_windows.c  |  4 ++++
 6 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/src/core/iomgr/iocp_windows.c b/src/core/iomgr/iocp_windows.c
index 349440fa88..791f2e39c8 100644
--- a/src/core/iomgr/iocp_windows.c
+++ b/src/core/iomgr/iocp_windows.c
@@ -119,9 +119,7 @@ void grpc_iocp_work(grpc_exec_ctx *exec_ctx, gpr_timespec deadline) {
     info->has_pending_iocp = 1;
   }
   gpr_mu_unlock(&socket->state_mu);
-  if (closure) {
-    closure->cb(exec_ctx, closure->cb_arg, 1);
-  }
+  grpc_exec_ctx_enqueue(exec_ctx, closure, 1);
 }
 
 void grpc_iocp_init(void) {
@@ -139,6 +137,14 @@ void grpc_iocp_kick(void) {
   GPR_ASSERT(success);
 }
 
+void grpc_iocp_flush(void) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  
+  do {
+    grpc_iocp_work(&exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC));
+  } while (grpc_exec_ctx_flush(&exec_ctx));
+}
+
 void grpc_iocp_shutdown(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   while (gpr_atm_acq_load(&g_custom_events)) {
diff --git a/src/core/iomgr/iocp_windows.h b/src/core/iomgr/iocp_windows.h
index 7e330e7ce2..75f3ba8477 100644
--- a/src/core/iomgr/iocp_windows.h
+++ b/src/core/iomgr/iocp_windows.h
@@ -41,6 +41,7 @@
 void grpc_iocp_work(grpc_exec_ctx *exec_ctx, gpr_timespec deadline);
 void grpc_iocp_init(void);
 void grpc_iocp_kick(void);
+void grpc_iocp_flush(void);
 void grpc_iocp_shutdown(void);
 void grpc_iocp_add_socket(grpc_winsocket *);
 
diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c
index 0c067e5187..a10399311f 100644
--- a/src/core/iomgr/iomgr.c
+++ b/src/core/iomgr/iomgr.c
@@ -91,6 +91,8 @@ void grpc_iomgr_shutdown(void) {
   gpr_timespec last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
+  grpc_iomgr_platform_flush();
+
   gpr_mu_lock(&g_mu);
   g_shutdown = 1;
   while (g_root_object.next != &g_root_object) {
diff --git a/src/core/iomgr/iomgr_internal.h b/src/core/iomgr/iomgr_internal.h
index 1a0724b431..e372c18e8a 100644
--- a/src/core/iomgr/iomgr_internal.h
+++ b/src/core/iomgr/iomgr_internal.h
@@ -50,6 +50,9 @@ void grpc_iomgr_register_object(grpc_iomgr_object *obj, const char *name);
 void grpc_iomgr_unregister_object(grpc_iomgr_object *obj);
 
 void grpc_iomgr_platform_init(void);
+/** flush any globally queued work from iomgr */
+void grpc_iomgr_platform_flush(void);
+/** tear down all platform specific global iomgr structures */
 void grpc_iomgr_platform_shutdown(void);
 
 #endif /* GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H */
diff --git a/src/core/iomgr/iomgr_posix.c b/src/core/iomgr/iomgr_posix.c
index db93d0a756..f6474b7e6d 100644
--- a/src/core/iomgr/iomgr_posix.c
+++ b/src/core/iomgr/iomgr_posix.c
@@ -45,6 +45,9 @@ void grpc_iomgr_platform_init(void) {
   grpc_register_tracer("tcp", &grpc_tcp_trace);
 }
 
+void grpc_iomgr_platform_flush(void) {
+}
+
 void grpc_iomgr_platform_shutdown(void) {
   grpc_fd_global_shutdown();
 }
diff --git a/src/core/iomgr/iomgr_windows.c b/src/core/iomgr/iomgr_windows.c
index b49cb87e97..93bdc5ec16 100644
--- a/src/core/iomgr/iomgr_windows.c
+++ b/src/core/iomgr/iomgr_windows.c
@@ -63,6 +63,10 @@ void grpc_iomgr_platform_init(void) {
   grpc_iocp_init();
 }
 
+void grpc_iomgr_platform_flush(void) {
+  grpc_iocp_flush();
+}
+
 void grpc_iomgr_platform_shutdown(void) {
   grpc_iocp_shutdown();
   winsock_shutdown();
-- 
GitLab