Separate event driver from ares wrapper
diff --git a/BUILD b/BUILD
index d19e2c2..b7adf18 100644
--- a/BUILD
+++ b/BUILD
@@ -303,6 +303,7 @@
     "src/core/ext/lb_policy/grpclb/grpclb.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
+    "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h",
     "src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h",
     "src/core/ext/load_reporting/load_reporting.h",
     "src/core/ext/load_reporting/load_reporting_filter.h",
@@ -486,11 +487,11 @@
     "src/core/ext/lb_policy/pick_first/pick_first.c",
     "src/core/ext/lb_policy/round_robin/round_robin.c",
     "src/core/ext/resolver/dns/c_ares/dns_resolver.c",
+    "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c",
     "src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c",
     "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
     "src/core/ext/load_reporting/load_reporting.c",
     "src/core/ext/load_reporting/load_reporting_filter.c",
-    "src/core/ext/c-ares/wrapper.c",
     "src/core/ext/census/base_resources.c",
     "src/core/ext/census/context.c",
     "src/core/ext/census/gen/census.pb.c",
@@ -1028,6 +1029,7 @@
     "src/core/ext/client_config/subchannel_call_holder.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
+    "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h",
     "src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h",
     "src/core/ext/load_reporting/load_reporting.h",
     "src/core/ext/load_reporting/load_reporting_filter.h",
@@ -1180,6 +1182,7 @@
     "src/core/ext/client_config/subchannel_index.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/resolver/dns/c_ares/dns_resolver.c",
+    "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c",
     "src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c",
     "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
     "src/core/ext/load_reporting/load_reporting.c",
@@ -1979,11 +1982,11 @@
     "src/core/ext/lb_policy/pick_first/pick_first.c",
     "src/core/ext/lb_policy/round_robin/round_robin.c",
     "src/core/ext/resolver/dns/c_ares/dns_resolver.c",
+    "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c",
     "src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c",
     "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
     "src/core/ext/load_reporting/load_reporting.c",
     "src/core/ext/load_reporting/load_reporting_filter.c",
-    "src/core/ext/c-ares/wrapper.c",
     "src/core/ext/census/base_resources.c",
     "src/core/ext/census/context.c",
     "src/core/ext/census/gen/census.pb.c",
@@ -2173,6 +2176,7 @@
     "src/core/ext/lb_policy/grpclb/grpclb.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
+    "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h",
     "src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h",
     "src/core/ext/load_reporting/load_reporting.h",
     "src/core/ext/load_reporting/load_reporting_filter.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3d98931..81a6021 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -451,11 +451,11 @@
   src/core/ext/lb_policy/pick_first/pick_first.c
   src/core/ext/lb_policy/round_robin/round_robin.c
   src/core/ext/resolver/dns/c_ares/dns_resolver.c
+  src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
   src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c
   src/core/ext/resolver/sockaddr/sockaddr_resolver.c
   src/core/ext/load_reporting/load_reporting.c
   src/core/ext/load_reporting/load_reporting_filter.c
-  src/core/ext/c-ares/wrapper.c
   src/core/ext/census/base_resources.c
   src/core/ext/census/context.c
   src/core/ext/census/gen/census.pb.c
@@ -901,6 +901,7 @@
   src/core/ext/client_config/subchannel_index.c
   src/core/ext/client_config/uri_parser.c
   src/core/ext/resolver/dns/c_ares/dns_resolver.c
+  src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
   src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c
   src/core/ext/resolver/sockaddr/sockaddr_resolver.c
   src/core/ext/load_reporting/load_reporting.c
diff --git a/Makefile b/Makefile
index f036c17..992f212 100644
--- a/Makefile
+++ b/Makefile
@@ -1251,6 +1251,7 @@
 	$(Q)cp third_party/c-ares/.libs/libcares.a $(LIBDIR)/$(CONFIG)/c-ares
 
 $(OBJDIR)/$(CONFIG)/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.o: third_party/c-ares/configure
+$(OBJDIR)/$(CONFIG)/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.o: third_party/c-ares/configure
 
 static: static_c static_cxx
 
@@ -2761,11 +2762,11 @@
     src/core/ext/lb_policy/pick_first/pick_first.c \
     src/core/ext/lb_policy/round_robin/round_robin.c \
     src/core/ext/resolver/dns/c_ares/dns_resolver.c \
+    src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
     src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c \
     src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
     src/core/ext/load_reporting/load_reporting.c \
     src/core/ext/load_reporting/load_reporting_filter.c \
-    src/core/ext/c-ares/wrapper.c \
     src/core/ext/census/base_resources.c \
     src/core/ext/census/context.c \
     src/core/ext/census/gen/census.pb.c \
@@ -3459,6 +3460,7 @@
     src/core/ext/client_config/subchannel_index.c \
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/resolver/dns/c_ares/dns_resolver.c \
+    src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
     src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c \
     src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
     src/core/ext/load_reporting/load_reporting.c \
@@ -15238,7 +15240,6 @@
 # This is to ensure the embedded OpenSSL is built beforehand, properly
 # installing headers to their final destination on the drive. We need this
 # otherwise parallel compilation will fail if a source is compiled first.
-src/core/ext/c-ares/wrapper.c: $(OPENSSL_DEP)
 src/core/ext/transport/chttp2/client/secure/secure_channel_create.c: $(OPENSSL_DEP)
 src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c: $(OPENSSL_DEP)
 src/core/ext/transport/cronet/client/secure/cronet_channel_create.c: $(OPENSSL_DEP)
