diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-04 22:27:43 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-04 22:27:43 +0000 |
commit | ef948e69b97c179af5eb69ae318714052230df4f (patch) | |
tree | cc76efb6983b1a5868f26769fb654185880f2805 /remoting/host/win | |
parent | 38091251bfc38e7ae748edbf66b13dd360f68bb4 (diff) | |
download | chromium_src-ef948e69b97c179af5eb69ae318714052230df4f.zip chromium_src-ef948e69b97c179af5eb69ae318714052230df4f.tar.gz chromium_src-ef948e69b97c179af5eb69ae318714052230df4f.tar.bz2 |
[Chromoting] Introducing refcount-based life time management of the message loops in the service (daemon) and me2me host (network) processes.
This CL introduces AutoMessageLoop wrapper that provides control over life time of a message loop via scoped_refptr references. This scheme is useful in the cases when shutdown code has to run on a particular thread or when the OS requires resources (such as windows) to be freed before exiting a message loop.
The CL switches threads, owned by remoting::HostService, remoting::HostProcess and remoting::ChromotingHostContext, to refcount-based lifetime management. This change required updating tear-down sequences in remoting_me2me_host and the host plugin code.
BUG=134694
Review URL: https://chromiumcodereview.appspot.com/10829467
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154827 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/host/win')
-rw-r--r-- | remoting/host/win/host_service.cc | 60 | ||||
-rw-r--r-- | remoting/host/win/host_service.h | 15 |
2 files changed, 49 insertions, 26 deletions
diff --git a/remoting/host/win/host_service.cc b/remoting/host/win/host_service.cc index 87088fe..92dda1d 100644 --- a/remoting/host/win/host_service.cc +++ b/remoting/host/win/host_service.cc @@ -24,6 +24,7 @@ #include "base/threading/thread.h" #include "base/utf_string_conversions.h" #include "base/win/wrapped_window_proc.h" +#include "remoting/base/auto_thread_task_runner.h" #include "remoting/base/breakpad.h" #include "remoting/base/scoped_sc_handle_win.h" #include "remoting/base/stoppable.h" @@ -92,6 +93,10 @@ void usage(const FilePath& program_name) { UTF16ToWide(program_name.value()).c_str()); } +void QuitMessageLoop(MessageLoop* message_loop) { + message_loop->PostTask(FROM_HERE, MessageLoop::QuitClosure()); +} + } // namespace namespace remoting { @@ -120,7 +125,7 @@ void HostService::RemoveWtsConsoleObserver(WtsConsoleObserver* observer) { void HostService::OnChildStopped() { child_.reset(NULL); - main_task_runner_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); + main_task_runner_ = NULL; } void HostService::OnSessionChange() { @@ -196,21 +201,14 @@ int HostService::Run() { return (this->*run_routine_)(); } -void HostService::RunMessageLoop(MessageLoop* message_loop) { - // Launch the I/O thread. - base::Thread io_thread(kIoThreadName); - base::Thread::Options io_thread_options(MessageLoop::TYPE_IO, 0); - if (!io_thread.StartWithOptions(io_thread_options)) { - LOG(ERROR) << "Failed to start the I/O thread"; - stopped_event_.Signal(); - return; - } +void HostService::CreateLauncher( + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) { #if defined(REMOTING_MULTI_PROCESS) child_ = DaemonProcess::Create( main_task_runner_, - io_thread.message_loop_proxy(), + io_task_runner, base::Bind(&HostService::OnChildStopped, base::Unretained(this))).PassAs<Stoppable>(); @@ -221,15 +219,25 @@ void HostService::RunMessageLoop(MessageLoop* message_loop) { base::Bind(&HostService::OnChildStopped, base::Unretained(this)), this, main_task_runner_, - io_thread.message_loop_proxy())); + io_task_runner)); #endif // !defined(REMOTING_MULTI_PROCESS) +} + +void HostService::RunMessageLoop(MessageLoop* message_loop) { + // Launch the I/O thread. + base::Thread io_thread(kIoThreadName); + base::Thread::Options io_thread_options(MessageLoop::TYPE_IO, 0); + if (!io_thread.StartWithOptions(io_thread_options)) { + LOG(FATAL) << "Failed to start the I/O thread"; + return; + } + + CreateLauncher(new AutoThreadTaskRunner(io_thread.message_loop_proxy(), + main_task_runner_)); // Run the service. message_loop->Run(); - - // Release the control handler. - stopped_event_.Signal(); } int HostService::Elevate() { @@ -279,8 +287,11 @@ int HostService::RunAsService() { int HostService::RunInConsole() { MessageLoop message_loop(MessageLoop::TYPE_UI); - // Allow other threads to post to our message loop. - main_task_runner_ = message_loop.message_loop_proxy(); + // Keep a reference to the main message loop while it is used. Once the last + // reference is dropped, QuitClosure() will be posted to the loop. + main_task_runner_ = + new AutoThreadTaskRunner(message_loop.message_loop_proxy(), + base::Bind(&QuitMessageLoop, &message_loop)); int result = kErrorExitCode; @@ -327,6 +338,9 @@ int HostService::RunInConsole() { // Run the service. RunMessageLoop(&message_loop); + // Release the control handler. + stopped_event_.Signal(); + WTSUnRegisterSessionNotification(window); result = kSuccessExitCode; } @@ -375,11 +389,14 @@ DWORD WINAPI HostService::ServiceControlHandler(DWORD control, } VOID WINAPI HostService::ServiceMain(DWORD argc, WCHAR* argv[]) { - MessageLoop message_loop; + MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); - // Allow other threads to post to our message loop. + // Keep a reference to the main message loop while it is used. Once the last + // reference is dropped QuitClosure() will be posted to the loop. HostService* self = HostService::GetInstance(); - self->main_task_runner_ = message_loop.message_loop_proxy(); + self->main_task_runner_ = + new AutoThreadTaskRunner(message_loop.message_loop_proxy(), + base::Bind(&QuitMessageLoop, &message_loop)); // Register the service control handler. self->service_status_handle_ = @@ -416,6 +433,9 @@ VOID WINAPI HostService::ServiceMain(DWORD argc, WCHAR* argv[]) { // Run the service. self->RunMessageLoop(&message_loop); + // Release the control handler. + self->stopped_event_.Signal(); + // Tell SCM that the service is stopped. service_status.dwCurrentState = SERVICE_STOPPED; service_status.dwControlsAccepted = 0; diff --git a/remoting/host/win/host_service.h b/remoting/host/win/host_service.h index 9533f02..80bbc90 100644 --- a/remoting/host/win/host_service.h +++ b/remoting/host/win/host_service.h @@ -22,14 +22,13 @@ class SingleThreadTaskRunner; namespace remoting { -#if defined(REMOTING_MULTI_PROCESS) -class DaemonProcess; -#endif // defined(REMOTING_MULTI_PROCESS) - +class AutoThreadTaskRunner; class Stoppable; class WtsConsoleObserver; -#if !defined(REMOTING_MULTI_PROCESS) +#if defined(REMOTING_MULTI_PROCESS) +class DaemonProcess; +#else // !defined(REMOTING_MULTI_PROCESS) class WtsSessionProcessLauncher; #endif // !defined(REMOTING_MULTI_PROCESS) @@ -57,6 +56,10 @@ class HostService : public WtsConsoleMonitor { // Notifies the service of changes in session state. void OnSessionChange(); + // Creates the process launcher. + void CreateLauncher( + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); + // This is a common entry point to the main service loop called by both // RunAsService() and RunInConsole(). void RunMessageLoop(MessageLoop* message_loop); @@ -98,7 +101,7 @@ class HostService : public WtsConsoleMonitor { scoped_ptr<Stoppable> child_; // Service message loop. - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + scoped_refptr<AutoThreadTaskRunner> main_task_runner_; // The action routine to be executed. int (HostService::*run_routine_)(); |