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

Side by Side Diff: tools/android/forwarder2/host_forwarder_main.cc

Issue 19478003: Remove Thread wrapper class in forwarder2. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address Marcus' comments Created 7 years, 4 months 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/android/forwarder2/host_controller.cc ('k') | tools/android/forwarder2/thread.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <errno.h> 5 #include <errno.h>
6 #include <signal.h> 6 #include <signal.h>
7 #include <sys/types.h> 7 #include <sys/types.h>
8 #include <sys/wait.h> 8 #include <sys/wait.h>
9 #include <unistd.h> 9 #include <unistd.h>
10 10
11 #include <cstdio> 11 #include <cstdio>
12 #include <iostream> 12 #include <iostream>
13 #include <limits> 13 #include <limits>
14 #include <string> 14 #include <string>
15 #include <utility> 15 #include <utility>
16 #include <vector> 16 #include <vector>
17 17
18 #include "base/at_exit.h" 18 #include "base/at_exit.h"
19 #include "base/basictypes.h"
19 #include "base/bind.h" 20 #include "base/bind.h"
20 #include "base/command_line.h" 21 #include "base/command_line.h"
21 #include "base/compiler_specific.h" 22 #include "base/compiler_specific.h"
22 #include "base/containers/hash_tables.h" 23 #include "base/containers/hash_tables.h"
23 #include "base/file_util.h" 24 #include "base/file_util.h"
24 #include "base/files/file_path.h" 25 #include "base/files/file_path.h"
25 #include "base/logging.h" 26 #include "base/logging.h"
26 #include "base/memory/linked_ptr.h" 27 #include "base/memory/linked_ptr.h"
27 #include "base/memory/scoped_vector.h" 28 #include "base/memory/scoped_vector.h"
29 #include "base/memory/weak_ptr.h"
28 #include "base/pickle.h" 30 #include "base/pickle.h"
29 #include "base/posix/eintr_wrapper.h" 31 #include "base/posix/eintr_wrapper.h"
30 #include "base/safe_strerror_posix.h" 32 #include "base/safe_strerror_posix.h"
31 #include "base/strings/string_number_conversions.h" 33 #include "base/strings/string_number_conversions.h"
32 #include "base/strings/string_piece.h" 34 #include "base/strings/string_piece.h"
33 #include "base/strings/string_split.h" 35 #include "base/strings/string_split.h"
34 #include "base/strings/string_util.h" 36 #include "base/strings/string_util.h"
35 #include "base/strings/stringprintf.h" 37 #include "base/strings/stringprintf.h"
36 #include "base/task_runner.h" 38 #include "base/task_runner.h"
37 #include "base/threading/thread.h" 39 #include "base/threading/thread.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 static int s_kill_handler_count = 0; 75 static int s_kill_handler_count = 0;
74 CHECK(g_notifier); 76 CHECK(g_notifier);
75 // If for some reason the forwarder get stuck in any socket waiting forever, 77 // If for some reason the forwarder get stuck in any socket waiting forever,
76 // we can send a SIGKILL or SIGINT three times to force it die 78 // we can send a SIGKILL or SIGINT three times to force it die
77 // (non-nicely). This is useful when debugging. 79 // (non-nicely). This is useful when debugging.
78 ++s_kill_handler_count; 80 ++s_kill_handler_count;
79 if (!g_notifier->Notify() || s_kill_handler_count > 2) 81 if (!g_notifier->Notify() || s_kill_handler_count > 2)
80 exit(1); 82 exit(1);
81 } 83 }
82 84
85 // Manages HostController instances. There is one HostController instance for
86 // each connection being forwarded. Note that forwarding can happen with many
87 // devices (identified with a serial id).
83 class HostControllersManager { 88 class HostControllersManager {
84 public: 89 public:
85 HostControllersManager() : has_failed_(false) {} 90 HostControllersManager()
91 : weak_ptr_factory_(this),
92 controllers_(new HostControllerMap()),
93 has_failed_(false) {
94 }
95
96 ~HostControllersManager() {
97 if (!thread_.get())
98 return;
99 // Delete the controllers on the thread they were created on.
100 thread_->message_loop_proxy()->DeleteSoon(
101 FROM_HERE, controllers_.release());
102 }
86 103
87 void HandleRequest(const std::string& device_serial, 104 void HandleRequest(const std::string& device_serial,
88 int device_port, 105 int device_port,
89 int host_port, 106 int host_port,
90 scoped_ptr<Socket> client_socket) { 107 scoped_ptr<Socket> client_socket) {
91 // Lazy initialize so that the CLI process doesn't get this thread created. 108 // Lazy initialize so that the CLI process doesn't get this thread created.
92 InitOnce(); 109 InitOnce();
93 thread_->message_loop_proxy()->PostTask( 110 thread_->message_loop_proxy()->PostTask(
94 FROM_HERE, 111 FROM_HERE,
95 base::Bind( 112 base::Bind(
(...skipping 14 matching lines...) Expand all
110 127
111 void InitOnce() { 128 void InitOnce() {
112 if (thread_.get()) 129 if (thread_.get())
113 return; 130 return;
114 at_exit_manager_.reset(new base::AtExitManager()); 131 at_exit_manager_.reset(new base::AtExitManager());
115 thread_.reset(new base::Thread("HostControllersManagerThread")); 132 thread_.reset(new base::Thread("HostControllersManagerThread"));
116 thread_->Start(); 133 thread_->Start();
117 } 134 }
118 135
119 // Invoked when a HostController instance reports an error (e.g. due to a 136 // Invoked when a HostController instance reports an error (e.g. due to a
120 // device connectivity issue). 137 // device connectivity issue). Note that this could be called after the
121 void DeleteHostController(HostController* host_controller) { 138 // controller manager was destroyed which is why a weak pointer is used.
122 if (!thread_->message_loop_proxy()->RunsTasksOnCurrentThread()) { 139 static void DeleteHostController(
123 // This can be invoked from the host controller internal thread. 140 const base::WeakPtr<HostControllersManager>& manager_ptr,
124 thread_->message_loop_proxy()->PostTask( 141 scoped_ptr<HostController> host_controller) {
125 FROM_HERE, 142 HostController* const controller = host_controller.release();
126 base::Bind( 143 HostControllersManager* const manager = manager_ptr.get();
127 &HostControllersManager::DeleteHostControllerOnInternalThread, 144 if (!manager) {
128 base::Unretained(this), host_controller)); 145 // Note that |controller| is not leaked in this case since the host
146 // controllers manager owns the controllers. If the manager was deleted
147 // then all the controllers (including |controller|) were also deleted.
129 return; 148 return;
130 } 149 }
131 DeleteHostControllerOnInternalThread(host_controller); 150 DCHECK(manager->thread_->message_loop_proxy()->RunsTasksOnCurrentThread());
132 } 151 // Note that this will delete |controller| which is owned by the map.
133 152 manager->controllers_->erase(
134 void DeleteHostControllerOnInternalThread(HostController* host_controller) { 153 MakeHostControllerMapKey(controller->adb_port(),
135 // Note that this will delete |host_controller| which is owned by the map. 154 controller->device_port()));
136 controllers_.erase(
137 MakeHostControllerMapKey(host_controller->adb_port(),
138 host_controller->device_port()));
139 } 155 }
140 156
141 void HandleRequestOnInternalThread(const std::string& device_serial, 157 void HandleRequestOnInternalThread(const std::string& device_serial,
142 int device_port, 158 int device_port,
143 int host_port, 159 int host_port,
144 scoped_ptr<Socket> client_socket) { 160 scoped_ptr<Socket> client_socket) {
145 const int adb_port = GetAdbPortForDevice(device_serial); 161 const int adb_port = GetAdbPortForDevice(device_serial);
146 if (adb_port < 0) { 162 if (adb_port < 0) {
147 SendMessage( 163 SendMessage(
148 "ERROR: could not get adb port for device. You might need to add " 164 "ERROR: could not get adb port for device. You might need to add "
149 "'adb' to your PATH or provide the device serial id.", 165 "'adb' to your PATH or provide the device serial id.",
150 client_socket.get()); 166 client_socket.get());
151 return; 167 return;
152 } 168 }
153 if (device_port < 0) { 169 if (device_port < 0) {
154 // Remove the previously created host controller. 170 // Remove the previously created host controller.
155 const std::string controller_key = MakeHostControllerMapKey( 171 const std::string controller_key = MakeHostControllerMapKey(
156 adb_port, -device_port); 172 adb_port, -device_port);
157 const HostControllerMap::size_type removed_elements = controllers_.erase( 173 const HostControllerMap::size_type removed_elements = controllers_->erase(
158 controller_key); 174 controller_key);
159 SendMessage( 175 SendMessage(
160 !removed_elements ? "ERROR: could not unmap port" : "OK", 176 !removed_elements ? "ERROR: could not unmap port" : "OK",
161 client_socket.get()); 177 client_socket.get());
162 return; 178 return;
163 } 179 }
164 if (host_port < 0) { 180 if (host_port < 0) {
165 SendMessage("ERROR: missing host port", client_socket.get()); 181 SendMessage("ERROR: missing host port", client_socket.get());
166 return; 182 return;
167 } 183 }
168 const bool use_dynamic_port_allocation = device_port == 0; 184 const bool use_dynamic_port_allocation = device_port == 0;
169 if (!use_dynamic_port_allocation) { 185 if (!use_dynamic_port_allocation) {
170 const std::string controller_key = MakeHostControllerMapKey( 186 const std::string controller_key = MakeHostControllerMapKey(
171 adb_port, device_port); 187 adb_port, device_port);
172 if (controllers_.find(controller_key) != controllers_.end()) { 188 if (controllers_->find(controller_key) != controllers_->end()) {
173 LOG(INFO) << "Already forwarding device port " << device_port 189 LOG(INFO) << "Already forwarding device port " << device_port
174 << " to host port " << host_port; 190 << " to host port " << host_port;
175 SendMessage(base::StringPrintf("%d:%d", device_port, host_port), 191 SendMessage(base::StringPrintf("%d:%d", device_port, host_port),
176 client_socket.get()); 192 client_socket.get());
177 return; 193 return;
178 } 194 }
179 } 195 }
180 // Create a new host controller. 196 // Create a new host controller.
181 scoped_ptr<HostController> host_controller( 197 scoped_ptr<HostController> host_controller(
182 new HostController( 198 HostController::Create(
183 device_port, "127.0.0.1", host_port, adb_port, GetExitNotifierFD(), 199 device_port, host_port, adb_port, GetExitNotifierFD(),
184 base::Bind(&HostControllersManager::DeleteHostController, 200 base::Bind(&HostControllersManager::DeleteHostController,
185 base::Unretained(this)))); 201 weak_ptr_factory_.GetWeakPtr())));
186 if (!host_controller->Connect()) { 202 if (!host_controller.get()) {
187 has_failed_ = true; 203 has_failed_ = true;
188 SendMessage("ERROR: Connection to device failed.", client_socket.get()); 204 SendMessage("ERROR: Connection to device failed.", client_socket.get());
189 return; 205 return;
190 } 206 }
191 // Get the current allocated port. 207 // Get the current allocated port.
192 device_port = host_controller->device_port(); 208 device_port = host_controller->device_port();
193 LOG(INFO) << "Forwarding device port " << device_port << " to host port " 209 LOG(INFO) << "Forwarding device port " << device_port << " to host port "
194 << host_port; 210 << host_port;
195 const std::string msg = base::StringPrintf("%d:%d", device_port, host_port); 211 const std::string msg = base::StringPrintf("%d:%d", device_port, host_port);
196 if (!SendMessage(msg, client_socket.get())) 212 if (!SendMessage(msg, client_socket.get()))
197 return; 213 return;
198 host_controller->Start(); 214 host_controller->Start();
199 controllers_.insert( 215 controllers_->insert(
200 std::make_pair(MakeHostControllerMapKey(adb_port, device_port), 216 std::make_pair(MakeHostControllerMapKey(adb_port, device_port),
201 linked_ptr<HostController>(host_controller.release()))); 217 linked_ptr<HostController>(host_controller.release())));
202 } 218 }
203 219
204 int GetAdbPortForDevice(const std::string& device_serial) { 220 int GetAdbPortForDevice(const std::string& device_serial) {
205 base::hash_map<std::string, int>::const_iterator it = 221 base::hash_map<std::string, int>::const_iterator it =
206 device_serial_to_adb_port_map_.find(device_serial); 222 device_serial_to_adb_port_map_.find(device_serial);
207 if (it != device_serial_to_adb_port_map_.end()) 223 if (it != device_serial_to_adb_port_map_.end())
208 return it->second; 224 return it->second;
209 Socket bind_socket; 225 Socket bind_socket;
(...skipping 15 matching lines...) Expand all
225 } 241 }
226 242
227 bool SendMessage(const std::string& msg, Socket* client_socket) { 243 bool SendMessage(const std::string& msg, Socket* client_socket) {
228 bool result = client_socket->WriteString(msg); 244 bool result = client_socket->WriteString(msg);
229 DCHECK(result); 245 DCHECK(result);
230 if (!result) 246 if (!result)
231 has_failed_ = true; 247 has_failed_ = true;
232 return result; 248 return result;
233 } 249 }
234 250
251 base::WeakPtrFactory<HostControllersManager> weak_ptr_factory_;
235 base::hash_map<std::string, int> device_serial_to_adb_port_map_; 252 base::hash_map<std::string, int> device_serial_to_adb_port_map_;
236 HostControllerMap controllers_; 253 scoped_ptr<HostControllerMap> controllers_;
237 bool has_failed_; 254 bool has_failed_;
238 scoped_ptr<base::AtExitManager> at_exit_manager_; // Needed by base::Thread. 255 scoped_ptr<base::AtExitManager> at_exit_manager_; // Needed by base::Thread.
239 scoped_ptr<base::Thread> thread_; 256 scoped_ptr<base::Thread> thread_;
240 }; 257 };
241 258
242 class ServerDelegate : public Daemon::ServerDelegate { 259 class ServerDelegate : public Daemon::ServerDelegate {
243 public: 260 public:
244 ServerDelegate() : has_failed_(false) {} 261 ServerDelegate() : has_failed_(false) {}
245 262
246 bool has_failed() const { 263 bool has_failed() const {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 405
389 return client_delegate.has_failed() || daemon_delegate.has_failed(); 406 return client_delegate.has_failed() || daemon_delegate.has_failed();
390 } 407 }
391 408
392 } // namespace 409 } // namespace
393 } // namespace forwarder2 410 } // namespace forwarder2
394 411
395 int main(int argc, char** argv) { 412 int main(int argc, char** argv) {
396 return forwarder2::RunHostForwarder(argc, argv); 413 return forwarder2::RunHostForwarder(argc, argv);
397 } 414 }
OLDNEW
« no previous file with comments | « tools/android/forwarder2/host_controller.cc ('k') | tools/android/forwarder2/thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698