Wait sooner for non-daemon threads

When the main thread returns, we attempt to shut down the runtime.
Sometime during that process we always waited for non-daemon threads
to complete as required. But previously we only did so after
the runtime was partially shut down, potentially causing the
remaining threads to deadlock.

This explicitly waits before we start destroying the runtime.

Add test to make sure that a long running child thread finishes
properly.

Bug: 148126377
Bug: 147619421
Test: New test fails without waiting call, passes with.
Change-Id: Ic60d695c8a03543b51d8532156f19fff00a58edc
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index ed28e74..330f1c1 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -1110,18 +1110,27 @@
   return nullptr;
 }
 
-void ThreadList::WaitForOtherNonDaemonThreadsToExit() {
+void ThreadList::WaitForOtherNonDaemonThreadsToExit(bool check_no_birth) {
   ScopedTrace trace(__PRETTY_FUNCTION__);
   Thread* self = Thread::Current();
   Locks::mutator_lock_->AssertNotHeld(self);
   while (true) {
-    {
+    Locks::runtime_shutdown_lock_->Lock(self);
+    if (check_no_birth) {
       // No more threads can be born after we start to shutdown.
-      MutexLock mu(self, *Locks::runtime_shutdown_lock_);
       CHECK(Runtime::Current()->IsShuttingDownLocked());
       CHECK_EQ(Runtime::Current()->NumberOfThreadsBeingBorn(), 0U);
+    } else {
+      if (Runtime::Current()->NumberOfThreadsBeingBorn() != 0U) {
+        // Awkward. Shutdown_cond_ is private, but the only live thread may not be registered yet.
+        // Fortunately, this is used mostly for testing, and not performance-critical.
+        Locks::runtime_shutdown_lock_->Unlock(self);
+        usleep(1000);
+        continue;
+      }
     }
     MutexLock mu(self, *Locks::thread_list_lock_);
+    Locks::runtime_shutdown_lock_->Unlock(self);
     // Also wait for any threads that are unregistering to finish. This is required so that no
     // threads access the thread list after it is deleted. TODO: This may not work for user daemon
     // threads since they could unregister at the wrong time.