diff options
author | Josh Gao <jmgao@google.com> | 2016-02-12 14:31:15 -0800 |
---|---|---|
committer | Josh Gao <jmgao@google.com> | 2016-02-12 15:23:54 -0800 |
commit | b5fea14e13bb6e41b36f374c954dc55faeef4627 (patch) | |
tree | 45ca9af113dedf1859237847583acb352aa7838e /adb/sysdeps.h | |
parent | dda68c0fcfe4ced4ae410821c7681f02a2b9aff2 (diff) | |
download | system_core-b5fea14e13bb6e41b36f374c954dc55faeef4627.tar.gz system_core-b5fea14e13bb6e41b36f374c954dc55faeef4627.tar.bz2 system_core-b5fea14e13bb6e41b36f374c954dc55faeef4627.zip |
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
Diffstat (limited to 'adb/sysdeps.h')
-rw-r--r-- | adb/sysdeps.h | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/adb/sysdeps.h b/adb/sysdeps.h index 761a4c799..f9f6f6905 100644 --- a/adb/sysdeps.h +++ b/adb/sysdeps.h @@ -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()); |