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

Side by Side Diff: docs/callback.md

Issue 2122543002: Replace Closure in TaskRunner::PostTask with OneShotCallback (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@07_oneshot
Patch Set: fix Created 4 years, 3 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
« no previous file with comments | « device/bluetooth/test/bluetooth_test_win.cc ('k') | ios/web/public/web_thread.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # base::Callback<> and base::Bind() 1 # Callback<> and Bind()
2 2
3 ## Introduction 3 ## Introduction
4 4
5 The templated `Callback<>` class is a generalized function object. Together with 5 The templated `Callback<>` class is a generalized function object. Together with
6 the `Bind()` function in base/bind.h, they provide a type-safe method for 6 the `Bind()` function in base/bind.h, they provide a type-safe method for
7 performing partial application of functions. 7 performing partial application of functions.
8 8
9 Partial application (or "currying") is the process of binding a subset of a 9 Partial application (or "currying") is the process of binding a subset of a
10 function's arguments to produce another function that takes fewer arguments. 10 function's arguments to produce another function that takes fewer arguments.
11 This can be used to pass around a unit of delayed execution, much like lexical 11 This can be used to pass around a unit of delayed execution, much like lexical
12 closures are used in other languages. For example, it is used in Chromium code 12 closures are used in other languages. For example, it is used in Chromium code
13 to schedule tasks on different MessageLoops. 13 to schedule tasks on different MessageLoops.
14 14
15 A callback with no unbound input parameters (`Callback<void()>`) is called a 15 A callback with no unbound input parameters (`Callback<void()>`) is called a
16 `Closure`. Note that this is NOT the same as what other languages refer to as a 16 `Closure`. Note that this is NOT the same as what other languages refer to as a
17 closure -- it does not retain a reference to its enclosing environment. 17 closure -- it does not retain a reference to its enclosing environment.
18 18
19 ### OnceCallback<> And RepeatingCallback<>
20
21 `OnceCallback<>` and `RepeatingCallback<>` are next gen callback classes, which
22 are under development.
23
24 `OnceCallback<>` is created by `BindOnce()` as a restricted variant of
25 `Callback<>`. This is a move-only type and can be run only once. It can handle
26 movable types better as its bound parameter, and has clearer lifetime. Thus,
27 thread hopping and result handning of an asynchronous operation are a good fit
28 for it.
29
30 `RepeatingCallback<>` is created by `BindRepeating()` as a loose variant.
31 Its internal storage is ref-counted and `RepeatingCallback<>` itself is a
32 copyable type. It can run more than once. So, it's suitable for event handlers
33 that may happen more than once. It's discouraged to use this for a thread hop,
34 since you cannot predict on which thread the callback object is destroyed.
35
36 The historycal `Callback<>` is `RepeatingCallback<>`. It's an alias of
37 `RepeatingCallback<>` for a while until the migration is completed, and
38 eventually `OnceCallback<>` will be renamed to `Callback<>`.
39
40 `RepeatingCallback<>` is convertible to `OnceCallback<>` by the implicit
41 conversion.
42
19 ### Memory Management And Passing 43 ### Memory Management And Passing
20 44
21 The Callback objects themselves should be passed by const-reference, and stored 45 When you take a `Callback` object as a function argument, take it by value if
22 by copy. They internally store their state via a refcounted class and thus do 46 you retain the ownership, otherwise take it by const-reference.
23 not need to be deleted.
24 47
25 The reason to pass via a const-reference is to avoid unnecessary AddRef/Release 48 ```cpp
26 pairs to the internal state. 49 // |Foo| just refers |cb|, but doesn't store it nor consume it. So the parameter
50 // type should be a const-reference.
51 bool Foo(const OnceCallback<void(int)>& cb) {
52 return cb.is_null();
53 }
54
55 // |Bar| takes the ownership of |cb| and stores |cb| into |g_cb|. Pass the
56 // Callback by value in this case.
57 OnceCallback<void(int)> g_cb;
58 void Bar(OnceCallback<void(int)> cb) {
59 g_cb = std::move(cb);
60 }
61
62 // |Baz| takes the ownership of |cb| and consumes |cb| by Run(). Pass the
63 // Callback by value in this case.
64 void Baz(OnceCallback<void(int)> cb) {
65 std::move(cb).Run(42);
66 }
67
68 // |Qux| takes the ownership of |cb| and forwards it to PostTask, which also
69 // takes the ownership of |cb|. Pass the Callback by value in this case.
70 void Qux(OnceCallback<void(int)> cb) {
71 PostTask(FROM_HERE, std::move(cb));
72 }
73 ```
74
75 When you pass a `Callback` object to a function parameter, use `std::move()` if
76 you don't need to keep a reference to it, otherwise, pass the object directly.
77 You may see a compile error when the function requires the exclusive ownership,
78 and you didn't pass the callback by move.
27 79
28 ## Quick reference for basic stuff 80 ## Quick reference for basic stuff
29 81
30 ### Binding A Bare Function 82 ### Binding A Bare Function
31 83
32 ```cpp 84 ```cpp
33 int Return5() { return 5; } 85 int Return5() { return 5; }
34 base::Callback<int()> func_cb = base::Bind(&Return5); 86 Callback<int()> func_cb = Bind(&Return5);
35 LOG(INFO) << func_cb.Run(); // Prints 5. 87 LOG(INFO) << func_cb.Run(); // Prints 5.
88
89 OnceCallback<int()> func_cb2 = BindOnce(&Return5);
90 LOG(INFO) << std::move(func_cb2).Run(); // Prints 5.
91 ```
92
93 ### Binding A Captureless Lambda
94
95 ```cpp
96 Callback<int()> lambda_cb = Bind([] { return 4; });
97 LOG(INFO) << lambda_cb.Run(); // Print 4.
98
99 OnceCallback<int()> lambda_cb2 = BindOnce([] { return 3; });
100 LOG(INFO) << std::move(lambda_cb2).Run(); // Print 3.
101
36 ``` 102 ```
37 103
38 ### Binding A Class Method 104 ### Binding A Class Method
39 105
40 The first argument to bind is the member function to call, the second is the 106 The first argument to bind is the member function to call, the second is the
41 object on which to call it. 107 object on which to call it.
42 108
43 ```cpp 109 ```cpp
44 class Ref : public base::RefCountedThreadSafe<Ref> { 110 class Ref : public RefCountedThreadSafe<Ref> {
45 public: 111 public:
46 int Foo() { return 3; } 112 int Foo() { return 3; }
47 void PrintBye() { LOG(INFO) << "bye."; }
48 }; 113 };
114
49 scoped_refptr<Ref> ref = new Ref(); 115 scoped_refptr<Ref> ref = new Ref();
50 base::Callback<void()> ref_cb = base::Bind(&Ref::Foo, ref); 116 Callback<void()> ref_cb = Bind(&Ref::Foo, ref);
51 LOG(INFO) << ref_cb.Run(); // Prints out 3. 117 LOG(INFO) << ref_cb.Run(); // Prints out 3.
52 ``` 118 ```
53 119
54 By default the object must support RefCounted or you will get a compiler 120 By default the object must support RefCounted or you will get a compiler
55 error. If you're passing between threads, be sure it's 121 error. If you're passing between threads, be sure it's RefCountedThreadSafe!
56 RefCountedThreadSafe! See "Advanced binding of member functions" below if 122 See "Advanced binding of member functions" below if you don't want to use
57 you don't want to use reference counting. 123 reference counting.
58 124
59 ### Running A Callback 125 ### Running A Callback
60 126
61 Callbacks can be run with their `Run` method, which has the same 127 Callbacks can be run with their "Run" method, which has the same signature as
62 signature as the template argument to the callback. 128 the template argument to the callback.
129
130 `RepeatingCallback<>` can be run directly.
63 131
64 ```cpp 132 ```cpp
65 void DoSomething(const base::Callback<void(int, std::string)>& callback) { 133 void DoSomething(const RepeatingCallback<void(int, std::string)>& callback) {
66 callback.Run(5, "hello"); 134 callback.Run(5, "hello");
67 } 135 }
68 ``` 136 ```
69 137
70 Callbacks can be run more than once (they don't get deleted or marked when
71 run). However, this precludes using base::Passed (see below).
72
73 ```cpp 138 ```cpp
74 void DoSomething(const base::Callback<double(double)>& callback) { 139 void DoSomething(const RepeatingCallback<double(double)>& callback) {
75 double myresult = callback.Run(3.14159); 140 double myresult = callback.Run(3.14159);
76 myresult += callback.Run(2.71828); 141 myresult += callback.Run(2.71828);
77 } 142 }
78 ``` 143 ```
79 144
145 `OnceCallback<>` can be run when it's a rvalue. Use `std::move` or
146 `ResetAndReturn` to run it.
147
148 ```cpp
149 void DoSomething(OnceCallback<void(int, double)> callback) {
150 std::move(callback).Run(1, 0.1);
151 }
152 ```
153
154 ```cpp
155 void DoSomething(OnceCallback<void()> callback) {
156 ResetAndReturn(&callback).Run();
157 }
158 ```
159
160 `RepeatingCallback<>` can be run more than once (they don't get deleted or
161 marked when run). However, this precludes using `Passed` (see below).
162
80 ### Passing Unbound Input Parameters 163 ### Passing Unbound Input Parameters
81 164
82 Unbound parameters are specified at the time a callback is `Run()`. They are 165 Unbound parameters are specified at the time a callback is `Run()`. They are
83 specified in the `Callback` template type: 166 specified in the `Callback` template type:
84 167
85 ```cpp 168 ```cpp
86 void MyFunc(int i, const std::string& str) {} 169 void MyFunc(int i, const std::string& str) {}
87 base::Callback<void(int, const std::string&)> cb = base::Bind(&MyFunc); 170 Callback<void(int, const std::string&)> cb = Bind(&MyFunc);
88 cb.Run(23, "hello, world"); 171 cb.Run(23, "hello, world");
89 ``` 172 ```
90 173
91 ### Passing Bound Input Parameters 174 ### Passing Bound Input Parameters
92 175
93 Bound parameters are specified when you create the callback as arguments to 176 Bound parameters are specified when you create the callback as arguments to
94 `Bind()`. They will be passed to the function and the `Run()`ner of the callback 177 `Bind()`. They will be passed to the function and the runner of the callback
95 doesn't see those values or even know that the function it's calling. 178 doesn't see those values or even know that the function it's calling.
96 179
97 ```cpp 180 ```cpp
98 void MyFunc(int i, const std::string& str) {} 181 void MyFunc(int i, const std::string& str) {}
99 base::Callback<void()> cb = base::Bind(&MyFunc, 23, "hello world"); 182 Callback<void()> cb = Bind(&MyFunc, 23, "hello world");
100 cb.Run(); 183 cb.Run();
101 ``` 184 ```
102 185
103 A callback with no unbound input parameters (`base::Callback<void()>`) is called 186 A callback with no unbound input parameters (`Callback<void()>`,
104 a `base::Closure`. So we could have also written: 187 `OnceCallback<void()>` and `RepeatingCallback<void()>`) is called a
188 `Closure`, `OnceClosure` and `RepeatingClosure`, respectively.
189 So we could have also written:
105 190
106 ```cpp 191 ```cpp
107 base::Closure cb = base::Bind(&MyFunc, 23, "hello world"); 192 Closure cb = Bind(&MyFunc, 23, "hello world");
108 ``` 193 ```
109 194
110 When calling member functions, bound parameters just go after the object 195 When calling member functions, bound parameters just go after the object
111 pointer. 196 pointer.
112 197
113 ```cpp 198 ```cpp
114 base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world"); 199 Closure cb = Bind(&MyClass::MyFunc, this, 23, "hello world");
115 ``` 200 ```
116 201
117 ### Partial Binding Of Parameters 202 ### Partial Binding Of Parameters
118 203
119 You can specify some parameters when you create the callback, and specify the 204 You can specify some parameters when you create the callback, and specify
120 rest when you execute the callback. 205 the rest when you execute the callback.
121 206
122 ```cpp 207 ```cpp
123 void MyFunc(int i, const std::string& str) {} 208 void MyFunc(int i, const std::string& str) {}
124 base::Callback<void(const std::string&)> cb = base::Bind(&MyFunc, 23); 209 Callback<void(const std::string&)> cb = Bind(&MyFunc, 23);
125 cb.Run("hello world"); 210 cb.Run("hello world");
126 ``` 211 ```
127 212
128 When calling a function bound parameters are first, followed by unbound
129 parameters.
130
131 ## Quick reference for advanced binding 213 ## Quick reference for advanced binding
132 214
133 ### Binding A Class Method With Weak Pointers 215 ### Binding A Class Method With Weak Pointers
134 216
135 ```cpp 217 ```cpp
136 base::Bind(&MyClass::Foo, GetWeakPtr()); 218 Bind(&MyClass::Foo, GetWeakPtr());
137 ``` 219 ```
138 220
139 The callback will not be run if the object has already been destroyed. 221 The callback will not be run if the object has already been destroyed.
140 **DANGER**: weak pointers are not threadsafe, so don't use this when passing bet ween 222
141 threads! 223 **DANGER**: weak pointers are not threadsafe, so don't use this when you pass it
224 between threads!
142 225
143 ### Binding A Class Method With Manual Lifetime Management 226 ### Binding A Class Method With Manual Lifetime Management
144 227
145 ```cpp 228 ```cpp
146 base::Bind(&MyClass::Foo, base::Unretained(this)); 229 Bind(&MyClass::Foo, Unretained(this));
147 ``` 230 ```
148 231
149 This disables all lifetime management on the object. You're responsible for 232 This disables all lifetime management on the object. You're responsible for
150 making sure the object is alive at the time of the call. You break it, you own 233 making sure the object is alive at the time of the call. You break it, you own
151 it! 234 it!
152 235
153 ### Binding A Class Method And Having The Callback Own The Class 236 ### Binding A Class Method And Having The Callback Own The Class
154 237
155 ```cpp 238 ```cpp
156 MyClass* myclass = new MyClass; 239 MyClass* myclass = new MyClass;
157 base::Bind(&MyClass::Foo, base::Owned(myclass)); 240 Bind(&MyClass::Foo, Owned(myclass));
158 ``` 241 ```
159 242
160 The object will be deleted when the callback is destroyed, even if it's not run 243 The object will be deleted when the callback is destroyed, even if it's not run
161 (like if you post a task during shutdown). Potentially useful for "fire and 244 (like if you post a task during shutdown). Potentially useful for "fire and
162 forget" cases. 245 forget" cases.
163 246
247 Also, smart pointers (e.g. `std::unique_ptr<>`) are supported as the receiver.
248
249 ```cpp
250 std::unique_ptr<MyClass> myclass(new MyClass);
251 Bind(&MyClass::Foo, std::move(myclass));
252 ```
253
164 ### Ignoring Return Values 254 ### Ignoring Return Values
165 255
166 Sometimes you want to call a function that returns a value in a callback that 256 Sometimes you want to call a function that returns a value in a callback that
167 doesn't expect a return value. 257 doesn't expect a return value.
168 258
169 ```cpp 259 ```cpp
170 int DoSomething(int arg) { cout << arg << endl; } 260 int DoSomething(int arg) { cout << arg << endl; }
171 base::Callback<void(int)> cb = 261 Callback<void(int)> cb =
172 base::Bind(base::IgnoreResult(&DoSomething)); 262 Bind(IgnoreResult(&DoSomething));
173 ``` 263 ```
174 264
175 ## Quick reference for binding parameters to Bind() 265 ## Quick reference for binding parameters to Bind()
176 266
177 Bound parameters are specified as arguments to `Bind()` and are passed to the 267 Bound parameters are specified as arguments to `Bind()` and are passed to the
178 function. A callback with no parameters or no unbound parameters is called a 268 function. A callback with no parameters or no unbound parameters is called a
179 `Closure` (`base::Callback<void()>` and `base::Closure` are the same thing). 269 `Closure` (`Callback<void()>` and `Closure` are the same thing).
180 270
181 ### Passing Parameters Owned By The Callback 271 ### Passing Parameters Owned By The Callback
182 272
183 ```cpp 273 ```cpp
184 void Foo(int* arg) { cout << *arg << endl; } 274 void Foo(int* arg) { cout << *arg << endl; }
185 int* pn = new int(1); 275 int* pn = new int(1);
186 base::Closure foo_callback = base::Bind(&foo, base::Owned(pn)); 276 Closure foo_callback = Bind(&foo, Owned(pn));
187 ``` 277 ```
188 278
189 The parameter will be deleted when the callback is destroyed, even if it's not 279 The parameter will be deleted when the callback is destroyed, even if it's
190 run (like if you post a task during shutdown). 280 not run (like if you post a task during shutdown).
191 281
192 ### Passing Parameters As A unique_ptr 282 ### Passing Parameters As A unique_ptr
193 283
194 ```cpp 284 ```cpp
195 void TakesOwnership(std::unique_ptr<Foo> arg) {} 285 void TakesOwnership(std::unique_ptr<Foo> arg) {}
196 std::unique_ptr<Foo> f(new Foo); 286 std::unique_ptr<Foo> f(new Foo);
197 // f becomes null during the following call. 287 // f becomes null during the following call.
198 base::Closure cb = base::Bind(&TakesOwnership, base::Passed(&f)); 288 RepeatingClosure cb = BindRepeating(&TakesOwnership, Passed(std::move(f)));
199 ``` 289 ```
200 290
201 Ownership of the parameter will be with the callback until the callback is run, 291 Ownership of the parameter will be with the callback until it is run, when
202 and then ownership is passed to the callback function. This means the callback 292 ownership is passed to the callback function. This means the callback can only
203 can only be run once. If the callback is never run, it will delete the object 293 be run once. If the callback is never run, it will delete the object when it's
204 when it's destroyed. 294 destroyed.
295
296 ```cpp
297 void TakesOwnership(std::unique_ptr<Foo> arg) {}
298 std::unique_ptr<Foo> f(new Foo);
299 // f becomes null during the following call.
300 OnceClosure cb = BindOnce(&TakesOwnership, std::move(f));
301 ```
302
303 Parameters bound by `BindOnce()` are passed out even without `Passed`.
304
305 ### Passing movable objects
306
307 ```cpp
308 void TakesMovableObject(std::vector<char> obj) {}
309 std::vector<char> buf;
310 Closure cb = Bind(&TakesMovableObject, Passed(&buf));
311 std::move(cb).Run();
312 ```
313
314 When a bound argument is wrapped by `Passed()`, `Bind` moves the argument into
315 its internal storage rather than copying it, and moves out it when the callback
316 is run.
317
318
319 ```cpp
320 void TakesMovableObject(std::vector<char> obj) {}
321 std::vector<char> buf;
322 OnceClosure cb = BindOnce(&TakesMovableObject, std::move(buf));
323 std::move(cb).Run();
324 ```
325
326 `OnceCallback` moves out bound arguments even without `Passed`.
327
328
329 ```cpp
330 void TakesMovableObject(std::vector<char> buf) {}
331 std::vector<char> buf;
332 Closure cb = Bind(&TakesMovableObject, std::move(buf));
333 cb.Run();
334 ```
335
336 In contrast, when an object is bound with `std::move` into a `RepeatingCallback` ,
337 the bound object is copied when the callback is run.
205 338
206 ### Passing Parameters As A scoped_refptr 339 ### Passing Parameters As A scoped_refptr
207 340
208 ```cpp 341 ```cpp
209 void TakesOneRef(scoped_refptr<Foo> arg) {} 342 void TakesOneRef(scoped_refptr<Foo> arg) {}
210 scoped_refptr<Foo> f(new Foo) 343 scoped_refptr<Foo> f(new Foo);
211 base::Closure cb = base::Bind(&TakesOneRef, f); 344 Closure cb = Bind(&TakesOneRef, f);
212 ``` 345 ```
213 346
214 This should "just work." The closure will take a reference as long as it is 347 This should "just work." The closure will take a reference as long as it is
215 alive, and another reference will be taken for the called function. 348 alive, and another reference will be taken for the called function.
216 349
350 ```cpp
351 void DontTakeRef(Foo* arg) {}
352 scoped_refptr<Foo> f(new Foo);
353 Closure cb = Bind(&DontTakeRef, RetainedRef(f));
354 ```
355
356 `RetainedRef` holds a reference to the object and passes a raw pointer to
357 the object when the Callback is run.
358
217 ### Passing Parameters By Reference 359 ### Passing Parameters By Reference
218 360
219 Const references are *copied* unless `ConstRef` is used. Example: 361 Const references are *copied* unless `ConstRef` is used. Example:
220 362
221 ```cpp 363 ```cpp
222 void foo(const int& arg) { printf("%d %p\n", arg, &arg); } 364 void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
223 int n = 1; 365 int n = 1;
224 base::Closure has_copy = base::Bind(&foo, n); 366 Closure has_copy = Bind(&foo, n);
225 base::Closure has_ref = base::Bind(&foo, base::ConstRef(n)); 367 Closure has_ref = Bind(&foo, ConstRef(n));
226 n = 2; 368 n = 2;
227 foo(n); // Prints "2 0xaaaaaaaaaaaa" 369 foo(n); // Prints "2 0xaaaaaaaaaaaa"
228 has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb" 370 has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
229 has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa" 371 has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
230 ``` 372 ```
231 373
232 Normally parameters are copied in the closure. 374 Normally parameters are copied in the closure.
233 **DANGER**: ConstRef stores a const reference instead, referencing the original 375
234 parameter. This means that you must ensure the object outlives the callback! 376 **DANGER**: `ConstRef` stores a const reference instead, referencing the
377 original parameter. This means that you must ensure the object outlives the
378 callback!
235 379
236 ## Implementation notes 380 ## Implementation notes
237 381
238 ### Where Is This Design From: 382 ### Where is This Design From:
239 383
240 The design `Callback` and Bind is heavily influenced by C++'s `tr1::function` / 384 The design `Callback` and `Bind` is heavily influenced by C++'s
241 `tr1::bind`, and by the "Google Callback" system used inside Google. 385 tr1::function/tr1::bind, and by the "Google Callback" system used inside Google.
386
387 ### Customizing the behavior
388
389 There are several injection points that controls `Bind` behavior from outside of
390 its implementation.
391
392 ```cpp
393 template <typename Receiver>
394 struct IsWeakReceiver {
395 static constexpr bool value = false;
396 };
397
398 template <typename Obj>
399 struct UnwrapTraits {
400 template <typename T>
401 T&& Unwrap(const T&& obj) {
402 return std::forward<T>(obj);
403 }
404 };
405 ```
406
407 If `IsWeakReceiver<Receiver>::value` is true on a receiver of a method, `Bind`
408 checks if the receiver is null and cancels the invocation if it's null.
409 You can specialize `IsWeakReceiver` to make an external smart pointer as a
410 weak pointer.
411
412 `UnwrapTraits<BoundObject>::Unwrap()` is called for each bound arguments right
413 before `Callback` calls the target function. You can specialize this to define
414 an argument wrapper such as Unretained, ConstRef, Owned, RetainedRef and Passed.
242 415
243 ### How The Implementation Works: 416 ### How The Implementation Works:
244 417
245 There are three main components to the system: 418 There are three main components to the system:
246 1) The Callback classes. 419 1) The `Callback<>` classes.
247 2) The `Bind()` functions. 420 2) The `Bind()` functions.
248 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`). 421 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`).
249 422
250 The Callback classes represent a generic function pointer. Internally, it stores 423 The Callback classes represent a generic function pointer. Internally, it stores
251 a refcounted piece of state that represents the target function and all its 424 a refcounted piece of state that represents the target function and all its
252 bound parameters. Each `Callback` specialization has a templated constructor 425 bound parameters. `Callback` has a constructor that takes a `BindStateBase*`
253 that takes an `BindState<>*`. In the context of the constructor, the static 426 and `&Invoker::Run`. A `BindState<>` holds a function object to run, and also
254 type of this `BindState<>` pointer uniquely identifies the function it is 427 holds bound parameters. `BindStateBase` is the base class of of `BindState<>`,
255 representing, all its bound parameters, and a `Run()` method that is capable of 428 without type information of bound data. In the context of the constructor of
256 invoking the target. 429 `Callback`, `Invoker::Run` has the static type of `BindState<>` that identifies
430 the function it is representing and all its bound parameters.
257 431
258 `Callback`'s constructor takes the `BindState<>*` that has the full static type 432 `Bind()` creates the `BindState<>` that has the full static type, and erases the
259 and erases the target function type as well as the types of the bound 433 target function type as well as the type of bound parameters. It does this by
260 parameters. It does this by storing a pointer to the specific `Run()` function, 434 taking a pointer to the specific `Invoker::Run()` function, and upcasting the
261 and upcasting the state of `BindState<>*` to a `BindStateBase*`. This is safe as 435 state of `BindState<>` to a `BindStateBase`. This is safe as long as this
262 long as this `BindStateBase` pointer is only used with the stored `Run()` 436 `BindStateBase` pointer is only used with the stored `Invoker::Run()` pointer.
263 pointer.
264 437
265 To `BindState<>` objects are created inside the `Bind()` functions. 438 To `BindState<>` objects are created inside the `Bind()` functions.
266 These functions, along with a set of internal templates, are responsible for 439 These functions, along with a set of internal templates, are responsible for
267 440
268 - Unwrapping the function signature into return type, and parameters 441 - Unwrapping the function signature into return type, and parameters
269 - Determining the number of parameters that are bound 442 - Determining the number of parameters that are bound
270 - Creating the BindState storing the bound parameters 443 - Creating the BindState storing the bound parameters
271 - Performing compile-time asserts to avoid error-prone behavior 444 - Performing compile-time asserts to avoid error-prone behavior
272 - Returning an `Callback<>` with an arity matching the number of unbound 445 - Returning an `Callback<>` with an arity matching the number of unbound
273 parameters and that knows the correct refcounting semantics for the 446 parameters and that knows the correct refcounting semantics for the
274 target object if we are binding a method. 447 target object if we are binding a method.
275 448
276 The `Bind` functions do the above using type-inference, and template
277 specializations.
278
279 By default `Bind()` will store copies of all bound parameters, and attempt to 449 By default `Bind()` will store copies of all bound parameters, and attempt to
280 refcount a target object if the function being bound is a class method. These 450 refcount a target object if the function being bound is a class method. These
281 copies are created even if the function takes parameters as const 451 copies are created even if the function takes parameters as const references.
282 references. (Binding to non-const references is forbidden, see bind.h.) 452 (Binding to non-const references is forbidden, see bind.h.)
283 453
284 To change this behavior, we introduce a set of argument wrappers (e.g., 454 To change this behavior, we introduce a set of argument wrappers (e.g.,
285 `Unretained()`, and `ConstRef()`). These are simple container templates that 455 `Unretained()`, and `ConstRef()`). These are simple container templates that
286 are passed by value, and wrap a pointer to argument. See the file-level comment 456 are passed by value, and wrap a pointer to argument. See the file-level comment
287 in base/bind_helpers.h for more info. 457 in base/bind_helpers.h for more info.
288 458
289 These types are passed to the `Unwrap()` functions, and the `MaybeRefcount()` 459 These types are passed to the Unwrap() functions, and the IsWeakReceiver<>
290 functions respectively to modify the behavior of `Bind()`. The `Unwrap()` and 460 traits respectively to modify the behavior of Bind().
291 `MaybeRefcount()` functions change behavior by doing partial specialization
292 based on whether or not a parameter is a wrapper type.
293 461
294 `ConstRef()` is similar to `tr1::cref`. `Unretained()` is specific to Chromium. 462 `ConstRef()` is similar to std::cref. `Unretained()` is specific to Chromium.
295 463 `Owned()` and `RetainedRef()` let `BindState<>` have the exclusive or shared
296 ### Why Not Tr1 Function/Bind? 464 ownership and pass the bound item as a raw pointer to the target function.
297
298 Direct use of `tr1::function` and `tr1::bind` was considered, but ultimately
299 rejected because of the number of copy constructors invocations involved in the
300 binding of arguments during construction, and the forwarding of arguments during
301 invocation. These copies will no longer be an issue in C++0x because C++0x will
302 support rvalue reference allowing for the compiler to avoid these copies.
303 However, waiting for C++0x is not an option.
304
305 Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the
306 `tr1::bind` call itself will invoke a non-trivial copy constructor three times
307 for each bound parameter. Also, each when passing a `tr1::function`, each bound
308 argument will be copied again.
309
310 In addition to the copies taken at binding and invocation, copying a
311 `tr1::function` causes a copy to be made of all the bound parameters and state.
312
313 Furthermore, in Chromium, it is desirable for the `Callback` to take a reference
314 on a target object when representing a class method call. This is not supported
315 by tr1.
316
317 Lastly, `tr1::function` and `tr1::bind` has a more general and flexible
318 API. This includes things like argument reordering by use of
319 `tr1::bind::placeholder`, support for non-const reference parameters, and some
320 limited amount of subtyping of the `tr1::function` object (e.g.,
321 `tr1::function<int(int)>` is convertible to `tr1::function<void(int)>`).
322
323 These are not features that are required in Chromium. Some of them, such as
324 allowing for reference parameters, and subtyping of functions, may actually
325 become a source of errors. Removing support for these features actually allows
326 for a simpler implementation, and a terser Currying API.
327
328 ### Why Not Google Callbacks?
329
330 The Google callback system also does not support refcounting. Furthermore, its
331 implementation has a number of strange edge cases with respect to type
332 conversion of its arguments. In particular, the argument's constness must at
333 times match exactly the function signature, or the type-inference might
334 break. Given the above, writing a custom solution was easier.
335
336 ### Missing Functionality
337 - Invoking the return of `Bind`. `Bind(&foo).Run()` does not work;
338 - Binding arrays to functions that take a non-const pointer.
339 Example:
340 ```cpp
341 void Foo(const char* ptr);
342 void Bar(char* ptr);
343 Bind(&Foo, "test");
344 Bind(&Bar, "test"); // This fails because ptr is not const.
345 ```
346
347 If you are thinking of forward declaring `Callback` in your own header file,
348 please include "base/callback_forward.h" instead.
OLDNEW
« no previous file with comments | « device/bluetooth/test/bluetooth_test_win.cc ('k') | ios/web/public/web_thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698