OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #ifndef PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_ |
| 6 #define PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_ |
| 7 |
| 8 #include "base/basictypes.h" |
| 9 #include "base/bind.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" |
| 13 |
| 14 namespace ppapi { |
| 15 |
| 16 class MessageLoopShared; |
| 17 |
| 18 namespace internal { |
| 19 |
| 20 class PPAPI_SHARED_EXPORT ThreadAwareCallbackBase { |
| 21 protected: |
| 22 ThreadAwareCallbackBase(); |
| 23 ~ThreadAwareCallbackBase(); |
| 24 |
| 25 bool ShouldPostToTargetLoop(); |
| 26 void RunIfNotAborted(const base::Closure& closure); |
| 27 |
| 28 private: |
| 29 class Core; |
| 30 |
| 31 scoped_refptr<MessageLoopShared> target_loop_; |
| 32 scoped_refptr<Core> core_; |
| 33 |
| 34 DISALLOW_COPY_AND_ASSIGN(ThreadAwareCallbackBase); |
| 35 }; |
| 36 |
| 37 } // namespace internal |
| 38 |
| 39 // Some PPB interfaces have methods that set a custom callback. Usually, the |
| 40 // callback has to be called on the same thread as the one it was set on. |
| 41 // ThreadAwareCallback keeps track of the target thread, and posts a task to run |
| 42 // on it if requested from a different thread. |
| 43 // |
| 44 // Please note that: |
| 45 // - Unlike TrackedCallback, there is no restriction on how many times the |
| 46 // callback will be called. |
| 47 // - When a ThreadAwareCallback object is destroyed, all pending tasks to run |
| 48 // the callback will be ignored. It is designed this way so that when the |
| 49 // resource is destroyed or the callback is cancelled by the plugin, we can |
| 50 // simply delete the ThreadAwareCallback object to prevent touching the |
| 51 // callback later. |
| 52 // - When RunOnTargetThread() (defined in those sepcialized versions of |
| 53 // the template) is called on the target thread, the callback runs |
| 54 // immediately. |
| 55 template <class FuncType> |
| 56 class ThreadAwareCallback; |
| 57 |
| 58 template <> |
| 59 class ThreadAwareCallback<void (*)()> |
| 60 : public internal::ThreadAwareCallbackBase { |
| 61 public: |
| 62 typedef void (*FuncType)(); |
| 63 |
| 64 explicit ThreadAwareCallback(FuncType func) : func_(func) { |
| 65 } |
| 66 ~ThreadAwareCallback() { |
| 67 } |
| 68 |
| 69 void RunOnTargetThread() { |
| 70 if (ShouldPostToTargetLoop()) |
| 71 RunIfNotAborted(base::Bind(func_)); |
| 72 else |
| 73 ppapi::CallWhileUnlocked<void>(func_); |
| 74 } |
| 75 |
| 76 private: |
| 77 FuncType func_; |
| 78 }; |
| 79 |
| 80 template <class P1> |
| 81 class ThreadAwareCallback<void (*)(P1)> |
| 82 : public internal::ThreadAwareCallbackBase { |
| 83 public: |
| 84 typedef void (*FuncType)(P1); |
| 85 |
| 86 explicit ThreadAwareCallback(FuncType func) : func_(func) { |
| 87 } |
| 88 ~ThreadAwareCallback() { |
| 89 } |
| 90 |
| 91 void RunOnTargetThread(const P1& p1) { |
| 92 if (ShouldPostToTargetLoop()) |
| 93 RunIfNotAborted(base::Bind(func_, p1)); |
| 94 else |
| 95 ppapi::CallWhileUnlocked<void, P1>(func_, p1); |
| 96 } |
| 97 |
| 98 private: |
| 99 FuncType func_; |
| 100 }; |
| 101 |
| 102 template <class P1, class P2> |
| 103 class ThreadAwareCallback<void (*)(P1, P2)> |
| 104 : public internal::ThreadAwareCallbackBase { |
| 105 public: |
| 106 typedef void (*FuncType)(P1, P2); |
| 107 |
| 108 explicit ThreadAwareCallback(FuncType func) : func_(func) { |
| 109 } |
| 110 ~ThreadAwareCallback() { |
| 111 } |
| 112 |
| 113 void RunOnTargetThread(const P1& p1, const P2& p2) { |
| 114 if (ShouldPostToTargetLoop()) |
| 115 RunIfNotAborted(base::Bind(func_, p1, p2)); |
| 116 else |
| 117 ppapi::CallWhileUnlocked<void, P1, P2>(func_, p1, p2); |
| 118 } |
| 119 |
| 120 private: |
| 121 FuncType func_; |
| 122 }; |
| 123 |
| 124 template <class P1, class P2, class P3> |
| 125 class ThreadAwareCallback<void (*)(P1, P2, P3)> |
| 126 : public internal::ThreadAwareCallbackBase { |
| 127 public: |
| 128 typedef void (*FuncType)(P1, P2, P3); |
| 129 |
| 130 explicit ThreadAwareCallback(FuncType func) : func_(func) { |
| 131 } |
| 132 ~ThreadAwareCallback() { |
| 133 } |
| 134 |
| 135 void RunOnTargetThread(const P1& p1, const P2& p2, const P3& p3) { |
| 136 if (ShouldPostToTargetLoop()) |
| 137 RunIfNotAborted(base::Bind(func_, p1, p2, p3)); |
| 138 else |
| 139 ppapi::CallWhileUnlocked<void, P1, P2, P3>(func_, p1, p2, p3); |
| 140 } |
| 141 |
| 142 private: |
| 143 FuncType func_; |
| 144 }; |
| 145 |
| 146 template <class P1, class P2, class P3, class P4> |
| 147 class ThreadAwareCallback<void (*)(P1, P2, P3, P4)> |
| 148 : public internal::ThreadAwareCallbackBase { |
| 149 public: |
| 150 typedef void (*FuncType)(P1, P2, P3, P4); |
| 151 |
| 152 explicit ThreadAwareCallback(FuncType func) : func_(func) { |
| 153 } |
| 154 ~ThreadAwareCallback() { |
| 155 } |
| 156 |
| 157 void RunOnTargetThread(const P1& p1, |
| 158 const P2& p2, |
| 159 const P3& p3, |
| 160 const P4& p4) { |
| 161 if (ShouldPostToTargetLoop()) |
| 162 RunIfNotAborted(base::Bind(func_, p1, p2, p3, p4)); |
| 163 else |
| 164 ppapi::CallWhileUnlocked<void, P1, P2, P3, P4>(func_, p1, p2, p3, p4); |
| 165 } |
| 166 |
| 167 private: |
| 168 FuncType func_; |
| 169 }; |
| 170 |
| 171 template <class P1, class P2, class P3, class P4, class P5> |
| 172 class ThreadAwareCallback<void (*)(P1, P2, P3, P4, P5)> |
| 173 : public internal::ThreadAwareCallbackBase { |
| 174 public: |
| 175 typedef void (*FuncType)(P1, P2, P3, P4, P5); |
| 176 |
| 177 explicit ThreadAwareCallback(FuncType func) : func_(func) { |
| 178 } |
| 179 ~ThreadAwareCallback() { |
| 180 } |
| 181 |
| 182 void RunOnTargetThread(const P1& p1, |
| 183 const P2& p2, |
| 184 const P3& p3, |
| 185 const P4& p4, |
| 186 const P5& p5) { |
| 187 if (ShouldPostToTargetLoop()) { |
| 188 RunIfNotAborted(base::Bind(func_, p1, p2, p3, p4, p5)); |
| 189 } else { |
| 190 ppapi::CallWhileUnlocked<void, P1, P2, P3, P4, P5>(func_, p1, p2, p3, p4, |
| 191 p5); |
| 192 } |
| 193 } |
| 194 |
| 195 private: |
| 196 FuncType func_; |
| 197 }; |
| 198 |
| 199 } // namespace ppapi |
| 200 |
| 201 #endif // PPAPI_SHARED_IMPL_THREAD_AWARE_CALLBACK_H_ |
OLD | NEW |