Split closures from iomgr.h
diff --git a/BUILD b/BUILD
index a7653d6..6574e6f 100644
--- a/BUILD
+++ b/BUILD
@@ -179,8 +179,10 @@
     "src/core/iomgr/alarm.h",
     "src/core/iomgr/alarm_heap.h",
     "src/core/iomgr/alarm_internal.h",
+    "src/core/iomgr/closure.h",
     "src/core/iomgr/endpoint.h",
     "src/core/iomgr/endpoint_pair.h",
+    "src/core/iomgr/exec_ctx.h",
     "src/core/iomgr/fd_posix.h",
     "src/core/iomgr/iocp_windows.h",
     "src/core/iomgr/iomgr.h",
@@ -310,6 +312,7 @@
     "src/core/httpcli/parser.c",
     "src/core/iomgr/alarm.c",
     "src/core/iomgr/alarm_heap.c",
+    "src/core/iomgr/closure.c",
     "src/core/iomgr/endpoint.c",
     "src/core/iomgr/endpoint_pair_posix.c",
     "src/core/iomgr/endpoint_pair_windows.c",
@@ -460,8 +463,10 @@
     "src/core/iomgr/alarm.h",
     "src/core/iomgr/alarm_heap.h",
     "src/core/iomgr/alarm_internal.h",
+    "src/core/iomgr/closure.h",
     "src/core/iomgr/endpoint.h",
     "src/core/iomgr/endpoint_pair.h",
+    "src/core/iomgr/exec_ctx.h",
     "src/core/iomgr/fd_posix.h",
     "src/core/iomgr/iocp_windows.h",
     "src/core/iomgr/iomgr.h",
@@ -571,6 +576,7 @@
     "src/core/httpcli/parser.c",
     "src/core/iomgr/alarm.c",
     "src/core/iomgr/alarm_heap.c",
+    "src/core/iomgr/closure.c",
     "src/core/iomgr/endpoint.c",
     "src/core/iomgr/endpoint_pair_posix.c",
     "src/core/iomgr/endpoint_pair_windows.c",
@@ -1092,6 +1098,7 @@
     "src/core/httpcli/parser.c",
     "src/core/iomgr/alarm.c",
     "src/core/iomgr/alarm_heap.c",
+    "src/core/iomgr/closure.c",
     "src/core/iomgr/endpoint.c",
     "src/core/iomgr/endpoint_pair_posix.c",
     "src/core/iomgr/endpoint_pair_windows.c",
@@ -1239,8 +1246,10 @@
     "src/core/iomgr/alarm.h",
     "src/core/iomgr/alarm_heap.h",
     "src/core/iomgr/alarm_internal.h",
+    "src/core/iomgr/closure.h",
     "src/core/iomgr/endpoint.h",
     "src/core/iomgr/endpoint_pair.h",
+    "src/core/iomgr/exec_ctx.h",
     "src/core/iomgr/fd_posix.h",
     "src/core/iomgr/iocp_windows.h",
     "src/core/iomgr/iomgr.h",
diff --git a/Makefile b/Makefile
index a66d366..05aa6ee 100644
--- a/Makefile
+++ b/Makefile
@@ -4075,6 +4075,7 @@
     src/core/httpcli/parser.c \
     src/core/iomgr/alarm.c \
     src/core/iomgr/alarm_heap.c \
+    src/core/iomgr/closure.c \
     src/core/iomgr/endpoint.c \
     src/core/iomgr/endpoint_pair_posix.c \
     src/core/iomgr/endpoint_pair_windows.c \
@@ -4355,6 +4356,7 @@
     src/core/httpcli/parser.c \
     src/core/iomgr/alarm.c \
     src/core/iomgr/alarm_heap.c \
+    src/core/iomgr/closure.c \
     src/core/iomgr/endpoint.c \
     src/core/iomgr/endpoint_pair_posix.c \
     src/core/iomgr/endpoint_pair_windows.c \
diff --git a/build.yaml b/build.yaml
index f16cb28..8e87d18 100644
--- a/build.yaml
+++ b/build.yaml
@@ -55,19 +55,20 @@
     src/core/client_config/uri_parser.h, src/core/compression/message_compress.h,
     src/core/debug/trace.h, src/core/httpcli/format_request.h, src/core/httpcli/httpcli.h,
     src/core/httpcli/parser.h, src/core/iomgr/alarm.h, src/core/iomgr/alarm_heap.h,
