1 // Copyright (c) 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.
5 #ifndef PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
6 #define PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_
8 #include "base/basictypes.h"
10 #include "base/memory/ref_counted.h"
11 #include "ppapi/shared_impl/ppapi_shared_export.h"
12 #include "ppapi/shared_impl/proxy_lock.h"
16 class MessageLoopShared
;
20 class PPAPI_SHARED_EXPORT ThreadAwareCallbackBase
{
22 ThreadAwareCallbackBase();
23 ~ThreadAwareCallbackBase();
25 static bool HasTargetLoop();
27 void InternalRunOnTargetThread(const base::Closure
& closure
);
32 scoped_refptr
<MessageLoopShared
> target_loop_
;
33 scoped_refptr
<Core
> core_
;
35 DISALLOW_COPY_AND_ASSIGN(ThreadAwareCallbackBase
);
38 } // namespace internal
40 // Some PPB interfaces have methods that set a custom callback. Usually, the
41 // callback has to be called on the same thread as the one it was set on.
42 // ThreadAwareCallback keeps track of the target thread, and posts a task to run
43 // on it if requested from a different thread.
46 // - Unlike TrackedCallback, there is no restriction on how many times the
47 // callback will be called.
48 // - When a ThreadAwareCallback object is destroyed, all pending tasks to run
49 // the callback will be ignored. It is designed this way so that when the
50 // resource is destroyed or the callback is cancelled by the plugin, we can
51 // simply delete the ThreadAwareCallback object to prevent touching the
53 // - When RunOnTargetThread() is called on the target thread, the callback runs
55 template <class FuncType
>
56 class ThreadAwareCallback
: public internal::ThreadAwareCallbackBase
{
58 // The caller takes ownership of the returned object.
59 // NULL is returned if the current thread doesn't have an associated Pepper
60 // message loop, or |func| is NULL.
61 static ThreadAwareCallback
* Create(FuncType func
) {
62 if (!func
|| !HasTargetLoop())
64 return new ThreadAwareCallback(func
);
67 ~ThreadAwareCallback() {
70 void RunOnTargetThread() {
71 InternalRunOnTargetThread(base::Bind(func_
));
75 void RunOnTargetThread(const P1
& p1
) {
76 InternalRunOnTargetThread(base::Bind(func_
, p1
));
79 template <class P1
, class P2
>
80 void RunOnTargetThread(const P1
& p1
, const P2
& p2
) {
81 InternalRunOnTargetThread(base::Bind(func_
, p1
, p2
));
84 template <class P1
, class P2
, class P3
>
85 void RunOnTargetThread(const P1
& p1
, const P2
& p2
, const P3
& p3
) {
86 InternalRunOnTargetThread(base::Bind(func_
, p1
, p2
, p3
));
89 template <class P1
, class P2
, class P3
, class P4
>
90 void RunOnTargetThread(const P1
& p1
,
94 InternalRunOnTargetThread(base::Bind(func_
, p1
, p2
, p3
, p4
));
97 template <class P1
, class P2
, class P3
, class P4
, class P5
>
98 void RunOnTargetThread(const P1
& p1
,
103 InternalRunOnTargetThread(base::Bind(func_
, p1
, p2
, p3
, p4
, p5
));
107 explicit ThreadAwareCallback(FuncType func
) : func_(func
) {
115 #endif // PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_