Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Unified Diff: tools/android/forwarder2/host_forwarder_main.cc

Issue 11360248: Use the new forwarder2's Daemon implementation in device_forwarder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address David's comments Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/android/forwarder2/forwarder.gyp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/android/forwarder2/host_forwarder_main.cc
diff --git a/tools/android/forwarder2/host_forwarder_main.cc b/tools/android/forwarder2/host_forwarder_main.cc
index d7f52d157e033815dc8f00aaab0809b68e51dde5..435cae43194dd449c8dcbce8c080e339fb73229d 100644
--- a/tools/android/forwarder2/host_forwarder_main.cc
+++ b/tools/android/forwarder2/host_forwarder_main.cc
@@ -4,14 +4,15 @@
#include <errno.h>
#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <unistd.h>
-#include <vector>
+#include <cstdio>
+#include <cstring>
#include <string>
+#include <vector>
#include "base/command_line.h"
+#include "base/compiler_specific.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
@@ -29,26 +30,36 @@
#include "tools/android/forwarder2/pipe_notifier.h"
#include "tools/android/forwarder2/socket.h"
-using base::StringToInt;
-
namespace forwarder2 {
namespace {
+const char kLogFilePath[] = "/tmp/host_forwarder_log";
const char kPIDFilePath[] = "/tmp/host_forwarder_pid";
-const char kCommandSocketPath[] = "host_forwarder_command_socket";
-const char kWelcomeMessage[] = "forwarder2";
+const char kDaemonIdentifier[] = "chrome_host_forwarder_daemon";
+
+const char kKillServerCommand[] = "kill-server";
+const char kForwardCommand[] = "forward";
+
const int kBufSize = 256;
-// Need to be global to be able to accessed from the signal handler.
-PipeNotifier* g_notifier;
+// Needs to be global to be able to be accessed from the signal handler.
+PipeNotifier* g_notifier = NULL;
+
+// Lets the daemon fetch the exit notifier file descriptor.
+int GetExitNotifierFD() {
+ DCHECK(g_notifier);
+ return g_notifier->receiver_fd();
+}
void KillHandler(int signal_number) {
+ char buf[kBufSize];
if (signal_number != SIGTERM && signal_number != SIGINT) {
- char buf[kBufSize];
snprintf(buf, sizeof(buf), "Ignoring unexpected signal %d.", signal_number);
SIGNAL_SAFE_LOG(WARNING, buf);
return;
}
+ snprintf(buf, sizeof(buf), "Received signal %d.", signal_number);
+ SIGNAL_SAFE_LOG(WARNING, buf);
static int s_kill_handler_count = 0;
CHECK(g_notifier);
// If for some reason the forwarder get stuck in any socket waiting forever,
@@ -59,34 +70,6 @@ void KillHandler(int signal_number) {
exit(1);
}
-enum {
- kConnectSingleTry = 1,
- kConnectNoIdleTime = 0,
-};
-
-scoped_ptr<Socket> ConnectToDaemon(int tries_count, int idle_time_msec) {
- for (int i = 0; i < tries_count; ++i) {
- scoped_ptr<Socket> socket(new Socket());
- if (!socket->ConnectUnix(kCommandSocketPath, true)) {
- if (idle_time_msec)
- usleep(idle_time_msec * 1000);
- continue;
- }
- char buf[sizeof(kWelcomeMessage)];
- memset(buf, 0, sizeof(buf));
- if (socket->Read(buf, sizeof(buf)) < 0) {
- perror("read");
- continue;
- }
- if (strcmp(buf, kWelcomeMessage)) {
- LOG(ERROR) << "Unexpected message read from daemon: " << buf;
- break;
- }
- return socket.Pass();
- }
- return scoped_ptr<Socket>(NULL);
-}
-
// Format of |command|:
// <ADB port>:<Device port>[:<Forward to port>:<Forward to address>].
bool ParseForwardCommand(const std::string& command,
@@ -98,12 +81,12 @@ bool ParseForwardCommand(const std::string& command,
base::SplitString(command, ':', &command_pieces);
if (command_pieces.size() < 2 ||
- !StringToInt(command_pieces[0], adb_port) ||
- !StringToInt(command_pieces[1], device_port))
+ !base::StringToInt(command_pieces[0], adb_port) ||
+ !base::StringToInt(command_pieces[1], device_port))
return false;
if (command_pieces.size() > 2) {
- if (!StringToInt(command_pieces[2], forward_to_port))
+ if (!base::StringToInt(command_pieces[2], forward_to_port))
return false;
if (command_pieces.size() > 3)
*forward_to_host = command_pieces[3];
@@ -121,44 +104,30 @@ bool IsForwardCommandValid(const std::string& command) {
command, &adb_port, &device_port, &forward_to_host, &forward_to_port);
}
-bool DaemonHandler() {
- LOG(INFO) << "Starting host process daemon (pid=" << getpid() << ")";
- DCHECK(!g_notifier);
- g_notifier = new PipeNotifier();
-
- const int notifier_fd = g_notifier->receiver_fd();
- Socket command_socket;
- if (!command_socket.BindUnix(kCommandSocketPath, true)) {
- LOG(ERROR) << "Could not bind Unix Domain Socket";
- return false;
- }
- command_socket.set_exit_notifier_fd(notifier_fd);
+class ServerDelegate : public Daemon::ServerDelegate {
+ public:
+ ServerDelegate() : has_failed_(false) {}
- signal(SIGTERM, KillHandler);
- signal(SIGINT, KillHandler);
+ bool has_failed() const { return has_failed_; }
- ScopedVector<HostController> controllers;
- int failed_count = 0;
+ // Daemon::ServerDelegate:
+ virtual void Init() OVERRIDE {
+ LOG(INFO) << "Starting host process daemon (pid=" << getpid() << ")";
+ DCHECK(!g_notifier);
+ g_notifier = new PipeNotifier();
+ signal(SIGTERM, KillHandler);
+ signal(SIGINT, KillHandler);
+ }
- for (;;) {
- Socket client_socket;
- if (!command_socket.Accept(&client_socket)) {
- if (command_socket.exited())
- return true;
- PError("Accept()");
- return false;
- }
- if (!client_socket.Write(kWelcomeMessage, sizeof(kWelcomeMessage))) {
- PError("Write()");
- continue;
- }
+ virtual void OnClientConnected(scoped_ptr<Socket> client_socket) OVERRIDE {
char buf[kBufSize];
- const int bytes_read = client_socket.Read(buf, sizeof(buf));
+ const int bytes_read = client_socket->Read(buf, sizeof(buf));
if (bytes_read <= 0) {
- if (client_socket.exited())
- break;
+ if (client_socket->exited())
+ return;
PError("Read()");
- ++failed_count;
+ has_failed_ = true;
+ return;
}
const std::string command(buf, bytes_read);
int adb_port = 0;
@@ -168,41 +137,81 @@ bool DaemonHandler() {
const bool succeeded = ParseForwardCommand(
command, &adb_port, &device_port, &forward_to_host, &forward_to_port);
if (!succeeded) {
- ++failed_count;
- client_socket.WriteString(
+ has_failed_ = true;
+ client_socket->WriteString(
base::StringPrintf("ERROR: Could not parse forward command '%s'",
command.c_str()));
- continue;
+ return;
}
scoped_ptr<HostController> host_controller(
new HostController(device_port, forward_to_host, forward_to_port,
- adb_port, notifier_fd));
+ adb_port, GetExitNotifierFD()));
if (!host_controller->Connect()) {
- ++failed_count;
- client_socket.WriteString("ERROR: Connection to device failed.");
- continue;
+ has_failed_ = true;
+ client_socket->WriteString("ERROR: Connection to device failed.");
+ return;
}
// Get the current allocated port.
device_port = host_controller->device_port();
LOG(INFO) << "Forwarding device port " << device_port << " to host "
<< forward_to_host << ":" << forward_to_port;
- if (!client_socket.WriteString(
+ if (!client_socket->WriteString(
base::StringPrintf("%d:%d", device_port, forward_to_port))) {
- ++failed_count;
- continue;
+ has_failed_ = true;
+ return;
}
host_controller->Start();
- controllers.push_back(host_controller.release());
+ controllers_.push_back(host_controller.release());
}
- for (int i = 0; i < controllers.size(); ++i)
- controllers[i]->Join();
- if (controllers.size() == 0) {
- LOG(ERROR) << "No forwarder servers could be started. Exiting.";
- return false;
+ virtual void OnServerExited() OVERRIDE {
+ for (int i = 0; i < controllers_.size(); ++i)
+ controllers_[i]->Join();
+ if (controllers_.size() == 0) {
+ LOG(ERROR) << "No forwarder servers could be started. Exiting.";
+ has_failed_ = true;
+ }
+ }
+
+ private:
+ ScopedVector<HostController> controllers_;
+ bool has_failed_;
+
+ DISALLOW_COPY_AND_ASSIGN(ServerDelegate);
+};
+
+class ClientDelegate : public Daemon::ClientDelegate {
+ public:
+ ClientDelegate(const std::string& forward_command)
+ : forward_command_(forward_command),
+ has_failed_(false) {
}
- return true;
-}
+
+ bool has_failed() const { return has_failed_; }
+
+ // Daemon::ClientDelegate:
+ virtual void OnDaemonReady(Socket* daemon_socket) OVERRIDE {
+ // Send the forward command to the daemon.
+ CHECK(daemon_socket->WriteString(forward_command_));
+ char buf[kBufSize];
+ const int bytes_read = daemon_socket->Read(
+ buf, sizeof(buf) - 1 /* leave space for null terminator */);
+ CHECK_GT(bytes_read, 0);
+ DCHECK(bytes_read < sizeof(buf));
+ buf[bytes_read] = 0;
+ base::StringPiece msg(buf, bytes_read);
+ if (msg.starts_with("ERROR")) {
+ LOG(ERROR) << msg;
+ has_failed_ = true;
+ return;
+ }
+ printf("%s\n", buf);
+ }
+
+ private:
+ const std::string forward_command_;
+ bool has_failed_;
+};
void PrintUsage(const char* program_name) {
LOG(ERROR) << program_name << " adb_port:from_port:to_port:to_host\n"
@@ -215,63 +224,36 @@ int RunHostForwarder(int argc, char** argv) {
return 1;
}
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- std::string command;
+ const char* command = NULL;
int adb_port = 0;
if (argc != 2) {
PrintUsage(argv[0]);
return 1;
}
- if (!strcmp(argv[1], "kill-server")) {
- command = "kill-server";
+ if (!strcmp(argv[1], kKillServerCommand)) {
+ command = kKillServerCommand;
} else {
- command = "forward";
+ command = kForwardCommand;
if (!IsForwardCommandValid(argv[1])) {
PrintUsage(argv[0]);
return 1;
}
}
- Daemon daemon(kPIDFilePath);
+ ClientDelegate client_delegate(argv[1]);
+ ServerDelegate daemon_delegate;
+ Daemon daemon(
+ kLogFilePath, kPIDFilePath, kDaemonIdentifier, &client_delegate,
+ &daemon_delegate, &GetExitNotifierFD);
- if (command == "kill-server")
+ if (command == kKillServerCommand)
return !daemon.Kill();
- bool is_daemon = false;
- scoped_ptr<Socket> daemon_socket = ConnectToDaemon(
- kConnectSingleTry, kConnectNoIdleTime);
- if (!daemon_socket) {
- if (!daemon.Spawn(&is_daemon))
- return 1;
- }
-
- if (is_daemon)
- return !DaemonHandler();
-
- if (!daemon_socket) {
- const int kTries = 10;
- const int kIdleTimeMsec = 10;
- daemon_socket = ConnectToDaemon(kTries, kIdleTimeMsec);
- if (!daemon_socket) {
- LOG(ERROR) << "Could not connect to daemon.";
- return 1;
- }
- }
-
- // Send the forward command to the daemon.
- CHECK(daemon_socket->Write(argv[1], strlen(argv[1])));
- char buf[kBufSize];
- const int bytes_read = daemon_socket->Read(
- buf, sizeof(buf) - 1 /* leave space for null terminator */);
- CHECK_GT(bytes_read, 0);
- DCHECK(bytes_read < sizeof(buf));
- buf[bytes_read] = 0;
- base::StringPiece msg(buf, bytes_read);
- if (msg.starts_with("ERROR")) {
- LOG(ERROR) << msg;
+ DCHECK(command == kForwardCommand);
+ if (!daemon.SpawnIfNeeded())
return 1;
- }
- printf("%s\n", buf);
- return 0;
+
+ return client_delegate.has_failed() || daemon_delegate.has_failed();
}
} // namespace
« no previous file with comments | « tools/android/forwarder2/forwarder.gyp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698