OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 #ifndef BASE_TASK_H_ | 5 #ifndef BASE_TASK_H_ |
6 #define BASE_TASK_H_ | 6 #define BASE_TASK_H_ |
7 | 7 |
8 #include "base/non_thread_safe.h" | 8 #include "base/non_thread_safe.h" |
9 #include "base/tracked.h" | 9 #include "base/tracked.h" |
10 #include "base/tuple.h" | 10 #include "base/tuple.h" |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 // | 198 // |
199 // This traits-class is used by RunnableMethod to manage the lifetime of the | 199 // This traits-class is used by RunnableMethod to manage the lifetime of the |
200 // callee object. By default, it is assumed that the callee supports AddRef | 200 // callee object. By default, it is assumed that the callee supports AddRef |
201 // and Release methods. A particular class can specialize this template to | 201 // and Release methods. A particular class can specialize this template to |
202 // define other lifetime management. For example, if the callee is known to | 202 // define other lifetime management. For example, if the callee is known to |
203 // live longer than the RunnableMethod object, then a RunnableMethodTraits | 203 // live longer than the RunnableMethod object, then a RunnableMethodTraits |
204 // struct could be defined with empty RetainCallee and ReleaseCallee methods. | 204 // struct could be defined with empty RetainCallee and ReleaseCallee methods. |
205 | 205 |
206 template <class T> | 206 template <class T> |
207 struct RunnableMethodTraits { | 207 struct RunnableMethodTraits { |
208 RunnableMethodTraits() { | 208 static void RetainCallee(T* obj) { |
209 #ifndef NDEBUG | |
210 origin_thread_id_ = PlatformThread::CurrentId(); | |
211 #endif | |
212 } | |
213 | |
214 ~RunnableMethodTraits() { | |
215 #ifndef NDEBUG | |
216 // If destroyed on a separate thread, then we had better have been using | |
217 // thread-safe reference counting! | |
218 if (origin_thread_id_ != PlatformThread::CurrentId()) | |
219 DCHECK(T::ImplementsThreadSafeReferenceCounting()); | |
220 #endif | |
221 } | |
222 | |
223 void RetainCallee(T* obj) { | |
224 obj->AddRef(); | 209 obj->AddRef(); |
225 } | 210 } |
226 | 211 static void ReleaseCallee(T* obj) { |
227 void ReleaseCallee(T* obj) { | |
228 obj->Release(); | 212 obj->Release(); |
229 } | 213 } |
230 | |
231 private: | |
232 #ifndef NDEBUG | |
233 PlatformThreadId origin_thread_id_; | |
234 #endif | |
235 }; | 214 }; |
236 | 215 |
237 // RunnableMethod and RunnableFunction ----------------------------------------- | 216 // RunnableMethod and RunnableFunction ----------------------------------------- |
238 // | 217 // |
239 // Runnable methods are a type of task that call a function on an object when | 218 // Runnable methods are a type of task that call a function on an object when |
240 // they are run. We implement both an object and a set of NewRunnableMethod and | 219 // they are run. We implement both an object and a set of NewRunnableMethod and |
241 // NewRunnableFunction functions for convenience. These functions are | 220 // NewRunnableFunction functions for convenience. These functions are |
242 // overloaded and will infer the template types, simplifying calling code. | 221 // overloaded and will infer the template types, simplifying calling code. |
243 // | 222 // |
244 // The template definitions all use the following names: | 223 // The template definitions all use the following names: |
245 // T - the class type of the object you're supplying | 224 // T - the class type of the object you're supplying |
246 // this is not needed for the Static version of the call | 225 // this is not needed for the Static version of the call |
247 // Method/Function - the signature of a pointer to the method or function you | 226 // Method/Function - the signature of a pointer to the method or function you |
248 // want to call | 227 // want to call |
249 // Param - the parameter(s) to the method, possibly packed as a Tuple | 228 // Param - the parameter(s) to the method, possibly packed as a Tuple |
250 // A - the first parameter (if any) to the method | 229 // A - the first parameter (if any) to the method |
251 // B - the second parameter (if any) to the mathod | 230 // B - the second parameter (if any) to the mathod |
252 // | 231 // |
253 // Put these all together and you get an object that can call a method whose | 232 // Put these all together and you get an object that can call a method whose |
254 // signature is: | 233 // signature is: |
255 // R T::MyFunction([A[, B]]) | 234 // R T::MyFunction([A[, B]]) |
256 // | 235 // |
257 // Usage: | 236 // Usage: |
258 // PostTask(FROM_HERE, NewRunnableMethod(object, &Object::method[, a[, b]]) | 237 // PostTask(FROM_HERE, NewRunnableMethod(object, &Object::method[, a[, b]]) |
259 // PostTask(FROM_HERE, NewRunnableFunction(&function[, a[, b]]) | 238 // PostTask(FROM_HERE, NewRunnableFunction(&function[, a[, b]]) |
260 | 239 |
261 // RunnableMethod and NewRunnableMethod implementation ------------------------- | 240 // RunnableMethod and NewRunnableMethod implementation ------------------------- |
262 | 241 |
263 template <class T, class Method, class Params> | 242 template <class T, class Method, class Params> |
264 class RunnableMethod : public CancelableTask { | 243 class RunnableMethod : public CancelableTask, |
| 244 public RunnableMethodTraits<T> { |
265 public: | 245 public: |
266 RunnableMethod(T* obj, Method meth, const Params& params) | 246 RunnableMethod(T* obj, Method meth, const Params& params) |
267 : obj_(obj), meth_(meth), params_(params) { | 247 : obj_(obj), meth_(meth), params_(params) { |
268 traits_.RetainCallee(obj_); | 248 RetainCallee(obj_); |
269 } | 249 } |
270 | |
271 ~RunnableMethod() { | 250 ~RunnableMethod() { |
272 ReleaseCallee(); | 251 ReleaseCallee(); |
273 } | 252 } |
274 | 253 |
275 virtual void Run() { | 254 virtual void Run() { |
276 if (obj_) | 255 if (obj_) |
277 DispatchToMethod(obj_, meth_, params_); | 256 DispatchToMethod(obj_, meth_, params_); |
278 } | 257 } |
279 | 258 |
280 virtual void Cancel() { | 259 virtual void Cancel() { |
281 ReleaseCallee(); | 260 ReleaseCallee(); |
282 } | 261 } |
283 | 262 |
284 private: | 263 private: |
285 void ReleaseCallee() { | 264 void ReleaseCallee() { |
286 if (obj_) { | 265 if (obj_) { |
287 traits_.ReleaseCallee(obj_); | 266 RunnableMethodTraits<T>::ReleaseCallee(obj_); |
288 obj_ = NULL; | 267 obj_ = NULL; |
289 } | 268 } |
290 } | 269 } |
291 | 270 |
292 T* obj_; | 271 T* obj_; |
293 Method meth_; | 272 Method meth_; |
294 Params params_; | 273 Params params_; |
295 RunnableMethodTraits<T> traits_; | |
296 }; | 274 }; |
297 | 275 |
298 template <class T, class Method> | 276 template <class T, class Method> |
299 inline CancelableTask* NewRunnableMethod(T* object, Method method) { | 277 inline CancelableTask* NewRunnableMethod(T* object, Method method) { |
300 return new RunnableMethod<T, Method, Tuple0>(object, method, MakeTuple()); | 278 return new RunnableMethod<T, Method, Tuple0>(object, method, MakeTuple()); |
301 } | 279 } |
302 | 280 |
303 template <class T, class Method, class A> | 281 template <class T, class Method, class A> |
304 inline CancelableTask* NewRunnableMethod(T* object, Method method, const A& a) { | 282 inline CancelableTask* NewRunnableMethod(T* object, Method method, const A& a) { |
305 return new RunnableMethod<T, Method, Tuple1<A> >(object, | 283 return new RunnableMethod<T, Method, Tuple1<A> >(object, |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 | 646 |
669 template <class T, typename ReturnValue> | 647 template <class T, typename ReturnValue> |
670 typename CallbackWithReturnValue<ReturnValue>::Type* | 648 typename CallbackWithReturnValue<ReturnValue>::Type* |
671 NewCallbackWithReturnValue(T* object, ReturnValue (T::*method)()) { | 649 NewCallbackWithReturnValue(T* object, ReturnValue (T::*method)()) { |
672 return new CallbackWithReturnValueImpl<T, ReturnValue (T::*)(), ReturnValue>( | 650 return new CallbackWithReturnValueImpl<T, ReturnValue (T::*)(), ReturnValue>( |
673 object, method); | 651 object, method); |
674 } | 652 } |
675 | 653 |
676 | 654 |
677 #endif // BASE_TASK_H_ | 655 #endif // BASE_TASK_H_ |
OLD | NEW |