diff options
-rw-r--r-- | adb/commandline.cpp | 4 | ||||
-rw-r--r-- | adb/services.cpp | 4 | ||||
-rw-r--r-- | adb/shell_service.cpp | 6 | ||||
-rw-r--r-- | adb/sysdeps.h | 48 | ||||
-rw-r--r-- | adb/sysdeps_test.cpp | 14 | ||||
-rw-r--r-- | adb/transport.cpp | 8 | ||||
-rw-r--r-- | adb/transport_local.cpp | 33 | ||||
-rw-r--r-- | adb/usb_linux.cpp | 3 | ||||
-rw-r--r-- | adb/usb_linux_client.cpp | 12 | ||||
-rw-r--r-- | adb/usb_osx.cpp | 5 | ||||
-rw-r--r-- | adb/usb_windows.cpp | 10 |
11 files changed, 77 insertions, 70 deletions
diff --git a/adb/commandline.cpp b/adb/commandline.cpp index 85ab4d18a..8e76168cb 100644 --- a/adb/commandline.cpp +++ b/adb/commandline.cpp @@ -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. diff --git a/adb/services.cpp b/adb/services.cpp index 9cbf78794..75cbe5dd1 100644 --- a/adb/services.cpp +++ b/adb/services.cpp @@ -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 diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp index d080e09bf..f84447f5f 100644 --- a/adb/shell_service.cpp +++ b/adb/shell_service.cpp @@ -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() { 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()); diff --git a/adb/sysdeps_test.cpp b/adb/sysdeps_test.cpp index 24a0d6f06..e6037d7a1 100644 --- a/adb/sysdeps_test.cpp +++ b/adb/sysdeps_test.cpp @@ -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)); +} diff --git a/adb/transport.cpp b/adb/transport.cpp index 6020ad5b1..d9180bc45 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -190,8 +190,7 @@ void send_packet(apacket *p, atransport *t) // // read_transport thread reads data from a transport (representing a usb/tcp connection), // and makes the main thread call handle_packet(). -static void *read_transport_thread(void *_t) -{ +static void read_transport_thread(void* _t) { atransport *t = reinterpret_cast<atransport*>(_t); apacket *p; @@ -244,13 +243,11 @@ oops: D("%s: read_transport thread is exiting", t->serial); kick_transport(t); transport_unref(t); - return 0; } // write_transport thread gets packets sent by the main thread (through send_packet()), // and writes to a transport (representing a usb/tcp connection). -static void *write_transport_thread(void *_t) -{ +static void write_transport_thread(void* _t) { atransport *t = reinterpret_cast<atransport*>(_t); apacket *p; int active = 0; @@ -295,7 +292,6 @@ static void *write_transport_thread(void *_t) D("%s: write_transport thread is exiting, fd %d", t->serial, t->fd); kick_transport(t); transport_unref(t); - return 0; } static void kick_transport_locked(atransport* t) { diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp index d2a375a24..e6e699b6d 100644 --- a/adb/transport_local.cpp +++ b/adb/transport_local.cpp @@ -121,8 +121,7 @@ int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* e } #if ADB_HOST -static void *client_socket_thread(void *x) -{ +static void client_socket_thread(void* x) { adb_thread_setname("client_socket_thread"); D("transport: client_socket_thread() starting"); while (true) { @@ -135,13 +134,11 @@ static void *client_socket_thread(void *x) } sleep(1); } - return 0; } #else // ADB_HOST -static void *server_socket_thread(void * arg) -{ +static void server_socket_thread(void* arg) { int serverfd, fd; sockaddr_storage ss; sockaddr *addrp = reinterpret_cast<sockaddr*>(&ss); @@ -174,7 +171,6 @@ static void *server_socket_thread(void * arg) } } D("transport: server_socket_thread() exiting"); - return 0; } /* This is relevant only for ADB daemon running inside the emulator. */ @@ -220,14 +216,13 @@ static void *server_socket_thread(void * arg) * the transport registration is completed. That's why we need to send the * 'start' request after the transport is registered. */ -static void *qemu_socket_thread(void * arg) -{ -/* 'accept' request to the adb QEMUD service. */ -static const char _accept_req[] = "accept"; -/* 'start' request to the adb QEMUD service. */ -static const char _start_req[] = "start"; -/* 'ok' reply from the adb QEMUD service. */ -static const char _ok_resp[] = "ok"; +static void qemu_socket_thread(void* arg) { + /* 'accept' request to the adb QEMUD service. */ + static const char _accept_req[] = "accept"; + /* 'start' request to the adb QEMUD service. */ + static const char _start_req[] = "start"; + /* 'ok' reply from the adb QEMUD service. */ + static const char _ok_resp[] = "ok"; const int port = (int) (uintptr_t) arg; int res, fd; @@ -247,7 +242,7 @@ static const char _ok_resp[] = "ok"; * implement adb QEMUD service. Fall back to the old TCP way. */ D("adb service is not available. Falling back to TCP socket."); adb_thread_create(server_socket_thread, arg); - return 0; + return; } for(;;) { @@ -275,21 +270,21 @@ static const char _ok_resp[] = "ok"; fd = qemu_pipe_open(con_name); if (fd < 0) { D("adb service become unavailable."); - return 0; + return; } } else { D("Unable to send the '%s' request to ADB service.", _accept_req); - return 0; + return; } } D("transport: qemu_socket_thread() exiting"); - return 0; + return; } #endif // !ADB_HOST void local_init(int port) { - void* (*func)(void *); + adb_thread_func_t func; const char* debug_name = ""; #if ADB_HOST diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp index ed5d2d67e..500898a70 100644 --- a/adb/usb_linux.cpp +++ b/adb/usb_linux.cpp @@ -571,7 +571,7 @@ static void register_device(const char* dev_name, const char* dev_path, register_usb_transport(done_usb, serial.c_str(), dev_path, done_usb->writeable); } -static void* device_poll_thread(void* unused) { +static void device_poll_thread(void*) { adb_thread_setname("device poll"); D("Created device thread"); while (true) { @@ -580,7 +580,6 @@ static void* device_poll_thread(void* unused) { kick_disconnected_devices(); sleep(1); } - return nullptr; } void usb_init() { diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp index a4f1a7054..c863ed205 100644 --- a/adb/usb_linux_client.cpp +++ b/adb/usb_linux_client.cpp @@ -232,10 +232,7 @@ static const struct { }, }; - - -static void *usb_adb_open_thread(void *x) -{ +static void usb_adb_open_thread(void* x) { struct usb_handle *usb = (struct usb_handle *)x; int fd; @@ -270,7 +267,7 @@ static void *usb_adb_open_thread(void *x) } // never gets here - return 0; + abort(); } static int usb_adb_write(usb_handle *h, const void *data, int len) @@ -434,8 +431,7 @@ err: return; } -static void *usb_ffs_open_thread(void *x) -{ +static void usb_ffs_open_thread(void* x) { struct usb_handle *usb = (struct usb_handle *)x; adb_thread_setname("usb ffs open"); @@ -462,7 +458,7 @@ static void *usb_ffs_open_thread(void *x) } // never gets here - return 0; + abort(); } static int usb_ffs_write(usb_handle* h, const void* data, int len) { diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp index 148be1d78..54d4c6c12 100644 --- a/adb/usb_osx.cpp +++ b/adb/usb_osx.cpp @@ -400,9 +400,7 @@ err_get_num_ep: return NULL; } - -void* RunLoopThread(void* unused) -{ +static void RunLoopThread(void* unused) { adb_thread_setname("RunLoop"); InitUSB(); @@ -420,7 +418,6 @@ void* RunLoopThread(void* unused) IONotificationPortDestroy(notificationPort); LOG(DEBUG) << "RunLoopThread done"; - return NULL; } static void usb_cleanup() { diff --git a/adb/usb_windows.cpp b/adb/usb_windows.cpp index e79008f48..8ecca3724 100644 --- a/adb/usb_windows.cpp +++ b/adb/usb_windows.cpp @@ -97,7 +97,7 @@ static void kick_devices(); /// Entry point for thread that polls (every second) for new usb interfaces. /// This routine calls find_devices in infinite loop. -void* device_poll_thread(void* unused); +static void device_poll_thread(void*); /// Initializes this module void usb_init(); @@ -172,7 +172,7 @@ int register_new_device(usb_handle* handle) { return 1; } -void* device_poll_thread(void* unused) { +void device_poll_thread(void*) { adb_thread_setname("Device Poll"); D("Created device thread"); @@ -180,8 +180,6 @@ void* device_poll_thread(void* unused) { find_devices(); adb_sleep_ms(1000); } - - return NULL; } static LRESULT CALLBACK _power_window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, @@ -203,7 +201,7 @@ static LRESULT CALLBACK _power_window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, return DefWindowProcW(hwnd, uMsg, wParam, lParam); } -static void* _power_notification_thread(void* unused) { +static void _power_notification_thread(void*) { // This uses a thread with its own window message pump to get power // notifications. If adb runs from a non-interactive service account, this // might not work (not sure). If that happens to not work, we could use @@ -255,8 +253,6 @@ static void* _power_notification_thread(void* unused) { // shutting down. Not a big deal since the whole process will be going away // soon anyway. D("Power notification thread exiting"); - - return NULL; } void usb_init() { |