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

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

Issue 12545006: The worker process launcher can now ask the worker to crash. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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 "base/location.h"
7 #include "base/logging.h" 8 #include "base/logging.h"
8 #include "base/single_thread_task_runner.h" 9 #include "base/single_thread_task_runner.h"
9 #include "base/time.h" 10 #include "base/time.h"
10 #include "base/timer.h" 11 #include "base/timer.h"
11 #include "base/win/object_watcher.h" 12 #include "base/win/object_watcher.h"
12 #include "base/win/windows_version.h" 13 #include "base/win/windows_version.h"
13 #include "ipc/ipc_listener.h" 14 #include "ipc/ipc_listener.h"
14 #include "ipc/ipc_message.h" 15 #include "ipc/ipc_message.h"
15 #include "net/base/backoff_entry.h" 16 #include "net/base/backoff_entry.h"
17 #include "remoting/host/chromoting_messages.h"
16 #include "remoting/host/worker_process_ipc_delegate.h" 18 #include "remoting/host/worker_process_ipc_delegate.h"
17 19
18 using base::TimeDelta; 20 using base::TimeDelta;
19 using base::win::ScopedHandle; 21 using base::win::ScopedHandle;
20 22
21 const net::BackoffEntry::Policy kDefaultBackoffPolicy = { 23 const net::BackoffEntry::Policy kDefaultBackoffPolicy = {
22 // Number of initial errors (in sequence) to ignore before applying 24 // Number of initial errors (in sequence) to ignore before applying
23 // exponential back-off rules. 25 // exponential back-off rules.
24 0, 26 0,
25 27
(...skipping 11 matching lines...) Expand all
37 60000, 39 60000,
38 40
39 // Time to keep an entry from being discarded even when it 41 // Time to keep an entry from being discarded even when it
40 // has no significant state, -1 to never discard. 42 // has no significant state, -1 to never discard.
41 -1, 43 -1,
42 44
43 // Don't use initial delay unless the last request was an error. 45 // Don't use initial delay unless the last request was an error.
44 false, 46 false,
45 }; 47 };
46 48
49 const int kDelayTimeoutSeconds = 5;
Wez 2013/03/07 01:54:35 nit: Naming. e.g. kCrashRequestTimeoutSeconds?
Wez 2013/03/07 01:54:35 5s is probably too short for many systems, BTW.
alexeypa (please no reviews) 2013/03/07 21:28:30 Done.
alexeypa (please no reviews) 2013/03/07 21:28:30 It is enough because the timeout is, strictly spea
Wez 2013/03/08 01:45:15 Right, but if the timeout is short then on slower,
47 50
48 namespace remoting { 51 namespace remoting {
49 52
50 // Launches a worker process that is controlled via an IPC channel. All 53 // Launches a worker process that is controlled via an IPC channel. All
51 // interaction with the spawned process is through the IPC::Listener and Send() 54 // interaction with the spawned process is through the IPC::Listener and Send()
52 // method. In case of error the channel is closed and the worker process is 55 // method. In case of error the channel is closed and the worker process is
53 // terminated. 56 // terminated.
54 class WorkerProcessLauncher::Core 57 class WorkerProcessLauncher::Core
55 : public base::RefCountedThreadSafe<WorkerProcessLauncher::Core>, 58 : public base::RefCountedThreadSafe<Core, Core>,
56 public base::win::ObjectWatcher::Delegate, 59 public base::win::ObjectWatcher::Delegate,
57 public IPC::Listener { 60 public IPC::Listener {
58 public: 61 public:
59 // Creates the launcher that will use |launcher_delegate| to manage the worker 62 // Creates the launcher that will use |launcher_delegate| to manage the worker
60 // process and |worker_delegate| to handle IPCs. The caller must ensure that 63 // process and |worker_delegate| to handle IPCs. The caller must ensure that
61 // |worker_delegate| remains valid until Stoppable::Stop() method has been 64 // |worker_delegate| remains valid until Stoppable::Stop() method has been
62 // called. 65 // called.
63 // 66 //
64 // The caller should call all the methods on this class on 67 // The caller should call all the methods on this class on
65 // the |caller_task_runner| thread. Methods of both delegate interfaces are 68 // the |caller_task_runner| thread. Methods of both delegate interfaces are
66 // called on the |caller_task_runner| thread as well. 69 // called on the |caller_task_runner| thread as well.
67 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 70 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
68 scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate, 71 scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate,
69 WorkerProcessIpcDelegate* worker_delegate); 72 WorkerProcessIpcDelegate* worker_delegate);
70 73
71 // Launches the worker process. 74 // Launches the worker process.
72 void Start(); 75 void Start();
73 76
74 // Stops the worker process asynchronously. The caller can drop the reference 77 // Stops the worker process asynchronously. The caller can drop the reference
75 // to |this| as soon as Stop() returns. 78 // to |this| as soon as Stop() returns.
76 void Stop(); 79 void Stop();
77 80
78 // Sends an IPC message to the worker process. The message will be silently 81 // See WorkerProcessLauncher::Crash().
79 // dropped if Send() is called before Start() or after stutdown has been 82 void Crash(const tracked_objects::Location& location);
80 // initiated. 83
84 // See WorkerProcessLauncher::Send().
81 void Send(IPC::Message* message); 85 void Send(IPC::Message* message);
82 86
83 // base::win::ObjectWatcher::Delegate implementation. 87 // base::win::ObjectWatcher::Delegate implementation.
84 virtual void OnObjectSignaled(HANDLE object) OVERRIDE; 88 virtual void OnObjectSignaled(HANDLE object) OVERRIDE;
85 89
86 // IPC::Listener implementation. 90 // IPC::Listener implementation.
87 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 91 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
88 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; 92 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
89 virtual void OnChannelError() OVERRIDE; 93 virtual void OnChannelError() OVERRIDE;
90 94
95 // Destroys |Core| instances on the |caller_task_runner_| thread. This is
96 // needed because base::OneShotTimer instances must be destroyed on the same
97 // thread they were created on.
98 static void Destruct(const Core* core);
Wez 2013/03/07 01:54:35 We use an explicit separate struct e.g. CoreTraits
alexeypa (please no reviews) 2013/03/07 21:28:30 WorkerProcessLauncher::Core is a private class dec
Wez 2013/03/08 01:45:15 Surely the friend declaration would be in the Core
alexeypa (please no reviews) 2013/03/08 17:43:19 No, there will be one in WorkerProcessLauncher and
99
91 private: 100 private:
92 friend class base::RefCountedThreadSafe<Core>; 101 friend class base::DeleteHelper<Core>;
93 virtual ~Core(); 102 virtual ~Core();
94 103
95 // Attempts to launch the worker process. Schedules next launch attempt if 104 // Attempts to launch the worker process. Schedules next launch attempt if
96 // creation of the process fails. 105 // creation of the process fails.
97 void LaunchWorker(); 106 void LaunchWorker();
98 107
99 // Records a successful launch attempt. 108 // Records a successful launch attempt.
100 void RecordSuccessfulLaunch(); 109 void RecordSuccessfulLaunch();
101 110
102 // Stops the worker process asynchronously and schedules next launch attempt 111 // Stops the worker process asynchronously and schedules next launch attempt
103 // unless Stop() has been called already. 112 // unless Stop() has been called already.
104 void StopWorker(); 113 void StopWorker();
105 114
106 // All public methods are called on the |caller_task_runner| thread. 115 // All public methods are called on the |caller_task_runner| thread.
107 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; 116 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
108 117
109 // Implements specifics of launching a worker process. 118 // Implements specifics of launching a worker process.
110 scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate_; 119 scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate_;
111 120
112 // Handles IPC messages sent by the worker process. 121 // Handles IPC messages sent by the worker process.
113 WorkerProcessIpcDelegate* worker_delegate_; 122 WorkerProcessIpcDelegate* worker_delegate_;
114 123
115 // Pointer to GetNamedPipeClientProcessId() API if it is available. 124 // Pointer to GetNamedPipeClientProcessId() API if it is available.
116 typedef BOOL (WINAPI * GetNamedPipeClientProcessIdFn)(HANDLE, DWORD*); 125 typedef BOOL (WINAPI * GetNamedPipeClientProcessIdFn)(HANDLE, DWORD*);
117 GetNamedPipeClientProcessIdFn get_named_pipe_client_pid_; 126 GetNamedPipeClientProcessIdFn get_named_pipe_client_pid_;
118 127
128 // The timer used to delay termination of the worker process when an IPC error
129 // occured or when Crash() request is pending
130 base::OneShotTimer<Core> delay_timer_;
Wez 2013/03/07 01:54:35 nit: Naming.
alexeypa (please no reviews) 2013/03/07 21:28:30 Done.
131
119 // True if IPC messages should be passed to |worker_delegate_|. 132 // True if IPC messages should be passed to |worker_delegate_|.
120 bool ipc_enabled_; 133 bool ipc_enabled_;
121 134
122 // The timer used to delay termination of the process in the case of an IPC
123 // error.
124 scoped_ptr<base::OneShotTimer<Core> > ipc_error_timer_;
125
126 // Launch backoff state. 135 // Launch backoff state.
127 net::BackoffEntry launch_backoff_; 136 net::BackoffEntry launch_backoff_;
128 137
129 // Timer used to delay recording a successfull launch. 138 // Timer used to delay recording a successfull launch.
130 scoped_ptr<base::OneShotTimer<Core> > launch_success_timer_; 139 base::OneShotTimer<Core> launch_success_timer_;
131 140
132 // Timer used to schedule the next attempt to launch the process. 141 // Timer used to schedule the next attempt to launch the process.
133 scoped_ptr<base::OneShotTimer<Core> > launch_timer_; 142 base::OneShotTimer<Core> launch_timer_;
134 143
135 // Used to determine when the launched process terminates. 144 // Used to determine when the launched process terminates.
136 base::win::ObjectWatcher process_watcher_; 145 base::win::ObjectWatcher process_watcher_;
137 146
138 // A waiting handle that becomes signalled once the launched process has 147 // A waiting handle that becomes signalled once the launched process has
139 // been terminated. 148 // been terminated.
140 ScopedHandle process_exit_event_; 149 ScopedHandle process_exit_event_;
141 150
142 // True when Stop() has been called. 151 // True when Stop() has been called.
143 bool stopping_; 152 bool stopping_;
144 153
145 DISALLOW_COPY_AND_ASSIGN(Core); 154 DISALLOW_COPY_AND_ASSIGN(Core);
146 }; 155 };
147 156
148 WorkerProcessLauncher::Delegate::~Delegate() { 157 WorkerProcessLauncher::Delegate::~Delegate() {
149 } 158 }
150 159
151 WorkerProcessLauncher::Core::Core( 160 WorkerProcessLauncher::Core::Core(
152 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 161 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
153 scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate, 162 scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate,
154 WorkerProcessIpcDelegate* worker_delegate) 163 WorkerProcessIpcDelegate* worker_delegate)
155 : caller_task_runner_(caller_task_runner), 164 : caller_task_runner_(caller_task_runner),
156 launcher_delegate_(launcher_delegate.Pass()), 165 launcher_delegate_(launcher_delegate.Pass()),
157 worker_delegate_(worker_delegate), 166 worker_delegate_(worker_delegate),
158 get_named_pipe_client_pid_(NULL), 167 get_named_pipe_client_pid_(NULL),
159 ipc_enabled_(false), 168 ipc_enabled_(false),
160 launch_backoff_(&kDefaultBackoffPolicy), 169 launch_backoff_(&kDefaultBackoffPolicy),
161 stopping_(false) { 170 stopping_(false) {
162 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 171 DCHECK(caller_task_runner_->BelongsToCurrentThread());
163
164 // base::OneShotTimer must be destroyed on the same thread it was created on.
165 ipc_error_timer_.reset(new base::OneShotTimer<Core>());
166 launch_success_timer_.reset(new base::OneShotTimer<Core>());
167 launch_timer_.reset(new base::OneShotTimer<Core>());
168 } 172 }
169 173
170 void WorkerProcessLauncher::Core::Start() { 174 void WorkerProcessLauncher::Core::Start() {
171 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 175 DCHECK(caller_task_runner_->BelongsToCurrentThread());
172 DCHECK(!stopping_); 176 DCHECK(!stopping_);
173 177
174 LaunchWorker(); 178 LaunchWorker();
175 } 179 }
176 180
177 void WorkerProcessLauncher::Core::Stop() { 181 void WorkerProcessLauncher::Core::Stop() {
178 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 182 DCHECK(caller_task_runner_->BelongsToCurrentThread());
179 183
180 if (!stopping_) { 184 if (!stopping_) {
181 stopping_ = true; 185 stopping_ = true;
182 worker_delegate_ = NULL; 186 worker_delegate_ = NULL;
183 StopWorker(); 187 StopWorker();
184 } 188 }
185 } 189 }
186 190
191 void WorkerProcessLauncher::Core::Crash(
192 const tracked_objects::Location& location) {
193 DCHECK(caller_task_runner_->BelongsToCurrentThread());
194
195 // Ask the worker process to crash voluntarily if it is still connected.
196 if (ipc_enabled_) {
197 Send(new ChromotingDaemonMsg_Crash(location.function_name(),
198 location.file_name(),
199 location.line_number()));
200 }
201
202 // Close the channel and ignore any not yet processed messages.
203 launcher_delegate_->CloseChannel();
204 ipc_enabled_ = false;
205
206 // Give the worker process some time to crash.
207 if (!delay_timer_.IsRunning()) {
208 delay_timer_.Start(FROM_HERE,
209 base::TimeDelta::FromSeconds(kDelayTimeoutSeconds), this,
210 &Core::StopWorker);
Wez 2013/03/07 01:54:35 StopWorker "stops the worker asynchronously". Is i
alexeypa (please no reviews) 2013/03/07 21:28:30 It is tougher than Chuck Norris (as long as we are
211 }
212 }
213
187 void WorkerProcessLauncher::Core::Send(IPC::Message* message) { 214 void WorkerProcessLauncher::Core::Send(IPC::Message* message) {
188 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 215 DCHECK(caller_task_runner_->BelongsToCurrentThread());
189 216
190 if (ipc_enabled_) { 217 if (ipc_enabled_) {
191 launcher_delegate_->Send(message); 218 launcher_delegate_->Send(message);
192 } else { 219 } else {
193 delete message; 220 delete message;
194 } 221 }
195 } 222 }
196 223
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 } 261 }
235 262
236 void WorkerProcessLauncher::Core::OnChannelError() { 263 void WorkerProcessLauncher::Core::OnChannelError() {
237 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 264 DCHECK(caller_task_runner_->BelongsToCurrentThread());
238 265
239 // Schedule a delayed termination of the worker process. Usually, the pipe is 266 // Schedule a delayed termination of the worker process. Usually, the pipe is
240 // disconnected when the worker process is about to exit. Waiting a little bit 267 // disconnected when the worker process is about to exit. Waiting a little bit
241 // here allows the worker to exit completely and so, notify 268 // here allows the worker to exit completely and so, notify
242 // |process_watcher_|. As the result KillProcess() will not be called and 269 // |process_watcher_|. As the result KillProcess() will not be called and
243 // the original exit code reported by the worker process will be retrieved. 270 // the original exit code reported by the worker process will be retrieved.
244 ipc_error_timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(5), 271 if (!delay_timer_.IsRunning()) {
245 this, &Core::StopWorker); 272 delay_timer_.Start(FROM_HERE,
273 base::TimeDelta::FromSeconds(kDelayTimeoutSeconds), this,
274 &Core::StopWorker);
275 }
276 }
277
278 // static
279 void WorkerProcessLauncher::Core::Destruct(const Core* core) {
280 core->caller_task_runner_->DeleteSoon(FROM_HERE, core);
246 } 281 }
247 282
248 WorkerProcessLauncher::Core::~Core() { 283 WorkerProcessLauncher::Core::~Core() {
284 DCHECK(caller_task_runner_->BelongsToCurrentThread());
249 DCHECK(stopping_); 285 DCHECK(stopping_);
250 } 286 }
251 287
252 void WorkerProcessLauncher::Core::LaunchWorker() { 288 void WorkerProcessLauncher::Core::LaunchWorker() {
253 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 289 DCHECK(caller_task_runner_->BelongsToCurrentThread());
254 DCHECK(!ipc_enabled_); 290 DCHECK(!ipc_enabled_);
255 DCHECK(!launch_success_timer_->IsRunning()); 291 DCHECK(!launch_success_timer_.IsRunning());
256 DCHECK(!launch_timer_->IsRunning()); 292 DCHECK(!launch_timer_.IsRunning());
257 DCHECK(!process_exit_event_.IsValid()); 293 DCHECK(!process_exit_event_.IsValid());
258 DCHECK(process_watcher_.GetWatchedObject() == NULL); 294 DCHECK(process_watcher_.GetWatchedObject() == NULL);
259 295
260 // Launch the process and attach an object watcher to the returned process 296 // Launch the process and attach an object watcher to the returned process
261 // handle so that we get notified if the process terminates. 297 // handle so that we get notified if the process terminates.
262 if (launcher_delegate_->LaunchProcess(this, &process_exit_event_)) { 298 if (launcher_delegate_->LaunchProcess(this, &process_exit_event_)) {
263 if (process_watcher_.StartWatching(process_exit_event_, this)) { 299 if (process_watcher_.StartWatching(process_exit_event_, this)) {
264 ipc_enabled_ = true; 300 ipc_enabled_ = true;
265 // Record a successful launch once the process has been running for at 301 // Record a successful launch once the process has been running for at
266 // least two seconds. 302 // least two seconds.
267 launch_success_timer_->Start(FROM_HERE, base::TimeDelta::FromSeconds(2), 303 launch_success_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(2),
268 this, &Core::RecordSuccessfulLaunch); 304 this, &Core::RecordSuccessfulLaunch);
269 return; 305 return;
270 } 306 }
271 307
272 launcher_delegate_->KillProcess(CONTROL_C_EXIT); 308 launcher_delegate_->KillProcess(CONTROL_C_EXIT);
273 } 309 }
274 310
275 launch_backoff_.InformOfRequest(false); 311 launch_backoff_.InformOfRequest(false);
276 StopWorker(); 312 StopWorker();
277 } 313 }
278 314
279 void WorkerProcessLauncher::Core::RecordSuccessfulLaunch() { 315 void WorkerProcessLauncher::Core::RecordSuccessfulLaunch() {
280 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 316 DCHECK(caller_task_runner_->BelongsToCurrentThread());
281 317
282 launch_backoff_.InformOfRequest(true); 318 launch_backoff_.InformOfRequest(true);
283 } 319 }
284 320
285 void WorkerProcessLauncher::Core::StopWorker() { 321 void WorkerProcessLauncher::Core::StopWorker() {
286 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 322 DCHECK(caller_task_runner_->BelongsToCurrentThread());
287 323
288 // Keep the object alive in case one of delegates decides to delete |this|. 324 // Keep the object alive in case one of delegates decides to delete |this|.
289 scoped_refptr<Core> self = this; 325 scoped_refptr<Core> self = this;
290 326
291 // Record a launch failure if the process exited too soon. 327 // Record a launch failure if the process exited too soon.
292 if (launch_success_timer_->IsRunning()) { 328 if (launch_success_timer_.IsRunning()) {
293 launch_success_timer_->Stop(); 329 launch_success_timer_.Stop();
294 launch_backoff_.InformOfRequest(false); 330 launch_backoff_.InformOfRequest(false);
295 } 331 }
296 332
297 // Ignore any remaining IPC messages. 333 // Ignore any remaining IPC messages.
298 ipc_enabled_ = false; 334 ipc_enabled_ = false;
299 335
300 // Kill the process if it has been started already. 336 // Kill the process if it has been started already.
301 if (process_watcher_.GetWatchedObject() != NULL) { 337 if (process_watcher_.GetWatchedObject() != NULL) {
302 launcher_delegate_->KillProcess(CONTROL_C_EXIT); 338 launcher_delegate_->KillProcess(CONTROL_C_EXIT);
303 339
304 // Wait until the process is actually stopped if the caller keeps 340 // Wait until the process is actually stopped if the caller keeps
305 // a reference to |this|. Otherwise terminate everything right now - there 341 // a reference to |this|. Otherwise terminate everything right now - there
306 // won't be a second chance. 342 // won't be a second chance.
307 if (!stopping_) 343 if (!stopping_)
308 return; 344 return;
309 345
310 process_watcher_.StopWatching(); 346 process_watcher_.StopWatching();
311 } 347 }
312 348
313 ipc_error_timer_->Stop(); 349 delay_timer_.Stop();
314 process_exit_event_.Close(); 350 process_exit_event_.Close();
315 351
316 // Do not relaunch the worker process if the caller has asked us to stop. 352 // Do not relaunch the worker process if the caller has asked us to stop.
317 if (stopping_) { 353 if (stopping_)
318 ipc_error_timer_.reset();
319 launch_timer_.reset();
320 return; 354 return;
321 }
322 355
323 if (launcher_delegate_->IsPermanentError(launch_backoff_.failure_count())) { 356 if (launcher_delegate_->IsPermanentError(launch_backoff_.failure_count())) {
324 if (!stopping_) 357 if (!stopping_)
325 worker_delegate_->OnPermanentError(); 358 worker_delegate_->OnPermanentError();
326 } else { 359 } else {
327 // Schedule the next attempt to launch the worker process. 360 // Schedule the next attempt to launch the worker process.
328 launch_timer_->Start(FROM_HERE, launch_backoff_.GetTimeUntilRelease(), 361 launch_timer_.Start(FROM_HERE, launch_backoff_.GetTimeUntilRelease(), this,
329 this, &Core::LaunchWorker); 362 &Core::LaunchWorker);
330 } 363 }
331 } 364 }
332 365
333 WorkerProcessLauncher::WorkerProcessLauncher( 366 WorkerProcessLauncher::WorkerProcessLauncher(
334 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 367 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
335 scoped_ptr<Delegate> launcher_delegate, 368 scoped_ptr<Delegate> launcher_delegate,
336 WorkerProcessIpcDelegate* worker_delegate) { 369 WorkerProcessIpcDelegate* worker_delegate) {
337 core_ = new Core(caller_task_runner, launcher_delegate.Pass(), 370 core_ = new Core(caller_task_runner, launcher_delegate.Pass(),
338 worker_delegate); 371 worker_delegate);
339 core_->Start(); 372 core_->Start();
340 } 373 }
341 374
342 WorkerProcessLauncher::~WorkerProcessLauncher() { 375 WorkerProcessLauncher::~WorkerProcessLauncher() {
343 core_->Stop(); 376 core_->Stop();
344 core_ = NULL; 377 core_ = NULL;
345 } 378 }
346 379
380 void WorkerProcessLauncher::Crash(const tracked_objects::Location& location) {
381 core_->Crash(location);
382 }
383
347 void WorkerProcessLauncher::Send(IPC::Message* message) { 384 void WorkerProcessLauncher::Send(IPC::Message* message) {
348 core_->Send(message); 385 core_->Send(message);
349 } 386 }
350 387
351 } // namespace remoting 388 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698