-    src/core/iomgr/alarm_internal.h, src/core/iomgr/endpoint.h, src/core/iomgr/endpoint_pair.h,
-    src/core/iomgr/fd_posix.h, src/core/iomgr/iocp_windows.h, src/core/iomgr/iomgr.h,
-    src/core/iomgr/iomgr_internal.h, src/core/iomgr/iomgr_posix.h, src/core/iomgr/pollset.h,
-    src/core/iomgr/pollset_posix.h, src/core/iomgr/pollset_set.h, src/core/iomgr/pollset_set_posix.h,
-    src/core/iomgr/pollset_set_windows.h, src/core/iomgr/pollset_windows.h, src/core/iomgr/resolve_address.h,
-    src/core/iomgr/sockaddr.h, src/core/iomgr/sockaddr_posix.h, src/core/iomgr/sockaddr_utils.h,
-    src/core/iomgr/sockaddr_win32.h, src/core/iomgr/socket_utils_posix.h, src/core/iomgr/socket_windows.h,
-    src/core/iomgr/tcp_client.h, src/core/iomgr/tcp_posix.h, src/core/iomgr/tcp_server.h,
-    src/core/iomgr/tcp_windows.h, src/core/iomgr/time_averaged_stats.h, src/core/iomgr/udp_server.h,
-    src/core/iomgr/wakeup_fd_pipe.h, src/core/iomgr/wakeup_fd_posix.h, src/core/iomgr/workqueue.h,
-    src/core/iomgr/workqueue_posix.h, src/core/iomgr/workqueue_windows.h, src/core/json/json.h,
-    src/core/json/json_common.h, src/core/json/json_reader.h, src/core/json/json_writer.h,
-    src/core/profiling/timers.h, src/core/statistics/census_interface.h, src/core/statistics/census_rpc_stats.h,
+    src/core/iomgr/alarm_internal.h, src/core/iomgr/closure.h, src/core/iomgr/endpoint.h,
+    src/core/iomgr/endpoint_pair.h, src/core/iomgr/exec_ctx.h, src/core/iomgr/fd_posix.h,
+    src/core/iomgr/iocp_windows.h, src/core/iomgr/iomgr.h, src/core/iomgr/iomgr_internal.h,
+    src/core/iomgr/iomgr_posix.h, src/core/iomgr/pollset.h, src/core/iomgr/pollset_posix.h,
+    src/core/iomgr/pollset_set.h, src/core/iomgr/pollset_set_posix.h, src/core/iomgr/pollset_set_windows.h,
+    src/core/iomgr/pollset_windows.h, src/core/iomgr/resolve_address.h, src/core/iomgr/sockaddr.h,
+    src/core/iomgr/sockaddr_posix.h, src/core/iomgr/sockaddr_utils.h, src/core/iomgr/sockaddr_win32.h,
+    src/core/iomgr/socket_utils_posix.h, src/core/iomgr/socket_windows.h, src/core/iomgr/tcp_client.h,
+    src/core/iomgr/tcp_posix.h, src/core/iomgr/tcp_server.h, src/core/iomgr/tcp_windows.h,
+    src/core/iomgr/time_averaged_stats.h, src/core/iomgr/udp_server.h, src/core/iomgr/wakeup_fd_pipe.h,
+    src/core/iomgr/wakeup_fd_posix.h, src/core/iomgr/workqueue.h, src/core/iomgr/workqueue_posix.h,
+    src/core/iomgr/workqueue_windows.h, src/core/json/json.h, src/core/json/json_common.h,
+    src/core/json/json_reader.h, src/core/json/json_writer.h, src/core/profiling/timers.h,
+    src/core/statistics/census_interface.h, src/core/statistics/census_rpc_stats.h,
     src/core/surface/byte_buffer_queue.h, src/core/surface/call.h, src/core/surface/channel.h,
     src/core/surface/completion_queue.h, src/core/surface/event_string.h, src/core/surface/init.h,
     src/core/surface/server.h, src/core/surface/surface_trace.h, src/core/transport/chttp2/alpn.h,
@@ -97,12 +98,12 @@
     src/core/client_config/uri_parser.c, src/core/compression/algorithm.c, src/core/compression/message_compress.c,
     src/core/debug/trace.c, src/core/httpcli/format_request.c, src/core/httpcli/httpcli.c,
     src/core/httpcli/parser.c, src/core/iomgr/alarm.c, src/core/iomgr/alarm_heap.c,
