Home | History | Annotate | Download | only in utility
      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