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/common/bindings_support_impl.h" 6 7 #include "base/atomic_ref_count.h" 8 #include "base/bind.h" 9 #include "base/lazy_instance.h" 10 #include "base/threading/thread_local.h" 11 #include "mojo/common/handle_watcher.h" 12 13 namespace mojo { 14 namespace common { 15 namespace { 16 base::LazyInstance<base::ThreadLocalPointer<Buffer> >::Leaky lazy_tls_ptr = 17 LAZY_INSTANCE_INITIALIZER; 18 } 19 20 // Context is used to track the number of HandleWatcher objects in use by a 21 // particular BindingsSupportImpl instance. 22 class BindingsSupportImpl::Context 23 : public base::RefCountedThreadSafe<BindingsSupportImpl::Context> { 24 public: 25 void CallOnHandleReady(HandleWatcher* watcher, 26 AsyncWaitCallback* callback, 27 MojoResult result) { 28 delete watcher; 29 callback->OnHandleReady(result); 30 } 31 32 private: 33 friend class base::RefCountedThreadSafe<Context>; 34 virtual ~Context() {} 35 }; 36 37 BindingsSupportImpl::BindingsSupportImpl() 38 : context_(new Context()) { 39 } 40 41 BindingsSupportImpl::~BindingsSupportImpl() { 42 // All HandleWatcher instances created through this interface should have 43 // been destroyed. 44 DCHECK(context_->HasOneRef()); 45 } 46 47 Buffer* BindingsSupportImpl::GetCurrentBuffer() { 48 return lazy_tls_ptr.Pointer()->Get(); 49 } 50 51 Buffer* BindingsSupportImpl::SetCurrentBuffer(Buffer* buf) { 52 Buffer* old_buf = lazy_tls_ptr.Pointer()->Get(); 53 lazy_tls_ptr.Pointer()->Set(buf); 54 return old_buf; 55 } 56 57 BindingsSupport::AsyncWaitID BindingsSupportImpl::AsyncWait( 58 const Handle& handle, 59 MojoWaitFlags flags, 60 AsyncWaitCallback* callback) { 61 // This instance will be deleted when done or cancelled. 62 HandleWatcher* watcher = new HandleWatcher(); 63 64 watcher->Start(handle, 65 flags, 66 MOJO_DEADLINE_INDEFINITE, 67 base::Bind(&Context::CallOnHandleReady, 68 context_, 69 watcher, 70 callback)); 71 return watcher; 72 } 73 74 void BindingsSupportImpl::CancelWait(AsyncWaitID async_wait_id) { 75 HandleWatcher* watcher = static_cast<HandleWatcher*>(async_wait_id); 76 delete watcher; 77 } 78 79 } // namespace common 80 } // namespace mojo 81