-    src/core/iomgr/endpoint.c, src/core/iomgr/endpoint_pair_posix.c, src/core/iomgr/endpoint_pair_windows.c,
-    src/core/iomgr/fd_posix.c, src/core/iomgr/iocp_windows.c, src/core/iomgr/iomgr.c,
-    src/core/iomgr/iomgr_posix.c, src/core/iomgr/iomgr_windows.c, src/core/iomgr/pollset_multipoller_with_epoll.c,
-    src/core/iomgr/pollset_multipoller_with_poll_posix.c, src/core/iomgr/pollset_posix.c,
-    src/core/iomgr/pollset_set_posix.c, src/core/iomgr/pollset_set_windows.c, src/core/iomgr/pollset_windows.c,
-    src/core/iomgr/resolve_address_posix.c, src/core/iomgr/resolve_address_windows.c,
+    src/core/iomgr/closure.c, src/core/iomgr/endpoint.c, src/core/iomgr/endpoint_pair_posix.c,
+    src/core/iomgr/endpoint_pair_windows.c, src/core/iomgr/fd_posix.c, src/core/iomgr/iocp_windows.c,
+    src/core/iomgr/iomgr.c, src/core/iomgr/iomgr_posix.c, src/core/iomgr/iomgr_windows.c,
+    src/core/iomgr/pollset_multipoller_with_epoll.c, src/core/iomgr/pollset_multipoller_with_poll_posix.c,
+    src/core/iomgr/pollset_posix.c, src/core/iomgr/pollset_set_posix.c, src/core/iomgr/pollset_set_windows.c,
+    src/core/iomgr/pollset_windows.c, src/core/iomgr/resolve_address_posix.c, src/core/iomgr/resolve_address_windows.c,
     src/core/iomgr/sockaddr_utils.c, src/core/iomgr/socket_utils_common_posix.c, src/core/iomgr/socket_utils_linux.c,
     src/core/iomgr/socket_utils_posix.c, src/core/iomgr/socket_windows.c, src/core/iomgr/tcp_client_posix.c,
     src/core/iomgr/tcp_client_windows.c, src/core/iomgr/tcp_posix.c, src/core/iomgr/tcp_server_posix.c,
diff --git a/gRPC.podspec b/gRPC.podspec
index 173628f..9a6b89f 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -181,8 +181,10 @@
                       'src/core/iomgr/alarm.h',
                       'src/core/iomgr/alarm_heap.h',
                       'src/core/iomgr/alarm_internal.h',
+                      'src/core/iomgr/closure.h',
                       'src/core/iomgr/endpoint.h',
                       'src/core/iomgr/endpoint_pair.h',
+                      'src/core/iomgr/exec_ctx.h',
                       'src/core/iomgr/fd_posix.h',
                       'src/core/iomgr/iocp_windows.h',
                       'src/core/iomgr/iomgr.h',
@@ -319,6 +321,7 @@
                       'src/core/httpcli/parser.c',
                       'src/core/iomgr/alarm.c',
                       'src/core/iomgr/alarm_heap.c',
+                      'src/core/iomgr/closure.c',
                       'src/core/iomgr/endpoint.c',
                       'src/core/iomgr/endpoint_pair_posix.c',
                       'src/core/iomgr/endpoint_pair_windows.c',
@@ -466,8 +469,10 @@
                               'src/core/iomgr/alarm.h',
                               'src/core/iomgr/alarm_heap.h',
                               'src/core/iomgr/alarm_internal.h',
+                              'src/core/iomgr/closure.h',
                               'src/core/iomgr/endpoint.h',
                               'src/core/iomgr/endpoint_pair.h',
+                              'src/core/iomgr/exec_ctx.h',
                               'src/core/iomgr/fd_posix.h',
                               'src/core/iomgr/iocp_windows.h',
                               'src/core/iomgr/iomgr.h',
diff --git a/src/core/iomgr/alarm.h b/src/core/iomgr/alarm.h
index 09bfa88..e420c3a 100644
--- a/src/core/iomgr/alarm.h
+++ b/src/core/iomgr/alarm.h
@@ -35,6 +35,7 @@
 #define GRPC_INTERNAL_CORE_IOMGR_ALARM_H
 
 #include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/exec_ctx.h"
 #include <grpc/support/port_platform.h>
 #include <grpc/support/time.h>
 
diff --git a/src/core/iomgr/alarm_internal.h b/src/core/iomgr/alarm_internal.h
index aebc789..4d6076a 100644
--- a/src/core/iomgr/alarm_internal.h
+++ b/src/core/iomgr/alarm_internal.h
@@ -34,6 +34,7 @@
 #ifndef GRPC_INTERNAL_CORE_IOMGR_ALARM_INTERNAL_H
 #define GRPC_INTERNAL_CORE_IOMGR_ALARM_INTERNAL_H
 
