// Copyright (c) 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.

#ifndef PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
#define PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_

#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "ppapi/shared_impl/ppapi_shared_export.h"
#include "ppapi/shared_impl/proxy_lock.h"

namespace ppapi {

class MessageLoopShared;

namespace internal {

class PPAPI_SHARED_EXPORT ThreadAwareCallbackBase {
 protected:
  ThreadAwareCallbackBase();
  ~ThreadAwareCallbackBase();

  static bool HasTargetLoop();

  void InternalRunOnTargetThread(const base::Closure& closure);

 private:
  class Core;

  scoped_refptr<MessageLoopShared> target_loop_;
  scoped_refptr<Core> core_;

  DISALLOW_COPY_AND_ASSIGN(ThreadAwareCallbackBase);
};

}  // namespace internal

// Some PPB interfaces have methods that set a custom callback. Usually, the
// callback has to be called on the same thread as the one it was set on.
// ThreadAwareCallback keeps track of the target thread, and posts a task to run
// on it if requested from a different thread.
//
// Please note that:
// - Unlike TrackedCallback, there is no restriction on how many times the
//   callback will be called.
// - When a ThreadAwareCallback object is destroyed, all pending tasks to run
//   the callback will be ignored. It is designed this way so that when the
//   resource is destroyed or the callback is cancelled by the plugin, we can
//   simply delete the ThreadAwareCallback object to prevent touching the
//   callback later.
// - When RunOnTargetThread() is called on the target thread, the callback runs
//   immediately.
template <class FuncType>
class ThreadAwareCallback : public internal::ThreadAwareCallbackBase {
 public:
  // The caller takes ownership of the returned object.
  // NULL is returned if the current thread doesn't have an associated Pepper
  // message loop, or |func| is NULL.
  static ThreadAwareCallback* Create(FuncType func) {
    if (!func || !HasTargetLoop())
      return NULL;
    return new ThreadAwareCallback(func);
  }

  ~ThreadAwareCallback() {}

  void RunOnTargetThread() { InternalRunOnTargetThread(base::Bind(func_)); }

  template <class P1>
  void RunOnTargetThread(const P1& p1) {
    InternalRunOnTargetThread(base::Bind(func_, p1));
  }

  template <class P1, class P2>
  void RunOnTargetThread(const P1& p1, const P2& p2) {
    InternalRunOnTargetThread(base::Bind(func_, p1, p2));
  }

  template <class P1, class P2, class P3>
  void RunOnTargetThread(const P1& p1, const P2& p2, const P3& p3) {
    InternalRunOnTargetThread(base::Bind(func_, p1, p2, p3));
  }

  template <class P1, class P2, class P3, class P4>
  void RunOnTargetThread(const P1& p1,
                         const P2& p2,
                         const P3& p3,
                         const P4& p4) {
    InternalRunOnTargetThread(base::Bind(func_, p1, p2, p3, p4));
  }

  template <class P1, class P2, class P3, class P4, class P5>
  void RunOnTargetThread(const P1& p1,
                         const P2& p2,
                         const P3& p3,
                         const P4& p4,
                         const P5& p5) {
    InternalRunOnTargetThread(base::Bind(func_, p1, p2, p3, p4, p5));
  }

 private:
  explicit ThreadAwareCallback(FuncType func) : func_(func) {}

  FuncType func_;
};

}  // namespace ppapi

#endif  // PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
