15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/win/worker_process_launcher.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/location.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "remoting/host/chromoting_messages.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "remoting/host/host_exit_codes.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/host/worker_process_ipc_delegate.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::win::ScopedHandle; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const net::BackoffEntry::Policy kDefaultBackoffPolicy = { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Number of initial errors (in sequence) to ignore before applying 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exponential back-off rules. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initial delay for exponential back-off in ms. 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 100, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Factor by which the waiting time will be multiplied. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fuzzing percentage. ex: 10% will spread requests randomly 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // between 90%-100% of the calculated time. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Maximum amount of time we are willing to delay our request in ms. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 60000, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Time to keep an entry from being discarded even when it 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has no significant state, -1 to never discard. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) -1, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't use initial delay unless the last request was an error. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kKillProcessTimeoutSeconds = 5; 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kLaunchResultTimeoutSeconds = 5; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WorkerProcessLauncher::Delegate::~Delegate() { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)WorkerProcessLauncher::WorkerProcessLauncher( 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate, 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WorkerProcessIpcDelegate* ipc_handler) 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : ipc_handler_(ipc_handler), 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_delegate_(launcher_delegate.Pass()), 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) exit_code_(CONTROL_C_EXIT), 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipc_enabled_(false), 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kill_process_timeout_( 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromSeconds(kKillProcessTimeoutSeconds)), 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) launch_backoff_(&kDefaultBackoffPolicy) { 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(ipc_handler_ != NULL); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LaunchWorker(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)WorkerProcessLauncher::~WorkerProcessLauncher() { 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ipc_handler_ = NULL; 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StopWorker(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WorkerProcessLauncher::Crash( 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const tracked_objects::Location& location) { 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ask the worker process to crash voluntarily if it is still connected. 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ipc_enabled_) { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Send(new ChromotingDaemonMsg_Crash(location.function_name(), 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) location.file_name(), 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) location.line_number())); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Close the channel and ignore any not yet processed messages. 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) launcher_delegate_->CloseChannel(); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ipc_enabled_ = false; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Give the worker process some time to crash. 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!kill_process_timer_.IsRunning()) { 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kill_process_timer_.Start(FROM_HERE, kill_process_timeout_, this, 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &WorkerProcessLauncher::StopWorker); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WorkerProcessLauncher::Send(IPC::Message* message) { 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ipc_enabled_) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launcher_delegate_->Send(message); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete message; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WorkerProcessLauncher::OnProcessLaunched( 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::win::ScopedHandle worker_process) { 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!ipc_enabled_); 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!launch_timer_.IsRunning()); 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!process_watcher_.GetWatchedObject()); 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!worker_process_.IsValid()); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!process_watcher_.StartWatching(worker_process.Get(), this)) { 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StopWorker(); 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ipc_enabled_ = true; 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) worker_process_ = worker_process.Pass(); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WorkerProcessLauncher::OnFatalError() { 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopWorker(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool WorkerProcessLauncher::OnMessageReceived( 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const IPC::Message& message) { 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ipc_enabled_) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ipc_handler_->OnMessageReceived(message); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WorkerProcessLauncher::OnChannelConnected(int32 peer_pid) { 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ipc_enabled_) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can result in |this| being deleted, so this call must be the last in 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this method. 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ipc_handler_->OnChannelConnected(peer_pid); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WorkerProcessLauncher::OnChannelError() { 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedule a delayed termination of the worker process. Usually, the pipe is 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disconnected when the worker process is about to exit. Waiting a little bit 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here allows the worker to exit completely and so, notify 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |process_watcher_|. As the result KillProcess() will not be called and 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the original exit code reported by the worker process will be retrieved. 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!kill_process_timer_.IsRunning()) { 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kill_process_timer_.Start(FROM_HERE, kill_process_timeout_, this, 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &WorkerProcessLauncher::StopWorker); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WorkerProcessLauncher::OnObjectSignaled(HANDLE object) { 16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!process_watcher_.GetWatchedObject()); 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(exit_code_, CONTROL_C_EXIT); 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(worker_process_.Get(), object); 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Get exit code of the worker process if it is available. 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!::GetExitCodeProcess(worker_process_.Get(), &exit_code_)) { 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PLOG(INFO) << "Failed to query the exit code of the worker process"; 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) exit_code_ = CONTROL_C_EXIT; 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) worker_process_.Close(); 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StopWorker(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WorkerProcessLauncher::LaunchWorker() { 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!ipc_enabled_); 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!kill_process_timer_.IsRunning()); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!launch_timer_.IsRunning()); 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!process_watcher_.GetWatchedObject()); 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!launch_result_timer_.IsRunning()); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) exit_code_ = CONTROL_C_EXIT; 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Make sure launching a process will not take forever. 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) launch_result_timer_.Start( 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) FROM_HERE, base::TimeDelta::FromSeconds(kLaunchResultTimeoutSeconds), 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) this, &WorkerProcessLauncher::RecordLaunchResult); 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) launcher_delegate_->LaunchProcess(this); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WorkerProcessLauncher::RecordLaunchResult() { 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!worker_process_.IsValid()) { 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(WARNING) << "A worker process failed to start within " 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) << kLaunchResultTimeoutSeconds << " seconds."; 20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) launch_backoff_.InformOfRequest(false); 20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StopWorker(); 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Assume success if the worker process has been running for a few seconds. 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launch_backoff_.InformOfRequest(true); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WorkerProcessLauncher::RecordSuccessfulLaunchForTest() { 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (launch_result_timer_.IsRunning()) { 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) launch_result_timer_.Stop(); 22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RecordLaunchResult(); 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WorkerProcessLauncher::SetKillProcessTimeoutForTest( 22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::TimeDelta& timeout) { 22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kill_process_timeout_ = timeout; 23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void WorkerProcessLauncher::StopWorker() { 23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(CalledOnValidThread()); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record a launch failure if the process exited too soon. 23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (launch_result_timer_.IsRunning()) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) launch_backoff_.InformOfRequest(false); 23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) launch_result_timer_.Stop(); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ignore any remaining IPC messages. 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipc_enabled_ = false; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Stop monitoring the worker process. 24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) process_watcher_.StopWatching(); 24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) worker_process_.Close(); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kill_process_timer_.Stop(); 24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) launcher_delegate_->KillProcess(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do not relaunch the worker process if the caller has asked us to stop. 25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (stopping()) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Stop trying to restart the worker process if it exited due to 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // misconfiguration. 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (kMinPermanentErrorExitCode <= exit_code_ && 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) exit_code_ <= kMaxPermanentErrorExitCode) { 259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ipc_handler_->OnPermanentError(exit_code_); 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Schedule the next attempt to launch the worker process. 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) launch_timer_.Start(FROM_HERE, launch_backoff_.GetTimeUntilRelease(), this, 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &WorkerProcessLauncher::LaunchWorker); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 269