OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "mojo/common/handle_watcher.h" | 5 #include "mojo/common/handle_watcher.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/atomic_sequence_num.h" | 9 #include "base/atomic_sequence_num.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
246 | 246 |
247 WatcherThreadManager::WatcherThreadManager() | 247 WatcherThreadManager::WatcherThreadManager() |
248 : thread_(kWatcherThreadName) { | 248 : thread_(kWatcherThreadName) { |
249 base::Thread::Options thread_options; | 249 base::Thread::Options thread_options; |
250 thread_options.message_pump_factory = base::Bind(&CreateMessagePumpMojo); | 250 thread_options.message_pump_factory = base::Bind(&CreateMessagePumpMojo); |
251 thread_.StartWithOptions(thread_options); | 251 thread_.StartWithOptions(thread_options); |
252 } | 252 } |
253 | 253 |
254 } // namespace | 254 } // namespace |
255 | 255 |
256 // HandleWatcher::StartState --------------------------------------------------- | 256 // HandleWatcher::State -------------------------------------------------------- |
257 | 257 |
258 // Contains the information passed to Start(). | 258 // Represents the state of the HandleWatcher. Owns the user's callback and |
259 struct HandleWatcher::StartState { | 259 // monitors the current thread's MessageLoop to know when to force the callback |
260 explicit StartState(HandleWatcher* watcher) : weak_factory(watcher) { | 260 // to run (with an error) even though the pipe hasn't been signaled yet. |
261 class HandleWatcher::State : public base::MessageLoop::DestructionObserver { | |
262 public: | |
263 explicit State(HandleWatcher* watcher, | |
sky
2014/05/13 21:22:42
nit: no explicit
| |
264 const Handle& handle, | |
265 MojoWaitFlags wait_flags, | |
266 MojoDeadline deadline, | |
267 const base::Callback<void(MojoResult)>& callback) | |
268 : watcher_(watcher), | |
269 callback_(callback), | |
270 weak_factory_(this) { | |
271 base::MessageLoop::current()->AddDestructionObserver(this); | |
272 | |
273 watcher_id_ = WatcherThreadManager::GetInstance()->StartWatching( | |
274 handle, | |
275 wait_flags, | |
276 MojoDeadlineToTimeTicks(deadline), | |
277 base::Bind(&State::OnHandleReady, weak_factory_.GetWeakPtr())); | |
261 } | 278 } |
262 | 279 |
263 ~StartState() { | 280 ~State() { |
281 base::MessageLoop::current()->RemoveDestructionObserver(this); | |
282 | |
283 WatcherThreadManager::GetInstance()->StopWatching(watcher_id_); | |
264 } | 284 } |
265 | 285 |
266 // ID assigned by WatcherThreadManager. | 286 private: |
267 WatcherID watcher_id; | 287 virtual void WillDestroyCurrentMessageLoop() OVERRIDE { |
288 // The current thread is exiting. Simulate a watch error. | |
289 OnHandleReady(MOJO_RESULT_ABORTED); | |
290 } | |
268 | 291 |
269 // Callback to notify when done. | 292 void OnHandleReady(MojoResult result) { |
270 base::Callback<void(MojoResult)> callback; | 293 base::Callback<void(MojoResult)> callback = callback_; |
294 watcher_->Stop(); // Destroys |this|. | |
271 | 295 |
272 // When Start() is invoked a callback is passed to WatcherThreadManager | 296 callback.Run(result); |
273 // using a WeakRef from |weak_refactory_|. The callback invokes | 297 } |
274 // OnHandleReady() (on the thread Start() is invoked from) which in turn | 298 |
275 // notifies |callback_|. Doing this allows us to reset state when the handle | 299 HandleWatcher* watcher_; |
276 // is ready, and then notify the callback. Doing this also means Stop() | 300 WatcherID watcher_id_; |
277 // cancels any pending callbacks that may be inflight. | 301 base::Callback<void(MojoResult)> callback_; |
278 base::WeakPtrFactory<HandleWatcher> weak_factory; | 302 |
303 // Used to weakly bind |this| to the WatcherThreadManager. | |
304 base::WeakPtrFactory<State> weak_factory_; | |
279 }; | 305 }; |
sky
2014/05/13 21:22:42
nit: DISALLOW_...
| |
280 | 306 |
281 // HandleWatcher --------------------------------------------------------------- | 307 // HandleWatcher --------------------------------------------------------------- |
282 | 308 |
283 HandleWatcher::HandleWatcher() { | 309 HandleWatcher::HandleWatcher() { |
284 } | 310 } |
285 | 311 |
286 HandleWatcher::~HandleWatcher() { | 312 HandleWatcher::~HandleWatcher() { |
287 Stop(); | |
288 } | 313 } |
289 | 314 |
290 void HandleWatcher::Start(const Handle& handle, | 315 void HandleWatcher::Start(const Handle& handle, |
291 MojoWaitFlags wait_flags, | 316 MojoWaitFlags wait_flags, |
292 MojoDeadline deadline, | 317 MojoDeadline deadline, |
293 const base::Callback<void(MojoResult)>& callback) { | 318 const base::Callback<void(MojoResult)>& callback) { |
294 DCHECK(handle.is_valid()); | 319 DCHECK(handle.is_valid()); |
295 DCHECK_NE(MOJO_WAIT_FLAG_NONE, wait_flags); | 320 DCHECK_NE(MOJO_WAIT_FLAG_NONE, wait_flags); |
296 | 321 |
297 Stop(); | 322 state_.reset(new State(this, handle, wait_flags, deadline, callback)); |
298 | |
299 start_state_.reset(new StartState(this)); | |
300 start_state_->callback = callback; | |
301 start_state_->watcher_id = | |
302 WatcherThreadManager::GetInstance()->StartWatching( | |
303 handle, | |
304 wait_flags, | |
305 MojoDeadlineToTimeTicks(deadline), | |
306 base::Bind(&HandleWatcher::OnHandleReady, | |
307 start_state_->weak_factory.GetWeakPtr())); | |
308 } | 323 } |
309 | 324 |
310 void HandleWatcher::Stop() { | 325 void HandleWatcher::Stop() { |
311 if (!start_state_.get()) | 326 state_.reset(); |
312 return; | |
313 | |
314 scoped_ptr<StartState> old_state(start_state_.Pass()); | |
315 WatcherThreadManager::GetInstance()->StopWatching(old_state->watcher_id); | |
316 } | |
317 | |
318 void HandleWatcher::OnHandleReady(MojoResult result) { | |
319 DCHECK(start_state_.get()); | |
320 scoped_ptr<StartState> old_state(start_state_.Pass()); | |
321 old_state->callback.Run(result); | |
322 | |
323 // NOTE: We may have been deleted during callback execution. | |
324 } | 327 } |
325 | 328 |
326 } // namespace common | 329 } // namespace common |
327 } // namespace mojo | 330 } // namespace mojo |
OLD | NEW |