Merge changes I9757ab85,Idac80a24

* changes:
  adb: change unsigned to uint32_t in sync struct definitions.
  adb: detect when the client disconnects in wait-for-device.
diff --git a/adb/file_sync_service.h b/adb/file_sync_service.h
index 38382c1..460e9dc 100644
--- a/adb/file_sync_service.h
+++ b/adb/file_sync_service.h
@@ -41,25 +41,25 @@
 
 union syncmsg {
     struct __attribute__((packed)) {
-        unsigned id;
-        unsigned mode;
-        unsigned size;
-        unsigned time;
+        uint32_t id;
+        uint32_t mode;
+        uint32_t size;
+        uint32_t time;
     } stat;
     struct __attribute__((packed)) {
-        unsigned id;
-        unsigned mode;
-        unsigned size;
-        unsigned time;
-        unsigned namelen;
+        uint32_t id;
+        uint32_t mode;
+        uint32_t size;
+        uint32_t time;
+        uint32_t namelen;
     } dent;
     struct __attribute__((packed)) {
-        unsigned id;
-        unsigned size;
+        uint32_t id;
+        uint32_t size;
     } data;
     struct __attribute__((packed)) {
-        unsigned id;
-        unsigned msglen;
+        uint32_t id;
+        uint32_t msglen;
     } status;
 };
 
diff --git a/adb/services.cpp b/adb/services.cpp
index 75cbe5d..2eef1c2 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -49,6 +49,7 @@
 #include "remount_service.h"
 #include "services.h"
 #include "shell_service.h"
+#include "sysdeps.h"
 #include "transport.h"
 
 struct stinfo {
@@ -369,12 +370,21 @@
         std::string error = "unknown error";
         const char* serial = sinfo->serial.length() ? sinfo->serial.c_str() : NULL;
         atransport* t = acquire_one_transport(sinfo->transport_type, serial, &is_ambiguous, &error);
-
         if (t != nullptr && t->connection_state == sinfo->state) {
             SendOkay(fd);
             break;
         } else if (!is_ambiguous) {
-            adb_sleep_ms(1000);
+            adb_pollfd pfd = {.fd = fd, .events = POLLIN };
+            int rc = adb_poll(&pfd, 1, 1000);
+            if (rc < 0) {
+                SendFail(fd, error);
+                break;
+            } else if (rc > 0 && (pfd.revents & POLLHUP) != 0) {
+                // The other end of the socket is closed, probably because the other side was
+                // terminated, bail out.
+                break;
+            }
+
             // Try again...
         } else {
             SendFail(fd, error);
diff --git a/adb/sysdeps_test.cpp b/adb/sysdeps_test.cpp
index 253d62f..3904cc0 100644
--- a/adb/sysdeps_test.cpp
+++ b/adb/sysdeps_test.cpp
@@ -112,8 +112,12 @@
     }
 
     void TearDown() override {
-        ASSERT_EQ(0, adb_close(fds[0]));
-        ASSERT_EQ(0, adb_close(fds[1]));
+        if (fds[0] >= 0) {
+            ASSERT_EQ(0, adb_close(fds[0]));
+        }
+        if (fds[1] >= 0) {
+            ASSERT_EQ(0, adb_close(fds[1]));
+        }
     }
 };
 
@@ -190,3 +194,20 @@
     EXPECT_EQ(POLLRDNORM, pfd[0].revents);
     EXPECT_EQ(POLLRDNORM, pfd[1].revents);
 }
+
+TEST_F(sysdeps_poll, disconnect) {
+    adb_pollfd pfd;
+    pfd.fd = fds[0];
+    pfd.events = POLLIN;
+
+    EXPECT_EQ(0, adb_poll(&pfd, 1, 0));
+    EXPECT_EQ(0, pfd.revents);
+
+    EXPECT_EQ(0, adb_close(fds[1]));
+    fds[1] = -1;
+
+    EXPECT_EQ(1, adb_poll(&pfd, 1, 100));
+
+    // Linux returns POLLIN | POLLHUP, Windows returns just POLLHUP.
+    EXPECT_EQ(POLLHUP, pfd.revents & POLLHUP);
+}