+#include "src/core/iomgr/exec_ctx.h"
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
 
diff --git a/src/core/iomgr/closure.c b/src/core/iomgr/closure.c
new file mode 100644
index 0000000..1827ac3
--- /dev/null
+++ b/src/core/iomgr/closure.c
@@ -0,0 +1,83 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/iomgr/closure.h"
+
+void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
+                       void *cb_arg) {
+  closure->cb = cb;
+  closure->cb_arg = cb_arg;
+  closure->next = NULL;
+}
+
+void grpc_closure_list_add(grpc_closure_list *closure_list,
+                           grpc_closure *closure, int success) {
+  if (closure == NULL) return;
+  closure->next = NULL;
+  closure->success = success;
+  if (closure_list->head == NULL) {
+    closure_list->head = closure;
+  } else {
+    closure_list->tail->next = closure;
+  }
+  closure_list->tail = closure;
+}
+
+void grpc_closure_list_run(grpc_closure_list *closure_list) {
+  while (!grpc_closure_list_empty(*closure_list)) {
+    grpc_closure *c = closure_list->head;
+    closure_list->head = closure_list->tail = NULL;
+    while (c != NULL) {
+      grpc_closure *next = c->next;
+      c->cb(c->cb_arg, c->success, closure_list);
+      c = next;
+    }
+  }
+}
+
+int grpc_closure_list_empty(grpc_closure_list closure_list) {
+  return closure_list.head == NULL;
+}
+
+void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst) {
+  if (src->head == NULL) {
+    return;
+  }
+  if (dst->head == NULL) {
+    *dst = *src;
+  } else {
+    dst->tail->next = src->head;
+    dst->tail = src->tail;
+  }
+  src->head = src->tail = NULL;
+}
diff --git a/src/core/iomgr/closure.h b/src/core/iomgr/closure.h
new file mode 100644
index 0000000..e8e1e04
--- /dev/null
+++ b/src/core/iomgr/closure.h
@@ -0,0 +1,85 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CORE_IOMGR_CLOSURE_H
+#define GRPC_INTERNAL_CORE_IOMGR_CLOSURE_H
+
+#include <stddef.h>
+
+struct grpc_closure;
+typedef struct grpc_closure grpc_closure;
+
+typedef struct grpc_closure_list {
+  grpc_closure *head;
+  grpc_closure *tail;
+} grpc_closure_list;
+
+/** gRPC Callback definition.
+ *
+ * \param arg Arbitrary input.
+ * \param success An indication on the state of the iomgr. On false, cleanup
+ * actions should be taken (eg, shutdown). */
+typedef void (*grpc_iomgr_cb_func)(void *arg, int success,
+                                   grpc_closure_list *closure_list);
+
+/** A closure over a grpc_iomgr_cb_func. */
+struct grpc_closure {
+  /** Bound callback. */
+  grpc_iomgr_cb_func cb;
+
+  /** Arguments to be passed to "cb". */
+  void *cb_arg;
+
+  /** Internal. A boolean indication to "cb" on the state of the iomgr.
+   * For instance, closures created during a shutdown would have this field set
+   * to false. */
+  int success;
+
+  /**< Internal. Do not touch */
+  struct grpc_closure *next;
+};
+
+/** Initializes \a closure with \a cb and \a cb_arg. */
+void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
+                       void *cb_arg);
+
+#define GRPC_CLOSURE_LIST_INIT \
+  { NULL, NULL }
+
+void grpc_closure_list_add(grpc_closure_list *list, grpc_closure *closure,
+                           int success);
+void grpc_closure_list_run(grpc_closure_list *list);
+void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst);
+int grpc_closure_list_empty(grpc_closure_list list);
+
+#endif /* GRPC_INTERNAL_CORE_IOMGR_CLOSURE_H */
diff --git a/src/core/iomgr/exec_ctx.h b/src/core/iomgr/exec_ctx.h
new file mode 100644
index 0000000..4d30feb
--- /dev/null
+++ b/src/core/iomgr/exec_ctx.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CORE_IOMGR_EXEC_CTX_H
+#define GRPC_INTERNAL_CORE_IOMGR_EXEC_CTX_H
+
+#include "src/core/iomgr/closure.h"
+
+#endif
diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c
index 9456bad..f009eb3 100644
--- a/src/core/iomgr/iomgr.c
+++ b/src/core/iomgr/iomgr.c
@@ -160,52 +160,3 @@
   gpr_mu_unlock(&g_mu);
   gpr_free(obj->name);
 }
