Chromium Code Reviews| 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 |