Chromium Code Reviews| Index: remoting/host/remoting_me2me_host.cc |
| diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc |
| index be25fa363bd9e0e28aa3ef1fa00777313f1a5ae9..404c248637c4d603ec59e787f1ead1ceb4aec1da 100644 |
| --- a/remoting/host/remoting_me2me_host.cc |
| +++ b/remoting/host/remoting_me2me_host.cc |
| @@ -28,6 +28,7 @@ |
| #include "ipc/ipc_channel_proxy.h" |
| #include "net/base/network_change_notifier.h" |
| #include "net/socket/ssl_server_socket.h" |
| +#include "remoting/base/auto_thread_task_runner.h" |
| #include "remoting/base/breakpad.h" |
| #include "remoting/base/constants.h" |
| #include "remoting/host/branding.h" |
| @@ -97,6 +98,10 @@ const char kOfficialOAuth2ClientId[] = |
| "440925447803-avn2sj1kc099s0r7v62je5s339mu0am1.apps.googleusercontent.com"; |
| const char kOfficialOAuth2ClientSecret[] = "Bgur6DFiOMM1h8x-AQpuTQlK"; |
| +void QuitMessageLoop(MessageLoop* message_loop) { |
| + message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| +} |
| + |
| } // namespace |
| namespace remoting { |
| @@ -105,8 +110,8 @@ class HostProcess |
| : public HeartbeatSender::Listener, |
| public IPC::Listener { |
| public: |
| - HostProcess() |
| - : message_loop_(MessageLoop::TYPE_UI), |
| + HostProcess(scoped_ptr<ChromotingHostContext> context) |
| + : context_(context.Pass()), |
| #ifdef OFFICIAL_BUILD |
| oauth_use_official_client_id_(true), |
| #else |
| @@ -123,9 +128,6 @@ class HostProcess |
| base::Unretained(this))) |
| #endif |
| { |
| - context_.reset( |
| - new ChromotingHostContext(message_loop_.message_loop_proxy())); |
| - context_->Start(); |
| network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); |
| config_updated_timer_.reset(new base::DelayTimer<HostProcess>( |
| FROM_HERE, base::TimeDelta::FromSeconds(2), this, |
| @@ -164,7 +166,7 @@ class HostProcess |
| } |
| void ConfigUpdated() { |
| - DCHECK(message_loop_.message_loop_proxy()->BelongsToCurrentThread()); |
| + DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| // Call ConfigUpdatedDelayed after a short delay, so that this object won't |
| // try to read the updated configuration file before it has been |
| @@ -175,7 +177,7 @@ class HostProcess |
| } |
| void ConfigUpdatedDelayed() { |
| - DCHECK(message_loop_.message_loop_proxy()->BelongsToCurrentThread()); |
| + DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| if (LoadConfig()) { |
| // PostTask to create new authenticator factory in case PIN has changed. |
| @@ -220,7 +222,7 @@ class HostProcess |
| #elif defined(OS_WIN) |
| scoped_refptr<base::files::FilePathWatcher::Delegate> delegate( |
| new ConfigChangedDelegate( |
| - message_loop_.message_loop_proxy(), |
| + context_->ui_task_runner(), |
| base::Bind(&HostProcess::ConfigUpdated, base::Unretained(this)))); |
| config_watcher_.reset(new base::files::FilePathWatcher()); |
| if (!config_watcher_->Watch(host_config_path_, delegate)) { |
| @@ -243,9 +245,16 @@ class HostProcess |
| return false; |
| } |
| - int Run() { |
| - if (!LoadConfig()) { |
| - return kInvalidHostConfigurationExitCode; |
| + void StartHostProcess() { |
| + DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| + |
| + if (!InitWithCommandLine(CommandLine::ForCurrentProcess()) || |
| + !LoadConfig()) { |
| + context_->network_task_runner()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&HostProcess::Shutdown, base::Unretained(this), |
| + kInvalidHostConfigurationExitCode)); |
| + return; |
| } |
| #if defined(OS_MACOSX) || defined(OS_WIN) |
| @@ -260,19 +269,28 @@ class HostProcess |
| base::Bind(&HostProcess::ListenForConfigChanges, |
| base::Unretained(this))); |
| #endif |
| - message_loop_.Run(); |
| + } |
| + |
| + int get_exit_code() const { return exit_code_; } |
| + |
| + private: |
| + void ShutdownHostProcess() { |
| + DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| + |
| + daemon_channel_.reset(); |
| #if defined(OS_MACOSX) || defined(OS_WIN) |
| host_user_interface_.reset(); |
| #endif |
| - daemon_channel_.reset(); |
| - base::WaitableEvent done_event(true, false); |
| - policy_watcher_->StopWatching(&done_event); |
| - done_event.Wait(); |
| - policy_watcher_.reset(); |
| + if (policy_watcher_.get()) { |
| + base::WaitableEvent done_event(true, false); |
| + policy_watcher_->StopWatching(&done_event); |
| + done_event.Wait(); |
| + policy_watcher_.reset(); |
| + } |
| - return exit_code_; |
| + context_.reset(); |
| } |
| // Overridden from HeartbeatSender::Listener |
| @@ -281,7 +299,6 @@ class HostProcess |
| Shutdown(kInvalidHostIdExitCode); |
| } |
| - private: |
| void StartWatchingPolicy() { |
| policy_watcher_.reset( |
| policy_hack::PolicyWatcher::Create(context_->file_task_runner())); |
| @@ -291,7 +308,7 @@ class HostProcess |
| // Read host config, returning true if successful. |
| bool LoadConfig() { |
| - DCHECK(message_loop_.message_loop_proxy()->BelongsToCurrentThread()); |
| + DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| // TODO(sergeyu): There is a potential race condition: this function is |
| // called on the main thread while the class members it mutates are used on |
| @@ -537,7 +554,7 @@ class HostProcess |
| // Invoked when the user uses the Disconnect windows to terminate |
| // the sessions. |
| void OnDisconnectRequested() { |
| - DCHECK(message_loop_.message_loop_proxy()->BelongsToCurrentThread()); |
| + DCHECK(context_->ui_task_runner()->BelongsToCurrentThread()); |
| host_->DisconnectAllClients(); |
| } |
| @@ -589,16 +606,20 @@ class HostProcess |
| // Destroy networking objects while we are on the network thread. |
| host_ = NULL; |
| + desktop_environment_.reset(); |
| host_event_logger_.reset(); |
| log_to_server_.reset(); |
| heartbeat_sender_.reset(); |
| signaling_connector_.reset(); |
| signal_strategy_.reset(); |
| - message_loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| + // Complete the rest of shutdown on the main thread. |
| + context_->ui_task_runner()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&HostProcess::ShutdownHostProcess, |
| + base::Unretained(this))); |
| } |
| - MessageLoop message_loop_; |
| scoped_ptr<ChromotingHostContext> context_; |
| scoped_ptr<IPC::ChannelProxy> daemon_channel_; |
| scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; |
| @@ -672,12 +693,11 @@ int main(int argc, char** argv) { |
| logging::APPEND_TO_OLD_LOG_FILE, |
| logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); |
| - const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
| - |
| #if defined(TOOLKIT_GTK) |
| // Required for any calls into GTK functions, such as the Disconnect and |
| // Continue windows, though these should not be used for the Me2Me case |
| // (crbug.com/104377). |
| + const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
| gfx::GtkInitFromCommandLine(*cmd_line); |
| #endif // TOOLKIT_GTK |
| @@ -686,15 +706,29 @@ int main(int argc, char** argv) { |
| net::EnableSSLServerSockets(); |
| #if defined(OS_LINUX) |
| - remoting::VideoFrameCapturer::EnableXDamage(true); |
| + remoting::VideoFrameCapturer::EnableXDamage(true); |
| #endif |
| - remoting::HostProcess me2me_host; |
| - if (!me2me_host.InitWithCommandLine(cmd_line)) { |
| - return remoting::kInvalidHostConfigurationExitCode; |
| - } |
| - |
| - return me2me_host.Run(); |
| + // Create the main message loop and start helper threads. |
| + MessageLoop message_loop(MessageLoop::TYPE_UI); |
| + base::Closure quit_message_loop = base::Bind(&QuitMessageLoop, |
| + base::Unretained(&message_loop)); |
|
Sergey Ulanov
2012/08/31 01:25:18
Do you really need Unretained here given that Quit
alexeypa (please no reviews)
2012/08/31 19:57:36
Done.
|
| + scoped_ptr<remoting::ChromotingHostContext> context( |
| + new remoting::ChromotingHostContext( |
| + new remoting::AutoThreadTaskRunner(message_loop.message_loop_proxy(), |
| + quit_message_loop))); |
| + if (!context->Start()) |
| + return remoting::kHostInitializationFailed; |
| + |
| + // Create the host process instance and run the rest of the initialization on |
| + // the main message loop. |
| + remoting::HostProcess me2me_host(context.Pass()); |
| + message_loop.PostTask( |
| + FROM_HERE, |
| + base::Bind(&remoting::HostProcess::StartHostProcess, |
| + base::Unretained(&me2me_host))); |
| + message_loop.Run(); |
| + return me2me_host.get_exit_code(); |
| } |
| #if defined(OS_WIN) |