diff --git a/binding.gyp b/binding.gyp
index 620a5b4..a4ddd61 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -736,11 +736,11 @@
         'src/core/ext/lb_policy/pick_first/pick_first.c',
         'src/core/ext/lb_policy/round_robin/round_robin.c',
         'src/core/ext/resolver/dns/c_ares/dns_resolver.c',
+        'src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c',
         'src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c',
         'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
         'src/core/ext/load_reporting/load_reporting.c',
         'src/core/ext/load_reporting/load_reporting_filter.c',
-        'src/core/ext/c-ares/wrapper.c',
         'src/core/ext/census/base_resources.c',
         'src/core/ext/census/context.c',
         'src/core/ext/census/gen/census.pb.c',
diff --git a/build.yaml b/build.yaml
index 82ccbf8..92abb2f 100644
--- a/build.yaml
+++ b/build.yaml
@@ -9,9 +9,6 @@
   '#5': See the expand_version.py for all the quirks here
   version: 1.1.0-dev
 filegroups:
-- name: cares_wrapper
-  src:
-  - src/core/ext/c-ares/wrapper.c
 - name: census
   public_headers:
   - include/grpc/census.h
@@ -423,9 +420,11 @@
   - grpc_base
 - name: grpc_resolver_dns_ares
   headers:
+  - src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h
   - src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h
   src:
   - src/core/ext/resolver/dns/c_ares/dns_resolver.c
+  - src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
   - src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c
   plugin: grpc_resolver_dns_ares
   uses:
@@ -840,7 +839,6 @@
   - grpc_lb_policy_grpclb
   - grpc_resolver_sockaddr
   - grpc_load_reporting
-  - cares_wrapper
   - grpc_secure
   - census
   generate_plugin_registry: true
diff --git a/config.m4 b/config.m4
index a02fa6d..9f0d368 100644
--- a/config.m4
+++ b/config.m4
@@ -255,11 +255,11 @@
     src/core/ext/lb_policy/pick_first/pick_first.c \
     src/core/ext/lb_policy/round_robin/round_robin.c \
     src/core/ext/resolver/dns/c_ares/dns_resolver.c \
+    src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
     src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c \
     src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
     src/core/ext/load_reporting/load_reporting.c \
     src/core/ext/load_reporting/load_reporting_filter.c \
-    src/core/ext/c-ares/wrapper.c \
     src/core/ext/census/base_resources.c \
     src/core/ext/census/context.c \
     src/core/ext/census/gen/census.pb.c \
@@ -578,7 +578,6 @@
   PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc)
 
   PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/c-ares)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/census)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/census/gen)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/client_config)
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 1e8d050..f72c00f 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -400,6 +400,7 @@
                       'third_party/nanopb/pb_common.h',
                       'third_party/nanopb/pb_decode.h',
                       'third_party/nanopb/pb_encode.h',
+                      'src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h',
                       'src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h',
                       'src/core/ext/load_reporting/load_reporting.h',
                       'src/core/ext/load_reporting/load_reporting_filter.h',
@@ -586,11 +587,11 @@
                       'src/core/ext/lb_policy/pick_first/pick_first.c',
                       'src/core/ext/lb_policy/round_robin/round_robin.c',
                       'src/core/ext/resolver/dns/c_ares/dns_resolver.c',
+                      'src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c',
                       'src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c',
                       'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
                       'src/core/ext/load_reporting/load_reporting.c',
                       'src/core/ext/load_reporting/load_reporting_filter.c',
-                      'src/core/ext/c-ares/wrapper.c',
                       'src/core/ext/census/base_resources.c',
                       'src/core/ext/census/context.c',
                       'src/core/ext/census/gen/census.pb.c',
@@ -764,6 +765,7 @@
                               'third_party/nanopb/pb_common.h',
                               'third_party/nanopb/pb_decode.h',
                               'third_party/nanopb/pb_encode.h',
+                              'src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h',
                               'src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h',
                               'src/core/ext/load_reporting/load_reporting.h',
                               'src/core/ext/load_reporting/load_reporting_filter.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 07c2aeb..e9d01af 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -319,6 +319,7 @@
   s.files += %w( third_party/nanopb/pb_common.h )
   s.files += %w( third_party/nanopb/pb_decode.h )
   s.files += %w( third_party/nanopb/pb_encode.h )
+  s.files += %w( src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h )
   s.files += %w( src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h )
   s.files += %w( src/core/ext/load_reporting/load_reporting.h )
   s.files += %w( src/core/ext/load_reporting/load_reporting_filter.h )
@@ -505,11 +506,11 @@
   s.files += %w( src/core/ext/lb_policy/pick_first/pick_first.c )
   s.files += %w( src/core/ext/lb_policy/round_robin/round_robin.c )
   s.files += %w( src/core/ext/resolver/dns/c_ares/dns_resolver.c )
+  s.files += %w( src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c )
   s.files += %w( src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c )
   s.files += %w( src/core/ext/resolver/sockaddr/sockaddr_resolver.c )
   s.files += %w( src/core/ext/load_reporting/load_reporting.c )
   s.files += %w( src/core/ext/load_reporting/load_reporting_filter.c )
