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

Commit d9db09c3 authored by Josh Gao's avatar Josh Gao
Browse files

adb: make adb_thread_func_t return void, add adb_thread_exit.

Windows restricts the return value of threads to 32-bits, even on 64-bit
platforms. Since we don't actually return meaningful values from thread,
resolve this inconsistency with POSIX by making adb's thread abstraction
only take void functions.

Change-Id: I5c23b4432314f13bf16d606fd5e6b6b7b6ef98b5
(cherry picked from commit b5fea14e)
parent 7e76c895
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -482,7 +482,7 @@ struct StdinReadArgs {
// Loops to read from stdin and push the data to the given FD.
// The argument should be a pointer to a StdinReadArgs object. This function
// will take ownership of the object and delete it when finished.
static void* stdin_read_thread_loop(void* x) {
static void stdin_read_thread_loop(void* x) {
    std::unique_ptr<StdinReadArgs> args(reinterpret_cast<StdinReadArgs*>(x));

#if !defined(_WIN32)
@@ -586,8 +586,6 @@ static void* stdin_read_thread_loop(void* x) {
            }
        }
    }

    return nullptr;
}

// Returns a shell service string with the indicated arguments and command.
+1 −3
Original line number Diff line number Diff line
@@ -57,13 +57,11 @@ struct stinfo {
    void *cookie;
};

void *service_bootstrap_func(void *x)
{
static void service_bootstrap_func(void* x) {
    stinfo* sti = reinterpret_cast<stinfo*>(x);
    adb_thread_setname(android::base::StringPrintf("service %d", sti->fd));
    sti->func(sti->fd, sti->cookie);
    free(sti);
    return 0;
}

#if !ADB_HOST
+2 −4
Original line number Diff line number Diff line
@@ -198,7 +198,7 @@ class Subprocess {
    // Opens the file at |pts_name|.
    int OpenPtyChildFd(const char* pts_name, ScopedFd* error_sfd);

    static void* ThreadHandler(void* userdata);
    static void ThreadHandler(void* userdata);
    void PassDataStreams();
    void WaitForExit();

@@ -465,7 +465,7 @@ int Subprocess::OpenPtyChildFd(const char* pts_name, ScopedFd* error_sfd) {
    return child_fd;
}

void* Subprocess::ThreadHandler(void* userdata) {
void Subprocess::ThreadHandler(void* userdata) {
    Subprocess* subprocess = reinterpret_cast<Subprocess*>(userdata);

    adb_thread_setname(android::base::StringPrintf(
@@ -475,8 +475,6 @@ void* Subprocess::ThreadHandler(void* userdata) {

    D("deleting Subprocess for PID %d", subprocess->pid());
    delete subprocess;

    return nullptr;
}

void Subprocess::PassDataStreams() {
+36 −12
Original line number Diff line number Diff line
@@ -115,25 +115,26 @@ static __inline__ void adb_mutex_unlock( adb_mutex_t* lock )
    LeaveCriticalSection( lock );
}

typedef void* (*adb_thread_func_t)(void* arg);
typedef void (*adb_thread_func_t)(void* arg);
typedef HANDLE adb_thread_t;

struct win_thread_args {
struct adb_winthread_args {
    adb_thread_func_t func;
    void* arg;
};

static unsigned __stdcall win_thread_wrapper(void* args) {
    win_thread_args thread_args = *static_cast<win_thread_args*>(args);
    delete static_cast<win_thread_args*>(args);
    void* result = thread_args.func(thread_args.arg);
    return reinterpret_cast<unsigned>(result);
static unsigned __stdcall adb_winthread_wrapper(void* heap_args) {
    // Move the arguments from the heap onto the thread's stack.
    adb_winthread_args thread_args = *static_cast<adb_winthread_args*>(heap_args);
    delete static_cast<adb_winthread_args*>(heap_args);
    thread_args.func(thread_args.arg);
    return 0;
}

static __inline__ bool adb_thread_create(adb_thread_func_t func, void* arg,
                                         adb_thread_t* thread = nullptr) {
    win_thread_args* args = new win_thread_args{.func = func, .arg = arg};
    uintptr_t handle = _beginthreadex(nullptr, 0, win_thread_wrapper, args, 0, nullptr);
    adb_winthread_args* args = new adb_winthread_args{.func = func, .arg = arg};
    uintptr_t handle = _beginthreadex(nullptr, 0, adb_winthread_wrapper, args, 0, nullptr);
    if (handle != static_cast<uintptr_t>(0)) {
        if (thread) {
            *thread = reinterpret_cast<HANDLE>(handle);
@@ -168,6 +169,10 @@ static __inline__ bool adb_thread_detach(adb_thread_t thread) {
    return true;
}

static __inline__ void __attribute__((noreturn)) adb_thread_exit() {
    ExitThread(0);
}

static __inline__ int adb_thread_setname(const std::string& name) {
    // TODO: See https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx for how to set
    // the thread name in Windows. Unfortunately, it only works during debugging, but
@@ -701,17 +706,32 @@ static __inline__ int adb_socket_accept(int serverfd, struct sockaddr* addr,
#define  unix_write  adb_write
#define  unix_close  adb_close

typedef void*  (*adb_thread_func_t)( void*  arg );

// Win32 is limited to DWORDs for thread return values; limit the POSIX systems to this as well to
// ensure compatibility.
typedef void (*adb_thread_func_t)(void* arg);
typedef pthread_t adb_thread_t;

struct adb_pthread_args {
    adb_thread_func_t func;
    void* arg;
};

static void* adb_pthread_wrapper(void* heap_args) {
    // Move the arguments from the heap onto the thread's stack.
    adb_pthread_args thread_args = *reinterpret_cast<adb_pthread_args*>(heap_args);
    delete static_cast<adb_pthread_args*>(heap_args);
    thread_args.func(thread_args.arg);
    return nullptr;
}

static __inline__ bool adb_thread_create(adb_thread_func_t start, void* arg,
                                         adb_thread_t* thread = nullptr) {
    pthread_t temp;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, thread ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED);
    errno = pthread_create(&temp, &attr, start, arg);
    auto* pthread_args = new adb_pthread_args{.func = start, .arg = arg};
    errno = pthread_create(&temp, &attr, adb_pthread_wrapper, pthread_args);
    if (errno == 0) {
        if (thread) {
            *thread = temp;
@@ -731,6 +751,10 @@ static __inline__ bool adb_thread_detach(adb_thread_t thread) {
    return errno == 0;
}

static __inline__ void __attribute__((noreturn)) adb_thread_exit() {
    pthread_exit(nullptr);
}

static __inline__ int adb_thread_setname(const std::string& name) {
#ifdef __APPLE__
    return pthread_setname_np(name.c_str());
+12 −2
Original line number Diff line number Diff line
@@ -20,10 +20,9 @@

#include "sysdeps.h"

static void* increment_atomic_int(void* c) {
static void increment_atomic_int(void* c) {
    sleep(1);
    reinterpret_cast<std::atomic<int>*>(c)->fetch_add(1);
    return nullptr;
}

TEST(sysdeps_thread, smoke) {
@@ -57,3 +56,14 @@ TEST(sysdeps_thread, join) {

    ASSERT_EQ(500, counter.load());
}

TEST(sysdeps_thread, exit) {
    adb_thread_t thread;
    ASSERT_TRUE(adb_thread_create(
        [](void*) {
            adb_thread_exit();
            for (;;) continue;
        },
        nullptr, &thread));
    ASSERT_TRUE(adb_thread_join(thread));
}
Loading