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 3 // found in the LICENSE file. 4 5 #include "mojo/public/utility/bindings_support_impl.h" 6 7 #include <assert.h> 8 9 #include "mojo/public/bindings/lib/buffer.h" 10 #include "mojo/public/utility/run_loop.h" 11 #include "mojo/public/utility/run_loop_handler.h" 12 #include "mojo/public/utility/thread_local.h" 13 14 namespace mojo { 15 namespace utility { 16 namespace internal { 17 namespace { 18 19 ThreadLocalPointer<Buffer>* tls_buffer = NULL; 20 21 // RunLoopHandler implementation used for a request to AsyncWait(). There are 22 // two ways RunLoopHandlerImpl is deleted: 23 // . when the handle is ready (or errored). 24 // . when BindingsSupport::CancelWait() is invoked. 25 class RunLoopHandlerImpl : public RunLoopHandler { 26 public: 27 RunLoopHandlerImpl(const Handle& handle, 28 BindingsSupport::AsyncWaitCallback* callback) 29 : handle_(handle), 30 callback_(callback) {} 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 BindingsSupport::AsyncWaitCallback* callback = callback_; 50 delete this; 51 52 callback->OnHandleReady(result); 53 } 54 55 const Handle handle_; 56 BindingsSupport::AsyncWaitCallback* callback_; 57 58 MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoopHandlerImpl); 59 }; 60 61 } // namespace 62 63 BindingsSupportImpl::BindingsSupportImpl() { 64 } 65 66 BindingsSupportImpl::~BindingsSupportImpl() { 67 } 68 69 // static 70 void BindingsSupportImpl::SetUp() { 71 assert(!tls_buffer); 72 tls_buffer = new ThreadLocalPointer<Buffer>; 73 } 74 75 // static 76 void BindingsSupportImpl::TearDown() { 77 assert(tls_buffer); 78 delete tls_buffer; 79 tls_buffer = NULL; 80 } 81 82 Buffer* BindingsSupportImpl::GetCurrentBuffer() { 83 return tls_buffer->Get(); 84 } 85 86 Buffer* BindingsSupportImpl::SetCurrentBuffer(Buffer* buf) { 87 Buffer* old_buf = tls_buffer->Get(); 88 tls_buffer->Set(buf); 89 return old_buf; 90 } 91 92 BindingsSupport::AsyncWaitID BindingsSupportImpl::AsyncWait( 93 const Handle& handle, 94 MojoWaitFlags flags, 95 AsyncWaitCallback* callback) { 96 RunLoop* run_loop = RunLoop::current(); 97 assert(run_loop); 98 // |run_loop_handler| is destroyed either when the handle is ready or if 99 // CancelWait is invoked. 100 RunLoopHandlerImpl* run_loop_handler = 101 new RunLoopHandlerImpl(handle, callback); 102 run_loop->AddHandler(run_loop_handler, handle, flags, 103 MOJO_DEADLINE_INDEFINITE); 104 return run_loop_handler; 105 } 106 107 void BindingsSupportImpl::CancelWait(AsyncWaitID async_wait_id) { 108 delete static_cast<RunLoopHandlerImpl*>(async_wait_id); 109 } 110 111 } // namespace internal 112 } // namespace utility 113 } // namespace mojo 114