Merge changes I0783be05,Id8178913 am: 09d5e258ef
am: 2c1b3e9761

Change-Id: I764488803977604f85000cbf12ecf25f2c60c695
diff --git a/adb/adb.cpp b/adb/adb.cpp
index ae8020e..c4df5c4 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -42,7 +42,6 @@
 #include <android-base/logging.h>
 #include <android-base/macros.h>
 #include <android-base/parsenetaddress.h>
-#include <android-base/quick_exit.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 
@@ -1059,7 +1058,7 @@
         SendOkay(reply_fd);
 
         // Rely on process exit to close the socket for us.
-        android::base::quick_exit(0);
+        exit(0);
     }
 
     // "transport:" is used for switching transport with a specified serial number
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index f0d0ce7..f28302b 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -28,7 +28,6 @@
 #include <android-base/errors.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
-#include <android-base/quick_exit.h>
 #include <android-base/stringprintf.h>
 
 #include "adb.h"
@@ -61,7 +60,7 @@
 static BOOL WINAPI ctrlc_handler(DWORD type) {
     // TODO: Consider trying to kill a starting up adb server (if we're in
     // launch_server) by calling GenerateConsoleCtrlEvent().
-    android::base::quick_exit(STATUS_CONTROL_C_EXIT);
+    exit(STATUS_CONTROL_C_EXIT);
     return TRUE;
 }
 #endif
@@ -95,7 +94,7 @@
     SetConsoleCtrlHandler(ctrlc_handler, TRUE);
 #else
     signal(SIGINT, [](int) {
-        fdevent_run_on_main_thread([]() { android::base::quick_exit(0); });
+        fdevent_run_on_main_thread([]() { exit(0); });
     });
 #endif
 
@@ -104,7 +103,7 @@
         setup_daemon_logging();
     }
 
-    android::base::at_quick_exit(adb_server_cleanup);
+    atexit(adb_server_cleanup);
 
     init_transport_registration();
     init_mdns_transport_discovery();
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp
index 18f585d..46c3f58 100644
--- a/adb/client/usb_libusb.cpp
+++ b/adb/client/usb_libusb.cpp
@@ -19,6 +19,7 @@
 #include "sysdeps.h"
 
 #include <stdint.h>
+#include <stdlib.h>
 
 #include <atomic>
 #include <chrono>
@@ -33,7 +34,6 @@
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
-#include <android-base/quick_exit.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 
diff --git a/adb/fdevent.cpp b/adb/fdevent.cpp
index b28de4b..d285561 100644
--- a/adb/fdevent.cpp
+++ b/adb/fdevent.cpp
@@ -26,6 +26,7 @@
 #include <unistd.h>
 
 #include <atomic>
+#include <deque>
 #include <functional>
 #include <list>
 #include <mutex>
@@ -81,7 +82,7 @@
 
 static auto& run_queue_notify_fd = *new unique_fd();
 static auto& run_queue_mutex = *new std::mutex();
-static auto& run_queue GUARDED_BY(run_queue_mutex) = *new std::vector<std::function<void()>>();
+static auto& run_queue GUARDED_BY(run_queue_mutex) = *new std::deque<std::function<void()>>();
 
 void check_main_thread() {
     if (main_thread_valid) {
@@ -359,11 +360,21 @@
 }
 #endif // !ADB_HOST
 
-static void fdevent_run_flush() REQUIRES(run_queue_mutex) {
-    for (auto& f : run_queue) {
-        f();
+static void fdevent_run_flush() EXCLUDES(run_queue_mutex) {
+    // We need to be careful around reentrancy here, since a function we call can queue up another
+    // function.
+    while (true) {
+        std::function<void()> fn;
+        {
+            std::lock_guard<std::mutex> lock(run_queue_mutex);
+            if (run_queue.empty()) {
+                break;
+            }
+            fn = run_queue.front();
+            run_queue.pop_front();
+        }
+        fn();
     }
-    run_queue.clear();
 }
 
 static void fdevent_run_func(int fd, unsigned ev, void* /* userdata */) {
@@ -377,22 +388,23 @@
         PLOG(FATAL) << "failed to empty run queue notify fd";
     }
 
-    std::lock_guard<std::mutex> lock(run_queue_mutex);
     fdevent_run_flush();
 }
 
 static void fdevent_run_setup() {
-    std::lock_guard<std::mutex> lock(run_queue_mutex);
-    CHECK(run_queue_notify_fd.get() == -1);
-    int s[2];
-    if (adb_socketpair(s) != 0) {
-        PLOG(FATAL) << "failed to create run queue notify socketpair";
-    }
+    {
+        std::lock_guard<std::mutex> lock(run_queue_mutex);
+        CHECK(run_queue_notify_fd.get() == -1);
+        int s[2];
+        if (adb_socketpair(s) != 0) {
+            PLOG(FATAL) << "failed to create run queue notify socketpair";
+        }
 
-    run_queue_notify_fd.reset(s[0]);
-    fdevent* fde = fdevent_create(s[1], fdevent_run_func, nullptr);
-    CHECK(fde != nullptr);
-    fdevent_add(fde, FDE_READ);
+        run_queue_notify_fd.reset(s[0]);
+        fdevent* fde = fdevent_create(s[1], fdevent_run_func, nullptr);
+        CHECK(fde != nullptr);
+        fdevent_add(fde, FDE_READ);
+    }
 
     fdevent_run_flush();
 }
diff --git a/adb/fdevent_test.cpp b/adb/fdevent_test.cpp
index 86e0209..63cc4d1 100644
--- a/adb/fdevent_test.cpp
+++ b/adb/fdevent_test.cpp
@@ -194,3 +194,31 @@
         ASSERT_EQ(i, vec[i]);
     }
 }
+
+static std::function<void()> make_appender(std::vector<int>* vec, int value) {
+    return [vec, value]() {
+        check_main_thread();
+        if (value == 100) {
+            return;
+        }
+
+        vec->push_back(value);
+        fdevent_run_on_main_thread(make_appender(vec, value + 1));
+    };
+}
+
+TEST_F(FdeventTest, run_on_main_thread_reentrant) {
+    std::vector<int> vec;
+
+    PrepareThread();
+    std::thread thread(fdevent_loop);
+
+    fdevent_run_on_main_thread(make_appender(&vec, 0));
+
+    TerminateThread(thread);
+
+    ASSERT_EQ(100u, vec.size());
+    for (int i = 0; i < 100; ++i) {
+        ASSERT_EQ(i, vec[i]);
+    }
+}
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 14888ab..6b1a00b 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -34,7 +34,6 @@
 
 #include <android-base/logging.h>
 #include <android-base/parsenetaddress.h>
-#include <android-base/quick_exit.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <android-base/thread_annotations.h>