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