Merge "logd: optimize code hotspots"
diff --git a/adb/adb_client.cpp b/adb/adb_client.cpp
index 63cb3c3..984910d 100644
--- a/adb/adb_client.cpp
+++ b/adb/adb_client.cpp
@@ -195,14 +195,15 @@
         adb_sleep_ms(3000);
         // fall through to _adb_connect
     } else {
-        // if server was running, check its version to make sure it is not out of date
+        // If a server is already running, check its version matches.
         int version = ADB_SERVER_VERSION - 1;
 
-        // if we have a file descriptor, then parse version result
+        // If we have a file descriptor, then parse version result.
         if (fd >= 0) {
             std::string version_string;
             if (!ReadProtocolString(fd, &version_string, error)) {
-                goto error;
+                adb_close(fd);
+                return -1;
             }
 
             adb_close(fd);
@@ -214,8 +215,8 @@
                 return -1;
             }
         } else {
-            // if fd is -1, then check for "unknown host service",
-            // which would indicate a version of adb that does not support the
+            // If fd is -1 check for "unknown host service" which would
+            // indicate a version of adb that does not support the
             // version command, in which case we should fall-through to kill it.
             if (*error != "unknown host service") {
                 return fd;
@@ -223,7 +224,8 @@
         }
 
         if (version != ADB_SERVER_VERSION) {
-            printf("adb server is out of date.  killing...\n");
+            printf("adb server version (%d) doesn't match this client (%d); killing...\n",
+                   version, ADB_SERVER_VERSION);
             fd = _adb_connect("host:kill", error);
             if (fd >= 0) {
                 adb_close(fd);
@@ -253,9 +255,6 @@
     D("adb_connect: return fd %d", fd);
 
     return fd;
-error:
-    adb_close(fd);
-    return -1;
 }
 
 
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index 2b1ec48..42f6d9b 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -659,6 +659,12 @@
           SystemErrorCodeToString(err).c_str());
         _socket_set_errno(err);
         result = -1;
+    } else {
+        // According to https://code.google.com/p/chromium/issues/detail?id=27870
+        // Winsock Layered Service Providers may cause this.
+        CHECK_LE(result, len) << "Tried to write " << len << " bytes to "
+                              << f->name << ", but " << result
+                              << " bytes reportedly written";
     }
     return result;
 }
@@ -705,6 +711,23 @@
     }
 }
 
+// Map a socket type to an explicit socket protocol instead of using the socket
+// protocol of 0. Explicit socket protocols are used by most apps and we should
+// do the same to reduce the chance of exercising uncommon code-paths that might
+// have problems or that might load different Winsock service providers that
+// have problems.
+static int GetSocketProtocolFromSocketType(int type) {
+    switch (type) {
+        case SOCK_STREAM:
+            return IPPROTO_TCP;
+        case SOCK_DGRAM:
+            return IPPROTO_UDP;
+        default:
+            LOG(FATAL) << "Unknown socket type: " << type;
+            return 0;
+    }
+}
+
 int network_loopback_client(int port, int type, std::string* error) {
     struct sockaddr_in addr;
     SOCKET  s;
@@ -723,7 +746,7 @@
     addr.sin_port = htons(port);
     addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
 
-    s = socket(AF_INET, type, 0);
+    s = socket(AF_INET, type, GetSocketProtocolFromSocketType(type));
     if(s == INVALID_SOCKET) {
         *error = android::base::StringPrintf("cannot create socket: %s",
                 SystemErrorCodeToString(WSAGetLastError()).c_str());
@@ -777,7 +800,7 @@
 
     // TODO: Consider using dual-stack socket that can simultaneously listen on
     // IPv4 and IPv6.
-    s = socket(AF_INET, type, 0);
+    s = socket(AF_INET, type, GetSocketProtocolFromSocketType(type));
     if (s == INVALID_SOCKET) {
         *error = android::base::StringPrintf("cannot create socket: %s",
                 SystemErrorCodeToString(WSAGetLastError()).c_str());
@@ -849,6 +872,7 @@
     memset(&hints, 0, sizeof(hints));
     hints.ai_family = AF_UNSPEC;
     hints.ai_socktype = type;
+    hints.ai_protocol = GetSocketProtocolFromSocketType(type);
 
     char port_str[16];
     snprintf(port_str, sizeof(port_str), "%d", port);
@@ -952,6 +976,11 @@
         errno = EBADF;
         return -1;
     }
+
+    // TODO: Once we can assume Windows Vista or later, if the caller is trying
+    // to set SOL_SOCKET, SO_SNDBUF/SO_RCVBUF, ignore it since the OS has
+    // auto-tuning.
+
     int result = setsockopt( fh->fh_socket, level, optname,
                              reinterpret_cast<const char*>(optval), optlen );
     if ( result == SOCKET_ERROR ) {