| 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..9a6d8d583280dd7cfdf2d934fe32fa5ed954b7e4 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_message_loop.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,18 +269,29 @@ class HostProcess
|
| base::Bind(&HostProcess::ListenForConfigChanges,
|
| base::Unretained(this)));
|
| #endif
|
| - message_loop_.Run();
|
| + }
|
| +
|
| + 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();
|
| + }
|
| +
|
| + context_.reset();
|
| + }
|
|
|
| + int Run(MessageLoop* message_loop) {
|
| + message_loop->Run();
|
| return exit_code_;
|
| }
|
|
|
| @@ -291,7 +311,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 +557,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 +609,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 +696,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 +709,28 @@ 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));
|
| + scoped_ptr<remoting::ChromotingHostContext> context(
|
| + new remoting::ChromotingHostContext(
|
| + new remoting::AutoMessageLoop(NULL, 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)));
|
| + return me2me_host.Run(&message_loop);
|
| }
|
|
|
| #if defined(OS_WIN)
|
|
|