-
-void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
-                       void *cb_arg) {
-  closure->cb = cb;
-  closure->cb_arg = cb_arg;
-  closure->next = NULL;
-}
-
-void grpc_closure_list_add(grpc_closure_list *closure_list,
-                           grpc_closure *closure, int success) {
-  if (closure == NULL) return;
-  closure->next = NULL;
-  closure->success = success;
-  if (closure_list->head == NULL) {
-    closure_list->head = closure;
-  } else {
-    closure_list->tail->next = closure;
-  }
-  closure_list->tail = closure;
-}
-
-void grpc_closure_list_run(grpc_closure_list *closure_list) {
-  while (!grpc_closure_list_empty(*closure_list)) {
-    grpc_closure *c = closure_list->head;
-    closure_list->head = closure_list->tail = NULL;
-    while (c != NULL) {
-      grpc_closure *next = c->next;
-      c->cb(c->cb_arg, c->success, closure_list);
-      c = next;
-    }
-  }
-}
-
-int grpc_closure_list_empty(grpc_closure_list closure_list) {
-  return closure_list.head == NULL;
-}
-
-void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst) {
-  if (src->head == NULL) {
-    return;
-  }
-  if (dst->head == NULL) {
-    *dst = *src;
-  } else {
-    dst->tail->next = src->head;
-    dst->tail = src->tail;
-  }
-  src->head = src->tail = NULL;
-}
diff --git a/src/core/iomgr/iomgr.h b/src/core/iomgr/iomgr.h
index bc01570..c9ea84c 100644
--- a/src/core/iomgr/iomgr.h
+++ b/src/core/iomgr/iomgr.h
@@ -34,52 +34,6 @@
 #ifndef GRPC_INTERNAL_CORE_IOMGR_IOMGR_H
 #define GRPC_INTERNAL_CORE_IOMGR_IOMGR_H
 
-struct grpc_closure;
-typedef struct grpc_closure grpc_closure;
-
-typedef struct grpc_closure_list {
-  grpc_closure *head;
-  grpc_closure *tail;
-} grpc_closure_list;
-
-/** gRPC Callback definition.
- *
- * \param arg Arbitrary input.
- * \param success An indication on the state of the iomgr. On false, cleanup
- * actions should be taken (eg, shutdown). */
-typedef void (*grpc_iomgr_cb_func)(void *arg, int success,
-                                   grpc_closure_list *closure_list);
-
-/** A closure over a grpc_iomgr_cb_func. */
-struct grpc_closure {
-  /** Bound callback. */
-  grpc_iomgr_cb_func cb;
-
-  /** Arguments to be passed to "cb". */
-  void *cb_arg;
-
-  /** Internal. A boolean indication to "cb" on the state of the iomgr.
-   * For instance, closures created during a shutdown would have this field set
-   * to false. */
-  int success;
-
-  /**< Internal. Do not touch */
-  struct grpc_closure *next;
-};
-
-/** Initializes \a closure with \a cb and \a cb_arg. */
-void grpc_closure_init(grpc_closure *closure, grpc_iomgr_cb_func cb,
-                       void *cb_arg);
-
-#define GRPC_CLOSURE_LIST_INIT \
-  { NULL, NULL }
-
-void grpc_closure_list_add(grpc_closure_list *list, grpc_closure *closure,
-                           int success);
-void grpc_closure_list_run(grpc_closure_list *list);
-void grpc_closure_list_move(grpc_closure_list *src, grpc_closure_list *dst);
-int grpc_closure_list_empty(grpc_closure_list list);
-
 /** Initializes the iomgr. */
 void grpc_iomgr_init(void);
 
diff --git a/src/core/iomgr/pollset_posix.h b/src/core/iomgr/pollset_posix.h
index 2f50cd2..4064d11 100644
--- a/src/core/iomgr/pollset_posix.h
+++ b/src/core/iomgr/pollset_posix.h
@@ -37,6 +37,7 @@
 #include <poll.h>
 
 #include <grpc/support/sync.h>
+#include "src/core/iomgr/exec_ctx.h"
 #include "src/core/iomgr/iomgr.h"
 #include "src/core/iomgr/wakeup_fd_posix.h"
 
