1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "mojo/public/cpp/environment/lib/default_async_waiter.h" 6 7 #include <assert.h> 8 9 #include "mojo/public/c/environment/async_waiter.h" 10 #include "mojo/public/cpp/utility/run_loop.h" 11 #include "mojo/public/cpp/utility/run_loop_handler.h" 12 13 namespace mojo { 14 15 namespace { 16 17 // RunLoopHandler implementation used for a request to AsyncWait(). There are 18 // two ways RunLoopHandlerImpl is deleted: 19 // . when the handle is ready (or errored). 20 // . when CancelWait() is invoked. 21 class RunLoopHandlerImpl : public RunLoopHandler { 22 public: 23 RunLoopHandlerImpl(const Handle& handle, 24 MojoAsyncWaitCallback callback, 25 void* closure) 26 : handle_(handle), 27 callback_(callback), 28 closure_(closure) { 29 } 30 31 virtual ~RunLoopHandlerImpl() { 32 RunLoop::current()->RemoveHandler(handle_); 33 } 34 35 // RunLoopHandler: 36 virtual void OnHandleReady(const Handle& handle) MOJO_OVERRIDE { 37 NotifyCallback(MOJO_RESULT_OK); 38 } 39 40 virtual void OnHandleError(const Handle& handle, 41 MojoResult result) MOJO_OVERRIDE { 42 NotifyCallback(result); 43 } 44 45 private: 46 void NotifyCallback(MojoResult result) { 47 // Delete this to unregister the handle. That way if the callback 48 // reregisters everything is ok. 49 MojoAsyncWaitCallback callback = callback_; 50 void* closure = closure_; 51 delete this; 52 53 callback(closure, result); 54 } 55 56 const Handle handle_; 57 MojoAsyncWaitCallback callback_; 58 void* closure_; 59 60 MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoopHandlerImpl); 61 }; 62 63 MojoAsyncWaitID AsyncWait(MojoHandle handle, 64 MojoHandleSignals signals, 65 MojoDeadline deadline, 66 MojoAsyncWaitCallback callback, 67 void* closure) { 68 RunLoop* run_loop = RunLoop::current(); 69 assert(run_loop); 70 71 // |run_loop_handler| is destroyed either when the handle is ready or if 72 // CancelWait is invoked. 73 RunLoopHandlerImpl* run_loop_handler = 74 new RunLoopHandlerImpl(Handle(handle), callback, closure); 75 run_loop->AddHandler(run_loop_handler, Handle(handle), signals, deadline); 76 return reinterpret_cast<MojoAsyncWaitID>(run_loop_handler); 77 } 78 79 void CancelWait(MojoAsyncWaitID wait_id) { 80 delete reinterpret_cast<RunLoopHandlerImpl*>(wait_id); 81 } 82 83 } // namespace 84 85 namespace internal { 86 87 const MojoAsyncWaiter kDefaultAsyncWaiter = { 88 AsyncWait, 89 CancelWait 90 }; 91 92 } // namespace internal 93 94 } // namespace mojo 95