-  s.files += %w( src/core/ext/c-ares/wrapper.c )
   s.files += %w( src/core/ext/census/base_resources.c )
   s.files += %w( src/core/ext/census/context.c )
   s.files += %w( src/core/ext/census/gen/census.pb.c )
diff --git a/package.xml b/package.xml
index acd00b4..709cda1 100644
--- a/package.xml
+++ b/package.xml
@@ -327,6 +327,7 @@
     <file baseinstalldir="/" name="third_party/nanopb/pb_common.h" role="src" />
     <file baseinstalldir="/" name="third_party/nanopb/pb_decode.h" role="src" />
     <file baseinstalldir="/" name="third_party/nanopb/pb_encode.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting_filter.h" role="src" />
@@ -513,11 +514,11 @@
     <file baseinstalldir="/" name="src/core/ext/lb_policy/pick_first/pick_first.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/round_robin/round_robin.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/resolver/dns/c_ares/dns_resolver.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/resolver/sockaddr/sockaddr_resolver.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting_filter.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/c-ares/wrapper.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/base_resources.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/context.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.c" role="src" />
diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c
index 1fd8fd9..2977639 100644
--- a/src/core/ext/client_config/client_channel.c
+++ b/src/core/ext/client_config/client_channel.c
@@ -36,9 +36,6 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "src/core/lib/iomgr/ev_posix.h"
-#include "src/core/lib/iomgr/sockaddr.h"
-
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
@@ -85,22 +82,6 @@
   grpc_pollset_set *interested_parties;
 } channel_data;
 
-struct grpc_pollset_set {
-  gpr_mu mu;
-
-  size_t pollset_count;
-  size_t pollset_capacity;
-  grpc_pollset **pollsets;
-
-  size_t pollset_set_count;
-  size_t pollset_set_capacity;
-  struct grpc_pollset_set **pollset_sets;
-
-  size_t fd_count;
-  size_t fd_capacity;
-  grpc_fd **fds;
-};
-
 /** We create one watcher for each new lb_policy that is returned from a
    resolver,
     to watch for state changes from the lb_policy. When a state change is seen,
diff --git a/src/core/ext/resolver/dns/c_ares/dns_resolver.c b/src/core/ext/resolver/dns/c_ares/dns_resolver.c
index 29caac1..e741f19 100644
--- a/src/core/ext/resolver/dns/c_ares/dns_resolver.c
+++ b/src/core/ext/resolver/dns/c_ares/dns_resolver.c
@@ -271,6 +271,7 @@
 static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
   dns_resolver *r = (dns_resolver *)gr;
   gpr_mu_destroy(&r->mu);
+  grpc_ares_cleanup();
   if (r->resolved_config) {
     grpc_client_config_unref(exec_ctx, r->resolved_config);
   }
@@ -285,6 +286,7 @@
                                  const char *default_port,
                                  const char *lb_policy_name) {
   dns_resolver *r;
+  grpc_error *error;
   const char *path = args->uri->path;
 
   if (0 != strcmp(args->uri->authority, "")) {
@@ -292,6 +294,12 @@
     return NULL;
   }
 
+  error = grpc_ares_init();
+  if (error != GRPC_ERROR_NONE) {
+    GRPC_LOG_IF_ERROR("fd_orphan", error);
+    return NULL;
+  }
+
   if (path[0] == '/') ++path;
 
   r = gpr_malloc(sizeof(dns_resolver));
@@ -306,7 +314,6 @@
                    BACKOFF_MIN_SECONDS * 1000, BACKOFF_MAX_SECONDS * 1000);
   grpc_client_channel_factory_ref(r->client_channel_factory);
   r->lb_policy_name = gpr_strdup(lb_policy_name);
-  grpc_ares_init();
   return &r->base;
 }
 
diff --git a/src/core/ext/c-ares/wrapper.c b/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_dirver_windows.c
similarity index 89%
rename from src/core/ext/c-ares/wrapper.c
rename to src/core/ext/resolver/dns/c_ares/grpc_ares_ev_dirver_windows.c
index 720163d..cd8dfbc 100644
--- a/src/core/ext/c-ares/wrapper.c
+++ b/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_dirver_windows.c
@@ -31,13 +31,4 @@
  *
  */
 
-#include <grpc/support/port_platform.h>
-#include <ares.h>
-
-int cares(void) {
-  ares_channel channelptr;
-
-  ares_init(&channelptr);
-  ares_destroy(channelptr);
-  return 0;
-}
+#include "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h"
diff --git a/src/core/ext/c-ares/wrapper.c b/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h
similarity index 81%
copy from src/core/ext/c-ares/wrapper.c
copy to src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h
index 720163d..cac8a67 100644
--- a/src/core/ext/c-ares/wrapper.c
+++ b/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h
@@ -31,13 +31,13 @@
  *
  */
 
-#include <grpc/support/port_platform.h>
 #include <ares.h>
 