diff --git a/src/core/iomgr/resolve_address.h b/src/core/iomgr/resolve_address.h
index 1744322..54e8add 100644
--- a/src/core/iomgr/resolve_address.h
+++ b/src/core/iomgr/resolve_address.h
@@ -35,6 +35,7 @@
 #define GRPC_INTERNAL_CORE_IOMGR_RESOLVE_ADDRESS_H
 
 #include <stddef.h>
+#include "src/core/iomgr/exec_ctx.h"
 #include "src/core/iomgr/iomgr.h"
 
 #define GRPC_MAX_SOCKADDR_SIZE 128
diff --git a/src/core/iomgr/workqueue.h b/src/core/iomgr/workqueue.h
index 0bec714..0bc7e31 100644
--- a/src/core/iomgr/workqueue.h
+++ b/src/core/iomgr/workqueue.h
@@ -36,6 +36,7 @@
 
 #include "src/core/iomgr/iomgr.h"
 #include "src/core/iomgr/pollset.h"
+#include "src/core/iomgr/closure.h"
 
 #ifdef GPR_POSIX_SOCKET
 #include "src/core/iomgr/workqueue_posix.h"
diff --git a/src/core/transport/chttp2/frame_data.h b/src/core/transport/chttp2/frame_data.h
index 89a503e..ccd56a1 100644
--- a/src/core/transport/chttp2/frame_data.h
+++ b/src/core/transport/chttp2/frame_data.h
@@ -36,7 +36,7 @@
 
 /* Parser for GRPC streams embedded in DATA frames */
 
-#include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/exec_ctx.h"
 #include <grpc/support/slice.h>
 #include <grpc/support/slice_buffer.h>
 #include "src/core/transport/stream_op.h"
diff --git a/src/core/transport/chttp2/frame_goaway.h b/src/core/transport/chttp2/frame_goaway.h
index 6f9ce94..e45d554 100644
--- a/src/core/transport/chttp2/frame_goaway.h
+++ b/src/core/transport/chttp2/frame_goaway.h
@@ -34,7 +34,7 @@
 #ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H
 #define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H
 
-#include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/exec_ctx.h"
 #include "src/core/transport/chttp2/frame.h"
 #include <grpc/support/port_platform.h>
 #include <grpc/support/slice.h>
diff --git a/src/core/transport/chttp2/frame_ping.h b/src/core/transport/chttp2/frame_ping.h
index fb31147..4224002 100644
--- a/src/core/transport/chttp2/frame_ping.h
+++ b/src/core/transport/chttp2/frame_ping.h
@@ -34,8 +34,8 @@
 #ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_PING_H
 #define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_PING_H
 
+#include "src/core/iomgr/exec_ctx.h"
 #include <grpc/support/slice.h>
