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

Side by Side Diff: mojo/common/handle_watcher.cc

Issue 62773003: Mojo: Add BindingsSupportImpl on top of HandleWatcher (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 1 month 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 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 #include <set> 8 #include <set>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 29 matching lines...) Expand all
40 // Returns the shared instance. 40 // Returns the shared instance.
41 static WatcherThreadManager* GetInstance(); 41 static WatcherThreadManager* GetInstance();
42 42
43 // Starts watching the requested handle. Returns a unique ID that is used to 43 // Starts watching the requested handle. Returns a unique ID that is used to
44 // stop watching the handle. When the handle is ready |callback| is notified 44 // stop watching the handle. When the handle is ready |callback| is notified
45 // on the thread StartWatching() was invoked on. 45 // on the thread StartWatching() was invoked on.
46 // This may be invoked on any thread. 46 // This may be invoked on any thread.
47 WatcherID StartWatching(MojoHandle handle, 47 WatcherID StartWatching(MojoHandle handle,
48 MojoWaitFlags wait_flags, 48 MojoWaitFlags wait_flags,
49 base::TimeTicks deadline, 49 base::TimeTicks deadline,
50 const base::Closure& callback); 50 const base::Callback<void(MojoResult)>& callback);
51 51
52 // Stops watching a handle. 52 // Stops watching a handle.
53 void StopWatching(WatcherID watcher_id); 53 void StopWatching(WatcherID watcher_id);
54 54
55 private: 55 private:
56 friend struct base::DefaultLazyInstanceTraits<WatcherThreadManager>; 56 friend struct base::DefaultLazyInstanceTraits<WatcherThreadManager>;
57 57
58 // Tracks a single request. 58 // Tracks a single request.
59 struct HandleAndCallback { 59 struct HandleAndCallback {
60 HandleAndCallback() 60 HandleAndCallback()
61 : handle(MOJO_HANDLE_INVALID), 61 : handle(MOJO_HANDLE_INVALID),
62 wait_flags(MOJO_WAIT_FLAG_NONE), 62 wait_flags(MOJO_WAIT_FLAG_NONE),
63 message_loop(NULL) {} 63 message_loop(NULL) {}
64 64
65 MojoHandle handle; 65 MojoHandle handle;
66 MojoWaitFlags wait_flags; 66 MojoWaitFlags wait_flags;
67 base::TimeTicks deadline; 67 base::TimeTicks deadline;
68 base::Closure callback; 68 base::Callback<void(MojoResult)> callback;
69 scoped_refptr<base::MessageLoopProxy> message_loop; 69 scoped_refptr<base::MessageLoopProxy> message_loop;
70 }; 70 };
71 71
72 // Contains the state needed for MojoWaitMany. 72 // Contains the state needed for MojoWaitMany.
73 // NOTE: |handles| and |wait_flags| are separate vectors to make it easy to 73 // NOTE: |handles| and |wait_flags| are separate vectors to make it easy to
74 // pass to MojoWaitMany. 74 // pass to MojoWaitMany.
75 struct WaitState { 75 struct WaitState {
76 // List of ids. 76 // List of ids.
77 std::vector<WatcherID> ids; 77 std::vector<WatcherID> ids;
78 78
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 131
132 DISALLOW_COPY_AND_ASSIGN(WatcherThreadManager); 132 DISALLOW_COPY_AND_ASSIGN(WatcherThreadManager);
133 }; 133 };
134 134
135 WatcherThreadManager* WatcherThreadManager::GetInstance() { 135 WatcherThreadManager* WatcherThreadManager::GetInstance() {
136 static base::LazyInstance<WatcherThreadManager> instance = 136 static base::LazyInstance<WatcherThreadManager> instance =
137 LAZY_INSTANCE_INITIALIZER; 137 LAZY_INSTANCE_INITIALIZER;
138 return &instance.Get(); 138 return &instance.Get();
139 } 139 }
140 140
141 WatcherID WatcherThreadManager::StartWatching(MojoHandle handle, 141 WatcherID WatcherThreadManager::StartWatching(
142 MojoWaitFlags wait_flags, 142 MojoHandle handle,
143 base::TimeTicks deadline, 143 MojoWaitFlags wait_flags,
144 const base::Closure& callback) { 144 base::TimeTicks deadline,
145 const base::Callback<void(MojoResult)>& callback) {
145 WatcherID id = 0; 146 WatcherID id = 0;
146 { 147 {
147 static int next_id = 0; 148 static int next_id = 0;
148 base::AutoLock lock(lock_); 149 base::AutoLock lock(lock_);
149 // TODO(sky): worry about overflow? 150 // TODO(sky): worry about overflow?
150 id = ++next_id; 151 id = ++next_id;
151 id_to_callback_[id].handle = handle; 152 id_to_callback_[id].handle = handle;
152 id_to_callback_[id].callback = callback; 153 id_to_callback_[id].callback = callback;
153 id_to_callback_[id].wait_flags = wait_flags; 154 id_to_callback_[id].wait_flags = wait_flags;
154 id_to_callback_[id].deadline = deadline; 155 id_to_callback_[id].deadline = deadline;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 void WatcherThreadManager::RemoveAndNotify(WatcherID id, MojoResult result) { 258 void WatcherThreadManager::RemoveAndNotify(WatcherID id, MojoResult result) {
258 HandleAndCallback to_notify; 259 HandleAndCallback to_notify;
259 { 260 {
260 base::AutoLock lock(lock_); 261 base::AutoLock lock(lock_);
261 IDToCallbackMap::iterator i = id_to_callback_.find(id); 262 IDToCallbackMap::iterator i = id_to_callback_.find(id);
262 if (i == id_to_callback_.end()) 263 if (i == id_to_callback_.end())
263 return; 264 return;
264 to_notify = i->second; 265 to_notify = i->second;
265 id_to_callback_.erase(i); 266 id_to_callback_.erase(i);
266 } 267 }
267 to_notify.message_loop->PostTask(FROM_HERE, to_notify.callback); 268 to_notify.message_loop->PostTask(FROM_HERE,
269 base::Bind(to_notify.callback, result));
268 } 270 }
269 271
270 void WatcherThreadManager::RemoveHandle(MojoHandle handle) { 272 void WatcherThreadManager::RemoveHandle(MojoHandle handle) {
271 { 273 {
272 base::AutoLock lock(lock_); 274 base::AutoLock lock(lock_);
273 for (IDToCallbackMap::iterator i = id_to_callback_.begin(); 275 for (IDToCallbackMap::iterator i = id_to_callback_.begin();
274 i != id_to_callback_.end(); ) { 276 i != id_to_callback_.end(); ) {
275 if (i->second.handle == handle) { 277 if (i->second.handle == handle) {
276 id_to_callback_.erase(i++); 278 id_to_callback_.erase(i++);
277 } else { 279 } else {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 explicit StartState(HandleWatcher* watcher) : weak_factory(watcher) { 323 explicit StartState(HandleWatcher* watcher) : weak_factory(watcher) {
322 } 324 }
323 325
324 ~StartState() { 326 ~StartState() {
325 } 327 }
326 328
327 // ID assigned by WatcherThreadManager. 329 // ID assigned by WatcherThreadManager.
328 WatcherID watcher_id; 330 WatcherID watcher_id;
329 331
330 // Callback to notify when done. 332 // Callback to notify when done.
331 base::Closure callback; 333 base::Callback<void(MojoResult)> callback;
332 334
333 // When Start() is invoked a callback is passed to WatcherThreadManager 335 // When Start() is invoked a callback is passed to WatcherThreadManager
334 // using a WeakRef from |weak_refactory_|. The callback invokes 336 // using a WeakRef from |weak_refactory_|. The callback invokes
335 // OnHandleReady() (on the thread Start() is invoked from) which in turn 337 // OnHandleReady() (on the thread Start() is invoked from) which in turn
336 // notifies |callback_|. Doing this allows us to reset state when the handle 338 // notifies |callback_|. Doing this allows us to reset state when the handle
337 // is ready, and then notify the callback. Doing this also means Stop() 339 // is ready, and then notify the callback. Doing this also means Stop()
338 // cancels any pending callbacks that may be inflight. 340 // cancels any pending callbacks that may be inflight.
339 base::WeakPtrFactory<HandleWatcher> weak_factory; 341 base::WeakPtrFactory<HandleWatcher> weak_factory;
340 }; 342 };
341 343
342 // HandleWatcher --------------------------------------------------------------- 344 // HandleWatcher ---------------------------------------------------------------
343 345
344 // static 346 // static
345 base::TickClock* HandleWatcher::tick_clock_ = NULL; 347 base::TickClock* HandleWatcher::tick_clock_ = NULL;
346 348
347 HandleWatcher::HandleWatcher() { 349 HandleWatcher::HandleWatcher() {
348 } 350 }
349 351
350 HandleWatcher::~HandleWatcher() { 352 HandleWatcher::~HandleWatcher() {
351 Stop(); 353 Stop();
352 } 354 }
353 355
354 void HandleWatcher::Start(MojoHandle handle, 356 void HandleWatcher::Start(MojoHandle handle,
355 MojoWaitFlags wait_flags, 357 MojoWaitFlags wait_flags,
356 MojoDeadline deadline, 358 MojoDeadline deadline,
357 const base::Closure& callback) { 359 const base::Callback<void(MojoResult)>& callback) {
358 DCHECK_NE(MOJO_HANDLE_INVALID, handle); 360 DCHECK_NE(MOJO_HANDLE_INVALID, handle);
359 DCHECK_NE(MOJO_WAIT_FLAG_NONE, wait_flags); 361 DCHECK_NE(MOJO_WAIT_FLAG_NONE, wait_flags);
360 362
361 Stop(); 363 Stop();
362 364
363 start_state_.reset(new StartState(this)); 365 start_state_.reset(new StartState(this));
364 start_state_->callback = callback; 366 start_state_->callback = callback;
365 start_state_->watcher_id = 367 start_state_->watcher_id =
366 WatcherThreadManager::GetInstance()->StartWatching( 368 WatcherThreadManager::GetInstance()->StartWatching(
367 handle, 369 handle,
368 wait_flags, 370 wait_flags,
369 MojoDeadlineToTimeTicks(deadline), 371 MojoDeadlineToTimeTicks(deadline),
370 base::Bind(&HandleWatcher::OnHandleReady, 372 base::Bind(&HandleWatcher::OnHandleReady,
371 start_state_->weak_factory.GetWeakPtr())); 373 start_state_->weak_factory.GetWeakPtr()));
372 } 374 }
373 375
374 void HandleWatcher::Stop() { 376 void HandleWatcher::Stop() {
375 if (!start_state_.get()) 377 if (!start_state_.get())
376 return; 378 return;
377 379
378 scoped_ptr<StartState> old_state(start_state_.Pass()); 380 scoped_ptr<StartState> old_state(start_state_.Pass());
379 WatcherThreadManager::GetInstance()->StopWatching(old_state->watcher_id); 381 WatcherThreadManager::GetInstance()->StopWatching(old_state->watcher_id);
380 } 382 }
381 383
382 void HandleWatcher::OnHandleReady() { 384 void HandleWatcher::OnHandleReady(MojoResult result) {
383 DCHECK(start_state_.get()); 385 DCHECK(start_state_.get());
384 scoped_ptr<StartState> old_state(start_state_.Pass()); 386 scoped_ptr<StartState> old_state(start_state_.Pass());
385 old_state->callback.Run(); 387 old_state->callback.Run(result);
388
389 // NOTE: We may have been deleted during callback execution.
386 } 390 }
387 391
388 // static 392 // static
389 base::TimeTicks HandleWatcher::NowTicks() { 393 base::TimeTicks HandleWatcher::NowTicks() {
390 return tick_clock_ ? tick_clock_->NowTicks() : base::TimeTicks::Now(); 394 return tick_clock_ ? tick_clock_->NowTicks() : base::TimeTicks::Now();
391 } 395 }
392 396
393 // static 397 // static
394 base::TimeTicks HandleWatcher::MojoDeadlineToTimeTicks(MojoDeadline deadline) { 398 base::TimeTicks HandleWatcher::MojoDeadlineToTimeTicks(MojoDeadline deadline) {
395 return deadline == MOJO_DEADLINE_INDEFINITE ? base::TimeTicks() : 399 return deadline == MOJO_DEADLINE_INDEFINITE ? base::TimeTicks() :
396 NowTicks() + base::TimeDelta::FromMicroseconds(deadline); 400 NowTicks() + base::TimeDelta::FromMicroseconds(deadline);
397 } 401 }
398 402
399 } // namespace common 403 } // namespace common
400 } // namespace mojo 404 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698