[dart] Port the runner to libasync.

Test: successfully ran (and stopped) hello_dart_*
Bug: DX-1077 #done
Change-Id: I88556503f96c73bb02dc617f0b20055ed4112c7d
diff --git a/runtime/dart_runner/BUILD.gn b/runtime/dart_runner/BUILD.gn
index 5dab00e..076aa0e 100644
--- a/runtime/dart_runner/BUILD.gn
+++ b/runtime/dart_runner/BUILD.gn
@@ -47,11 +47,12 @@
              "//garnet/public/lib/fsl",
              "//garnet/public/lib/fxl",
              "//garnet/public/lib/svc/cpp",
-             "//topaz/lib/deprecated_loop",
              "//topaz/runtime/dart/utils",
              "//third_party/tonic",
-             "//topaz/lib/deprecated_loop",
              "//topaz/public/dart-pkg/fuchsia",
+             "//zircon/public/lib/async",
+             "//zircon/public/lib/async-loop",
+             "//zircon/public/lib/async-loop-cpp",
              "//zircon/public/lib/trace-provider",
            ] + dart_deps + extra_deps
   }
diff --git a/runtime/dart_runner/builtin_libraries.cc b/runtime/dart_runner/builtin_libraries.cc
index a76897c..5d7a91d 100644
--- a/runtime/dart_runner/builtin_libraries.cc
+++ b/runtime/dart_runner/builtin_libraries.cc
@@ -15,7 +15,6 @@
 #include "third_party/tonic/converter/dart_converter.h"
 #include "third_party/tonic/dart_microtask_queue.h"
 #include "third_party/tonic/logging/dart_error.h"
-#include "topaz/lib/deprecated_loop/message_loop.h"
 
 using tonic::ToDart;
 
@@ -145,7 +144,7 @@
     schedule_immediate_closure = Dart_Invoke(
         isolate_lib, ToDart("_getIsolateScheduleImmediateClosure"), 0, nullptr);
   } else {
-    // Running on deprecated_loop::MessageLoop.
+    // Running on async::Loop.
     schedule_immediate_closure = Dart_Invoke(
         builtin_lib, ToDart("_getScheduleMicrotaskClosure"), 0, nullptr);
   }
diff --git a/runtime/dart_runner/dart_component_controller.cc b/runtime/dart_runner/dart_component_controller.cc
index e023550..91e8660 100644
--- a/runtime/dart_runner/dart_component_controller.cc
+++ b/runtime/dart_runner/dart_component_controller.cc
@@ -5,6 +5,8 @@
 #include "topaz/runtime/dart_runner/dart_component_controller.h"
 
 #include <fcntl.h>
+#include <lib/async/default.h>
+#include <lib/async-loop/loop.h>
 #include <lib/fdio/namespace.h>
 #include <lib/fdio/util.h>
 #include <sys/stat.h>
@@ -27,7 +29,6 @@
 #include "third_party/tonic/dart_microtask_queue.h"
 #include "third_party/tonic/dart_state.h"
 #include "third_party/tonic/logging/dart_error.h"
-#include "topaz/lib/deprecated_loop/message_loop.h"
 #include "topaz/runtime/dart/utils/handle_exception.h"
 #include "topaz/runtime/dart/utils/tempfs.h"
 
