Remove the separate JdwpTransport objects.

Structs containing nothing but function pointers? What are we? C programmers?

Change-Id: I4fbc9dc0d8fc10557afa020b27cda85c939965c3
diff --git a/src/jdwp/jdwp_adb.cc b/src/jdwp/jdwp_adb.cc
index 3ce2064..9652f60 100644
--- a/src/jdwp/jdwp_adb.cc
+++ b/src/jdwp/jdwp_adb.cc
@@ -52,66 +52,77 @@
 
 namespace JDWP {
 
-struct JdwpNetState : public JdwpNetStateBase {
-  int                 controlSock;
-  bool                shuttingDown;
-  int                 wakeFds[2];
+struct JdwpAdbState : public JdwpNetStateBase {
+ public:
+  JdwpAdbState(JdwpState* state) : JdwpNetStateBase(state) {
+    control_sock_ = -1;
+    shutting_down_ = false;
 
-  socklen_t           controlAddrLen;
+    control_addr_.controlAddrUn.sun_family = AF_UNIX;
+    control_addr_len_ = sizeof(control_addr_.controlAddrUn.sun_family) + kJdwpControlNameLen;
+    memcpy(control_addr_.controlAddrUn.sun_path, kJdwpControlName, kJdwpControlNameLen);
+  }
+
+  ~JdwpAdbState() {
+    if (clientSock != -1) {
+      shutdown(clientSock, SHUT_RDWR);
+      close(clientSock);
+    }
+    if (control_sock_ != -1) {
+      shutdown(control_sock_, SHUT_RDWR);
+      close(control_sock_);
+    }
+  }
+
+  virtual bool Accept();
+
+  virtual bool Establish(const JdwpOptions*) {
+    return false;
+  }
+
+  virtual void Shutdown() {
+    shutting_down_ = true;
+
+    int control_sock = this->control_sock_;
+    int clientSock = this->clientSock;
+
+    /* clear these out so it doesn't wake up and try to reuse them */
+    this->control_sock_ = this->clientSock = -1;
+
+    if (clientSock != -1) {
+      shutdown(clientSock, SHUT_RDWR);
+    }
+
+    if (control_sock != -1) {
+      shutdown(control_sock, SHUT_RDWR);
+    }
+
+    WakePipe();
+  }
+
+  virtual bool ProcessIncoming();
+
+ private:
+  int ReceiveClientFd();
+
+  int control_sock_;
+  bool shutting_down_;
+
+  socklen_t control_addr_len_;
   union {
-    sockaddr_un  controlAddrUn;
-    sockaddr     controlAddrPlain;
-  } controlAddr;
-
-  JdwpNetState() {
-    controlSock = -1;
-    shuttingDown = false;
-    wakeFds[0] = -1;
-    wakeFds[1] = -1;
-
-    controlAddr.controlAddrUn.sun_family = AF_UNIX;
-    controlAddrLen = sizeof(controlAddr.controlAddrUn.sun_family) + kJdwpControlNameLen;
-    memcpy(controlAddr.controlAddrUn.sun_path, kJdwpControlName, kJdwpControlNameLen);
-  }
+    sockaddr_un controlAddrUn;
+    sockaddr controlAddrPlain;
+  } control_addr_;
 };
 
-static JdwpNetState* GetNetState(JdwpState* state) {
-  return reinterpret_cast<JdwpNetState*>(state->netState);
-}
-
-static void adbStateFree(JdwpNetState* netState) {
-  if (netState == NULL) {
-    return;
-  }
-
-  if (netState->clientSock >= 0) {
-    shutdown(netState->clientSock, SHUT_RDWR);
-    close(netState->clientSock);
-  }
-  if (netState->controlSock >= 0) {
-    shutdown(netState->controlSock, SHUT_RDWR);
-    close(netState->controlSock);
-  }
-  if (netState->wakeFds[0] >= 0) {
-    close(netState->wakeFds[0]);
-    netState->wakeFds[0] = -1;
-  }
-  if (netState->wakeFds[1] >= 0) {
-    close(netState->wakeFds[1]);
-    netState->wakeFds[1] = -1;
-  }
-
-  delete netState;
-}
-
 /*
  * Do initial prep work, e.g. binding to ports and opening files.  This
  * runs in the main thread, before the JDWP thread starts, so it shouldn't
  * do anything that might block forever.
  */
-static bool startup(JdwpState* state, const JdwpOptions*) {
+bool InitAdbTransport(JdwpState* state, const JdwpOptions*) {
   VLOG(jdwp) << "ADB transport startup";
-  state->netState = new JdwpNetState;
+  state->netState = new JdwpAdbState(state);
   return (state->netState != NULL);
 }
 
@@ -120,21 +131,20 @@
  * directly with a debugger or DDMS.
  *
  * Returns the file descriptor on success.  On failure, returns -1 and
- * closes netState->controlSock.
+ * closes netState->control_sock_.
  */
-static int  receiveClientFd(JdwpNetState*  netState) {
-  msghdr    msg;
-  cmsghdr*  cmsg;
-  iovec     iov;
-  char             dummy = '!';
+int JdwpAdbState::ReceiveClientFd() {
+  char dummy = '!';
   union {
     cmsghdr cm;
     char buffer[CMSG_SPACE(sizeof(int))];
   } cm_un;
-  int              ret;
 
+  iovec iov;
   iov.iov_base       = &dummy;
   iov.iov_len        = 1;
+
+  msghdr msg;
   msg.msg_name       = NULL;
   msg.msg_namelen    = 0;
   msg.msg_iov        = &iov;
@@ -143,22 +153,20 @@
   msg.msg_control    = cm_un.buffer;
   msg.msg_controllen = sizeof(cm_un.buffer);
 
-  cmsg = CMSG_FIRSTHDR(&msg);
+  cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
   cmsg->cmsg_len   = msg.msg_controllen;
   cmsg->cmsg_level = SOL_SOCKET;
   cmsg->cmsg_type  = SCM_RIGHTS;
   ((int*)(void*)CMSG_DATA(cmsg))[0] = -1;
 
-  do {
-    ret = recvmsg(netState->controlSock, &msg, 0);
-  } while (ret < 0 && errno == EINTR);
+  int rc = TEMP_FAILURE_RETRY(recvmsg(control_sock_, &msg, 0));
 
-  if (ret <= 0) {
-    if (ret < 0) {
-      PLOG(WARNING) << "Receiving file descriptor from ADB failed (socket " << netState->controlSock << ")";
+  if (rc <= 0) {
+    if (rc == -1) {
+      PLOG(WARNING) << "Receiving file descriptor from ADB failed (socket " << control_sock_ << ")";
     }
-    close(netState->controlSock);
-    netState->controlSock = -1;
+    close(control_sock_);
+    control_sock_ = -1;
     return -1;
   }
 
@@ -172,30 +180,28 @@
  * This needs to un-block and return "false" if the VM is shutting down.  It
  * should return "true" when it successfully accepts a connection.
  */
-static bool acceptConnection(JdwpState* state) {
-  JdwpNetState* netState = GetNetState(state);
+bool JdwpAdbState::Accept() {
   int retryCount = 0;
 
   /* first, ensure that we get a connection to the ADB daemon */
 
  retry:
-  if (netState->shuttingDown) {
+  if (shutting_down_) {
     return false;
   }
 
-  if (netState->controlSock < 0) {
+  if (control_sock_ == -1) {
     int        sleep_ms     = 500;
     const int  sleep_max_ms = 2*1000;
     char       buff[5];
 
-    netState->controlSock = socket(PF_UNIX, SOCK_STREAM, 0);
-    if (netState->controlSock < 0) {
+    control_sock_ = socket(PF_UNIX, SOCK_STREAM, 0);
+    if (control_sock_ < 0) {
       PLOG(ERROR) << "Could not create ADB control socket";
       return false;
     }
 
-    if (pipe(netState->wakeFds) < 0) {
-      PLOG(ERROR) << "pipe failed";
+    if (!MakePipe()) {
       return false;
     }
 
@@ -216,11 +222,11 @@
        * up after a few minutes in case somebody ships an app with
        * the debuggable flag set.
        */
-      int  ret = connect(netState->controlSock, &netState->controlAddr.controlAddrPlain, netState->controlAddrLen);
+      int  ret = connect(control_sock_, &control_addr_.controlAddrPlain, control_addr_len_);
       if (!ret) {
 #ifdef HAVE_ANDROID_OS
-        if (!socket_peer_is_trusted(netState->controlSock)) {
-          if (shutdown(netState->controlSock, SHUT_RDWR)) {
+        if (!socket_peer_is_trusted(control_sock_)) {
+          if (shutdown(control_sock_, SHUT_RDWR)) {
             PLOG(ERROR) << "trouble shutting down socket";
           }
           return false;
@@ -228,7 +234,7 @@
 #endif
 
         /* now try to send our pid to the ADB daemon */
-        ret = TEMP_FAILURE_RETRY(send(netState->controlSock, buff, 4, 0));
+        ret = TEMP_FAILURE_RETRY(send(control_sock_, buff, 4, 0));
         if (ret >= 0) {
           VLOG(jdwp) << StringPrintf("PID sent as '%.*s' to ADB", 4, buff);
           break;
@@ -247,7 +253,7 @@
       if (sleep_ms > sleep_max_ms) {
         sleep_ms = sleep_max_ms;
       }
-      if (netState->shuttingDown) {
+      if (shutting_down_) {
         return false;
       }
     }
@@ -255,78 +261,25 @@
 
   VLOG(jdwp) << "trying to receive file descriptor from ADB";
   /* now we can receive a client file descriptor */
-  netState->clientSock = receiveClientFd(netState);
-  if (netState->shuttingDown) {
+  clientSock = ReceiveClientFd();
+  if (shutting_down_) {
     return false;       // suppress logs and additional activity
   }
-  if (netState->clientSock < 0) {
+  if (clientSock == -1) {
     if (++retryCount > 5) {
       LOG(ERROR) << "adb connection max retries exceeded";
       return false;
     }
     goto retry;
   } else {
-    VLOG(jdwp) << "received file descriptor " << netState->clientSock << " from ADB";
-    netState->SetAwaitingHandshake(true);
-    netState->inputCount = 0;
+    VLOG(jdwp) << "received file descriptor " << clientSock << " from ADB";
+    SetAwaitingHandshake(true);
+    input_count_ = 0;
     return true;
   }
 }
 
 /*
- * Connect out to a debugger (for server=n).  Not required.
- */
-static bool establishConnection(JdwpState*, const JdwpOptions*) {
-  return false;
-}
-
-/*
- * Close all network stuff, including the socket we use to listen for
- * new connections.
- *
- * May be called from a non-JDWP thread, e.g. when the VM is shutting down.
- */
-static void adbStateShutdown(JdwpNetState* netState) {
-  int  controlSock;
-  int  clientSock;
-
-  if (netState == NULL) {
-    return;
-  }
-
-  netState->shuttingDown = true;
-
-  clientSock = netState->clientSock;
-  if (clientSock >= 0) {
-    shutdown(clientSock, SHUT_RDWR);
-    netState->clientSock = -1;
-  }
-
-  controlSock = netState->controlSock;
-  if (controlSock >= 0) {
-    shutdown(controlSock, SHUT_RDWR);
-    netState->controlSock = -1;
-  }
-
-  if (netState->wakeFds[1] >= 0) {
-    VLOG(jdwp) << "+++ writing to wakePipe";
-    TEMP_FAILURE_RETRY(write(netState->wakeFds[1], "", 1));
-  }
-}
-
-static void netShutdown(JdwpState* state) {
-  adbStateShutdown(GetNetState(state));
-}
-
-/*
- * Free up anything we put in state->netState.  This is called after
- * "netShutdown", after the JDWP thread has stopped.
- */
-static void netFree(JdwpState* state) {
-  adbStateFree(GetNetState(state));
-}
-
-/*
  * Process incoming data.  If no data is available, this will block until
  * some arrives.
  *
@@ -341,13 +294,12 @@
  * Returns "false" on error (indicating that the connection has been severed),
  * "true" if things are still okay.
  */
-static bool processIncoming(JdwpState* state) {
-  JdwpNetState* netState = GetNetState(state);
+bool JdwpAdbState::ProcessIncoming() {
   int readCount;
 
-  CHECK_GE(netState->clientSock, 0);
+  CHECK(clientSock != -1);
 
-  if (!netState->HaveFullPacket()) {
+  if (!HaveFullPacket()) {
     /* read some more, looping until we have data */
     errno = 0;
     while (1) {
@@ -359,21 +311,21 @@
       FD_ZERO(&readfds);
 
       /* configure fds; note these may get zapped by another thread */
-      fd = netState->controlSock;
+      fd = control_sock_;
       if (fd >= 0) {
         FD_SET(fd, &readfds);
         if (maxfd < fd) {
           maxfd = fd;
         }
       }
-      fd = netState->clientSock;
+      fd = clientSock;
       if (fd >= 0) {
         FD_SET(fd, &readfds);
         if (maxfd < fd) {
           maxfd = fd;
         }
       }
-      fd = netState->wakeFds[0];
+      fd = wake_pipe_[0];
       if (fd >= 0) {
         FD_SET(fd, &readfds);
         if (maxfd < fd) {
@@ -395,7 +347,7 @@
        * and accept(), but not select()).
        *
        * We can do one of three things: (1) send a signal and catch
-       * EINTR, (2) open an additional fd ("wakePipe") and write to
+       * EINTR, (2) open an additional fd ("wake pipe") and write to
        * it when it's time to exit, or (3) time out periodically and
        * re-issue the select.  We're currently using #2, as it's more
        * reliable than #1 and generally better than #3.  Wastes two fds.
@@ -409,26 +361,25 @@
         goto fail;
       }
 
-      if (netState->wakeFds[0] >= 0 && FD_ISSET(netState->wakeFds[0], &readfds)) {
+      if (wake_pipe_[0] >= 0 && FD_ISSET(wake_pipe_[0], &readfds)) {
         LOG(DEBUG) << "Got wake-up signal, bailing out of select";
         goto fail;
       }
-      if (netState->controlSock >= 0 && FD_ISSET(netState->controlSock, &readfds)) {
-        int  sock = receiveClientFd(netState);
+      if (control_sock_ >= 0 && FD_ISSET(control_sock_, &readfds)) {
+        int  sock = ReceiveClientFd();
         if (sock >= 0) {
           LOG(INFO) << "Ignoring second debugger -- accepting and dropping";
           close(sock);
         } else {
-          CHECK_LT(netState->controlSock, 0);
+          CHECK(control_sock_ == -1);
           /*
            * Remote side most likely went away, so our next read
-           * on netState->clientSock will fail and throw us out
-           * of the loop.
+           * on clientSock will fail and throw us out of the loop.
            */
         }
       }
-      if (netState->clientSock >= 0 && FD_ISSET(netState->clientSock, &readfds)) {
-        readCount = read(netState->clientSock, netState->inputBuffer + netState->inputCount, sizeof(netState->inputBuffer) - netState->inputCount);
+      if (clientSock >= 0 && FD_ISSET(clientSock, &readfds)) {
+        readCount = read(clientSock, input_buffer_ + input_count_, sizeof(input_buffer_) - input_count_);
         if (readCount < 0) {
           /* read failed */
           if (errno != EINTR) {
@@ -446,8 +397,8 @@
       }
     }
 
-    netState->inputCount += readCount;
-    if (!netState->HaveFullPacket()) {
+    input_count_ += readCount;
+    if (!HaveFullPacket()) {
       return true;        /* still not there yet */
     }
   }
@@ -460,23 +411,21 @@
    *
    * Other than this one case, the protocol [claims to be] stateless.
    */
-  if (netState->IsAwaitingHandshake()) {
-    int cc;
-
-    if (memcmp(netState->inputBuffer, kMagicHandshake, kMagicHandshakeLen) != 0) {
-      LOG(ERROR) << StringPrintf("ERROR: bad handshake '%.14s'", netState->inputBuffer);
+  if (IsAwaitingHandshake()) {
+    if (memcmp(input_buffer_, kMagicHandshake, kMagicHandshakeLen) != 0) {
+      LOG(ERROR) << StringPrintf("ERROR: bad handshake '%.14s'", input_buffer_);
       goto fail;
     }
 
     errno = 0;
-    cc = TEMP_FAILURE_RETRY(write(netState->clientSock, netState->inputBuffer, kMagicHandshakeLen));
+    int cc = TEMP_FAILURE_RETRY(write(clientSock, input_buffer_, kMagicHandshakeLen));
     if (cc != kMagicHandshakeLen) {
       PLOG(ERROR) << "Failed writing handshake bytes (" << cc << " of " << kMagicHandshakeLen << ")";
       goto fail;
     }
 
-    netState->ConsumeBytes(kMagicHandshakeLen);
-    netState->SetAwaitingHandshake(false);
+    ConsumeBytes(kMagicHandshakeLen);
+    SetAwaitingHandshake(false);
     VLOG(jdwp) << "+++ handshake complete";
     return true;
   }
@@ -484,32 +433,13 @@
   /*
    * Handle this packet.
    */
-  return state->HandlePacket();
+  return state_->HandlePacket();
 
  fail:
-  netState->Close();
+  Close();
   return false;
 }
 
-/*
- * Our functions.
- */
-static const JdwpTransport adbTransport = {
-  startup,
-  acceptConnection,
-  establishConnection,
-  netShutdown,
-  netFree,
-  processIncoming,
-};
-
-/*
- * Return our set.
- */
-const JdwpTransport* AndroidAdbTransport() {
-  return &adbTransport;
-}
-
 }  // namespace JDWP
 
 }  // namespace art