Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(382)

Side by Side Diff: remoting/host/win/worker_process_launcher.cc

Issue 11118005: Pass the client end handle of the network-to-daemon IPC channel via handle inheritance. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/win/worker_process_launcher.h" 5 #include "remoting/host/win/worker_process_launcher.h"
6 6
7 #include <sddl.h>
8 #include <limits>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/logging.h" 7 #include "base/logging.h"
13 #include "base/single_thread_task_runner.h" 8 #include "base/single_thread_task_runner.h"
14 #include "base/process_util.h"
15 #include "base/rand_util.h"
16 #include "base/stringprintf.h"
17 #include "base/time.h" 9 #include "base/time.h"
18 #include "base/timer.h" 10 #include "base/timer.h"
19 #include "base/utf_string_conversions.h"
20 #include "base/win/object_watcher.h" 11 #include "base/win/object_watcher.h"
21 #include "base/win/scoped_handle.h" 12 #include "ipc/ipc_listener.h"
22 #include "ipc/ipc_channel.h"
23 #include "ipc/ipc_channel_proxy.h"
24 #include "ipc/ipc_message.h" 13 #include "ipc/ipc_message.h"
25 #include "net/base/backoff_entry.h" 14 #include "net/base/backoff_entry.h"
26 #include "remoting/host/host_exit_codes.h" 15 #include "remoting/host/host_exit_codes.h"
27 #include "remoting/host/worker_process_ipc_delegate.h" 16 #include "remoting/host/worker_process_ipc_delegate.h"
28 17
18 using base::TimeDelta;
29 using base::win::ScopedHandle; 19 using base::win::ScopedHandle;
30 using base::TimeDelta;
31
32 // Match the pipe name prefix used by Chrome IPC channels so that the client
33 // could use Chrome IPC APIs instead of connecting manually.
34 const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome.";
35
36 // The minimum and maximum delays between attempts to inject host process into
37 // a session.
38 const int kMaxLaunchDelaySeconds = 60;
39 const int kMinLaunchDelaySeconds = 1;
40 20
41 const net::BackoffEntry::Policy kDefaultBackoffPolicy = { 21 const net::BackoffEntry::Policy kDefaultBackoffPolicy = {
42 // Number of initial errors (in sequence) to ignore before applying 22 // Number of initial errors (in sequence) to ignore before applying
43 // exponential back-off rules. 23 // exponential back-off rules.
44 0, 24 0,
45 25
46 // Initial delay for exponential back-off in ms. 26 // Initial delay for exponential back-off in ms.
47 1000, 27 1000,
48 28
49 // Factor by which the waiting time will be multiplied. 29 // Factor by which the waiting time will be multiplied.
(...skipping 26 matching lines...) Expand all
76 public base::win::ObjectWatcher::Delegate, 56 public base::win::ObjectWatcher::Delegate,
77 public IPC::Listener { 57 public IPC::Listener {
78 public: 58 public:
79 // Creates the launcher that will use |launcher_delegate| to manage the worker 59 // Creates the launcher that will use |launcher_delegate| to manage the worker
80 // process and |worker_delegate| to handle IPCs. The caller must ensure that 60 // process and |worker_delegate| to handle IPCs. The caller must ensure that
81 // |worker_delegate| remains valid until Stoppable::Stop() method has been 61 // |worker_delegate| remains valid until Stoppable::Stop() method has been
82 // called. 62 // called.
83 // 63 //
84 // The caller should call all the methods on this class on 64 // The caller should call all the methods on this class on
85 // the |caller_task_runner| thread. Methods of both delegate interfaces are 65 // the |caller_task_runner| thread. Methods of both delegate interfaces are
86 // called on the |caller_task_runner| thread as well. |io_task_runner| is used 66 // called on the |caller_task_runner| thread as well.
87 // to perform background IPC I/O.
88 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 67 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
89 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
90 scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate, 68 scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate,
91 WorkerProcessIpcDelegate* worker_delegate, 69 WorkerProcessIpcDelegate* worker_delegate);
92 const std::string& pipe_security_descriptor);
93 70
94 // Launches the worker process. 71 // Launches the worker process.
95 void Start(); 72 void Start();
96 73
97 // Stops the worker process asynchronously. The caller can drop the reference 74 // Stops the worker process asynchronously. The caller can drop the reference
98 // to |this| as soon as Stop() returns. 75 // to |this| as soon as Stop() returns.
99 void Stop(); 76 void Stop();
100 77
101 // Sends an IPC message to the worker process. The message will be silently 78 // Sends an IPC message to the worker process. The message will be silently
102 // dropped if Send() is called before Start() or after stutdown has been 79 // dropped if Send() is called before Start() or after stutdown has been
103 // initiated. 80 // initiated.
104 void Send(IPC::Message* message); 81 void Send(IPC::Message* message);
105 82
106 // base::win::ObjectWatcher::Delegate implementation. 83 // base::win::ObjectWatcher::Delegate implementation.
107 virtual void OnObjectSignaled(HANDLE object) OVERRIDE; 84 virtual void OnObjectSignaled(HANDLE object) OVERRIDE;
108 85
109 // IPC::Listener implementation. 86 // IPC::Listener implementation.
110 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 87 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
111 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; 88 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
112 virtual void OnChannelError() OVERRIDE; 89 virtual void OnChannelError() OVERRIDE;
113 90
114 private: 91 private:
115 friend class base::RefCountedThreadSafe<Core>; 92 friend class base::RefCountedThreadSafe<Core>;
116 virtual ~Core(); 93 virtual ~Core();
117 94
118 // Creates the server end of the Chromoting IPC channel.
119 bool CreatePipeForIpcChannel(const std::string& channel_name,
120 const std::string& pipe_security_descriptor,
121 base::win::ScopedHandle* pipe_out);
122
123 // Generates random channel ID.
124 std::string GenerateRandomChannelId();
125
126 // Attempts to launch the worker process. Schedules next launch attempt if 95 // Attempts to launch the worker process. Schedules next launch attempt if
127 // creation of the process fails. 96 // creation of the process fails.
128 void LaunchWorker(); 97 void LaunchWorker();
129 98
130 // Records a successfull launch attempt. 99 // Records a successfull launch attempt.
131 void RecordSuccessfullLaunch(); 100 void RecordSuccessfullLaunch();
132 101
133 // Stops the worker process asynchronously and schedules next launch attempt 102 // Stops the worker process asynchronously and schedules next launch attempt
134 // unless Stop() has been called already. 103 // unless Stop() has been called already.
135 void StopWorker(); 104 void StopWorker();
136 105
137 // All public methods are called on the |caller_task_runner| thread. 106 // All public methods are called on the |caller_task_runner| thread.
138 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; 107 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
139 108
140 // The task runner is used perform background IPC I/O.
141 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
142
143 // Implements specifics of launching a worker process. 109 // Implements specifics of launching a worker process.
144 scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate_; 110 scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate_;
145 111
146 // Handles IPC messages sent by the worker process. 112 // Handles IPC messages sent by the worker process.
147 WorkerProcessIpcDelegate* worker_delegate_; 113 WorkerProcessIpcDelegate* worker_delegate_;
148 114
149 // The IPC channel connecting to the launched process. 115 // True if IPC messages should be passed to |worker_delegate_|.
150 scoped_ptr<IPC::ChannelProxy> ipc_channel_; 116 bool ipc_enabled_;
151 117
152 // The timer used to delay termination of the process in the case of an IPC 118 // The timer used to delay termination of the process in the case of an IPC
153 // error. 119 // error.
154 scoped_ptr<base::OneShotTimer<Core> > ipc_error_timer_; 120 scoped_ptr<base::OneShotTimer<Core> > ipc_error_timer_;
155 121
156 // Launch backoff state. 122 // Launch backoff state.
157 net::BackoffEntry launch_backoff_; 123 net::BackoffEntry launch_backoff_;
158 124
159 // Timer used to delay recording a successfull launch. 125 // Timer used to delay recording a successfull launch.
160 scoped_ptr<base::OneShotTimer<Core> > launch_success_timer_; 126 scoped_ptr<base::OneShotTimer<Core> > launch_success_timer_;
161 127
162 // Timer used to schedule the next attempt to launch the process. 128 // Timer used to schedule the next attempt to launch the process.
163 scoped_ptr<base::OneShotTimer<Core> > launch_timer_; 129 scoped_ptr<base::OneShotTimer<Core> > launch_timer_;
164 130
165 // Used to determine when the launched process terminates. 131 // Used to determine when the launched process terminates.
166 base::win::ObjectWatcher process_watcher_; 132 base::win::ObjectWatcher process_watcher_;
167 133
168 // A waiting handle that becomes signalled once the launched process has 134 // A waiting handle that becomes signalled once the launched process has
169 // been terminated. 135 // been terminated.
170 base::win::ScopedHandle process_exit_event_; 136 ScopedHandle process_exit_event_;
171
172 // The server end of the pipe.
173 base::win::ScopedHandle pipe_;
174
175 // The security descriptor (as SDDL) of the server end of the pipe.
176 std::string pipe_security_descriptor_;
177 137
178 // Self reference to keep the object alive while the worker process is being 138 // Self reference to keep the object alive while the worker process is being
179 // terminated. 139 // terminated.
180 scoped_refptr<Core> self_; 140 scoped_refptr<Core> self_;
181 141
182 // True when Stop() has been called. 142 // True when Stop() has been called.
183 bool stopping_; 143 bool stopping_;
184 144
185 DISALLOW_COPY_AND_ASSIGN(Core); 145 DISALLOW_COPY_AND_ASSIGN(Core);
186 }; 146 };
187 147
188 WorkerProcessLauncher::Delegate::~Delegate() { 148 WorkerProcessLauncher::Delegate::~Delegate() {
189 } 149 }
190 150
191 WorkerProcessLauncher::Core::Core( 151 WorkerProcessLauncher::Core::Core(
192 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 152 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
193 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
194 scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate, 153 scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate,
195 WorkerProcessIpcDelegate* worker_delegate, 154 WorkerProcessIpcDelegate* worker_delegate)
196 const std::string& pipe_security_descriptor)
197 : caller_task_runner_(caller_task_runner), 155 : caller_task_runner_(caller_task_runner),
198 io_task_runner_(io_task_runner),
199 launcher_delegate_(launcher_delegate.Pass()), 156 launcher_delegate_(launcher_delegate.Pass()),
200 worker_delegate_(worker_delegate), 157 worker_delegate_(worker_delegate),
158 ipc_enabled_(false),
201 launch_backoff_(&kDefaultBackoffPolicy), 159 launch_backoff_(&kDefaultBackoffPolicy),
202 pipe_security_descriptor_(pipe_security_descriptor),
203 stopping_(false) { 160 stopping_(false) {
204 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 161 DCHECK(caller_task_runner_->BelongsToCurrentThread());
205 162
206 // base::OneShotTimer must be destroyed on the same thread it was created on. 163 // base::OneShotTimer must be destroyed on the same thread it was created on.
207 ipc_error_timer_.reset(new base::OneShotTimer<Core>()); 164 ipc_error_timer_.reset(new base::OneShotTimer<Core>());
208 launch_success_timer_.reset(new base::OneShotTimer<Core>()); 165 launch_success_timer_.reset(new base::OneShotTimer<Core>());
209 launch_timer_.reset(new base::OneShotTimer<Core>()); 166 launch_timer_.reset(new base::OneShotTimer<Core>());
210 } 167 }
211 168
212 void WorkerProcessLauncher::Core::Start() { 169 void WorkerProcessLauncher::Core::Start() {
213 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 170 DCHECK(caller_task_runner_->BelongsToCurrentThread());
214 DCHECK(!stopping_); 171 DCHECK(!stopping_);
215 172
216 LaunchWorker(); 173 LaunchWorker();
217 } 174 }
218 175
219 void WorkerProcessLauncher::Core::Stop() { 176 void WorkerProcessLauncher::Core::Stop() {
220 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 177 DCHECK(caller_task_runner_->BelongsToCurrentThread());
221 178
222 if (!stopping_) { 179 if (!stopping_) {
223 stopping_ = true; 180 stopping_ = true;
224 worker_delegate_ = NULL; 181 worker_delegate_ = NULL;
225 StopWorker(); 182 StopWorker();
226 } 183 }
227 } 184 }
228 185
229 void WorkerProcessLauncher::Core::Send(IPC::Message* message) { 186 void WorkerProcessLauncher::Core::Send(IPC::Message* message) {
230 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 187 DCHECK(caller_task_runner_->BelongsToCurrentThread());
231 188
232 if (ipc_channel_.get()) { 189 launcher_delegate_->Send(message);
233 ipc_channel_->Send(message);
234 } else {
235 delete message;
236 }
237 } 190 }
238 191
239 void WorkerProcessLauncher::Core::OnObjectSignaled(HANDLE object) { 192 void WorkerProcessLauncher::Core::OnObjectSignaled(HANDLE object) {
240 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 193 DCHECK(caller_task_runner_->BelongsToCurrentThread());
241 DCHECK(process_watcher_.GetWatchedObject() == NULL); 194 DCHECK(process_watcher_.GetWatchedObject() == NULL);
242 195
243 StopWorker(); 196 StopWorker();
244 } 197 }
245 198
246 bool WorkerProcessLauncher::Core::OnMessageReceived( 199 bool WorkerProcessLauncher::Core::OnMessageReceived(
247 const IPC::Message& message) { 200 const IPC::Message& message) {
248 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 201 DCHECK(caller_task_runner_->BelongsToCurrentThread());
249 DCHECK(ipc_channel_.get() != NULL); 202
203 if (!ipc_enabled_)
204 return false;
250 205
251 return worker_delegate_->OnMessageReceived(message); 206 return worker_delegate_->OnMessageReceived(message);
252 } 207 }
253 208
254 void WorkerProcessLauncher::Core::OnChannelConnected(int32 peer_pid) { 209 void WorkerProcessLauncher::Core::OnChannelConnected(int32 peer_pid) {
255 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 210 DCHECK(caller_task_runner_->BelongsToCurrentThread());
256 DCHECK(ipc_channel_.get() != NULL);
257 211
258 // |peer_pid| is send by the client and cannot be trusted. 212 // |peer_pid| is send by the client and cannot be trusted.
259 // GetNamedPipeClientProcessId() is not available on XP. The pipe's security 213 // GetNamedPipeClientProcessId() is not available on XP. The pipe's security
260 // descriptor is the only protection we currently have against malicious 214 // descriptor is the only protection we currently have against malicious
261 // clients. 215 // clients.
262 // 216 //
263 // If we'd like to be able to launch low-privileged workers and let them 217 // If we'd like to be able to launch low-privileged workers and let them
264 // connect back, the pipe handle should be passed to the worker instead of 218 // connect back, the pipe handle should be passed to the worker instead of
265 // the pipe name. 219 // the pipe name.
266 worker_delegate_->OnChannelConnected(); 220 if (ipc_enabled_)
221 worker_delegate_->OnChannelConnected();
267 } 222 }
268 223
269 void WorkerProcessLauncher::Core::OnChannelError() { 224 void WorkerProcessLauncher::Core::OnChannelError() {
270 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 225 DCHECK(caller_task_runner_->BelongsToCurrentThread());
271 DCHECK(ipc_channel_.get() != NULL);
272 226
273 // Schedule a delayed termination of the worker process. Usually, the pipe is 227 // Schedule a delayed termination of the worker process. Usually, the pipe is
274 // disconnected when the worker process is about to exit. Waiting a little bit 228 // disconnected when the worker process is about to exit. Waiting a little bit
275 // here allows the worker to exit completely and so, notify 229 // here allows the worker to exit completely and so, notify
276 // |process_watcher_|. As the result KillProcess() will not be called and 230 // |process_watcher_|. As the result KillProcess() will not be called and
277 // the original exit code reported by the worker process will be retrieved. 231 // the original exit code reported by the worker process will be retrieved.
278 ipc_error_timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(5), 232 ipc_error_timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(5),
279 this, &Core::StopWorker); 233 this, &Core::StopWorker);
280 } 234 }
281 235
282 WorkerProcessLauncher::Core::~Core() { 236 WorkerProcessLauncher::Core::~Core() {
283 DCHECK(stopping_); 237 DCHECK(stopping_);
284 } 238 }
285 239
286 // Creates the server end of the Chromoting IPC channel.
287 bool WorkerProcessLauncher::Core::CreatePipeForIpcChannel(
288 const std::string& channel_name,
289 const std::string& pipe_security_descriptor,
290 ScopedHandle* pipe_out) {
291 // Create security descriptor for the channel.
292 SECURITY_ATTRIBUTES security_attributes;
293 security_attributes.nLength = sizeof(security_attributes);
294 security_attributes.bInheritHandle = FALSE;
295
296 ULONG security_descriptor_length = 0;
297 if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
298 UTF8ToUTF16(pipe_security_descriptor).c_str(),
299 SDDL_REVISION_1,
300 reinterpret_cast<PSECURITY_DESCRIPTOR*>(
301 &security_attributes.lpSecurityDescriptor),
302 &security_descriptor_length)) {
303 LOG_GETLASTERROR(ERROR) <<
304 "Failed to create a security descriptor for the Chromoting IPC channel";
305 return false;
306 }
307
308 // Convert the channel name to the pipe name.
309 std::string pipe_name(kChromePipeNamePrefix);
310 pipe_name.append(channel_name);
311
312 // Create the server end of the pipe. This code should match the code in
313 // IPC::Channel with exception of passing a non-default security descriptor.
314 base::win::ScopedHandle pipe;
315 pipe.Set(CreateNamedPipe(
316 UTF8ToUTF16(pipe_name).c_str(),
317 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
318 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
319 1,
320 IPC::Channel::kReadBufferSize,
321 IPC::Channel::kReadBufferSize,
322 5000,
323 &security_attributes));
324 if (!pipe.IsValid()) {
325 LOG_GETLASTERROR(ERROR) <<
326 "Failed to create the server end of the Chromoting IPC channel";
327 LocalFree(security_attributes.lpSecurityDescriptor);
328 return false;
329 }
330
331 LocalFree(security_attributes.lpSecurityDescriptor);
332
333 *pipe_out = pipe.Pass();
334 return true;
335 }
336
337 // N.B. Copied from src/content/common/child_process_host_impl.cc
338 std::string WorkerProcessLauncher::Core::GenerateRandomChannelId() {
339 return base::StringPrintf("%d.%p.%d",
340 base::GetCurrentProcId(), this,
341 base::RandInt(0, std::numeric_limits<int>::max()));
342 }
343
344 void WorkerProcessLauncher::Core::LaunchWorker() { 240 void WorkerProcessLauncher::Core::LaunchWorker() {
345 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 241 DCHECK(caller_task_runner_->BelongsToCurrentThread());
346 DCHECK(ipc_channel_.get() == NULL); 242 DCHECK(!ipc_enabled_);
347 DCHECK(!launch_success_timer_->IsRunning()); 243 DCHECK(!launch_success_timer_->IsRunning());
348 DCHECK(!launch_timer_->IsRunning()); 244 DCHECK(!launch_timer_->IsRunning());
349 DCHECK(!pipe_.IsValid());
350 DCHECK(!process_exit_event_.IsValid()); 245 DCHECK(!process_exit_event_.IsValid());
351 DCHECK(process_watcher_.GetWatchedObject() == NULL); 246 DCHECK(process_watcher_.GetWatchedObject() == NULL);
352 247
353 std::string channel_name = GenerateRandomChannelId(); 248 // Launch the process and attach an object watcher to the returned process
354 if (CreatePipeForIpcChannel(channel_name, pipe_security_descriptor_, 249 // handle so that we get notified if the process terminates.
355 &pipe_)) { 250 if (launcher_delegate_->LaunchProcess(this, &process_exit_event_)) {
356 // Wrap the pipe into an IPC channel. 251 if (process_watcher_.StartWatching(process_exit_event_, this)) {
357 ipc_channel_.reset(new IPC::ChannelProxy( 252 ipc_enabled_ = true;
358 IPC::ChannelHandle(pipe_), 253 // Record a successful launch once the process has been running for at
359 IPC::Channel::MODE_SERVER, 254 // least two seconds.
360 this, 255 launch_success_timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(2),
361 io_task_runner_)); 256 this, &Core::RecordSuccessfullLaunch);
simonmorris 2012/10/12 16:31:13 Successfull -> Successful
alexeypa (please no reviews) 2012/10/12 18:44:39 Done.
257 return;
258 }
362 259
363 // Launch the process and attach an object watcher to the returned process 260 launcher_delegate_->KillProcess(CONTROL_C_EXIT);
364 // handle so that we get notified if the process terminates.
365 if (launcher_delegate_->LaunchProcess(channel_name, &process_exit_event_)) {
366 if (process_watcher_.StartWatching(process_exit_event_, this)) {
367 // Record a successful launch once the process has been running for at
368 // least two seconds.
369 launch_success_timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(2),
370 this, &Core::RecordSuccessfullLaunch);
371 return;
372 }
373
374 launcher_delegate_->KillProcess(CONTROL_C_EXIT);
375 }
376 } 261 }
377 262
378 launch_backoff_.InformOfRequest(false); 263 launch_backoff_.InformOfRequest(false);
379 StopWorker(); 264 StopWorker();
380 } 265 }
381 266
382 void WorkerProcessLauncher::Core::RecordSuccessfullLaunch() { 267 void WorkerProcessLauncher::Core::RecordSuccessfullLaunch() {
383 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 268 DCHECK(caller_task_runner_->BelongsToCurrentThread());
384 269
385 launch_backoff_.InformOfRequest(true); 270 launch_backoff_.InformOfRequest(true);
386 } 271 }
387 272
388 void WorkerProcessLauncher::Core::StopWorker() { 273 void WorkerProcessLauncher::Core::StopWorker() {
389 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 274 DCHECK(caller_task_runner_->BelongsToCurrentThread());
390 275
391 // Record a launch failure if the process exited too soon. 276 // Record a launch failure if the process exited too soon.
392 if (launch_success_timer_->IsRunning()) { 277 if (launch_success_timer_->IsRunning()) {
393 launch_success_timer_->Stop(); 278 launch_success_timer_->Stop();
394 launch_backoff_.InformOfRequest(false); 279 launch_backoff_.InformOfRequest(false);
395 } 280 }
396 281
397 // Keep |this| alive until the worker process is terminated. 282 // Keep |this| alive until the worker process is terminated.
398 self_ = this; 283 self_ = this;
399 284
400 ipc_channel_.reset(); 285 // Ignore any remaining IPC messages.
401 pipe_.Close(); 286 ipc_enabled_ = false;
402 287
403 // Kill the process if it has been started already. 288 // Kill the process if it has been started already.
404 if (process_watcher_.GetWatchedObject() != NULL) { 289 if (process_watcher_.GetWatchedObject() != NULL) {
405 launcher_delegate_->KillProcess(CONTROL_C_EXIT); 290 launcher_delegate_->KillProcess(CONTROL_C_EXIT);
406 return; 291 return;
407 } 292 }
408 293
409 ipc_error_timer_->Stop();
410
411 DCHECK(ipc_channel_.get() == NULL);
412 DCHECK(!pipe_.IsValid());
413 DCHECK(process_watcher_.GetWatchedObject() == NULL); 294 DCHECK(process_watcher_.GetWatchedObject() == NULL);
414 295
296 ipc_error_timer_->Stop();
415 process_exit_event_.Close(); 297 process_exit_event_.Close();
416 298
417 // Do not relaunch the worker process if the caller has asked us to stop. 299 // Do not relaunch the worker process if the caller has asked us to stop.
418 if (stopping_) { 300 if (stopping_) {
419 ipc_error_timer_.reset(); 301 ipc_error_timer_.reset();
420 launch_timer_.reset(); 302 launch_timer_.reset();
421 self_ = NULL; 303 self_ = NULL;
422 return; 304 return;
423 } 305 }
424 306
(...skipping 11 matching lines...) Expand all
436 return; 318 return;
437 } 319 }
438 320
439 // Schedule the next attempt to launch the worker process. 321 // Schedule the next attempt to launch the worker process.
440 launch_timer_->Start(FROM_HERE, launch_backoff_.GetTimeUntilRelease(), 322 launch_timer_->Start(FROM_HERE, launch_backoff_.GetTimeUntilRelease(),
441 this, &Core::LaunchWorker); 323 this, &Core::LaunchWorker);
442 } 324 }
443 325
444 WorkerProcessLauncher::WorkerProcessLauncher( 326 WorkerProcessLauncher::WorkerProcessLauncher(
445 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 327 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
446 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
447 scoped_ptr<Delegate> launcher_delegate, 328 scoped_ptr<Delegate> launcher_delegate,
448 WorkerProcessIpcDelegate* worker_delegate, 329 WorkerProcessIpcDelegate* worker_delegate) {
449 const std::string& pipe_security_descriptor) { 330 core_ = new Core(caller_task_runner, launcher_delegate.Pass(),
450 core_ = new Core(caller_task_runner, io_task_runner, launcher_delegate.Pass(), 331 worker_delegate);
451 worker_delegate, pipe_security_descriptor);
452 core_->Start(); 332 core_->Start();
453 } 333 }
454 334
455 WorkerProcessLauncher::~WorkerProcessLauncher() { 335 WorkerProcessLauncher::~WorkerProcessLauncher() {
456 core_->Stop(); 336 core_->Stop();
457 core_ = NULL; 337 core_ = NULL;
458 } 338 }
459 339
460 void WorkerProcessLauncher::Send(IPC::Message* message) { 340 void WorkerProcessLauncher::Send(IPC::Message* message) {
461 core_->Send(message); 341 core_->Send(message);
462 } 342 }
463 343
464 } // namespace remoting 344 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698