adb: set thread names (linux & mac)

Bug: 23423333
Change-Id: I0069f32ddbae2a10fb130064f721facf45b2cc09
diff --git a/adb/adb.cpp b/adb/adb.cpp
index fa935f6..eb01da8 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -670,10 +670,12 @@
 }
 
 static unsigned __stdcall _redirect_stdout_thread(HANDLE h) {
+    adb_thread_setname("stdout redirect");
     return _redirect_pipe_thread(h, STD_OUTPUT_HANDLE);
 }
 
 static unsigned __stdcall _redirect_stderr_thread(HANDLE h) {
+    adb_thread_setname("stderr redirect");
     return _redirect_pipe_thread(h, STD_ERROR_HANDLE);
 }
 
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index b92757f..6325e64 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -374,6 +374,8 @@
     fdi = fds[1];
     free(fds);
 
+    adb_thread_setname("stdin reader");
+
     while (true) {
         /* fdi is really the client's stdin, so use read, not adb_read here */
         D("stdin_read_thread(): pre unix_read(fdi=%d,...)\n", fdi);
diff --git a/adb/services.cpp b/adb/services.cpp
index c8c2d54..4606804 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -67,6 +67,7 @@
 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;
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index a58a762..5918a94 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -111,6 +111,13 @@
     return (tid != static_cast<uintptr_t>(-1L));
 }
 
+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
+    // our build process doesn't generate PDB files needed for debugging.
+    return 0;
+}
+
 static __inline__  unsigned long adb_thread_id()
 {
     return GetCurrentThreadId();
@@ -617,7 +624,26 @@
     return (errno == 0);
 }
 
-static __inline__  int  adb_socket_setbufsize( int   fd, int  bufsize )
+static __inline__ int adb_thread_setname(const std::string& name) {
+#ifdef __APPLE__
+    return pthread_setname_np(name.c_str());
+#else
+    const char *s = name.c_str();
+
+    // pthread_setname_np fails rather than truncating long strings.
+    const int max_task_comm_len = 16; // including the null terminator
+    if (name.length() > (max_task_comm_len - 1)) {
+        char buf[max_task_comm_len];
+        strncpy(buf, name.c_str(), sizeof(buf) - 1);
+        buf[sizeof(buf) - 1] = '\0';
+        s = buf;
+    }
+
+    return pthread_setname_np(pthread_self(), s) ;
+#endif
+}
+
+static __inline__  int  adb_socket_setbufsize(int fd, int  bufsize )
 {
     int opt = bufsize;
     return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 6ce5d7f..bd3bf16 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -193,6 +193,7 @@
     atransport *t = reinterpret_cast<atransport*>(_t);
     apacket *p;
 
+    adb_thread_setname("to transport");
     D("%s: starting transport output thread on fd %d, SYNC online (%d)\n",
        t->serial, t->fd, t->sync_token + 1);
     p = get_apacket();
@@ -249,6 +250,7 @@
     apacket *p;
     int active = 0;
 
+    adb_thread_setname("from transport");
     D("%s: starting transport input thread, reading from fd %d\n",
        t->serial, t->fd);
 
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 6a17497..6821cfc 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -123,6 +123,7 @@
 #if ADB_HOST
 static void *client_socket_thread(void *x)
 {
+    adb_thread_setname("client_socket_thread");
     D("transport: client_socket_thread() starting\n");
     while (true) {
         int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
@@ -146,6 +147,7 @@
     socklen_t alen;
     int port = (int) (uintptr_t) arg;
 
+    adb_thread_setname("server socket");
     D("transport: server_socket_thread() starting\n");
     serverfd = -1;
     for(;;) {
@@ -231,6 +233,7 @@
     char tmp[256];
     char con_name[32];
 
+    adb_thread_setname("qemu socket");
     D("transport: qemu_socket_thread() starting\n");
 
     /* adb QEMUD service connection request. */
diff --git a/adb/usb_linux.cpp b/adb/usb_linux.cpp
index dd22712..6ccc8e2 100644
--- a/adb/usb_linux.cpp
+++ b/adb/usb_linux.cpp
@@ -572,6 +572,7 @@
 }
 
 static void* device_poll_thread(void* unused) {
+    adb_thread_setname("device poll");
     D("Created device thread\n");
     while (true) {
         // TODO: Use inotify.
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index dc44f16..e1d7594 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -209,6 +209,8 @@
     struct usb_handle *usb = (struct usb_handle *)x;
     int fd;
 
+    adb_thread_setname("usb open");
+
     while (true) {
         // wait until the USB device needs opening
         adb_mutex_lock(&usb->lock);
@@ -403,6 +405,8 @@
 {
     struct usb_handle *usb = (struct usb_handle *)x;
 
+    adb_thread_setname("usb ffs open");
+
     while (true) {
         // wait until the USB device needs opening
         adb_mutex_lock(&usb->lock);
diff --git a/adb/usb_osx.cpp b/adb/usb_osx.cpp
index 0ce85f3..d9e2fb2 100644
--- a/adb/usb_osx.cpp
+++ b/adb/usb_osx.cpp
@@ -403,6 +403,7 @@
 
 void* RunLoopThread(void* unused)
 {
+    adb_thread_setname("RunLoop");
     InitUSB();
 
     currentRunLoop = CFRunLoopGetCurrent();
diff --git a/adb/usb_windows.cpp b/adb/usb_windows.cpp
index b8cc5cf..ab36475 100644
--- a/adb/usb_windows.cpp
+++ b/adb/usb_windows.cpp
@@ -171,6 +171,7 @@
 }
 
 void* device_poll_thread(void* unused) {
+  adb_thread_setname("Device Poll");
   D("Created device thread\n");
 
   while(1) {
@@ -208,6 +209,7 @@
   // of a developer's interactive session, a window message pump is more
   // appropriate.
   D("Created power notification thread\n");
+  adb_thread_setname("Power Notifier");
 
   // Window class names are process specific.
   static const WCHAR kPowerNotificationWindowClassName[] =