普通文本  |  81行  |  2.29 KB

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "mojo/common/bindings_support_impl.h"

#include "base/atomic_ref_count.h"
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/threading/thread_local.h"
#include "mojo/common/handle_watcher.h"

namespace mojo {
namespace common {
namespace {
base::LazyInstance<base::ThreadLocalPointer<Buffer> >::Leaky lazy_tls_ptr =
    LAZY_INSTANCE_INITIALIZER;
}

// Context is used to track the number of HandleWatcher objects in use by a
// particular BindingsSupportImpl instance.
class BindingsSupportImpl::Context
    : public base::RefCountedThreadSafe<BindingsSupportImpl::Context> {
 public:
  void CallOnHandleReady(HandleWatcher* watcher,
                         AsyncWaitCallback* callback,
                         MojoResult result) {
    delete watcher;
    callback->OnHandleReady(result);
  }

 private:
  friend class base::RefCountedThreadSafe<Context>;
  virtual ~Context() {}
};

BindingsSupportImpl::BindingsSupportImpl()
    : context_(new Context()) {
}

BindingsSupportImpl::~BindingsSupportImpl() {
  // All HandleWatcher instances created through this interface should have
  // been destroyed.
  DCHECK(context_->HasOneRef());
}

Buffer* BindingsSupportImpl::GetCurrentBuffer() {
  return lazy_tls_ptr.Pointer()->Get();
}

Buffer* BindingsSupportImpl::SetCurrentBuffer(Buffer* buf) {
  Buffer* old_buf = lazy_tls_ptr.Pointer()->Get();
  lazy_tls_ptr.Pointer()->Set(buf);
  return old_buf;
}

BindingsSupport::AsyncWaitID BindingsSupportImpl::AsyncWait(
    const Handle& handle,
    MojoWaitFlags flags,
    AsyncWaitCallback* callback) {
  // This instance will be deleted when done or cancelled.
  HandleWatcher* watcher = new HandleWatcher();

  watcher->Start(handle,
                 flags,
                 MOJO_DEADLINE_INDEFINITE,
                 base::Bind(&Context::CallOnHandleReady,
                            context_,
                            watcher,
                            callback));
  return watcher;
}

void BindingsSupportImpl::CancelWait(AsyncWaitID async_wait_id) {
  HandleWatcher* watcher = static_cast<HandleWatcher*>(async_wait_id);
  delete watcher;
}

}  // namespace common
}  // namespace mojo