-int cares(void) {
-  ares_channel channelptr;
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/pollset_set.h"
 
-  ares_init(&channelptr);
-  ares_destroy(channelptr);
-  return 0;
-}
+typedef struct grpc_ares_ev_driver grpc_ares_ev_driver;
+
+void grpc_ares_notify_on_event(grpc_exec_ctx *exec_ctx, grpc_ares_ev_driver *ev_driver);
+
+grpc_ares_ev_driver *grpc_ares_ev_driver_create(ares_channel *channel, grpc_pollset_set *pollset_set);
diff --git a/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c b/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
new file mode 100644
index 0000000..ee1c0e1
--- /dev/null
+++ b/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
@@ -0,0 +1,176 @@
+/*
+ *
+ * Copyright 2016, 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 <grpc/support/port_platform.h>
+#ifdef GPR_POSIX_SOCKET
+
+#include "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h"
+
+
+#include "src/core/lib/iomgr/ev_posix.h"
+#include "src/core/lib/iomgr/sockaddr.h"
+
+#include <ares.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+#include "src/core/lib/iomgr/iomgr_internal.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/iomgr/unix_sockets_posix.h"
+#include "src/core/lib/support/block_annotate.h"
+#include "src/core/lib/support/string.h"
+
+typedef struct fd_pair {
+ grpc_fd *grpc_fd;
+ int fd;
+ struct fd_pair *next;
+} fd_pair;
+
+struct grpc_ares_ev_driver {
+ int id;
+ ares_socket_t socks[ARES_GETSOCK_MAXNUM];
+ int bitmask;
+ grpc_closure driver_closure;
+ grpc_pollset_set *pollset_set;
+ ares_channel *channel;
+ fd_pair *fds;
+};
+
+static fd_pair *get_fd(fd_pair **head, int fd) {
+  fd_pair dummy_head;
+  fd_pair *node;
+  fd_pair *ret;
+  dummy_head.next = *head;
+  node = &dummy_head;
+  while (node->next != NULL) {
+    if (node->next->fd == fd) {
+      ret = node->next;
+      node->next = node->next->next;
+      *head = dummy_head.next;
+      return ret;
+    }
+  }
+  return NULL;
+}
+
+static void driver_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+  grpc_ares_ev_driver *d = arg;
+  size_t i;
+  gpr_log(GPR_ERROR, "driver_cb");
+  if (error == GRPC_ERROR_NONE) {
+    gpr_log(GPR_ERROR, "GRPC_ERROR_NONE");
+    for (i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
+      ares_process_fd(
+          *d->channel,
+          ARES_GETSOCK_READABLE(d->bitmask, i) ? d->socks[i] : ARES_SOCKET_BAD,
+          ARES_GETSOCK_WRITABLE(d->bitmask, i) ? d->socks[i] : ARES_SOCKET_BAD);
+    }
+  }
+  grpc_ares_notify_on_event(exec_ctx, d);
+  grpc_exec_ctx_flush(exec_ctx);
+}
+
+void grpc_ares_notify_on_event(grpc_exec_ctx *exec_ctx, grpc_ares_ev_driver *ev_driver) {
+  size_t i;
+  fd_pair *new_list = NULL;
+  ev_driver->bitmask =
+      ares_getsock(*ev_driver->channel, ev_driver->socks, ARES_GETSOCK_MAXNUM);
+  grpc_closure_init(&ev_driver->driver_closure, driver_cb, ev_driver);
+  for (i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
+    char *final_name;
+    gpr_asprintf(&final_name, "host1%" PRIuPTR, i);
+
+    if (ARES_GETSOCK_READABLE(ev_driver->bitmask, i) ||
+        ARES_GETSOCK_WRITABLE(ev_driver->bitmask, i)) {
+      gpr_log(GPR_ERROR, "%d", ev_driver->socks[i]);
+      fd_pair *fdp = get_fd(&ev_driver->fds, ev_driver->socks[i]);
+      if (!fdp) {
+        gpr_log(GPR_ERROR, "new fd");
+        fdp = gpr_malloc(sizeof(fd_pair));
+        fdp->grpc_fd = grpc_fd_create(ev_driver->socks[i], final_name);
+        fdp->fd = ev_driver->socks[i];
+        grpc_pollset_set_add_fd(exec_ctx, ev_driver->pollset_set, fdp->grpc_fd);
+        // new_fd_pair->grpc_fd = fd;
+        // new_fd_pair->next = ev_driver->fds;
+      }
+      fdp->next = new_list;
+      new_list = fdp;
+
+      if (ARES_GETSOCK_READABLE(ev_driver->bitmask, i)) {
+        gpr_log(GPR_ERROR, "READABLE");
+
+        grpc_fd_notify_on_read(exec_ctx, fdp->grpc_fd,
+                               &ev_driver->driver_closure);
+      }
+      if (ARES_GETSOCK_WRITABLE(ev_driver->bitmask, i)) {
+        gpr_log(GPR_ERROR, "writable");
+
+        grpc_fd_notify_on_write(exec_ctx, fdp->grpc_fd,
+                                &ev_driver->driver_closure);
+      }
+    }
+    gpr_free(final_name);
+  }
+
+  while (ev_driver->fds != NULL) {
+    fd_pair *cur;
+    // int fd;s
+    cur = ev_driver->fds;
+    ev_driver->fds = ev_driver->fds->next;
+    gpr_log(GPR_ERROR, "fd in ev_driver: %d\n", cur->fd);
+    grpc_pollset_set_del_fd(exec_ctx, ev_driver->pollset_set, cur->grpc_fd);
+    gpr_log(GPR_ERROR, "grpc_pollset_set_del_fd");
+    grpc_fd_shutdown(exec_ctx, cur->grpc_fd);
+    gpr_log(GPR_ERROR, "grpc_fd_shutdown");
+    grpc_fd_orphan(exec_ctx, cur->grpc_fd, NULL, NULL, "come on..");
+    gpr_log(GPR_ERROR, "grpc_fd_orphan");
+    gpr_free(cur);
+  }
+
+  ev_driver->fds = new_list;
+
+  gpr_log(GPR_ERROR, "eof notify_on_event");
+}
+
+
+
+grpc_ares_ev_driver *grpc_ares_ev_driver_create(ares_channel *channel, grpc_pollset_set *pollset_set) {
+  grpc_ares_ev_driver *ev_driver = gpr_malloc(sizeof(grpc_ares_ev_driver));
+  ev_driver->channel = channel;
+  ev_driver->pollset_set = pollset_set;
+  ev_driver->fds = NULL;
+  return ev_driver;
+}
+
+#endif
diff --git a/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c b/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c
index 73563ea..3db974b 100644
--- a/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c
+++ b/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c
@@ -33,10 +33,6 @@
 
 #include <grpc/support/port_platform.h>
 
-#include "src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h"
-#include "src/core/lib/iomgr/ev_posix.h"
-#include "src/core/lib/iomgr/sockaddr.h"
-
 #ifdef GPR_POSIX_SOCKET
 #include <arpa/inet.h>
 #endif
@@ -45,6 +41,10 @@
 #include <winsock2.h>
 #endif
 
+#include "src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h"
+// #include "src/core/lib/iomgr/ev_posix.h"
+// #include "src/core/lib/iomgr/sockaddr.h"
+
 #include <string.h>
 #include <sys/types.h>
 
@@ -56,6 +56,7 @@
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
+#include "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h"
 #include "src/core/lib/iomgr/executor.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -63,22 +64,6 @@
 #include "src/core/lib/support/block_annotate.h"
 #include "src/core/lib/support/string.h"
 
-typedef struct fd_pair {
-  grpc_fd *grpc_fd;
-  int fd;
-  struct fd_pair *next;
-} fd_pair;
-
-typedef struct {
-  int id;
-  ares_socket_t socks[ARES_GETSOCK_MAXNUM];
-  int bitmask;
-  grpc_closure driver_closure;
-  grpc_pollset_set *pollset_set;
-  ares_channel *channel;
-  fd_pair *fds;
-} driver;
-
 struct grpc_ares_request {
   char *name;
   char *host;
@@ -90,122 +75,122 @@
   grpc_closure request_closure;
   void *arg;
   ares_channel channel;
-  driver ev_driver;
+  grpc_ares_ev_driver* ev_driver;
 };
 
-struct grpc_pollset_set {
-  gpr_mu mu;
+// struct grpc_pollset_set {
+//   gpr_mu mu;
+//
+//   size_t pollset_count;
+//   size_t pollset_capacity;
+//   grpc_pollset **pollsets;
+//
+//   size_t pollset_set_count;
+//   size_t pollset_set_capacity;
+//   struct grpc_pollset_set **pollset_sets;
+//
+//   size_t fd_count;
+//   size_t fd_capacity;
+//   grpc_fd **fds;
+// };
 
-  size_t pollset_count;
-  size_t pollset_capacity;
-  grpc_pollset **pollsets;
-
-  size_t pollset_set_count;
-  size_t pollset_set_capacity;
-  struct grpc_pollset_set **pollset_sets;
-
-  size_t fd_count;
-  size_t fd_capacity;
-  grpc_fd **fds;
-};
-
-static void driver_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
-
-static fd_pair *get_fd(fd_pair **head, int fd) {
-  fd_pair dummy_head;
-  fd_pair *node;
-  fd_pair *ret;
-  dummy_head.next = *head;
-  node = &dummy_head;
-  while (node->next != NULL) {
-    if (node->next->fd == fd) {
-      ret = node->next;
-      node->next = node->next->next;
-      *head = dummy_head.next;
-      return ret;
-    }
-  }
-  return NULL;
-}
-
-static void notify_on_event(grpc_exec_ctx *exec_ctx, driver *ev_driver) {
-  size_t i;
-  fd_pair *new_list = NULL;
-  ev_driver->bitmask =
-      ares_getsock(*ev_driver->channel, ev_driver->socks, ARES_GETSOCK_MAXNUM);
-  grpc_closure_init(&ev_driver->driver_closure, driver_cb, ev_driver);
-  for (i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
-    char *final_name;
-    gpr_asprintf(&final_name, "host1%" PRIuPTR, i);
-
-    if (ARES_GETSOCK_READABLE(ev_driver->bitmask, i) ||
-        ARES_GETSOCK_WRITABLE(ev_driver->bitmask, i)) {
-      gpr_log(GPR_ERROR, "%d", ev_driver->socks[i]);
-      fd_pair *fdp = get_fd(&ev_driver->fds, ev_driver->socks[i]);
-      if (!fdp) {
-        gpr_log(GPR_ERROR, "new fd");
-        fdp = gpr_malloc(sizeof(fd_pair));
-        fdp->grpc_fd = grpc_fd_create(ev_driver->socks[i], final_name);
-        fdp->fd = ev_driver->socks[i];
-        grpc_pollset_set_add_fd(exec_ctx, ev_driver->pollset_set, fdp->grpc_fd);
-        // new_fd_pair->grpc_fd = fd;
-        // new_fd_pair->next = ev_driver->fds;
-      }
-      fdp->next = new_list;
-      new_list = fdp;
-
-      if (ARES_GETSOCK_READABLE(ev_driver->bitmask, i)) {
-        gpr_log(GPR_ERROR, "READABLE");
-
-        grpc_fd_notify_on_read(exec_ctx, fdp->grpc_fd,
-                               &ev_driver->driver_closure);
-      }
-      if (ARES_GETSOCK_WRITABLE(ev_driver->bitmask, i)) {
-        gpr_log(GPR_ERROR, "writable");
-
-        grpc_fd_notify_on_write(exec_ctx, fdp->grpc_fd,
-                                &ev_driver->driver_closure);
-      }
-    }
-    gpr_free(final_name);
-  }
-
-  while (ev_driver->fds != NULL) {
-    fd_pair *cur;
-    // int fd;s
-    cur = ev_driver->fds;
-    ev_driver->fds = ev_driver->fds->next;
-    gpr_log(GPR_ERROR, "fd in ev_driver: %d\n", cur->fd);
-    grpc_pollset_set_del_fd(exec_ctx, ev_driver->pollset_set, cur->grpc_fd);
-    gpr_log(GPR_ERROR, "grpc_pollset_set_del_fd");
-    grpc_fd_shutdown(exec_ctx, cur->grpc_fd);
-    gpr_log(GPR_ERROR, "grpc_fd_shutdown");
-    grpc_fd_orphan(exec_ctx, cur->grpc_fd, NULL, NULL, "come on..");
-    gpr_log(GPR_ERROR, "grpc_fd_orphan");
-    gpr_free(cur);
-  }
-
-  ev_driver->fds = new_list;
-
-  gpr_log(GPR_ERROR, "eof notify_on_event");
-}
-
-static void driver_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
-  driver *d = arg;
-  size_t i;
-  gpr_log(GPR_ERROR, "driver_cb");
-  if (error == GRPC_ERROR_NONE) {
-    gpr_log(GPR_ERROR, "GRPC_ERROR_NONE");
-    for (i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
-      ares_process_fd(
-          *d->channel,
-          ARES_GETSOCK_READABLE(d->bitmask, i) ? d->socks[i] : ARES_SOCKET_BAD,
-          ARES_GETSOCK_WRITABLE(d->bitmask, i) ? d->socks[i] : ARES_SOCKET_BAD);
-    }
-  }
-  notify_on_event(exec_ctx, d);
-  grpc_exec_ctx_flush(exec_ctx);
-}
+// static void driver_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
+//
+// static fd_pair *get_fd(fd_pair **head, int fd) {
+//   fd_pair dummy_head;
+//   fd_pair *node;
+//   fd_pair *ret;
+//   dummy_head.next = *head;
+//   node = &dummy_head;
+//   while (node->next != NULL) {
+//     if (node->next->fd == fd) {
+//       ret = node->next;
+//       node->next = node->next->next;
+//       *head = dummy_head.next;
+//       return ret;
+//     }
+//   }
+//   return NULL;
+// }
+//
+// static void notify_on_event(grpc_exec_ctx *exec_ctx, driver *ev_driver) {
+//   size_t i;
+//   fd_pair *new_list = NULL;
+//   ev_driver->bitmask =
+//       ares_getsock(*ev_driver->channel, ev_driver->socks, ARES_GETSOCK_MAXNUM);
+//   grpc_closure_init(&ev_driver->driver_closure, driver_cb, ev_driver);
+//   for (i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
+//     char *final_name;
+//     gpr_asprintf(&final_name, "host1%" PRIuPTR, i);
+//
+//     if (ARES_GETSOCK_READABLE(ev_driver->bitmask, i) ||
+//         ARES_GETSOCK_WRITABLE(ev_driver->bitmask, i)) {
+//       gpr_log(GPR_ERROR, "%d", ev_driver->socks[i]);
+//       fd_pair *fdp = get_fd(&ev_driver->fds, ev_driver->socks[i]);
+//       if (!fdp) {
+//         gpr_log(GPR_ERROR, "new fd");
+//         fdp = gpr_malloc(sizeof(fd_pair));
+//         fdp->grpc_fd = grpc_fd_create(ev_driver->socks[i], final_name);
+//         fdp->fd = ev_driver->socks[i];
+//         grpc_pollset_set_add_fd(exec_ctx, ev_driver->pollset_set, fdp->grpc_fd);
+//         // new_fd_pair->grpc_fd = fd;
+//         // new_fd_pair->next = ev_driver->fds;
+//       }
+//       fdp->next = new_list;
+//       new_list = fdp;
+//
+//       if (ARES_GETSOCK_READABLE(ev_driver->bitmask, i)) {
+//         gpr_log(GPR_ERROR, "READABLE");
+//
+//         grpc_fd_notify_on_read(exec_ctx, fdp->grpc_fd,
+//                                &ev_driver->driver_closure);
+//       }
+//       if (ARES_GETSOCK_WRITABLE(ev_driver->bitmask, i)) {
+//         gpr_log(GPR_ERROR, "writable");
+//
+//         grpc_fd_notify_on_write(exec_ctx, fdp->grpc_fd,
+//                                 &ev_driver->driver_closure);
+//       }
+//     }
+//     gpr_free(final_name);
+//   }
+//
+//   while (ev_driver->fds != NULL) {
+//     fd_pair *cur;
+//     // int fd;s
+//     cur = ev_driver->fds;
+//     ev_driver->fds = ev_driver->fds->next;
+//     gpr_log(GPR_ERROR, "fd in ev_driver: %d\n", cur->fd);
+//     grpc_pollset_set_del_fd(exec_ctx, ev_driver->pollset_set, cur->grpc_fd);
+//     gpr_log(GPR_ERROR, "grpc_pollset_set_del_fd");
+//     grpc_fd_shutdown(exec_ctx, cur->grpc_fd);
+//     gpr_log(GPR_ERROR, "grpc_fd_shutdown");
+//     grpc_fd_orphan(exec_ctx, cur->grpc_fd, NULL, NULL, "come on..");
+//     gpr_log(GPR_ERROR, "grpc_fd_orphan");
+//     gpr_free(cur);
+//   }
+//
+//   ev_driver->fds = new_list;
+//
+//   gpr_log(GPR_ERROR, "eof notify_on_event");
+// }
+//
+// static void driver_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+//   driver *d = arg;
+//   size_t i;
+//   gpr_log(GPR_ERROR, "driver_cb");
+//   if (error == GRPC_ERROR_NONE) {
+//     gpr_log(GPR_ERROR, "GRPC_ERROR_NONE");
+//     for (i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
+//       ares_process_fd(
+//           *d->channel,
+//           ARES_GETSOCK_READABLE(d->bitmask, i) ? d->socks[i] : ARES_SOCKET_BAD,
+//           ARES_GETSOCK_WRITABLE(d->bitmask, i) ? d->socks[i] : ARES_SOCKET_BAD);
+//     }
+//   }
+//   notify_on_event(exec_ctx, d);
+//   grpc_exec_ctx_flush(exec_ctx);
+// }
 
 static void on_done_cb(void *arg, int status, int timeouts,
                        struct hostent *hostent) {
@@ -277,25 +262,12 @@
 
 static void resolve_address_impl(grpc_exec_ctx *exec_ctx, void *arg,
                                  grpc_error *error) {
-  int status;
-
   grpc_ares_request *r = (grpc_ares_request *)arg;
-  gpr_log(GPR_ERROR, "Really?");
 
-  status = ares_init(&r->channel);
-  if (status != ARES_SUCCESS) {
-    gpr_log(GPR_ERROR, "ares_init failed");
-  }
-
-  driver *ev_driver = &r->ev_driver;
-  ev_driver->channel = &r->channel;
   gpr_log(GPR_ERROR, "before ares_gethostbyname %s", r->host);
   ares_gethostbyname(r->channel, r->host, AF_UNSPEC, on_done_cb, r);
   gpr_log(GPR_ERROR, "before ares_getsock");
-  notify_on_event(exec_ctx, &r->ev_driver);
-
-  gpr_log(GPR_ERROR, "before poll");
-
+  grpc_ares_notify_on_event(exec_ctx, r->ev_driver);
   gpr_log(GPR_ERROR, "eof resolve_address_impl");
 }
 
@@ -344,14 +316,21 @@
   char *host;
   char *port;
   grpc_error *err;
+  int status;
 
   grpc_ares_request *r = gpr_malloc(sizeof(grpc_ares_request));
   r->name = gpr_strdup(name);
   r->default_port = gpr_strdup(default_port);
   r->on_done = on_done;
   r->addrs_out = addrs;
-  r->ev_driver.pollset_set = pollset_set;
-  r->ev_driver.fds = NULL;
+
+  status = ares_init(&r->channel);
+  if (status != ARES_SUCCESS) {
+    grpc_exec_ctx_sched(exec_ctx, on_done, GRPC_ERROR_CREATE("Failed to init ares"), NULL);
+    return r;
+  }
+
+  r->ev_driver = grpc_ares_ev_driver_create(&r->channel, pollset_set);
 
   if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' &&
       name[4] == ':' && name[5] != 0) {
@@ -385,9 +364,14 @@
   return r;
 }
 
-void grpc_ares_init(void) {
+grpc_error *grpc_ares_init(void) {
   int status = ares_library_init(ARES_LIB_INIT_ALL);
   if (status != ARES_SUCCESS) {
-    gpr_log(GPR_ERROR, "ares_library_init failed");
+    return GRPC_ERROR_CREATE("ares_library_init failed");
   }
+  return GRPC_ERROR_NONE;
+}
+
+void grpc_ares_cleanup(void) {
+  ares_library_cleanup();
 }
diff --git a/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h
index 6d931c7..f4468df 100644
--- a/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h
+++ b/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -47,6 +47,8 @@
     grpc_pollset_set *pollset_set, grpc_closure *on_done,
     grpc_resolved_addresses **addresses);
 
-void grpc_ares_init(void);
+grpc_error *grpc_ares_init(void);
+
+void grpc_ares_cleanup(void);
 
 #endif /* GRPC_CORE_EXT_RESOLVER_DNS_CARES_RESOLVE_ADDRESS_CARES_H */
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 8f02d25..f4b3d35 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -249,11 +249,11 @@
   'src/core/ext/lb_policy/pick_first/pick_first.c',
   'src/core/ext/lb_policy/round_robin/round_robin.c',
   'src/core/ext/resolver/dns/c_ares/dns_resolver.c',
