Commit 18c1dbb1 authored by alexeypa@chromium.org's avatar alexeypa@chromium.org

Introducing remoting::Stoppable helper base class implementing asynchronous...

Introducing remoting::Stoppable helper base class implementing asynchronous shutdown on a specific thread.


Review URL: https://chromiumcodereview.appspot.com/10796099

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149273 0039d316-1c4b-4281-b951-d872f2087c98
parent f53465f9
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/base/stoppable.h"
#include "base/message_loop.h"
#include "base/single_thread_task_runner.h"
namespace remoting {
Stoppable::Stoppable(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const base::Closure& stopped_callback)
: state_(kRunning),
stopped_callback_(stopped_callback),
task_runner_(task_runner) {
}
Stoppable::~Stoppable() {
DCHECK_EQ(state_, kStopped);
}
void Stoppable::Stop() {
DCHECK(task_runner_->BelongsToCurrentThread());
if (state_ == kRunning) {
state_ = kStopping;
DoStop();
}
}
void Stoppable::CompleteStopping() {
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK_EQ(state_, kStopping);
state_ = kStopped;
task_runner_->PostTask(FROM_HERE, stopped_callback_);
}
} // namespace remoting
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_BASE_STOPPABLE_H_
#define REMOTING_BASE_STOPPABLE_H_
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/ref_counted.h"
namespace base {
class SingleThreadTaskRunner;
} // namespace base
namespace remoting {
// A helper base class that implements asynchronous shutdown on a specific
// thread.
class Stoppable {
public:
// Constructs an object and stores the callback to be posted to |task_runner|
// once the object has been shutdown completely.
explicit Stoppable(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
const base::Closure& stopped_callback);
virtual ~Stoppable();
// Initiates shutdown. It can be called by both the owner of the object and
// the object itself resulting in the same shutdown sequence.
void Stop();
protected:
// Called by derived classes to notify about shutdown completion. Posts
// the completion task on |task_runner_| message loop.
void CompleteStopping();
// Derived classes have to override this method to implement the shutdown
// logic.
virtual void DoStop() = 0;
enum State {
kRunning,
kStopping,
kStopped
};
State stoppable_state() const { return state_; }
private:
State state_;
// A callback to be called when shutdown is completed.
base::Closure stopped_callback_;
// The target task runner where the shutdown notification will be posted.
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
DISALLOW_COPY_AND_ASSIGN(Stoppable);
};
} // namespace remoting
#endif // REMOTING_BASE_STOPPABLE_H_
...@@ -19,12 +19,14 @@ ...@@ -19,12 +19,14 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/single_thread_task_runner.h"
#include "base/stringprintf.h" #include "base/stringprintf.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#include "base/win/wrapped_window_proc.h" #include "base/win/wrapped_window_proc.h"
#include "remoting/base/breakpad.h" #include "remoting/base/breakpad.h"
#include "remoting/base/scoped_sc_handle_win.h" #include "remoting/base/scoped_sc_handle_win.h"
#include "remoting/base/stoppable.h"
#include "remoting/host/branding.h" #include "remoting/host/branding.h"
#include "remoting/host/usage_stats_consent.h" #include "remoting/host/usage_stats_consent.h"
#include "remoting/host/win/host_service_resource.h" #include "remoting/host/win/host_service_resource.h"
...@@ -82,11 +84,9 @@ namespace remoting { ...@@ -82,11 +84,9 @@ namespace remoting {
HostService::HostService() : HostService::HostService() :
console_session_id_(kInvalidSessionId), console_session_id_(kInvalidSessionId),
message_loop_(NULL),
run_routine_(&HostService::RunAsService), run_routine_(&HostService::RunAsService),
service_name_(kWindowsServiceName), service_name_(kWindowsServiceName),
service_status_handle_(0), service_status_handle_(0),
shutting_down_(false),
stopped_event_(true, false) { stopped_event_(true, false) {
} }
...@@ -94,20 +94,20 @@ HostService::~HostService() { ...@@ -94,20 +94,20 @@ HostService::~HostService() {
} }
void HostService::AddWtsConsoleObserver(WtsConsoleObserver* observer) { void HostService::AddWtsConsoleObserver(WtsConsoleObserver* observer) {
DCHECK(message_loop_->message_loop_proxy()->BelongsToCurrentThread()); DCHECK(main_task_runner_->BelongsToCurrentThread());
console_observers_.AddObserver(observer); console_observers_.AddObserver(observer);
} }
void HostService::RemoveWtsConsoleObserver(WtsConsoleObserver* observer) { void HostService::RemoveWtsConsoleObserver(WtsConsoleObserver* observer) {
DCHECK(message_loop_->message_loop_proxy()->BelongsToCurrentThread()); DCHECK(main_task_runner_->BelongsToCurrentThread());
console_observers_.RemoveObserver(observer); console_observers_.RemoveObserver(observer);
}
// Stop the service if there are no more observers. void HostService::OnLauncherShutdown() {
if (!console_observers_.might_have_observers()) { launcher_.reset(NULL);
message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); main_task_runner_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
}
} }
void HostService::OnSessionChange() { void HostService::OnSessionChange() {
...@@ -116,10 +116,7 @@ void HostService::OnSessionChange() { ...@@ -116,10 +116,7 @@ void HostService::OnSessionChange() {
// the console session is still the same every time a session change // the console session is still the same every time a session change
// notification event is posted. This also takes care of coalescing multiple // notification event is posted. This also takes care of coalescing multiple
// events into one since we look at the latest state. // events into one since we look at the latest state.
uint32 console_session_id = kInvalidSessionId; uint32 console_session_id = WTSGetActiveConsoleSessionId();
if (!shutting_down_) {
console_session_id = WTSGetActiveConsoleSessionId();
}
if (console_session_id_ != console_session_id) { if (console_session_id_ != console_session_id) {
if (console_session_id_ != kInvalidSessionId) { if (console_session_id_ != kInvalidSessionId) {
FOR_EACH_OBSERVER(WtsConsoleObserver, FOR_EACH_OBSERVER(WtsConsoleObserver,
...@@ -145,7 +142,9 @@ BOOL WINAPI HostService::ConsoleControlHandler(DWORD event) { ...@@ -145,7 +142,9 @@ BOOL WINAPI HostService::ConsoleControlHandler(DWORD event) {
case CTRL_CLOSE_EVENT: case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT: case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT: case CTRL_SHUTDOWN_EVENT:
self->message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); self->main_task_runner_->PostTask(FROM_HERE, base::Bind(
&WtsSessionProcessLauncher::Stop,
base::Unretained(self->launcher_.get())));
self->stopped_event_.Wait(); self->stopped_event_.Wait();
return TRUE; return TRUE;
...@@ -195,27 +194,26 @@ int HostService::Run() { ...@@ -195,27 +194,26 @@ int HostService::Run() {
return (this->*run_routine_)(); return (this->*run_routine_)();
} }
void HostService::RunMessageLoop() { void HostService::RunMessageLoop(MessageLoop* message_loop) {
// Launch the I/O thread. // Launch the I/O thread.
base::Thread io_thread(kIoThreadName); base::Thread io_thread(kIoThreadName);
base::Thread::Options io_thread_options(MessageLoop::TYPE_IO, 0); 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"; LOG(FATAL) << "Failed to start the I/O thread";
shutting_down_ = true;
stopped_event_.Signal(); stopped_event_.Signal();
return; return;
} }
WtsSessionProcessLauncher launcher(this, host_binary_, // Create the session process launcher.
message_loop_->message_loop_proxy(), launcher_.reset(new WtsSessionProcessLauncher(
io_thread.message_loop_proxy()); base::Bind(&HostService::OnLauncherShutdown, base::Unretained(this)),
this,
host_binary_,
main_task_runner_,
io_thread.message_loop_proxy()));
// Run the service. // Run the service.
message_loop_->Run(); message_loop->Run();
// Clean up the observers by emulating detaching from the console.
shutting_down_ = true;
OnSessionChange();
// Release the control handler. // Release the control handler.
stopped_event_.Signal(); stopped_event_.Signal();
...@@ -240,7 +238,7 @@ int HostService::RunInConsole() { ...@@ -240,7 +238,7 @@ int HostService::RunInConsole() {
MessageLoop message_loop(MessageLoop::TYPE_UI); MessageLoop message_loop(MessageLoop::TYPE_UI);
// Allow other threads to post to our message loop. // Allow other threads to post to our message loop.
message_loop_ = &message_loop; main_task_runner_ = message_loop.message_loop_proxy();
int result = kErrorExitCode; int result = kErrorExitCode;
...@@ -278,14 +276,14 @@ int HostService::RunInConsole() { ...@@ -278,14 +276,14 @@ int HostService::RunInConsole() {
// Post a dummy session change notification to peek up the current console // Post a dummy session change notification to peek up the current console
// session. // session.
message_loop.PostTask(FROM_HERE, base::Bind( main_task_runner_->PostTask(FROM_HERE, base::Bind(
&HostService::OnSessionChange, base::Unretained(this))); &HostService::OnSessionChange, base::Unretained(this)));
// Subscribe to session change notifications. // Subscribe to session change notifications.
if (WTSRegisterSessionNotification(window, if (WTSRegisterSessionNotification(window,
NOTIFY_FOR_ALL_SESSIONS) != FALSE) { NOTIFY_FOR_ALL_SESSIONS) != FALSE) {
// Run the service. // Run the service.
RunMessageLoop(); RunMessageLoop(&message_loop);
WTSUnRegisterSessionNotification(window); WTSUnRegisterSessionNotification(window);
result = kSuccessExitCode; result = kSuccessExitCode;
...@@ -305,7 +303,6 @@ cleanup: ...@@ -305,7 +303,6 @@ cleanup:
// it crashes nothing is going to be broken because of it. // it crashes nothing is going to be broken because of it.
SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, FALSE); SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, FALSE);
message_loop_ = NULL;
return result; return result;
} }
...@@ -320,12 +317,14 @@ DWORD WINAPI HostService::ServiceControlHandler(DWORD control, ...@@ -320,12 +317,14 @@ DWORD WINAPI HostService::ServiceControlHandler(DWORD control,
case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_STOP:
self->message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); self->main_task_runner_->PostTask(FROM_HERE, base::Bind(
&WtsSessionProcessLauncher::Stop,
base::Unretained(self->launcher_.get())));
self->stopped_event_.Wait(); self->stopped_event_.Wait();
return NO_ERROR; return NO_ERROR;
case SERVICE_CONTROL_SESSIONCHANGE: case SERVICE_CONTROL_SESSIONCHANGE:
self->message_loop_->PostTask(FROM_HERE, base::Bind( self->main_task_runner_->PostTask(FROM_HERE, base::Bind(
&HostService::OnSessionChange, base::Unretained(self))); &HostService::OnSessionChange, base::Unretained(self)));
return NO_ERROR; return NO_ERROR;
...@@ -339,7 +338,7 @@ VOID WINAPI HostService::ServiceMain(DWORD argc, WCHAR* argv[]) { ...@@ -339,7 +338,7 @@ VOID WINAPI HostService::ServiceMain(DWORD argc, WCHAR* argv[]) {
// Allow other threads to post to our message loop. // Allow other threads to post to our message loop.
HostService* self = HostService::GetInstance(); HostService* self = HostService::GetInstance();
self->message_loop_ = &message_loop; self->main_task_runner_ = message_loop.message_loop_proxy();
// Register the service control handler. // Register the service control handler.
self->service_status_handle_ = self->service_status_handle_ =
...@@ -370,11 +369,11 @@ VOID WINAPI HostService::ServiceMain(DWORD argc, WCHAR* argv[]) { ...@@ -370,11 +369,11 @@ VOID WINAPI HostService::ServiceMain(DWORD argc, WCHAR* argv[]) {
// Post a dummy session change notification to peek up the current console // Post a dummy session change notification to peek up the current console
// session. // session.
message_loop.PostTask(FROM_HERE, base::Bind( self->main_task_runner_->PostTask(FROM_HERE, base::Bind(
&HostService::OnSessionChange, base::Unretained(self))); &HostService::OnSessionChange, base::Unretained(self)));
// Run the service. // Run the service.
self->RunMessageLoop(); self->RunMessageLoop(&message_loop);
// Tell SCM that the service is stopped. // Tell SCM that the service is stopped.
service_status.dwCurrentState = SERVICE_STOPPED; service_status.dwCurrentState = SERVICE_STOPPED;
...@@ -385,8 +384,6 @@ VOID WINAPI HostService::ServiceMain(DWORD argc, WCHAR* argv[]) { ...@@ -385,8 +384,6 @@ VOID WINAPI HostService::ServiceMain(DWORD argc, WCHAR* argv[]) {
<< "Failed to report service status to the service control manager"; << "Failed to report service status to the service control manager";
return; return;
} }
self->message_loop_ = NULL;
} }
LRESULT CALLBACK HostService::SessionChangeNotificationProc(HWND hwnd, LRESULT CALLBACK HostService::SessionChangeNotificationProc(HWND hwnd,
......
...@@ -8,18 +8,24 @@ ...@@ -8,18 +8,24 @@
#include <windows.h> #include <windows.h>
#include "base/file_path.h" #include "base/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "remoting/host/win/wts_console_monitor.h" #include "remoting/host/win/wts_console_monitor.h"
class CommandLine; class CommandLine;
class MessageLoop; class MessageLoop;
namespace base {
class SingleThreadTaskRunner;
} // namespace base
namespace remoting { namespace remoting {
class Stoppable;
class WtsConsoleObserver; class WtsConsoleObserver;
class WtsSessionProcessLauncher;
class HostService : public WtsConsoleMonitor { class HostService : public WtsConsoleMonitor {
public: public:
...@@ -40,12 +46,14 @@ class HostService : public WtsConsoleMonitor { ...@@ -40,12 +46,14 @@ class HostService : public WtsConsoleMonitor {
HostService(); HostService();
~HostService(); ~HostService();
void OnLauncherShutdown();
// Notifies the service of changes in session state. // Notifies the service of changes in session state.
void OnSessionChange(); void OnSessionChange();
// This is a common entry point to the main service loop called by both // This is a common entry point to the main service loop called by both
// RunAsService() and RunInConsole(). // RunAsService() and RunInConsole().
void RunMessageLoop(); void RunMessageLoop(MessageLoop* message_loop);
// This function handshakes with the service control manager and starts // This function handshakes with the service control manager and starts
// the service. // the service.
...@@ -78,11 +86,13 @@ class HostService : public WtsConsoleMonitor { ...@@ -78,11 +86,13 @@ class HostService : public WtsConsoleMonitor {
// to the physical console. // to the physical console.
ObserverList<WtsConsoleObserver> console_observers_; ObserverList<WtsConsoleObserver> console_observers_;
scoped_ptr<WtsSessionProcessLauncher> launcher_;
// The host binary name. // The host binary name.
FilePath host_binary_; FilePath host_binary_;
// Service message loop. // Service message loop.
MessageLoop* message_loop_; scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
// The action routine to be executed. // The action routine to be executed.
int (HostService::*run_routine_)(); int (HostService::*run_routine_)();
...@@ -93,9 +103,6 @@ class HostService : public WtsConsoleMonitor { ...@@ -93,9 +103,6 @@ class HostService : public WtsConsoleMonitor {
// The service status handle. // The service status handle.
SERVICE_STATUS_HANDLE service_status_handle_; SERVICE_STATUS_HANDLE service_status_handle_;
// True if the service is being stopped.
bool shutting_down_;
// A waitable event that is used to wait until the service is stopped. // A waitable event that is used to wait until the service is stopped.
base::WaitableEvent stopped_event_; base::WaitableEvent stopped_event_;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/message_loop_proxy.h" #include "base/single_thread_task_runner.h"
#include "base/process_util.h" #include "base/process_util.h"
#include "base/rand_util.h" #include "base/rand_util.h"
#include "base/stringprintf.h" #include "base/stringprintf.h"
...@@ -212,11 +212,13 @@ namespace remoting { ...@@ -212,11 +212,13 @@ namespace remoting {
const uint32 kInvalidSessionId = 0xffffffff; const uint32 kInvalidSessionId = 0xffffffff;
WtsSessionProcessLauncher::WtsSessionProcessLauncher( WtsSessionProcessLauncher::WtsSessionProcessLauncher(
const base::Closure& stopped_callback,
WtsConsoleMonitor* monitor, WtsConsoleMonitor* monitor,
const FilePath& host_binary, const FilePath& host_binary,
scoped_refptr<base::MessageLoopProxy> main_message_loop, scoped_refptr<base::SingleThreadTaskRunner> main_message_loop,
scoped_refptr<base::MessageLoopProxy> ipc_message_loop) scoped_refptr<base::SingleThreadTaskRunner> ipc_message_loop)
: host_binary_(host_binary), : Stoppable(main_message_loop, stopped_callback),
host_binary_(host_binary),
main_message_loop_(main_message_loop), main_message_loop_(main_message_loop),
ipc_message_loop_(ipc_message_loop), ipc_message_loop_(ipc_message_loop),
monitor_(monitor), monitor_(monitor),
...@@ -225,14 +227,16 @@ WtsSessionProcessLauncher::WtsSessionProcessLauncher( ...@@ -225,14 +227,16 @@ WtsSessionProcessLauncher::WtsSessionProcessLauncher(
} }
WtsSessionProcessLauncher::~WtsSessionProcessLauncher() { WtsSessionProcessLauncher::~WtsSessionProcessLauncher() {
monitor_->RemoveWtsConsoleObserver(this);
if (state_ != StateDetached) {
OnSessionDetached();
}
DCHECK(state_ == StateDetached); DCHECK(state_ == StateDetached);
DCHECK(!timer_.IsRunning()); DCHECK(!timer_.IsRunning());
DCHECK(process_.handle() == NULL); DCHECK(process_.handle() == NULL);
DCHECK(process_watcher_.GetWatchedObject() == NULL); DCHECK(process_watcher_.GetWatchedObject() == NULL);
DCHECK(chromoting_channel_.get() == NULL); DCHECK(chromoting_channel_.get() == NULL);
if (monitor_ != NULL) {
monitor_->RemoveWtsConsoleObserver(this);
}
} }
void WtsSessionProcessLauncher::LaunchProcess() { void WtsSessionProcessLauncher::LaunchProcess() {
...@@ -328,12 +332,7 @@ void WtsSessionProcessLauncher::OnObjectSignaled(HANDLE object) { ...@@ -328,12 +332,7 @@ void WtsSessionProcessLauncher::OnObjectSignaled(HANDLE object) {
state_ = StateStarting; state_ = StateStarting;
if (stop_trying) { if (stop_trying) {
OnSessionDetached(); Stop();
// N.B. The service will stop once the last observer is removed from
// the list.
monitor_->RemoveWtsConsoleObserver(this);
monitor_ = NULL;
return; return;
} }
...@@ -386,6 +385,11 @@ void WtsSessionProcessLauncher::OnSendSasToConsole() { ...@@ -386,6 +385,11 @@ void WtsSessionProcessLauncher::OnSendSasToConsole() {
void WtsSessionProcessLauncher::OnSessionAttached(uint32 session_id) { void WtsSessionProcessLauncher::OnSessionAttached(uint32 session_id) {
DCHECK(main_message_loop_->BelongsToCurrentThread()); DCHECK(main_message_loop_->BelongsToCurrentThread());
if (stoppable_state() != Stoppable::kRunning) {
return;
}
DCHECK(state_ == StateDetached); DCHECK(state_ == StateDetached);
DCHECK(!timer_.IsRunning()); DCHECK(!timer_.IsRunning());
DCHECK(process_.handle() == NULL); DCHECK(process_.handle() == NULL);
...@@ -463,4 +467,12 @@ void WtsSessionProcessLauncher::OnSessionDetached() { ...@@ -463,4 +467,12 @@ void WtsSessionProcessLauncher::OnSessionDetached() {
session_token_.Close(); session_token_.Close();
} }
void WtsSessionProcessLauncher::DoStop() {
if (state_ != StateDetached) {
OnSessionDetached();
}
CompleteStopping();
}
} // namespace remoting } // namespace remoting
...@@ -18,11 +18,11 @@ ...@@ -18,11 +18,11 @@
#include "base/win/scoped_handle.h" #include "base/win/scoped_handle.h"
#include "base/win/object_watcher.h" #include "base/win/object_watcher.h"
#include "ipc/ipc_channel.h" #include "ipc/ipc_channel.h"
#include "remoting/base/stoppable.h"
#include "remoting/host/win/wts_console_observer.h" #include "remoting/host/win/wts_console_observer.h"
namespace base { namespace base {
class MessageLoopProxy; class SingleThreadTaskRunner;
} // namespace base } // namespace base
namespace IPC { namespace IPC {
...@@ -39,7 +39,8 @@ class SasInjector; ...@@ -39,7 +39,8 @@ class SasInjector;
class WtsConsoleMonitor; class WtsConsoleMonitor;
class WtsSessionProcessLauncher class WtsSessionProcessLauncher
: public base::win::ObjectWatcher::Delegate, : public Stoppable,
public base::win::ObjectWatcher::Delegate,
public IPC::Listener, public IPC::Listener,
public WtsConsoleObserver { public WtsConsoleObserver {
public: public:
...@@ -48,10 +49,11 @@ class WtsSessionProcessLauncher ...@@ -48,10 +49,11 @@ class WtsSessionProcessLauncher
// |monitor| should happen on |main_message_loop|. |ipc_message_loop| has // |monitor| should happen on |main_message_loop|. |ipc_message_loop| has
// to be an I/O message loop. // to be an I/O message loop.
WtsSessionProcessLauncher( WtsSessionProcessLauncher(
const base::Closure& stopped_callback,
WtsConsoleMonitor* monitor, WtsConsoleMonitor* monitor,
const FilePath& host_binary, const FilePath& host_binary,
scoped_refptr<base::MessageLoopProxy> main_message_loop, scoped_refptr<base::SingleThreadTaskRunner> main_message_loop,
scoped_refptr<base::MessageLoopProxy> ipc_message_loop); scoped_refptr<base::SingleThreadTaskRunner> ipc_message_loop);
virtual ~WtsSessionProcessLauncher(); virtual ~WtsSessionProcessLauncher();
...@@ -65,6 +67,10 @@ class WtsSessionProcessLauncher ...@@ -65,6 +67,10 @@ class WtsSessionProcessLauncher
virtual void OnSessionAttached(uint32 session_id) OVERRIDE; virtual void OnSessionAttached(uint32 session_id) OVERRIDE;
virtual void OnSessionDetached() OVERRIDE; virtual void OnSessionDetached() OVERRIDE;
protected:
// Stoppable implementation.
virtual void DoStop() OVERRIDE;
private: private:
// Attempts to launch the host process in the current console session. // Attempts to launch the host process in the current console session.
// Schedules next launch attempt if creation of the process fails for any // Schedules next launch attempt if creation of the process fails for any
...@@ -88,10 +94,10 @@ class WtsSessionProcessLauncher ...@@ -88,10 +94,10 @@ class WtsSessionProcessLauncher
base::OneShotTimer<WtsSessionProcessLauncher> timer_; base::OneShotTimer<WtsSessionProcessLauncher> timer_;
// The main service message loop. // The main service message loop.
scoped_refptr<base::MessageLoopProxy> main_message_loop_; scoped_refptr<base::SingleThreadTaskRunner> main_message_loop_;
// Message loop used by the IPC channel. // Message loop used by the IPC channel.
scoped_refptr<base::MessageLoopProxy> ipc_message_loop_; scoped_refptr<base::SingleThreadTaskRunner> ipc_message_loop_;
// This pointer is used to unsubscribe from session attach and detach events. // This pointer is used to unsubscribe from session attach and detach events.
WtsConsoleMonitor* monitor_; WtsConsoleMonitor* monitor_;
......
...@@ -584,6 +584,7 @@ ...@@ -584,6 +584,7 @@
'../base/base.gyp:base_static', '../base/base.gyp:base_static',
'../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
'../ipc/ipc.gyp:ipc', '../ipc/ipc.gyp:ipc',
'remoting_base',
'remoting_breakpad', 'remoting_breakpad',
'remoting_version_resources', 'remoting_version_resources',
], ],
...@@ -1165,6 +1166,8 @@ ...@@ -1165,6 +1166,8 @@
'base/rate_counter.h', 'base/rate_counter.h',
'base/running_average.cc', 'base/running_average.cc',
'base/running_average.h', 'base/running_average.h',
'base/stoppable.cc',
'base/stoppable.h',
'base/util.cc', 'base/util.cc',
'base/util.h', 'base/util.h',
], ],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment