Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9083ff1c authored by Josh Gao's avatar Josh Gao Committed by Gerrit Code Review
Browse files

Merge changes from topic 'adb_thread_safety'

* changes:
  adb: wait for devices to come up instead of sleeping for 3s.
  adb: initialize mDNS asynchronously.
  adb: add fdevent_run_on_main_thread.
parents c5dbd713 fd713e53
Loading
Loading
Loading
Loading
+51 −4
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@
#include <time.h>

#include <chrono>
#include <condition_variable>
#include <mutex>
#include <string>
#include <thread>
#include <vector>
@@ -48,6 +50,7 @@
#include "adb_io.h"
#include "adb_listeners.h"
#include "adb_utils.h"
#include "sysdeps/chrono.h"
#include "transport.h"

#if !ADB_HOST
@@ -313,19 +316,15 @@ void parse_banner(const std::string& banner, atransport* t) {
    if (type == "bootloader") {
        D("setting connection_state to kCsBootloader");
        t->SetConnectionState(kCsBootloader);
        update_transports();
    } else if (type == "device") {
        D("setting connection_state to kCsDevice");
        t->SetConnectionState(kCsDevice);
        update_transports();
    } else if (type == "recovery") {
        D("setting connection_state to kCsRecovery");
        t->SetConnectionState(kCsRecovery);
        update_transports();
    } else if (type == "sideload") {
        D("setting connection_state to kCsSideload");
        t->SetConnectionState(kCsSideload);
        update_transports();
    } else {
        D("setting connection_state to kCsHost");
        t->SetConnectionState(kCsHost);
@@ -353,6 +352,8 @@ static void handle_new_connection(atransport* t, apacket* p) {
        send_auth_request(t);
    }
#endif

    update_transports();
}

void handle_packet(apacket *p, atransport *t)
@@ -1229,4 +1230,50 @@ int handle_host_request(const char* service, TransportType type,
      return ret - 1;
    return -1;
}

static auto& init_mutex = *new std::mutex();
static auto& init_cv = *new std::condition_variable();
static bool device_scan_complete = false;
static bool transports_ready = false;

void update_transport_status() {
    bool result = iterate_transports([](const atransport* t) {
        if (t->type == kTransportUsb && t->online != 1) {
            return false;
        }
        return true;
    });

    D("update_transport_status: transports_ready = %s", result ? "true" : "false");

    bool ready;

    {
        std::lock_guard<std::mutex> lock(init_mutex);
        transports_ready = result;
        ready = transports_ready && device_scan_complete;
    }

    if (ready) {
        D("update_transport_status: notifying");
        init_cv.notify_all();
    }
}

void adb_notify_device_scan_complete() {
    D("device scan complete");

    {
        std::lock_guard<std::mutex> lock(init_mutex);
        device_scan_complete = true;
    }

    update_transport_status();
}

void adb_wait_for_device_initialization() {
    std::unique_lock<std::mutex> lock(init_mutex);
    init_cv.wait_for(lock, 3s, []() { return device_scan_complete && transports_ready; });
}

#endif  // ADB_HOST
+14 −0
Original line number Diff line number Diff line
@@ -228,4 +228,18 @@ void SendConnectOnHost(atransport* t);

void parse_banner(const std::string&, atransport* t);

// On startup, the adb server needs to wait until all of the connected devices are ready.
// To do this, we need to know when the scan has identified all of the potential new transports, and
// when each transport becomes ready.
// TODO: Do this for mDNS as well, instead of just USB?

// We've found all of the transports we potentially care about.
void adb_notify_device_scan_complete();

// One or more transports have changed status, check to see if we're ready.
void update_transport_status();

// Wait until device scan has completed and every transport is ready, or a timeout elapses.
void adb_wait_for_device_initialization();

#endif
+5 −3
Original line number Diff line number Diff line
@@ -28,12 +28,15 @@
#include <sys/stat.h>
#include <sys/types.h>

#include <condition_variable>
#include <mutex>
#include <string>
#include <thread>
#include <vector>

#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/thread_annotations.h>
#include <cutils/sockets.h>

#include "adb_io.h"
@@ -177,9 +180,8 @@ int adb_connect(const std::string& service, std::string* error) {
        } else {
            fprintf(stderr, "* daemon started successfully\n");
        }
        // Give the server some time to start properly and detect devices.
        std::this_thread::sleep_for(3s);
        // fall through to _adb_connect
        // The server will wait until it detects all of its connected devices before acking.
        // Fall through to _adb_connect.
    } else {
        // If a server is already running, check its version matches.
        int version = ADB_SERVER_VERSION - 1;
+29 −24
Original line number Diff line number Diff line
@@ -156,7 +156,10 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply
        }
#endif

        // Inform our parent that we are up and running.
        // Wait for the USB scan to complete before notifying the parent that we're up.
        // We need to perform this in a thread, because we would otherwise block the event loop.
        std::thread notify_thread([ack_reply_fd]() {
            adb_wait_for_device_initialization();

            // Any error output written to stderr now goes to adb.log. We could
            // keep around a copy of the stderr fd and use that to write any errors
@@ -171,8 +174,8 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply
                      android::base::SystemErrorCodeToString(GetLastError()).c_str());
            }
            if (written != bytes_to_write) {
            fatal("adb: cannot write %lu bytes of ACK: only wrote %lu bytes",
                  bytes_to_write, written);
                fatal("adb: cannot write %lu bytes of ACK: only wrote %lu bytes", bytes_to_write,
                      written);
            }
            CloseHandle(ack_reply_handle);
#else
@@ -183,6 +186,8 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply
            }
            unix_close(ack_reply_fd);
#endif
        });
        notify_thread.detach();
    }

    D("Event loop starting");
+2 −0
Original line number Diff line number Diff line
@@ -352,6 +352,8 @@ static void poll_for_devices() {
        }
        libusb_free_device_list(list, 1);

        adb_notify_device_scan_complete();

        std::this_thread::sleep_for(500ms);
    }
}
Loading