12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/ppapi_shared_export.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ppapi {
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MessageLoopShared;
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PPAPI_SHARED_EXPORT ThreadAwareCallbackBase {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ThreadAwareCallbackBase();
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~ThreadAwareCallbackBase();
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool HasTargetLoop();
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void InternalRunOnTargetThread(const base::Closure& closure);
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class Core;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<MessageLoopShared> target_loop_;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<Core> core_;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ThreadAwareCallbackBase);
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace internal
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Some PPB interfaces have methods that set a custom callback. Usually, the
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// callback has to be called on the same thread as the one it was set on.
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ThreadAwareCallback keeps track of the target thread, and posts a task to run
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// on it if requested from a different thread.
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Please note that:
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - Unlike TrackedCallback, there is no restriction on how many times the
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   callback will be called.
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - When a ThreadAwareCallback object is destroyed, all pending tasks to run
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   the callback will be ignored. It is designed this way so that when the
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   resource is destroyed or the callback is cancelled by the plugin, we can
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   simply delete the ThreadAwareCallback object to prevent touching the
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   callback later.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - When RunOnTargetThread() is called on the target thread, the callback runs
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   immediately.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <class FuncType>
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ThreadAwareCallback : public internal::ThreadAwareCallbackBase {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The caller takes ownership of the returned object.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // NULL is returned if the current thread doesn't have an associated Pepper
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // message loop, or |func| is NULL.
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static ThreadAwareCallback* Create(FuncType func) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!func || !HasTargetLoop())
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return new ThreadAwareCallback(func);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ~ThreadAwareCallback() {}
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void RunOnTargetThread() { InternalRunOnTargetThread(base::Bind(func_)); }
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  template <class P1>
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RunOnTargetThread(const P1& p1) {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InternalRunOnTargetThread(base::Bind(func_, p1));
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  template <class P1, class P2>
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RunOnTargetThread(const P1& p1, const P2& p2) {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InternalRunOnTargetThread(base::Bind(func_, p1, p2));
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  template <class P1, class P2, class P3>
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RunOnTargetThread(const P1& p1, const P2& p2, const P3& p3) {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InternalRunOnTargetThread(base::Bind(func_, p1, p2, p3));
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  template <class P1, class P2, class P3, class P4>
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RunOnTargetThread(const P1& p1,
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const P2& p2,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const P3& p3,
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const P4& p4) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InternalRunOnTargetThread(base::Bind(func_, p1, p2, p3, p4));
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  template <class P1, class P2, class P3, class P4, class P5>
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RunOnTargetThread(const P1& p1,
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const P2& p2,
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const P3& p3,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const P4& p4,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const P5& p5) {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InternalRunOnTargetThread(base::Bind(func_, p1, p2, p3, p4, p5));
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  explicit ThreadAwareCallback(FuncType func) : func_(func) {}
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FuncType func_;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ppapi
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
112