-#include "src/core/iomgr/iomgr.h"
 #include "src/core/transport/chttp2/frame.h"
 
 typedef struct {
diff --git a/src/core/transport/chttp2/frame_rst_stream.h b/src/core/transport/chttp2/frame_rst_stream.h
index 05d9e56..5d66096 100644
--- a/src/core/transport/chttp2/frame_rst_stream.h
+++ b/src/core/transport/chttp2/frame_rst_stream.h
@@ -36,7 +36,7 @@
 
 #include <grpc/support/slice.h>
 #include "src/core/transport/chttp2/frame.h"
-#include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/exec_ctx.h"
 
 typedef struct {
   gpr_uint8 byte;
diff --git a/src/core/transport/chttp2/frame_settings.h b/src/core/transport/chttp2/frame_settings.h
index 7931b8b..f08d527 100644
--- a/src/core/transport/chttp2/frame_settings.h
+++ b/src/core/transport/chttp2/frame_settings.h
@@ -37,7 +37,7 @@
 #include <grpc/support/port_platform.h>
 #include <grpc/support/slice.h>
 #include "src/core/transport/chttp2/frame.h"
-#include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/exec_ctx.h"
 
 typedef enum {
   GRPC_CHTTP2_SPS_ID0,
diff --git a/src/core/transport/chttp2/frame_window_update.h b/src/core/transport/chttp2/frame_window_update.h
index 0893104..b8fe909 100644
--- a/src/core/transport/chttp2/frame_window_update.h
+++ b/src/core/transport/chttp2/frame_window_update.h
@@ -34,7 +34,7 @@
 #ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H
 #define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H
 
-#include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/exec_ctx.h"
 #include <grpc/support/slice.h>
 #include "src/core/transport/chttp2/frame.h"
 
diff --git a/src/core/transport/chttp2/hpack_parser.h b/src/core/transport/chttp2/hpack_parser.h
index 946f8e3..0d6d268 100644
--- a/src/core/transport/chttp2/hpack_parser.h
+++ b/src/core/transport/chttp2/hpack_parser.h
@@ -37,7 +37,7 @@
 #include <stddef.h>
 
 #include <grpc/support/port_platform.h>
-#include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/exec_ctx.h"
 #include "src/core/transport/chttp2/frame.h"
 #include "src/core/transport/chttp2/hpack_table.h"
 #include "src/core/transport/metadata.h"
diff --git a/src/core/transport/connectivity_state.h b/src/core/transport/connectivity_state.h
index 26f8874..9b4d8da 100644
--- a/src/core/transport/connectivity_state.h
+++ b/src/core/transport/connectivity_state.h
@@ -35,7 +35,7 @@
 #define GRPC_INTERNAL_CORE_TRANSPORT_CONNECTIVITY_STATE_H
 
 #include <grpc/grpc.h>
-#include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/exec_ctx.h"
 
 typedef struct grpc_connectivity_state_watcher {
   /** we keep watchers in a linked list */
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 8323465..04729c3 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -815,8 +815,10 @@
 src/core/iomgr/alarm.h \
 src/core/iomgr/alarm_heap.h \
 src/core/iomgr/alarm_internal.h \
+src/core/iomgr/closure.h \
 src/core/iomgr/endpoint.h \
 src/core/iomgr/endpoint_pair.h \
+src/core/iomgr/exec_ctx.h \
 src/core/iomgr/fd_posix.h \
 src/core/iomgr/iocp_windows.h \
 src/core/iomgr/iomgr.h \
@@ -946,6 +948,7 @@
 src/core/httpcli/parser.c \
 src/core/iomgr/alarm.c \
 src/core/iomgr/alarm_heap.c \
+src/core/iomgr/closure.c \
 src/core/iomgr/endpoint.c \
 src/core/iomgr/endpoint_pair_posix.c \
 src/core/iomgr/endpoint_pair_windows.c \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 5eb82b7..27a4120 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -12311,8 +12311,10 @@
       "src/core/iomgr/alarm.h", 
       "src/core/iomgr/alarm_heap.h", 
       "src/core/iomgr/alarm_internal.h", 
+      "src/core/iomgr/closure.h", 
       "src/core/iomgr/endpoint.h", 
       "src/core/iomgr/endpoint_pair.h", 
+      "src/core/iomgr/exec_ctx.h", 
       "src/core/iomgr/fd_posix.h", 
       "src/core/iomgr/iocp_windows.h", 
       "src/core/iomgr/iomgr.h", 
@@ -12485,11 +12487,14 @@
       "src/core/iomgr/alarm_heap.c", 
       "src/core/iomgr/alarm_heap.h", 
       "src/core/iomgr/alarm_internal.h", 
+      "src/core/iomgr/closure.c", 
+      "src/core/iomgr/closure.h", 
       "src/core/iomgr/endpoint.c", 
       "src/core/iomgr/endpoint.h", 
       "src/core/iomgr/endpoint_pair.h", 
       "src/core/iomgr/endpoint_pair_posix.c", 
       "src/core/iomgr/endpoint_pair_windows.c", 
+      "src/core/iomgr/exec_ctx.h", 
       "src/core/iomgr/fd_posix.c", 
       "src/core/iomgr/fd_posix.h", 
       "src/core/iomgr/iocp_windows.c", 
@@ -12808,8 +12813,10 @@
       "src/core/iomgr/alarm.h", 
       "src/core/iomgr/alarm_heap.h", 
       "src/core/iomgr/alarm_internal.h", 
+      "src/core/iomgr/closure.h", 
       "src/core/iomgr/endpoint.h", 
       "src/core/iomgr/endpoint_pair.h", 
+      "src/core/iomgr/exec_ctx.h", 
       "src/core/iomgr/fd_posix.h", 
       "src/core/iomgr/iocp_windows.h", 
       "src/core/iomgr/iomgr.h", 
@@ -12967,11 +12974,14 @@
       "src/core/iomgr/alarm_heap.c", 
       "src/core/iomgr/alarm_heap.h", 
       "src/core/iomgr/alarm_internal.h", 
+      "src/core/iomgr/closure.c", 
+      "src/core/iomgr/closure.h", 
       "src/core/iomgr/endpoint.c", 
       "src/core/iomgr/endpoint.h", 
       "src/core/iomgr/endpoint_pair.h", 
       "src/core/iomgr/endpoint_pair_posix.c", 
       "src/core/iomgr/endpoint_pair_windows.c", 
+      "src/core/iomgr/exec_ctx.h", 
       "src/core/iomgr/fd_posix.c", 
       "src/core/iomgr/fd_posix.h", 
       "src/core/iomgr/iocp_windows.c", 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index f7217b1..d88e038 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -277,8 +277,10 @@
     <ClInclude Include="..\..\..\src\core\iomgr\alarm.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\alarm_heap.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\alarm_internal.h" />
+    <ClInclude Include="..\..\..\src\core\iomgr\closure.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\endpoint.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\endpoint_pair.h" />
+    <ClInclude Include="..\..\..\src\core\iomgr\exec_ctx.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\fd_posix.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\iocp_windows.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\iomgr.h" />
@@ -466,6 +468,8 @@
     </ClCompile>
     <ClCompile Include="..\..\..\src\core\iomgr\alarm_heap.c">
     </ClCompile>
+    <ClCompile Include="..\..\..\src\core\iomgr\closure.c">
+    </ClCompile>
     <ClCompile Include="..\..\..\src\core\iomgr\endpoint.c">
     </ClCompile>
     <ClCompile Include="..\..\..\src\core\iomgr\endpoint_pair_posix.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index d373226..a835e8b 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -169,6 +169,9 @@
     <ClCompile Include="..\..\..\src\core\iomgr\alarm_heap.c">
       <Filter>src\core\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\src\core\iomgr\closure.c">
+      <Filter>src\core\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\..\src\core\iomgr\endpoint.c">
       <Filter>src\core\iomgr</Filter>
     </ClCompile>
@@ -608,12 +611,18 @@
     <ClInclude Include="..\..\..\src\core\iomgr\alarm_internal.h">
       <Filter>src\core\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\src\core\iomgr\closure.h">
+      <Filter>src\core\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\..\src\core\iomgr\endpoint.h">
       <Filter>src\core\iomgr</Filter>
     </ClInclude>
     <ClInclude Include="..\..\..\src\core\iomgr\endpoint_pair.h">
       <Filter>src\core\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\src\core\iomgr\exec_ctx.h">
+      <Filter>src\core\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\..\src\core\iomgr\fd_posix.h">
       <Filter>src\core\iomgr</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index ecc1d26..d8e9c1d 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -256,8 +256,10 @@
     <ClInclude Include="..\..\..\src\core\iomgr\alarm.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\alarm_heap.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\alarm_internal.h" />
+    <ClInclude Include="..\..\..\src\core\iomgr\closure.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\endpoint.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\endpoint_pair.h" />
+    <ClInclude Include="..\..\..\src\core\iomgr\exec_ctx.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\fd_posix.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\iocp_windows.h" />
     <ClInclude Include="..\..\..\src\core\iomgr\iomgr.h" />
@@ -405,6 +407,8 @@
     </ClCompile>
     <ClCompile Include="..\..\..\src\core\iomgr\alarm_heap.c">
     </ClCompile>
+    <ClCompile Include="..\..\..\src\core\iomgr\closure.c">
+    </ClCompile>
     <ClCompile Include="..\..\..\src\core\iomgr\endpoint.c">
     </ClCompile>
     <ClCompile Include="..\..\..\src\core\iomgr\endpoint_pair_posix.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 3813fb5..b2f9636 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -109,6 +109,9 @@
     <ClCompile Include="..\..\..\src\core\iomgr\alarm_heap.c">
       <Filter>src\core\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\src\core\iomgr\closure.c">
+      <Filter>src\core\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\..\src\core\iomgr\endpoint.c">
       <Filter>src\core\iomgr</Filter>
     </ClCompile>
@@ -506,12 +509,18 @@
     <ClInclude Include="..\..\..\src\core\iomgr\alarm_internal.h">
       <Filter>src\core\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\src\core\iomgr\closure.h">
+      <Filter>src\core\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\..\src\core\iomgr\endpoint.h">
       <Filter>src\core\iomgr</Filter>
     </ClInclude>
     <ClInclude Include="..\..\..\src\core\iomgr\endpoint_pair.h">
       <Filter>src\core\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\src\core\iomgr\exec_ctx.h">
+      <Filter>src\core\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\..\src\core\iomgr\fd_posix.h">
       <Filter>src\core\iomgr</Filter>
     </ClInclude>