OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // ============================================================================ | 5 // ============================================================================ |
6 // **************************************************************************** | 6 // **************************************************************************** |
7 // * THIS HEADER IS DEPRECATED, SEE base/callback.h FOR NEW IMPLEMENTATION * | 7 // * THIS HEADER IS DEPRECATED, SEE base/callback.h FOR NEW IMPLEMENTATION * |
8 // **************************************************************************** | 8 // **************************************************************************** |
9 // ============================================================================ | 9 // ============================================================================ |
10 // ============================================================================ | 10 // ============================================================================ |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 | 63 |
64 // Not all tasks support cancellation. | 64 // Not all tasks support cancellation. |
65 virtual void Cancel() = 0; | 65 virtual void Cancel() = 0; |
66 }; | 66 }; |
67 | 67 |
68 template<typename T> | 68 template<typename T> |
69 void DeletePointer(T* obj) { | 69 void DeletePointer(T* obj) { |
70 delete obj; | 70 delete obj; |
71 } | 71 } |
72 | 72 |
73 // RunnableMethodTraits -------------------------------------------------------- | 73 template<typename T> |
74 // | 74 void ReleasePointer(T* obj) { |
75 // This traits-class is used by RunnableMethod to manage the lifetime of the | 75 obj->Release(); |
76 // callee object. By default, it is assumed that the callee supports AddRef | |
77 // and Release methods. A particular class can specialize this template to | |
78 // define other lifetime management. For example, if the callee is known to | |
79 // live longer than the RunnableMethod object, then a RunnableMethodTraits | |
80 // struct could be defined with empty RetainCallee and ReleaseCallee methods. | |
81 // | |
82 // The DISABLE_RUNNABLE_METHOD_REFCOUNT macro is provided as a convenient way | |
83 // for declaring a RunnableMethodTraits that disables refcounting. | |
84 | |
85 template <class T> | |
86 struct RunnableMethodTraits { | |
87 RunnableMethodTraits() { | |
88 #ifndef NDEBUG | |
89 origin_thread_id_ = base::PlatformThread::CurrentId(); | |
90 #endif | |
91 } | |
92 | |
93 ~RunnableMethodTraits() { | |
94 #ifndef NDEBUG | |
95 // If destroyed on a separate thread, then we had better have been using | |
96 // thread-safe reference counting! | |
97 if (origin_thread_id_ != base::PlatformThread::CurrentId()) | |
98 DCHECK(T::ImplementsThreadSafeReferenceCounting()); | |
99 #endif | |
100 } | |
101 | |
102 void RetainCallee(T* obj) { | |
103 #ifndef NDEBUG | |
104 // Catch NewRunnableMethod being called in an object's constructor. This | |
105 // isn't safe since the method can be invoked before the constructor | |
106 // completes, causing the object to be deleted. | |
107 obj->AddRef(); | |
108 obj->Release(); | |
109 #endif | |
110 obj->AddRef(); | |
111 } | |
112 | |
113 void ReleaseCallee(T* obj) { | |
114 obj->Release(); | |
115 } | |
116 | |
117 private: | |
118 #ifndef NDEBUG | |
119 base::PlatformThreadId origin_thread_id_; | |
120 #endif | |
121 }; | |
122 | |
123 // Convenience macro for declaring a RunnableMethodTraits that disables | |
124 // refcounting of a class. This is useful if you know that the callee | |
125 // will outlive the RunnableMethod object and thus do not need the ref counts. | |
126 // | |
127 // The invocation of DISABLE_RUNNABLE_METHOD_REFCOUNT should be done at the | |
128 // global namespace scope. Example: | |
129 // | |
130 // namespace foo { | |
131 // class Bar { | |
132 // ... | |
133 // }; | |
134 // } // namespace foo | |
135 // | |
136 // DISABLE_RUNNABLE_METHOD_REFCOUNT(foo::Bar); | |
137 // | |
138 // This is different from DISALLOW_COPY_AND_ASSIGN which is declared inside the | |
139 // class. | |
140 #define DISABLE_RUNNABLE_METHOD_REFCOUNT(TypeName) \ | |
141 template <> \ | |
142 struct RunnableMethodTraits<TypeName> { \ | |
143 void RetainCallee(TypeName* manager) {} \ | |
144 void ReleaseCallee(TypeName* manager) {} \ | |
145 } | |
146 | |
147 // RunnableMethod -------------------------------------------------------------- | |
148 // | |
149 // Runnable methods are a type of task that call a function on an object when | |
150 // they are run. We implement both an object and a set of NewRunnableMethod | |
151 // functions for convenience. These functions are overloaded and will infer the | |
152 // template types, simplifying calling code. | |
153 // | |
154 // The template definitions all use the following names: | |
155 // T - the class type of the object you're supplying | |
156 // this is not needed for the Static version of the call | |
157 // Method/Function - the signature of a pointer to the method or function you | |
158 // want to call | |
159 // Param - the parameter(s) to the method, possibly packed as a Tuple | |
160 // A - the first parameter (if any) to the method | |
161 // B - the second parameter (if any) to the method | |
162 // | |
163 // Put these all together and you get an object that can call a method whose | |
164 // signature is: | |
165 // R T::MyFunction([A[, B]]) | |
166 // | |
167 // Usage: | |
168 // PostTask(FROM_HERE, NewRunnableMethod(object, &Object::method[, a[, b]]) | |
169 | |
170 // RunnableMethod and NewRunnableMethod implementation ------------------------- | |
171 | |
172 template <class T, class Method, class Params> | |
173 class RunnableMethod : public CancelableTask { | |
174 public: | |
175 RunnableMethod(T* obj, Method meth, const Params& params) | |
176 : obj_(obj), meth_(meth), params_(params) { | |
177 traits_.RetainCallee(obj_); | |
178 COMPILE_ASSERT( | |
179 (base::internal::ParamsUseScopedRefptrCorrectly<Params>::value), | |
180 badrunnablemethodparams); | |
181 } | |
182 | |
183 ~RunnableMethod() { | |
184 ReleaseCallee(); | |
185 obj_ = reinterpret_cast<T*>(base::kDeadTask); | |
186 } | |
187 | |
188 virtual void Run() { | |
189 if (obj_) | |
190 DispatchToMethod(obj_, meth_, params_); | |
191 } | |
192 | |
193 virtual void Cancel() { | |
194 ReleaseCallee(); | |
195 } | |
196 | |
197 private: | |
198 void ReleaseCallee() { | |
199 T* obj = obj_; | |
200 obj_ = NULL; | |
201 if (obj) | |
202 traits_.ReleaseCallee(obj); | |
203 } | |
204 | |
205 T* obj_; | |
206 Method meth_; | |
207 Params params_; | |
208 RunnableMethodTraits<T> traits_; | |
209 }; | |
210 | |
211 template <class T, class Method> | |
212 inline CancelableTask* NewRunnableMethod(T* object, Method method) { | |
213 return new RunnableMethod<T, Method, Tuple0>(object, method, MakeTuple()); | |
214 } | |
215 | |
216 template <class T, class Method, class A> | |
217 inline CancelableTask* NewRunnableMethod(T* object, Method method, const A& a) { | |
218 return new RunnableMethod<T, Method, Tuple1<A> >(object, | |
219 method, | |
220 MakeTuple(a)); | |
221 } | |
222 | |
223 template <class T, class Method, class A, class B> | |
224 inline CancelableTask* NewRunnableMethod(T* object, Method method, | |
225 const A& a, const B& b) { | |
226 return new RunnableMethod<T, Method, Tuple2<A, B> >(object, method, | |
227 MakeTuple(a, b)); | |
228 } | |
229 | |
230 template <class T, class Method, class A, class B, class C> | |
231 inline CancelableTask* NewRunnableMethod(T* object, Method method, | |
232 const A& a, const B& b, const C& c) { | |
233 return new RunnableMethod<T, Method, Tuple3<A, B, C> >(object, method, | |
234 MakeTuple(a, b, c)); | |
235 } | |
236 | |
237 template <class T, class Method, class A, class B, class C, class D> | |
238 inline CancelableTask* NewRunnableMethod(T* object, Method method, | |
239 const A& a, const B& b, | |
240 const C& c, const D& d) { | |
241 return new RunnableMethod<T, Method, Tuple4<A, B, C, D> >(object, method, | |
242 MakeTuple(a, b, | |
243 c, d)); | |
244 } | |
245 | |
246 template <class T, class Method, class A, class B, class C, class D, class E> | |
247 inline CancelableTask* NewRunnableMethod(T* object, Method method, | |
248 const A& a, const B& b, | |
249 const C& c, const D& d, const E& e) { | |
250 return new RunnableMethod<T, | |
251 Method, | |
252 Tuple5<A, B, C, D, E> >(object, | |
253 method, | |
254 MakeTuple(a, b, c, d, e)); | |
255 } | |
256 | |
257 template <class T, class Method, class A, class B, class C, class D, class E, | |
258 class F> | |
259 inline CancelableTask* NewRunnableMethod(T* object, Method method, | |
260 const A& a, const B& b, | |
261 const C& c, const D& d, const E& e, | |
262 const F& f) { | |
263 return new RunnableMethod<T, | |
264 Method, | |
265 Tuple6<A, B, C, D, E, F> >(object, | |
266 method, | |
267 MakeTuple(a, b, c, d, e, | |
268 f)); | |
269 } | |
270 | |
271 template <class T, class Method, class A, class B, class C, class D, class E, | |
272 class F, class G> | |
273 inline CancelableTask* NewRunnableMethod(T* object, Method method, | |
274 const A& a, const B& b, | |
275 const C& c, const D& d, const E& e, | |
276 const F& f, const G& g) { | |
277 return new RunnableMethod<T, | |
278 Method, | |
279 Tuple7<A, B, C, D, E, F, G> >(object, | |
280 method, | |
281 MakeTuple(a, b, c, d, | |
282 e, f, g)); | |
283 } | |
284 | |
285 template <class T, class Method, class A, class B, class C, class D, class E, | |
286 class F, class G, class H> | |
287 inline CancelableTask* NewRunnableMethod(T* object, Method method, | |
288 const A& a, const B& b, | |
289 const C& c, const D& d, const E& e, | |
290 const F& f, const G& g, const H& h) { | |
291 return new RunnableMethod<T, | |
292 Method, | |
293 Tuple8<A, B, C, D, E, F, G, H> >(object, | |
294 method, | |
295 MakeTuple(a, b, c, | |
296 d, e, f, | |
297 g, h)); | |
298 } | 76 } |
299 | 77 |
300 namespace base { | 78 namespace base { |
301 | 79 |
302 // ScopedTaskRunner is akin to scoped_ptr for Tasks. It ensures that the Task | 80 // ScopedTaskRunner is akin to scoped_ptr for Tasks. It ensures that the Task |
303 // is executed and deleted no matter how the current scope exits. | 81 // is executed and deleted no matter how the current scope exits. |
304 class BASE_EXPORT ScopedTaskRunner { | 82 class BASE_EXPORT ScopedTaskRunner { |
305 public: | 83 public: |
306 // Takes ownership of the task. | 84 // Takes ownership of the task. |
307 explicit ScopedTaskRunner(Task* task); | 85 explicit ScopedTaskRunner(Task* task); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 Task* task_; | 140 Task* task_; |
363 bool* should_leak_task_; | 141 bool* should_leak_task_; |
364 static bool kTaskLeakingDefault; | 142 static bool kTaskLeakingDefault; |
365 }; | 143 }; |
366 | 144 |
367 } // namespace subtle | 145 } // namespace subtle |
368 | 146 |
369 } // namespace base | 147 } // namespace base |
370 | 148 |
371 #endif // BASE_TASK_H_ | 149 #endif // BASE_TASK_H_ |
OLD | NEW |