+  'src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c',
   'src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c',
   'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
   'src/core/ext/load_reporting/load_reporting.c',
   'src/core/ext/load_reporting/load_reporting_filter.c',
-  'src/core/ext/c-ares/wrapper.c',
   'src/core/ext/census/base_resources.c',
   'src/core/ext/census/context.c',
   'src/core/ext/census/gen/census.pb.c',
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 27b6df6..507e1f8 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -894,6 +894,7 @@
   	$(Q)cp third_party/c-ares/.libs/libcares.a $(LIBDIR)/$(CONFIG)/c-ares
 
   $(OBJDIR)/$(CONFIG)/src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.o: third_party/c-ares/configure
+  $(OBJDIR)/$(CONFIG)/src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.o: third_party/c-ares/configure
 
   static: static_c static_cxx
 
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index f11694a..e368e6d 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -938,6 +938,7 @@
 third_party/nanopb/pb_common.h \
 third_party/nanopb/pb_decode.h \
 third_party/nanopb/pb_encode.h \
+src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h \
 src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h \
 src/core/ext/load_reporting/load_reporting.h \
 src/core/ext/load_reporting/load_reporting_filter.h \
@@ -1124,11 +1125,11 @@
 src/core/ext/lb_policy/pick_first/pick_first.c \
 src/core/ext/lb_policy/round_robin/round_robin.c \
 src/core/ext/resolver/dns/c_ares/dns_resolver.c \