@@ -41,12 +42,21 @@
 
 namespace {
 
-void AfterTask() {
+void AfterTask(async_loop_t*, void*) {
   tonic::DartMicrotaskQueue* queue =
       tonic::DartMicrotaskQueue::GetForCurrentThread();
-  queue->RunMicrotasks();
+  // Verify that the queue exists, as this method could have been called back as
+  // part of the exit routine, after the destruction of the microtask queue.
+  if (queue) {
+    queue->RunMicrotasks();
+  }
 }
 
+constexpr async_loop_config_t kLoopConfig = {
+  .make_default_for_current_thread = true,
+  .epilogue = &AfterTask,
+};
+
 // Find the last path component.
 // fuchsia-pkg://fuchsia.com/hello_dart#meta/hello_dart.cmx -> hello_dart.cmx
 std::string GetLabelFromURL(const std::string& url) {
@@ -65,7 +75,8 @@
     fuchsia::sys::StartupInfo startup_info,
     std::shared_ptr<component::Services> runner_incoming_services,
     fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller)
-    : label_(GetLabelFromURL(package.resolved_url)),
+    : loop_(new async::Loop(&kLoopConfig)),
+      label_(GetLabelFromURL(package.resolved_url)),
       url_(std::move(package.resolved_url)),
       package_(std::move(package)),
       startup_info_(std::move(startup_info)),
@@ -311,10 +322,9 @@
 
   state->get()->SetIsolate(isolate_);
 
-  auto task_runner = deprecated_loop::MessageLoop::GetCurrent()->task_runner();
   tonic::DartMessageHandler::TaskDispatcher dispatcher =
-      [task_runner](auto callback) {
-        task_runner->PostTask(std::move(callback));
+      [loop = loop_.get()](auto callback) {
+        async::PostTask(loop->dispatcher(), std::move(callback));
       };
   state->get()->message_handler().Initialize(dispatcher);
 
@@ -324,11 +334,20 @@
   return true;
 }
 
+void DartComponentController::Run() {
+  async::PostTask(loop_->dispatcher(), [loop = loop_.get(), app = this] {
+    if (!app->Main()) {
+      loop->Quit();
+    }
+  });
+  loop_->Run();
+  SendReturnCode();
+}
+
 bool DartComponentController::Main() {
   Dart_EnterScope();
 
   tonic::DartMicrotaskQueue::StartForCurrentThread();
-  deprecated_loop::MessageLoop::GetCurrent()->SetAfterTaskCallback(AfterTask);
 
   std::vector<std::string> arguments =
       std::move(startup_info_.launch_info.arguments);
@@ -399,10 +418,9 @@
 
 void DartComponentController::Kill() {
   if (Dart_CurrentIsolate()) {
-    deprecated_loop::MessageLoop::GetCurrent()->SetAfterTaskCallback(nullptr);
     tonic::DartMicrotaskQueue::GetForCurrentThread()->Destroy();
 
-    deprecated_loop::MessageLoop::GetCurrent()->QuitNow();
+    loop_->Quit();
 
     // TODO(rosswang): The docs warn of threading issues if doing this again,
     // but without this, attempting to shut down the isolate finalizes app
diff --git a/runtime/dart_runner/dart_component_controller.h b/runtime/dart_runner/dart_component_controller.h
index 563efba..c0b98e4 100644
--- a/runtime/dart_runner/dart_component_controller.h
+++ b/runtime/dart_runner/dart_component_controller.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include <lib/async/cpp/wait.h>
+#include <lib/async-loop/cpp/loop.h>
 #include <lib/fdio/namespace.h>
 #include <lib/zx/timer.h>
 
@@ -33,6 +34,7 @@
   ~DartComponentController() override;
 
   bool Setup();
+  void Run();
   bool Main();
   void SendReturnCode();
 
@@ -58,6 +60,9 @@
   void OnIdleTimer(async_dispatcher_t* dispatcher, async::WaitBase* wait,
                    zx_status_t status, const zx_packet_signal* signal);
 
+  // The loop must be the first declared member so that it gets destroyed after
+  // binding_ which expects the existence of a loop.
+  std::unique_ptr<async::Loop> loop_;
   std::string label_;
   std::string url_;
   fuchsia::sys::Package package_;
diff --git a/runtime/dart_runner/dart_runner.cc b/runtime/dart_runner/dart_runner.cc
index 18bf514..89feb9e 100644
--- a/runtime/dart_runner/dart_runner.cc
+++ b/runtime/dart_runner/dart_runner.cc
@@ -5,6 +5,8 @@
 #include "topaz/runtime/dart_runner/dart_runner.h"
 
 #include <errno.h>
+#include <lib/async/default.h>
+#include <lib/async-loop/loop.h>
 #include <sys/stat.h>
 #include <trace/event.h>
 #include <zircon/status.h>
@@ -16,7 +18,6 @@
 #include "third_party/dart/runtime/include/bin/dart_io_api.h"
 #include "third_party/tonic/dart_microtask_queue.h"
 #include "third_party/tonic/dart_state.h"
-#include "topaz/lib/deprecated_loop/message_loop.h"
 #include "topaz/runtime/dart/utils/vmservice_object.h"
 #include "topaz/runtime/dart_runner/dart_component_controller.h"
 #include "topaz/runtime/dart_runner/service_isolate.h"
@@ -74,13 +75,12 @@
 
 void IsolateShutdownCallback(void* callback_data) {
   // The service isolate (and maybe later the kernel isolate) doesn't have an
-  // deprecated_loop::MessageLoop.
-  deprecated_loop::MessageLoop* loop =
-      deprecated_loop::MessageLoop::GetCurrent();
+  // async loop.
+  auto dispatcher = async_get_default_dispatcher();
+  auto loop = async_loop_from_dispatcher(dispatcher);
   if (loop) {
-    loop->SetAfterTaskCallback(nullptr);
     tonic::DartMicrotaskQueue::GetForCurrentThread()->Destroy();
-    loop->QuitNow();
+    async_loop_quit(loop);
   }
 }
 
@@ -94,7 +94,6 @@
     std::shared_ptr<component::Services> runner_incoming_services,
     ::fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
   int64_t start = Dart_TimelineGetMicros();
-  deprecated_loop::MessageLoop loop;
   DartComponentController app(std::move(package),
                               std::move(startup_info), runner_incoming_services,
                               std::move(controller));
@@ -103,13 +102,7 @@
   Dart_TimelineEvent("DartComponentController::Setup", start, end,
                      Dart_Timeline_Event_Duration, 0, NULL, NULL);
   if (success) {
-    loop.task_runner()->PostTask([&loop, &app] {
-      if (!app.Main())
-        loop.PostQuitTask();
-    });
-
-    loop.Run();
-    app.SendReturnCode();
+    app.Run();
   }
 
   if (Dart_CurrentIsolate()) {
@@ -125,8 +118,7 @@
 }  // namespace
 
 DartRunner::DartRunner()
-    : context_(component::StartupContext::CreateFromStartupInfo()),
-      loop_(deprecated_loop::MessageLoop::GetCurrent()) {
+    : context_(component::StartupContext::CreateFromStartupInfo()) {
   context_->outgoing().AddPublicService<fuchsia::sys::Runner>(
       [this](fidl::InterfaceRequest<fuchsia::sys::Runner> request) {
         bindings_.AddBinding(this, std::move(request));
@@ -189,7 +181,7 @@
     fuchsia::sys::Package package, fuchsia::sys::StartupInfo startup_info,
     ::fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
   TRACE_DURATION("dart", "StartComponent", "url", package.resolved_url);
-  std::thread thread(RunApplication, this, 
+  std::thread thread(RunApplication, this,
                      std::move(package), std::move(startup_info),
                      context_->incoming_services(), std::move(controller));
   thread.detach();
diff --git a/runtime/dart_runner/dart_runner.h b/runtime/dart_runner/dart_runner.h
index e305c49..72e6e2c 100644
--- a/runtime/dart_runner/dart_runner.h
+++ b/runtime/dart_runner/dart_runner.h
@@ -6,11 +6,11 @@
 #define TOPAZ_RUNTIME_DART_RUNNER_DART_RUNNER_H_
 
 #include <fuchsia/sys/cpp/fidl.h>
+
 #include "lib/component/cpp/connect.h"
 #include "lib/component/cpp/startup_context.h"
 #include "lib/fidl/cpp/binding.h"
 #include "lib/fxl/macros.h"
-#include "topaz/lib/deprecated_loop/message_loop.h"
 #include "topaz/runtime/dart_runner/mapped_resource.h"
 
 namespace dart_runner {
@@ -28,7 +28,6 @@
       override;
 
   std::unique_ptr<component::StartupContext> context_;
-  deprecated_loop::MessageLoop* loop_;
   fidl::BindingSet<fuchsia::sys::Runner> bindings_;
 
 #if !defined(AOT_RUNTIME)
diff --git a/runtime/dart_runner/main.cc b/runtime/dart_runner/main.cc
index 71d7203..23c5073 100644
--- a/runtime/dart_runner/main.cc
+++ b/runtime/dart_runner/main.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <lib/async-loop/cpp/loop.h>
 #include <trace-provider/provider.h>
 #include <trace/event.h>
 
-#include "topaz/lib/deprecated_loop/message_loop.h"
 #include "topaz/runtime/dart/utils/tempfs.h"
 #include "topaz/runtime/dart_runner/dart_runner.h"
 
 int main(int argc, const char** argv) {
-  deprecated_loop::MessageLoop loop;
+  async::Loop loop(&kAsyncLoopConfigAttachToThread);
   fbl::unique_ptr<trace::TraceProvider> provider;
   {
     TRACE_DURATION("dart", "CreateTraceProvider");