Chromium Code Reviews| Index: remoting/host/host_service_win.cc |
| diff --git a/remoting/host/host_service_win.cc b/remoting/host/host_service_win.cc |
| index 41a35a3a226c391195614d1280ff1852dbb00795..241de8a1ced7f829ae06d0f2db17852e881bfb4d 100644 |
| --- a/remoting/host/host_service_win.cc |
| +++ b/remoting/host/host_service_win.cc |
| @@ -23,8 +23,11 @@ |
| #include "base/threading/thread.h" |
| #include "base/utf_string_conversions.h" |
| #include "base/win/wrapped_window_proc.h" |
| +#include "remoting/base/auto_message_loop.h" |
| +#include "remoting/base/auto_thread.h" |
| #include "remoting/base/breakpad.h" |
| #include "remoting/base/scoped_sc_handle_win.h" |
| +#include "remoting/base/shutdownable.h" |
| #include "remoting/host/branding.h" |
| #include "remoting/host/host_service_resource.h" |
| #include "remoting/host/usage_stats_consent.h" |
| @@ -82,11 +85,9 @@ namespace remoting { |
| HostService::HostService() : |
| console_session_id_(kInvalidSessionId), |
| - message_loop_(NULL), |
| run_routine_(&HostService::RunAsService), |
| service_name_(kWindowsServiceName), |
| service_status_handle_(0), |
| - shutting_down_(false), |
| stopped_event_(true, false) { |
| } |
| @@ -94,20 +95,20 @@ HostService::~HostService() { |
| } |
| void HostService::AddWtsConsoleObserver(WtsConsoleObserver* observer) { |
| - DCHECK(message_loop_->message_loop_proxy()->BelongsToCurrentThread()); |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| console_observers_.AddObserver(observer); |
| } |
| void HostService::RemoveWtsConsoleObserver(WtsConsoleObserver* observer) { |
| - DCHECK(message_loop_->message_loop_proxy()->BelongsToCurrentThread()); |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| console_observers_.RemoveObserver(observer); |
| +} |
| - // Stop the service if there are no more observers. |
| - if (!console_observers_.might_have_observers()) { |
| - message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| - } |
| +void HostService::OnLauncherShutdown(Shutdownable* /* launcher */) { |
| + launcher_.reset(NULL); |
| + message_loop_ = NULL; |
| } |
| void HostService::OnSessionChange() { |
| @@ -116,10 +117,7 @@ void HostService::OnSessionChange() { |
| // the console session is still the same every time a session change |
| // notification event is posted. This also takes care of coalescing multiple |
| // events into one since we look at the latest state. |
| - uint32 console_session_id = kInvalidSessionId; |
| - if (!shutting_down_) { |
| - console_session_id = WTSGetActiveConsoleSessionId(); |
| - } |
| + uint32 console_session_id = WTSGetActiveConsoleSessionId(); |
| if (console_session_id_ != console_session_id) { |
| if (console_session_id_ != kInvalidSessionId) { |
| FOR_EACH_OBSERVER(WtsConsoleObserver, |
| @@ -145,7 +143,9 @@ BOOL WINAPI HostService::ConsoleControlHandler(DWORD event) { |
| case CTRL_CLOSE_EVENT: |
| case CTRL_LOGOFF_EVENT: |
| case CTRL_SHUTDOWN_EVENT: |
| - self->message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| + self->message_loop_->PostTask(FROM_HERE, base::Bind( |
| + &WtsSessionProcessLauncher::Shutdown, |
| + base::Unretained(self->launcher_.get()))); |
| self->stopped_event_.Wait(); |
| return TRUE; |
| @@ -195,27 +195,31 @@ int HostService::Run() { |
| return (this->*run_routine_)(); |
| } |
| -void HostService::RunMessageLoop() { |
| +bool HostService::BeforeMessageLoop() { |
| // Launch the I/O thread. |
| - base::Thread io_thread(kIoThreadName); |
| + scoped_refptr<AutoThread> io_thread( |
| + new AutoThread(kIoThreadName, message_loop_)); |
|
Sergey Ulanov
2012/07/23 22:44:37
Why do we need thread to be refcounted?
Can we us
alexeypa (please no reviews)
2012/07/23 23:44:53
To make sure it is alive until all objects dependi
|
| + |
| base::Thread::Options io_thread_options(MessageLoop::TYPE_IO, 0); |
| - if (!io_thread.StartWithOptions(io_thread_options)) { |
| + if (!io_thread->StartWithOptions(io_thread_options)) { |
| LOG(FATAL) << "Failed to start the I/O thread"; |
| - shutting_down_ = true; |
| - stopped_event_.Signal(); |
| - return; |
| + return false; |
| } |
| - WtsSessionProcessLauncher launcher(this, host_binary_, |
| - message_loop_->message_loop_proxy(), |
| - io_thread.message_loop_proxy()); |
| - |
| + // Create the session process launcher. |
| + launcher_.reset(new WtsSessionProcessLauncher( |
| + base::Bind(&HostService::OnLauncherShutdown, base::Unretained(this)), |
| + this, |
| + host_binary_, |
| + message_loop_, |
| + io_thread)); |
| + return true; |
| +} |
| +void HostService::RunMessageLoop() { |
| // Run the service. |
| - message_loop_->Run(); |
| - |
| - // Clean up the observers by emulating detaching from the console. |
| - shutting_down_ = true; |
| - OnSessionChange(); |
| + if (BeforeMessageLoop()) { |
| + message_loop_->Run(); |
| + } |
| // Release the control handler. |
| stopped_event_.Signal(); |
| @@ -237,10 +241,10 @@ int HostService::RunAsService() { |
| } |
| int HostService::RunInConsole() { |
| - MessageLoop message_loop(MessageLoop::TYPE_UI); |
| + AutoMessageLoop message_loop(MessageLoop::TYPE_UI); |
|
Sergey Ulanov
2012/07/23 22:44:37
You are creating ref-counted object on stack. That
alexeypa (please no reviews)
2012/07/23 23:44:53
I control the destruction logic for this object. A
|
| // Allow other threads to post to our message loop. |
| - message_loop_ = &message_loop; |
| + message_loop_ = scoped_refptr<AutoMessageLoop>(&message_loop); |
| int result = kErrorExitCode; |
| @@ -304,8 +308,6 @@ cleanup: |
| // we can do about it now and the program is about to exit anyway. Even if |
| // it crashes nothing is going to be broken because of it. |
| SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, FALSE); |
| - |
| - message_loop_ = NULL; |
| return result; |
| } |
| @@ -320,7 +322,9 @@ DWORD WINAPI HostService::ServiceControlHandler(DWORD control, |
| case SERVICE_CONTROL_SHUTDOWN: |
| case SERVICE_CONTROL_STOP: |
| - self->message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
| + self->message_loop_->PostTask(FROM_HERE, base::Bind( |
| + &WtsSessionProcessLauncher::Shutdown, |
| + base::Unretained(self->launcher_.get()))); |
| self->stopped_event_.Wait(); |
| return NO_ERROR; |
| @@ -335,11 +339,11 @@ DWORD WINAPI HostService::ServiceControlHandler(DWORD control, |
| } |
| VOID WINAPI HostService::ServiceMain(DWORD argc, WCHAR* argv[]) { |
| - MessageLoop message_loop; |
| + AutoMessageLoop message_loop(MessageLoop::TYPE_DEFAULT); |
|
Sergey Ulanov
2012/07/23 22:44:37
Why do we need MessageLoop to be refcounted here?
alexeypa (please no reviews)
2012/07/23 23:44:53
It doe snot have to outlive ServiceMain(). It is r
|
| // Allow other threads to post to our message loop. |
| HostService* self = HostService::GetInstance(); |
| - self->message_loop_ = &message_loop; |
| + self->message_loop_ = scoped_refptr<AutoMessageLoop>(&message_loop); |
| // Register the service control handler. |
| self->service_status_handle_ = |
| @@ -385,8 +389,6 @@ VOID WINAPI HostService::ServiceMain(DWORD argc, WCHAR* argv[]) { |
| << "Failed to report service status to the service control manager"; |
| return; |
| } |
| - |
| - self->message_loop_ = NULL; |
| } |
| LRESULT CALLBACK HostService::SessionChangeNotificationProc(HWND hwnd, |