summaryrefslogtreecommitdiffstats
path: root/remoting/host/win
diff options
context:
space:
mode:
authoralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-04 22:27:43 +0000
committeralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-04 22:27:43 +0000
commitef948e69b97c179af5eb69ae318714052230df4f (patch)
treecc76efb6983b1a5868f26769fb654185880f2805 /remoting/host/win
parent38091251bfc38e7ae748edbf66b13dd360f68bb4 (diff)
downloadchromium_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.cc60
-rw-r--r--remoting/host/win/host_service.h15
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_)();