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

Commit 01b7bc43 authored by Josh Gao's avatar Josh Gao
Browse files

adb: move all cleanup to a function with defined ordering.

We want to explicitly define the order in which we teardown adb, so
move all of the at_quick_exits sprinkled throughout into one function
containing all of the cleanup functions.

Bug: http://b/37104408
Test: adb kill-server; adb start-server
Change-Id: I394f5782eb147e394d4b87df1ba364c061de4b90
parent b3c14ec6
Loading
Loading
Loading
Loading
+26 −7
Original line number Diff line number Diff line
@@ -19,8 +19,12 @@
#include <stdio.h>
#include <stdlib.h>

#include <algorithm>
#include <list>

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

#include "socket_spec.h"
@@ -64,8 +68,9 @@ alistener::~alistener() {

// listener_list retains ownership of all created alistener objects. Removing an alistener from
// this list will cause it to be deleted.
static auto& listener_list_mutex = *new std::mutex();
typedef std::list<std::unique_ptr<alistener>> ListenerList;
static ListenerList& listener_list = *new ListenerList();
static ListenerList& listener_list GUARDED_BY(listener_list_mutex) = *new ListenerList();

static void ss_listener_event_func(int _fd, unsigned ev, void *_l) {
    if (ev & FDE_READ) {
@@ -108,7 +113,8 @@ static void listener_event_func(int _fd, unsigned ev, void* _l)
}

// Called as a transport disconnect function. |arg| is the raw alistener*.
static void listener_disconnect(void* arg, atransport*) {
static void listener_disconnect(void* arg, atransport*) EXCLUDES(listener_list_mutex) {
    std::lock_guard<std::mutex> lock(listener_list_mutex);
    for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
        if (iter->get() == arg) {
            (*iter)->transport = nullptr;
@@ -119,7 +125,8 @@ static void listener_disconnect(void* arg, atransport*) {
}

// Write the list of current listeners (network redirections) into a string.
std::string format_listeners() {
std::string format_listeners() EXCLUDES(listener_list_mutex) {
    std::lock_guard<std::mutex> lock(listener_list_mutex);
    std::string result;
    for (auto& l : listener_list) {
        // Ignore special listeners like those for *smartsocket*
@@ -135,7 +142,9 @@ std::string format_listeners() {
    return result;
}

InstallStatus remove_listener(const char* local_name, atransport* transport) {
InstallStatus remove_listener(const char* local_name, atransport* transport)
    EXCLUDES(listener_list_mutex) {
    std::lock_guard<std::mutex> lock(listener_list_mutex);
    for (auto iter = listener_list.begin(); iter != listener_list.end(); ++iter) {
        if (local_name == (*iter)->local_name) {
            listener_list.erase(iter);
@@ -145,7 +154,8 @@ InstallStatus remove_listener(const char* local_name, atransport* transport) {
    return INSTALL_STATUS_LISTENER_NOT_FOUND;
}

void remove_all_listeners() {
void remove_all_listeners() EXCLUDES(listener_list_mutex) {
    std::lock_guard<std::mutex> lock(listener_list_mutex);
    auto iter = listener_list.begin();
    while (iter != listener_list.end()) {
        // Never remove smart sockets.
@@ -157,9 +167,18 @@ void remove_all_listeners() {
    }
}

void close_smartsockets() EXCLUDES(listener_list_mutex) {
    std::lock_guard<std::mutex> lock(listener_list_mutex);
    auto pred = [](const std::unique_ptr<alistener>& listener) {
        return listener->local_name == "*smartsocket*";
    };
    listener_list.erase(std::remove_if(listener_list.begin(), listener_list.end(), pred));
}

InstallStatus install_listener(const std::string& local_name, const char* connect_to,
                               atransport* transport, int no_rebind, int* resolved_tcp_port,
                               std::string* error) {
                               std::string* error) EXCLUDES(listener_list_mutex) {
    std::lock_guard<std::mutex> lock(listener_list_mutex);
    for (auto& l : listener_list) {
        if (local_name == l->local_name) {
            // Can't repurpose a smartsocket.
+2 −0
Original line number Diff line number Diff line
@@ -41,4 +41,6 @@ std::string format_listeners();
InstallStatus remove_listener(const char* local_name, atransport* transport);
void remove_all_listeners(void);

void close_smartsockets();

#endif /* __ADB_LISTENERS_H */
+13 −2
Original line number Diff line number Diff line
@@ -92,6 +92,16 @@ static BOOL WINAPI ctrlc_handler(DWORD type) {
}
#endif

void adb_server_cleanup() {
    // Upon exit, we want to clean up in the following order:
    //   1. close_smartsockets, so that we don't get any new clients
    //   2. kick_all_transports, to avoid writing only part of a packet to a transport.
    //   3. usb_cleanup, to tear down the USB stack.
    close_smartsockets();
    kick_all_transports();
    usb_cleanup();
}

int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply_fd) {
#if defined(_WIN32)
    // adb start-server starts us up with stdout and stderr hooked up to
@@ -111,12 +121,13 @@ int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply
    SetConsoleCtrlHandler(ctrlc_handler, TRUE);
#else
    signal(SIGINT, [](int) {
        android::base::quick_exit(0);
        fdevent_run_on_main_thread([]() { android::base::quick_exit(0); });
    });
#endif

    init_transport_registration();
    android::base::at_quick_exit(adb_server_cleanup);

    init_transport_registration();
    init_mdns_transport_discovery();

    usb_init();
+6 −0
Original line number Diff line number Diff line
@@ -27,6 +27,12 @@ void usb_init() {
    }
}

void usb_cleanup() {
    if (should_use_libusb()) {
        libusb::usb_cleanup();
    }
}

int usb_write(usb_handle* h, const void* data, int len) {
    return should_use_libusb()
               ? libusb::usb_write(reinterpret_cast<libusb::usb_handle*>(h), data, len)
+13 −7
Original line number Diff line number Diff line
@@ -415,15 +415,21 @@ void usb_init() {

    // Spawn a thread to do device enumeration.
    // TODO: Use libusb_hotplug_* instead?
    std::unique_lock<std::mutex> lock(device_poll_mutex);
    device_poll_thread = new std::thread(poll_for_devices);
    android::base::at_quick_exit([]() {
}

void usb_cleanup() {
    {
        std::unique_lock<std::mutex> lock(device_poll_mutex);
        terminate_device_poll_thread = true;

        if (!device_poll_thread) {
            return;
        }
    }
    device_poll_cv.notify_all();
    device_poll_thread->join();
    });
}

// Dispatch a libusb transfer, unlock |device_lock|, and then wait for the result.
Loading