Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(109)

Side by Side Diff: base/task.h

Issue 9034032: And now NewRunnableMethod(), you die. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix chrome_frame_automation Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/message_pump_glib_unittest.cc ('k') | base/task_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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_
OLDNEW
« no previous file with comments | « base/message_pump_glib_unittest.cc ('k') | base/task_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698