Chromium Code Reviews| 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 f14583275011646139c89cfaedb090a7dd5a3643..5d1776dab7749f5b14b9b7520bb56eeda8773c00 100644 |
| --- a/tools/android/forwarder2/host_forwarder_main.cc |
| +++ b/tools/android/forwarder2/host_forwarder_main.cc |
| @@ -6,16 +6,20 @@ |
| #include <signal.h> |
| #include <unistd.h> |
| +#include <cmath> |
| #include <cstdio> |
| #include <cstring> |
| #include <string> |
| +#include <utility> |
| #include <vector> |
| #include "base/command_line.h" |
| #include "base/compiler_specific.h" |
| #include "base/file_util.h" |
| #include "base/files/file_path.h" |
| +#include "base/hash_tables.h" |
| #include "base/logging.h" |
| +#include "base/memory/linked_ptr.h" |
| #include "base/memory/scoped_vector.h" |
| #include "base/posix/eintr_wrapper.h" |
| #include "base/safe_strerror_posix.h" |
| @@ -122,7 +126,7 @@ class ServerDelegate : public Daemon::ServerDelegate { |
| char buf[kBufSize]; |
| const int bytes_read = client_socket->Read(buf, sizeof(buf)); |
| if (bytes_read <= 0) { |
| - if (client_socket->exited()) |
| + if (client_socket->DidReceiveEvent()) |
| return; |
| PError("Read()"); |
| has_failed_ = true; |
| @@ -137,35 +141,53 @@ class ServerDelegate : public Daemon::ServerDelegate { |
| command, &adb_port, &device_port, &forward_to_host, &forward_to_port); |
| if (!succeeded) { |
| has_failed_ = true; |
| - client_socket->WriteString( |
| - base::StringPrintf("ERROR: Could not parse forward command '%s'", |
| - command.c_str())); |
| + const std::string msg = base::StringPrintf( |
| + "ERROR: Could not parse forward command '%s'", command.c_str()); |
| + SendMessage(msg, client_socket.get()); |
| return; |
| } |
| + if (device_port < 0) { |
| + // Remove the previously created host controller. |
| + const std::string controller_key = MakeHostControllerMapKey( |
| + adb_port, std::abs(device_port)); |
|
digit1
2013/05/15 10:13:46
I believe -device_port might work as well since yo
Philippe
2013/05/15 11:40:50
Done.
|
| + const HostControllerMap::size_type removed_elements = controllers_.erase( |
| + controller_key); |
| + SendMessage( |
| + !removed_elements ? "ERROR: could not unmap port" : "OK", |
| + client_socket.get()); |
| + return; |
| + } |
| + // Create a new host controller. |
| scoped_ptr<HostController> host_controller( |
| new HostController(device_port, forward_to_host, forward_to_port, |
| adb_port, GetExitNotifierFD())); |
| if (!host_controller->Connect()) { |
| has_failed_ = true; |
| - client_socket->WriteString("ERROR: Connection to device failed."); |
| + SendMessage("ERROR: Connection to device failed.", client_socket.get()); |
| 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( |
| - base::StringPrintf("%d:%d", device_port, forward_to_port))) { |
| - has_failed_ = true; |
| + const std::string msg = base::StringPrintf( |
| + "%d:%d", device_port, forward_to_port); |
| + if (!SendMessage(msg, client_socket.get())) |
| return; |
| - } |
| host_controller->Start(); |
| - controllers_.push_back(host_controller.release()); |
| + const std::string controller_key = MakeHostControllerMapKey( |
| + adb_port, device_port); |
| + controllers_.insert( |
| + std::make_pair(controller_key, |
| + linked_ptr<HostController>(host_controller.release()))); |
| } |
| virtual void OnServerExited() OVERRIDE { |
| - for (int i = 0; i < controllers_.size(); ++i) |
| - controllers_[i]->Join(); |
| + for (HostControllerMap::iterator it = controllers_.begin(); |
| + it != controllers_.end(); ++it) { |
| + linked_ptr<HostController> host_controller = it->second; |
| + host_controller->Join(); |
| + } |
| if (controllers_.size() == 0) { |
| LOG(ERROR) << "No forwarder servers could be started. Exiting."; |
| has_failed_ = true; |
| @@ -173,7 +195,22 @@ class ServerDelegate : public Daemon::ServerDelegate { |
| } |
| private: |
| - ScopedVector<HostController> controllers_; |
| + typedef base::hash_map< |
| + std::string, linked_ptr<HostController> > HostControllerMap; |
| + |
| + static std::string MakeHostControllerMapKey(int adb_port, int device_port) { |
| + return base::StringPrintf("%d:%d", adb_port, device_port); |
| + } |
| + |
| + bool SendMessage(const std::string& msg, Socket* client_socket) { |
| + bool result = client_socket->WriteString(msg); |
| + DCHECK(result); |
| + if (!result) |
| + has_failed_ = true; |
| + return result; |
| + } |
| + |
| + HostControllerMap controllers_; |
| bool has_failed_; |
| DISALLOW_COPY_AND_ASSIGN(ServerDelegate); |
| @@ -214,7 +251,8 @@ class ClientDelegate : public Daemon::ClientDelegate { |
| void PrintUsage(const char* program_name) { |
| LOG(ERROR) << program_name << " adb_port:from_port:to_port:to_host\n" |
| - "<adb port> is the TCP port Adb is configured to forward to."; |
| + "<adb port> is the TCP port Adb is configured to forward to.\n" |
| + "Note that <from_port> can be unmapped by making it negative."; |
| } |
| int RunHostForwarder(int argc, char** argv) { |