Chromium Code Reviews| Index: remoting/host/wts_session_process_launcher_win.cc |
| diff --git a/remoting/host/wts_session_process_launcher_win.cc b/remoting/host/wts_session_process_launcher_win.cc |
| index 44fe38aa0a10f572a821e2a65f6ac879332b55d4..478ed5433dbddfec4810320139c961888dc0af20 100644 |
| --- a/remoting/host/wts_session_process_launcher_win.cc |
| +++ b/remoting/host/wts_session_process_launcher_win.cc |
| @@ -11,13 +11,15 @@ |
| #include <sddl.h> |
| #include <limits> |
| +#include "base/bind.h" |
| +#include "base/bind_helpers.h" |
| #include "base/command_line.h" |
| #include "base/logging.h" |
| +#include "base/message_loop_proxy.h" |
| #include "base/process_util.h" |
| #include "base/rand_util.h" |
| #include "base/string16.h" |
| #include "base/stringprintf.h" |
| -#include "base/threading/thread.h" |
| #include "base/utf_string_conversions.h" |
| #include "base/win/scoped_handle.h" |
| #include "base/win/scoped_process_information.h" |
| @@ -34,6 +36,10 @@ using base::TimeDelta; |
| namespace { |
| +// The exit code returned by the host process when its configuration is not |
| +// valid. |
| +const int kInvalidHostConfigurationExitCode = 1; |
| + |
| // The minimum and maximum delays between attempts to inject host process into |
| // a session. |
| const int kMaxLaunchDelaySeconds = 60; |
| @@ -247,9 +253,11 @@ namespace remoting { |
| WtsSessionProcessLauncher::WtsSessionProcessLauncher( |
| WtsConsoleMonitor* monitor, |
| const FilePath& host_binary, |
| - base::Thread* io_thread) |
| + scoped_refptr<base::MessageLoopProxy> main_message_loop, |
| + scoped_refptr<base::MessageLoopProxy> ipc_message_loop) |
| : host_binary_(host_binary), |
| - io_thread_(io_thread), |
| + main_message_loop_(main_message_loop), |
| + ipc_message_loop_(ipc_message_loop), |
| monitor_(monitor), |
| state_(StateDetached) { |
| monitor_->AddWtsConsoleObserver(this); |
| @@ -266,6 +274,7 @@ WtsSessionProcessLauncher::~WtsSessionProcessLauncher() { |
| } |
| void WtsSessionProcessLauncher::LaunchProcess() { |
| + DCHECK(main_message_loop_->BelongsToCurrentThread()); |
| DCHECK(state_ == StateStarting); |
| DCHECK(!timer_.IsRunning()); |
| DCHECK(process_.handle() == NULL); |
| @@ -282,7 +291,7 @@ void WtsSessionProcessLauncher::LaunchProcess() { |
| IPC::ChannelHandle(pipe.Get()), |
| IPC::Channel::MODE_SERVER, |
| this, |
| - io_thread_->message_loop_proxy().get())); |
| + ipc_message_loop_)); |
| // Create the host process command line passing the name of the IPC channel |
| // to use and copying known switches from the service's command line. |
| @@ -320,17 +329,34 @@ void WtsSessionProcessLauncher::LaunchProcess() { |
| } |
| void WtsSessionProcessLauncher::OnObjectSignaled(HANDLE object) { |
| + if (!main_message_loop_->BelongsToCurrentThread()) { |
| + main_message_loop_->PostTask( |
| + FROM_HERE, base::Bind(&WtsSessionProcessLauncher::OnObjectSignaled, |
| + base::Unretained(this), object)); |
|
Wez
2012/04/10 21:26:20
How to do you ensure there are no tasks posted to
alexeypa (please no reviews)
2012/04/10 22:18:16
Good question. The shutdown sequence is indeed scr
|
| + return; |
| + } |
| + |
| DCHECK(state_ == StateAttached); |
| DCHECK(!timer_.IsRunning()); |
| DCHECK(process_.handle() != NULL); |
| DCHECK(process_watcher_.GetWatchedObject() == NULL); |
| DCHECK(chromoting_channel_.get() != NULL); |
| + // Stop trying to restart the host process exited due misconfiguration. |
|
Wez
2012/04/10 21:26:20
typo: missing "if it", I think.
alexeypa (please no reviews)
2012/04/10 22:18:16
Done.
|
| + DWORD exit_code; |
| + bool stop_trying = GetExitCodeProcess(process_.handle(), &exit_code) && |
| + exit_code == kInvalidHostConfigurationExitCode; |
| + |
| // The host process has been terminated for some reason. The handle can now be |
| // closed. |
| process_.Close(); |
| chromoting_channel_.reset(); |
| + if (stop_trying) { |
| + monitor_->RemoveWtsConsoleObserver(this); |
|
Wez
2012/04/10 21:26:20
nit: Mention that once all observers are gone the
alexeypa (please no reviews)
2012/04/10 22:18:16
Done.
|
| + return; |
| + } |
| + |
| // Expand the backoff interval if the process has died quickly or reset it if |
| // it was up longer than the maximum backoff delay. |
| base::TimeDelta delta = base::Time::Now() - launch_time_; |
| @@ -361,6 +387,13 @@ bool WtsSessionProcessLauncher::OnMessageReceived(const IPC::Message& message) { |
| } |
| void WtsSessionProcessLauncher::OnSendSasToConsole() { |
| + if (!main_message_loop_->BelongsToCurrentThread()) { |
| + main_message_loop_->PostTask( |
| + FROM_HERE, base::Bind(&WtsSessionProcessLauncher::OnSendSasToConsole, |
| + base::Unretained(this))); |
| + return; |
| + } |
| + |
| if (state_ == StateAttached) { |
| if (sas_injector_.get() == NULL) { |
| sas_injector_ = SasInjector::Create(); |
| @@ -373,6 +406,7 @@ void WtsSessionProcessLauncher::OnSendSasToConsole() { |
| } |
| void WtsSessionProcessLauncher::OnSessionAttached(uint32 session_id) { |
| + DCHECK(main_message_loop_->BelongsToCurrentThread()); |
| DCHECK(state_ == StateDetached); |
| DCHECK(!timer_.IsRunning()); |
| DCHECK(process_.handle() == NULL); |
| @@ -410,6 +444,7 @@ void WtsSessionProcessLauncher::OnSessionAttached(uint32 session_id) { |
| } |
| void WtsSessionProcessLauncher::OnSessionDetached() { |
| + DCHECK(main_message_loop_->BelongsToCurrentThread()); |
| DCHECK(state_ == StateDetached || |
| state_ == StateStarting || |
| state_ == StateAttached); |