+src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c \
 src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c \
 src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
 src/core/ext/load_reporting/load_reporting.c \
 src/core/ext/load_reporting/load_reporting_filter.c \
-src/core/ext/c-ares/wrapper.c \
 src/core/ext/census/base_resources.c \
 src/core/ext/census/context.c \
 src/core/ext/census/gen/census.pb.c \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 06198a9..5a9441d 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -4211,7 +4211,6 @@
   }, 
   {
     "deps": [
-      "cares_wrapper", 
       "census", 
       "gpr", 
       "grpc_base", 
@@ -5533,17 +5532,6 @@
     "type": "lib"
   }, 
   {
-    "deps": [], 
-    "headers": [], 
-    "language": "c", 
-    "name": "cares_wrapper", 
-    "src": [
-      "src/core/ext/c-ares/wrapper.c"
-    ], 
-    "third_party": false, 
-    "type": "filegroup"
-  }, 
-  {
     "deps": [
       "gpr", 
       "grpc_base", 
@@ -6214,12 +6202,15 @@
       "grpc_client_config"
     ], 
     "headers": [
+      "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h", 
       "src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h"
     ], 
     "language": "c", 
     "name": "grpc_resolver_dns_ares", 
     "src": [
       "src/core/ext/resolver/dns/c_ares/dns_resolver.c", 
+      "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver.h", 
+      "src/core/ext/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c", 
       "src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.c", 
       "src/core/ext/resolver/dns/c_ares/grpc_ares_wrapper.h"
     ], 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index df51caa..e65c110 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -447,6 +447,7 @@
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_common.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_ev_driver.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.h" />
@@ -809,6 +810,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\dns_resolver.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_ev_driver_posix.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
@@ -817,8 +820,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\c-ares\wrapper.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\base_resources.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\context.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 9a12796..4cdd31f 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -523,6 +523,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\dns_resolver.c">
       <Filter>src\core\ext\resolver\dns\c_ares</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_ev_driver_posix.c">
+      <Filter>src\core\ext\resolver\dns\c_ares</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.c">
       <Filter>src\core\ext\resolver\dns\c_ares</Filter>
     </ClCompile>
@@ -535,9 +538,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.c">
       <Filter>src\core\ext\load_reporting</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\c-ares\wrapper.c">
-      <Filter>src\core\ext\c-ares</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\base_resources.c">
       <Filter>src\core\ext\census</Filter>
     </ClCompile>
@@ -1115,6 +1115,9 @@
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h">
       <Filter>third_party\nanopb</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_ev_driver.h">
+      <Filter>src\core\ext\resolver\dns\c_ares</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.h">
       <Filter>src\core\ext\resolver\dns\c_ares</Filter>
     </ClInclude>
@@ -1175,9 +1178,6 @@
     <Filter Include="src\core\ext">
       <UniqueIdentifier>{3f32a58f-394f-5f13-06aa-6cc52cc2daaf}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\c-ares">
-      <UniqueIdentifier>{10af2444-c936-0d6b-042b-b9d576c199fe}</UniqueIdentifier>
-    </Filter>
     <Filter Include="src\core\ext\census">
       <UniqueIdentifier>{9bf70bd2-f553-11b2-c237-abd148971eea}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index f348d12..d69de11 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -405,6 +405,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_call_holder.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_ev_driver.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.h" />
@@ -700,6 +701,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\dns_resolver.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_ev_driver_posix.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 2619ed2..015533e 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -412,6 +412,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\dns_resolver.c">
       <Filter>src\core\ext\resolver\dns\c_ares</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_ev_driver_posix.c">
+      <Filter>src\core\ext\resolver\dns\c_ares</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.c">
       <Filter>src\core\ext\resolver\dns\c_ares</Filter>
     </ClCompile>
@@ -926,6 +929,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_ev_driver.h">
+      <Filter>src\core\ext\resolver\dns\c_ares</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\resolver\dns\c_ares\grpc_ares_wrapper.h">
       <Filter>src\core\ext\resolver\dns\c_ares</Filter>
     </ClInclude>