| Index: tools/android/forwarder2/device_forwarder_main.cc
|
| diff --git a/tools/android/forwarder2/device_forwarder_main.cc b/tools/android/forwarder2/device_forwarder_main.cc
|
| index 5c94769f8e2b3c3c1b88fafbdf431231901a1fd3..cad46f465a686922ca318f19783c7b0ee801c332 100644
|
| --- a/tools/android/forwarder2/device_forwarder_main.cc
|
| +++ b/tools/android/forwarder2/device_forwarder_main.cc
|
| @@ -48,6 +48,25 @@ class ServerDelegate : public Daemon::ServerDelegate {
|
| public:
|
| ServerDelegate() : initialized_(false) {}
|
|
|
| + virtual ~ServerDelegate() {
|
| + if (!controller_thread_.get())
|
| + return;
|
| + // The DeviceController instance, if any, is constructed on the controller
|
| + // thread. Make sure that it gets deleted on that same thread. Note that
|
| + // DeleteSoon() is not used here since it would imply reading |controller_|
|
| + // from the main thread while it's set on the internal thread.
|
| + controller_thread_->message_loop_proxy()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&ServerDelegate::DeleteControllerOnInternalThread,
|
| + base::Unretained(this)));
|
| + }
|
| +
|
| + void DeleteControllerOnInternalThread() {
|
| + DCHECK(
|
| + controller_thread_->message_loop_proxy()->RunsTasksOnCurrentThread());
|
| + controller_.reset();
|
| + }
|
| +
|
| // Daemon::ServerDelegate:
|
| virtual void Init() OVERRIDE {
|
| DCHECK(!g_notifier);
|
| @@ -65,31 +84,30 @@ class ServerDelegate : public Daemon::ServerDelegate {
|
| }
|
| controller_thread_->message_loop()->PostTask(
|
| FROM_HERE,
|
| - base::Bind(&ServerDelegate::StartController, GetExitNotifierFD(),
|
| - base::Passed(&client_socket)));
|
| + base::Bind(&ServerDelegate::StartController, base::Unretained(this),
|
| + GetExitNotifierFD(), base::Passed(&client_socket)));
|
| initialized_ = true;
|
| }
|
|
|
| private:
|
| - static void StartController(int exit_notifier_fd,
|
| - scoped_ptr<Socket> client_socket) {
|
| - forwarder2::DeviceController controller(exit_notifier_fd);
|
| - if (!controller.Init(kUnixDomainSocketPath)) {
|
| + void StartController(int exit_notifier_fd, scoped_ptr<Socket> client_socket) {
|
| + DCHECK(!controller_.get());
|
| + scoped_ptr<DeviceController> controller(
|
| + DeviceController::Create(kUnixDomainSocketPath, exit_notifier_fd));
|
| + if (!controller.get()) {
|
| client_socket->WriteString(
|
| base::StringPrintf("ERROR: Could not initialize device controller "
|
| "with ADB socket path: %s",
|
| kUnixDomainSocketPath));
|
| return;
|
| }
|
| + controller_.swap(controller);
|
| + controller_->Start();
|
| client_socket->WriteString("OK");
|
| client_socket->Close();
|
| - // Note that the following call is blocking which explains why the device
|
| - // controller has to live on a separate thread (so that the daemon command
|
| - // server is not blocked).
|
| - controller.Start();
|
| }
|
|
|
| - base::AtExitManager at_exit_manager_; // Used by base::Thread.
|
| + scoped_ptr<DeviceController> controller_;
|
| scoped_ptr<base::Thread> controller_thread_;
|
| bool initialized_;
|
| };
|
| @@ -128,6 +146,7 @@ int RunDeviceForwarder(int argc, char** argv) {
|
| std::cerr << "Usage: device_forwarder [--kill-server]" << std::endl;
|
| return 1;
|
| }
|
| + base::AtExitManager at_exit_manager; // Used by base::Thread.
|
| ClientDelegate client_delegate;
|
| ServerDelegate daemon_delegate;
|
| const char kLogFilePath[] = ""; // Log to logcat.
|
|
|