[vm/fuchsia]: Safely shutdown the async message loop.

Shut down the message loop before destroying it, and also clear the
default dispatcher.

Bug: https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=59293
Change-Id: I77ba07f4139309e70f812cd4f921e6af4bdc4957
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/161462
Reviewed-by: Zach Anderson <zra@google.com>
Commit-Queue: Liam Appelbe <liama@google.com>
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 6ad304e..0a9ffa1 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -353,7 +353,7 @@
 }
 
 void OS::Init() {
-  if (async_get_default_dispatcher() == NULL) {
+  if (async_get_default_dispatcher() == nullptr) {
     async_loop_create(&kAsyncLoopConfigAttachToCurrentThread, &message_loop);
     async_set_default_dispatcher(async_loop_get_dispatcher(message_loop));
     async_loop_start_thread(message_loop, "Fuchsia async loop", nullptr);
@@ -368,9 +368,19 @@
 }
 
 void OS::Cleanup() {
+  if (message_loop != nullptr) {
+    async_loop_shutdown(message_loop);
+  }
+
   metrics = nullptr;
   component_inspector = nullptr;
+
   if (message_loop != nullptr) {
+    // Check message_loop is still the default dispatcher before clearing it.
+    if (async_get_default_dispatcher() ==
+        async_loop_get_dispatcher(message_loop)) {
+      async_set_default_dispatcher(nullptr);
+    }
     async_loop_destroy(message_loop);
     message_loop = nullptr;
   }