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

Side by Side Diff: docs/callback.md

Issue 2318113002: Update //docs/callback.md for OnceCallback and RepeatingCallback (Closed)
Patch Set: rebase 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 | « no previous file | no next file » | 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
dcheng 2016/09/08 00:34:40 `OnceCallback<>` is created by `BindOnce()`. This
tzik 2016/10/04 06:02:45 Done.
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,
dcheng 2016/09/08 00:34:40 Maybe clarify what 'better' means here. Perhaps om
tzik 2016/10/04 06:02:46 Done.
27 thread hopping and result handning of an asynchronous operation are a good fit
dcheng 2016/09/08 00:34:40 Typo: handling. But I would change this to indicat
tzik 2016/10/04 06:02:46 Done.
28 for it.
29
30 `RepeatingCallback<>` is created by `BindRepeating()` as a loose variant.
dcheng 2016/09/08 00:34:39 Delete "as a loose variant".
tzik 2016/10/04 06:02:46 Done.
31 Its internal storage is ref-counted and `RepeatingCallback<>` itself is a
dcheng 2016/09/08 00:34:40 Technically, the internal storage of OnceCallback
tzik 2016/10/04 06:02:46 Right, removing the refcount gains the binary size
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
dcheng 2016/09/08 00:34:40 Typo: historical Perhaps word this as: The legac
tzik 2016/10/04 06:02:46 Done.
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
dcheng 2016/09/08 00:34:40 Simplify this to: Pass `Callback` objects by valu
tzik 2016/10/04 06:02:46 Done.
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
dcheng 2016/09/08 00:34:40 |Foo| refers to |cb| but doesn't store it nor cons
tzik 2016/10/04 06:02:46 OK, let me omit latter one.
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
dcheng 2016/09/08 00:34:40 "transfers ownership to PostTask()." Otherwise, i
tzik 2016/10/04 06:02:45 Done.
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 OnceCallback<int()> func_cb = BindOnce(&Return5);
87 LOG(INFO) << std::move(func_cb).Run(); // Prints 5.
88 ```
89
90 ```cpp
91 int Return5() { return 5; }
92 RepeatingCallback<int()> func_cb = BindRepeating(&Return5);
35 LOG(INFO) << func_cb.Run(); // Prints 5. 93 LOG(INFO) << func_cb.Run(); // Prints 5.
36 ``` 94 ```
37 95
96 ### Binding A Captureless Lambda
97
98 ```cpp
99 Callback<int()> lambda_cb = Bind([] { return 4; });
100 LOG(INFO) << lambda_cb.Run(); // Print 4.
101
102 OnceCallback<int()> lambda_cb2 = BindOnce([] { return 3; });
103 LOG(INFO) << std::move(lambda_cb2).Run(); // Print 3.
104 ```
105
38 ### Binding A Class Method 106 ### Binding A Class Method
39 107
40 The first argument to bind is the member function to call, the second is the 108 The first argument to bind is the member function to call, the second is the
41 object on which to call it. 109 object on which to call it.
42 110
43 ```cpp 111 ```cpp
44 class Ref : public base::RefCountedThreadSafe<Ref> { 112 class Ref : public RefCountedThreadSafe<Ref> {
45 public: 113 public:
46 int Foo() { return 3; } 114 int Foo() { return 3; }
47 void PrintBye() { LOG(INFO) << "bye."; }
48 }; 115 };
49 scoped_refptr<Ref> ref = new Ref(); 116 scoped_refptr<Ref> ref = new Ref();
50 base::Callback<void()> ref_cb = base::Bind(&Ref::Foo, ref); 117 Callback<void()> ref_cb = Bind(&Ref::Foo, ref);
51 LOG(INFO) << ref_cb.Run(); // Prints out 3. 118 LOG(INFO) << ref_cb.Run(); // Prints out 3.
52 ``` 119 ```
53 120
54 By default the object must support RefCounted or you will get a compiler 121 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 122 error. If you're passing between threads, be sure it's RefCountedThreadSafe! See
56 RefCountedThreadSafe! See "Advanced binding of member functions" below if 123 "Advanced binding of member functions" below if you don't want to use reference
57 you don't want to use reference counting. 124 counting.
58 125
59 ### Running A Callback 126 ### Running A Callback
60 127
61 Callbacks can be run with their `Run` method, which has the same 128 Callbacks can be run with their `Run` method, which has the same signature as
62 signature as the template argument to the callback. 129 the template argument to the callback. Note that `OnceCallback::Run` consumes
130 the callback object, and to ensure that, it can be invoked only from rvalue
dcheng 2016/09/08 00:34:40 consumes the callback object and can only be invok
tzik 2016/10/04 06:02:45 Done.
131 reference. Use `std::move` on `OnceCallback::Run` invocation.
63 132
64 ```cpp 133 ```cpp
65 void DoSomething(const base::Callback<void(int, std::string)>& callback) { 134 void DoSomething(const Callback<void(int, std::string)>& callback) {
66 callback.Run(5, "hello"); 135 callback.Run(5, "hello");
67 } 136 }
137
138 void DoSomethingOther(OnceCallback<void(int, std::string)> callback) {
139 std::move(callback).Run(5, "hello");
140 }
68 ``` 141 ```
69 142
70 Callbacks can be run more than once (they don't get deleted or marked when 143 RepeatingCallbacks can be run more than once (they don't get deleted or marked
71 run). However, this precludes using base::Passed (see below). 144 when run). However, this precludes using Passed (see below).
72 145
73 ```cpp 146 ```cpp
74 void DoSomething(const base::Callback<double(double)>& callback) { 147 void DoSomething(const RepeatingCallback<double(double)>& callback) {
75 double myresult = callback.Run(3.14159); 148 double myresult = callback.Run(3.14159);
76 myresult += callback.Run(2.71828); 149 myresult += callback.Run(2.71828);
77 } 150 }
78 ``` 151 ```
79 152
80 ### Passing Unbound Input Parameters 153 ### Passing Unbound Input Parameters
81 154
82 Unbound parameters are specified at the time a callback is `Run()`. They are 155 Unbound parameters are specified at the time a callback is `Run()`. They are
83 specified in the `Callback` template type: 156 specified in the `Callback` template type:
84 157
85 ```cpp 158 ```cpp
86 void MyFunc(int i, const std::string& str) {} 159 void MyFunc(int i, const std::string& str) {}
87 base::Callback<void(int, const std::string&)> cb = base::Bind(&MyFunc); 160 Callback<void(int, const std::string&)> cb = Bind(&MyFunc);
88 cb.Run(23, "hello, world"); 161 cb.Run(23, "hello, world");
89 ``` 162 ```
90 163
91 ### Passing Bound Input Parameters 164 ### Passing Bound Input Parameters
92 165
93 Bound parameters are specified when you create the callback as arguments to 166 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 167 `Bind()`. They will be passed to the function and the `Run()`ner of the callback
95 doesn't see those values or even know that the function it's calling. 168 doesn't see those values or even know that the function it's calling.
96 169
97 ```cpp 170 ```cpp
98 void MyFunc(int i, const std::string& str) {} 171 void MyFunc(int i, const std::string& str) {}
99 base::Callback<void()> cb = base::Bind(&MyFunc, 23, "hello world"); 172 Callback<void()> cb = Bind(&MyFunc, 23, "hello world");
100 cb.Run(); 173 cb.Run();
101 ``` 174 ```
102 175
103 A callback with no unbound input parameters (`base::Callback<void()>`) is called 176 A callback with no unbound input parameters (`Callback<void()>`) is called a
104 a `base::Closure`. So we could have also written: 177 `Closure`. So we could have also written:
105 178
106 ```cpp 179 ```cpp
107 base::Closure cb = base::Bind(&MyFunc, 23, "hello world"); 180 Closure cb = Bind(&MyFunc, 23, "hello world");
108 ``` 181 ```
109 182
110 When calling member functions, bound parameters just go after the object 183 When calling member functions, bound parameters just go after the object
111 pointer. 184 pointer.
112 185
113 ```cpp 186 ```cpp
114 base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world"); 187 Closure cb = Bind(&MyClass::MyFunc, this, 23, "hello world");
115 ``` 188 ```
116 189
117 ### Partial Binding Of Parameters 190 ### Partial Binding Of Parameters
118 191
119 You can specify some parameters when you create the callback, and specify the 192 You can specify some parameters when you create the callback, and specify the
120 rest when you execute the callback. 193 rest when you execute the callback.
121 194
122 ```cpp 195 ```cpp
123 void MyFunc(int i, const std::string& str) {} 196 void MyFunc(int i, const std::string& str) {}
124 base::Callback<void(const std::string&)> cb = base::Bind(&MyFunc, 23); 197 Callback<void(const std::string&)> cb = Bind(&MyFunc, 23);
125 cb.Run("hello world"); 198 cb.Run("hello world");
126 ``` 199 ```
127 200
128 When calling a function bound parameters are first, followed by unbound 201 When calling a function bound parameters are first, followed by unbound
129 parameters. 202 parameters.
130 203
204 ### Move In and Move Out
205
206 A parameter of `Bind()` is moved into its internal storage if you use
dcheng 2016/09/08 00:34:39 What if the parameter is already an rvalue, e.g.
tzik 2016/10/04 06:02:46 Hmm, let me rephrase it to just "if the parameter
207 `std::move()` for the parameter.
208
209 ```cpp
210 std::vector<int> v = {1, 2, 3};
211 // |v| is moved into the internal storage without copy.
212 Bind(&Foo, std::move(v));
213 ```
214
215 A bound object is moved out to the target function if you use `Passed()` for
216 the parameter of `BindRepeating()`, or if you use `BindOnce()`.
dcheng 2016/09/08 00:34:40 This section is a bit confusing. Passed() can also
tzik 2016/10/04 06:02:45 Right. Rephrased this to
217
218 ```cpp
219 void Foo(std::unique_ptr<int>) {}
220 std::unique_ptr<int> p(new int(42));
221
222 // |p| is moved into the internal storage of Bind(), and moved out to |Foo|.
223 BindOnce(&Foo, std::move(p));
224 BindRepeating(&Foo, Passed(&p));
225 ```
226
131 ## Quick reference for advanced binding 227 ## Quick reference for advanced binding
132 228
133 ### Binding A Class Method With Weak Pointers 229 ### Binding A Class Method With Weak Pointers
134 230
135 ```cpp 231 ```cpp
136 base::Bind(&MyClass::Foo, GetWeakPtr()); 232 Bind(&MyClass::Foo, GetWeakPtr());
137 ``` 233 ```
138 234
139 The callback will not be run if the object has already been destroyed. 235 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 236 **DANGER**: weak pointers are not threadsafe, so don't use this when passing bet ween
141 threads! 237 threads!
142 238
143 ### Binding A Class Method With Manual Lifetime Management 239 ### Binding A Class Method With Manual Lifetime Management
144 240
145 ```cpp 241 ```cpp
146 base::Bind(&MyClass::Foo, base::Unretained(this)); 242 Bind(&MyClass::Foo, Unretained(this));
147 ``` 243 ```
148 244
149 This disables all lifetime management on the object. You're responsible for 245 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 246 making sure the object is alive at the time of the call. You break it, you own
151 it! 247 it!
152 248
153 ### Binding A Class Method And Having The Callback Own The Class 249 ### Binding A Class Method And Having The Callback Own The Class
154 250
155 ```cpp 251 ```cpp
156 MyClass* myclass = new MyClass; 252 MyClass* myclass = new MyClass;
157 base::Bind(&MyClass::Foo, base::Owned(myclass)); 253 Bind(&MyClass::Foo, Owned(myclass));
158 ``` 254 ```
159 255
160 The object will be deleted when the callback is destroyed, even if it's not run 256 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 257 (like if you post a task during shutdown). Potentially useful for "fire and
162 forget" cases. 258 forget" cases.
163 259
260 Also, smart pointers (e.g. `std::unique_ptr<>`) are supported as the receiver.
dcheng 2016/09/08 00:34:40 Nit: Smart pointers (e.g. ...) are also supported
tzik 2016/10/04 06:02:45 Done.
261
262 ```cpp
263 std::unique_ptr<MyClass> myclass(new MyClass);
264 Bind(&MyClass::Foo, std::move(myclass));
265 ```
266
164 ### Ignoring Return Values 267 ### Ignoring Return Values
165 268
166 Sometimes you want to call a function that returns a value in a callback that 269 Sometimes you want to call a function that returns a value in a callback that
167 doesn't expect a return value. 270 doesn't expect a return value.
168 271
169 ```cpp 272 ```cpp
170 int DoSomething(int arg) { cout << arg << endl; } 273 int DoSomething(int arg) { cout << arg << endl; }
171 base::Callback<void(int)> cb = 274 Callback<void(int)> cb =
172 base::Bind(base::IgnoreResult(&DoSomething)); 275 Bind(IgnoreResult(&DoSomething));
173 ``` 276 ```
174 277
175 ## Quick reference for binding parameters to Bind() 278 ## Quick reference for binding parameters to Bind()
176 279
177 Bound parameters are specified as arguments to `Bind()` and are passed to the 280 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 281 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). 282 `Closure` (`Callback<void()>` and `Closure` are the same thing).
180 283
181 ### Passing Parameters Owned By The Callback 284 ### Passing Parameters Owned By The Callback
182 285
183 ```cpp 286 ```cpp
184 void Foo(int* arg) { cout << *arg << endl; } 287 void Foo(int* arg) { cout << *arg << endl; }
185 int* pn = new int(1); 288 int* pn = new int(1);
186 base::Closure foo_callback = base::Bind(&foo, base::Owned(pn)); 289 Closure foo_callback = Bind(&foo, Owned(pn));
187 ``` 290 ```
188 291
189 The parameter will be deleted when the callback is destroyed, even if it's not 292 The parameter will be deleted when the callback is destroyed, even if it's not
190 run (like if you post a task during shutdown). 293 run (like if you post a task during shutdown).
191 294
192 ### Passing Parameters As A unique_ptr 295 ### Passing Parameters As A unique_ptr
193 296
194 ```cpp 297 ```cpp
195 void TakesOwnership(std::unique_ptr<Foo> arg) {} 298 void TakesOwnership(std::unique_ptr<Foo> arg) {}
196 std::unique_ptr<Foo> f(new Foo); 299 std::unique_ptr<Foo> f(new Foo);
197 // f becomes null during the following call. 300 // f becomes null during the following call.
198 base::Closure cb = base::Bind(&TakesOwnership, base::Passed(&f)); 301 RepeatingClosure cb = BindRepeating(&TakesOwnership, Passed(&f));
199 ``` 302 ```
200 303
201 Ownership of the parameter will be with the callback until the callback is run, 304 Ownership of the parameter will be with the callback until the callback is run,
202 and then ownership is passed to the callback function. This means the callback 305 and then ownership is passed to the callback function. This means the callback
203 can only be run once. If the callback is never run, it will delete the object 306 can only be run once. If the callback is never run, it will delete the object
204 when it's destroyed. 307 when it's destroyed.
205 308
206 ### Passing Parameters As A scoped_refptr 309 ### Passing Parameters As A scoped_refptr
207 310
208 ```cpp 311 ```cpp
209 void TakesOneRef(scoped_refptr<Foo> arg) {} 312 void TakesOneRef(scoped_refptr<Foo> arg) {}
210 scoped_refptr<Foo> f(new Foo) 313 scoped_refptr<Foo> f(new Foo);
211 base::Closure cb = base::Bind(&TakesOneRef, f); 314 Closure cb = Bind(&TakesOneRef, f);
212 ``` 315 ```
213 316
214 This should "just work." The closure will take a reference as long as it is 317 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. 318 alive, and another reference will be taken for the called function.
216 319
320 ```cpp
321 void DontTakeRef(Foo* arg) {}
322 scoped_refptr<Foo> f(new Foo);
323 Closure cb = Bind(&DontTakeRef, RetainedRef(f));
324 ```
325
326 `RetainedRef` holds a reference to the object and passes a raw pointer to
327 the object when the Callback is run.
328
217 ### Passing Parameters By Reference 329 ### Passing Parameters By Reference
218 330
219 Const references are *copied* unless `ConstRef` is used. Example: 331 Const references are *copied* unless `ConstRef` is used. Example:
220 332
221 ```cpp 333 ```cpp
222 void foo(const int& arg) { printf("%d %p\n", arg, &arg); } 334 void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
223 int n = 1; 335 int n = 1;
224 base::Closure has_copy = base::Bind(&foo, n); 336 Closure has_copy = Bind(&foo, n);
225 base::Closure has_ref = base::Bind(&foo, base::ConstRef(n)); 337 Closure has_ref = Bind(&foo, ConstRef(n));
226 n = 2; 338 n = 2;
227 foo(n); // Prints "2 0xaaaaaaaaaaaa" 339 foo(n); // Prints "2 0xaaaaaaaaaaaa"
228 has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb" 340 has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
229 has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa" 341 has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
230 ``` 342 ```
231 343
232 Normally parameters are copied in the closure. 344 Normally parameters are copied in the closure.
233 **DANGER**: ConstRef stores a const reference instead, referencing the original 345 **DANGER**: `ConstRef` stores a const reference instead, referencing the
234 parameter. This means that you must ensure the object outlives the callback! 346 original parameter. This means that you must ensure the object outlives the
347 callback!
235 348
236 ## Implementation notes 349 ## Implementation notes
237 350
238 ### Where Is This Design From: 351 ### Where Is This Design From:
239 352
240 The design `Callback` and Bind is heavily influenced by C++'s `tr1::function` / 353 The design `Callback` and Bind is heavily influenced by C++'s `tr1::function` /
241 `tr1::bind`, and by the "Google Callback" system used inside Google. 354 `tr1::bind`, and by the "Google Callback" system used inside Google.
242 355
356 ### Customizing the behavior
357
358 There are several injection points that controls `Bind` behavior from outside of
359 its implementation.
360
361 ```cpp
362 template <typename Receiver>
363 struct IsWeakReceiver {
364 static constexpr bool value = false;
365 };
366
367 template <typename Obj>
368 struct UnwrapTraits {
369 template <typename T>
370 T&& Unwrap(const T&& obj) {
dcheng 2016/09/08 00:34:40 Just curious: why is this a const rvalue reference
tzik 2016/10/04 06:02:46 Oh, right it's a bug. Fixed.
371 return std::forward<T>(obj);
372 }
373 };
374 ```
375
376 If `IsWeakReceiver<Receiver>::value` is true on a receiver of a method, `Bind`
377 checks if the receiver is null and cancels the invocation if it's null. You can
dcheng 2016/09/08 00:34:40 Strictly speaking, we don't check if it's null: we
tzik 2016/10/04 06:02:45 Replaced it with "checks if the receiver is evalua
378 specialize `IsWeakReceiver` to make an external smart pointer as a weak pointer.
379
380 `UnwrapTraits<BoundObject>::Unwrap()` is called for each bound arguments right
381 before `Callback` calls the target function. You can specialize this to define
382 an argument wrapper such as Unretained, ConstRef, Owned, RetainedRef and Passed.
dcheng 2016/09/08 00:34:40 Nit: wrap Unretained and the rest of the list item
tzik 2016/10/04 06:02:46 Done.
383
243 ### How The Implementation Works: 384 ### How The Implementation Works:
244 385
245 There are three main components to the system: 386 There are three main components to the system:
246 1) The Callback classes. 387 1) The `Callback<>` classes.
247 2) The `Bind()` functions. 388 2) The `Bind()` functions.
248 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`). 389 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`).
249 390
250 The Callback classes represent a generic function pointer. Internally, it stores 391 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 392 a refcounted piece of state that represents the target function and all its
252 bound parameters. Each `Callback` specialization has a templated constructor 393 bound parameters. The `Callback` constructor takes a `BindStateBase*`, which is
253 that takes an `BindState<>*`. In the context of the constructor, the static 394 upcasted from a `BindState<>`. In the context of the constructor, the static
254 type of this `BindState<>` pointer uniquely identifies the function it is 395 type of this `BindState<>` pointer uniquely identifies the function it is
255 representing, all its bound parameters, and a `Run()` method that is capable of 396 representing, all its bound parameters, and a `Run()` method that is capable of
256 invoking the target. 397 invoking the target.
257 398
258 `Callback`'s constructor takes the `BindState<>*` that has the full static type 399 `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 400 target function type as well as the types of the bound parameters. It does this
260 parameters. It does this by storing a pointer to the specific `Run()` function, 401 by storing a pointer to the specific `Run()` function, and upcasting the state
261 and upcasting the state of `BindState<>*` to a `BindStateBase*`. This is safe as 402 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()` 403 `BindStateBase` pointer is only used with the stored `Run()` pointer.
263 pointer.
264 404
265 To `BindState<>` objects are created inside the `Bind()` functions. 405 To `BindState<>` objects are created inside the `Bind()` functions.
266 These functions, along with a set of internal templates, are responsible for 406 These functions, along with a set of internal templates, are responsible for
267 407
268 - Unwrapping the function signature into return type, and parameters 408 - Unwrapping the function signature into return type, and parameters
269 - Determining the number of parameters that are bound 409 - Determining the number of parameters that are bound
270 - Creating the BindState storing the bound parameters 410 - Creating the BindState storing the bound parameters
271 - Performing compile-time asserts to avoid error-prone behavior 411 - Performing compile-time asserts to avoid error-prone behavior
272 - Returning an `Callback<>` with an arity matching the number of unbound 412 - Returning an `Callback<>` with an arity matching the number of unbound
273 parameters and that knows the correct refcounting semantics for the 413 parameters and that knows the correct refcounting semantics for the
274 target object if we are binding a method. 414 target object if we are binding a method.
275 415
276 The `Bind` functions do the above using type-inference, and template 416 The `Bind` functions do the above using type-inference, and variadic templates.
dcheng 2016/09/08 00:34:40 Nit: this is pre-existing, but remove the comma be
tzik 2016/10/04 06:02:45 Done.
277 specializations.
278 417
279 By default `Bind()` will store copies of all bound parameters, and attempt to 418 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 419 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 420 copies are created even if the function takes parameters as const
282 references. (Binding to non-const references is forbidden, see bind.h.) 421 references. (Binding to non-const references is forbidden, see bind.h.)
283 422
284 To change this behavior, we introduce a set of argument wrappers (e.g., 423 To change this behavior, we introduce a set of argument wrappers (e.g.,
285 `Unretained()`, and `ConstRef()`). These are simple container templates that 424 `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 425 are passed by value, and wrap a pointer to argument. See the file-level comment
287 in base/bind_helpers.h for more info. 426 in base/bind_helpers.h for more info.
288 427
289 These types are passed to the `Unwrap()` functions, and the `MaybeRefcount()` 428 These types are passed to the `Unwrap()` functions to modify the behavior of
290 functions respectively to modify the behavior of `Bind()`. The `Unwrap()` and 429 `Bind()`. The `Unwrap()` functions change behavior by doing partial
291 `MaybeRefcount()` functions change behavior by doing partial specialization 430 specialization based on whether or not a parameter is a wrapper type.
292 based on whether or not a parameter is a wrapper type.
293 431
294 `ConstRef()` is similar to `tr1::cref`. `Unretained()` is specific to Chromium. 432 `ConstRef()` is similar to `tr1::cref`. `Unretained()` is specific to Chromium.
295 433
296 ### Why Not Tr1 Function/Bind?
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 434 ### 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. 435 - Binding arrays to functions that take a non-const pointer.
339 Example: 436 Example:
340 ```cpp 437 ```cpp
341 void Foo(const char* ptr); 438 void Foo(const char* ptr);
342 void Bar(char* ptr); 439 void Bar(char* ptr);
343 Bind(&Foo, "test"); 440 Bind(&Foo, "test");
344 Bind(&Bar, "test"); // This fails because ptr is not const. 441 Bind(&Bar, "test"); // This fails because ptr is not const.
345 ``` 442 ```
346 443
347 If you are thinking of forward declaring `Callback` in your own header file, 444 If you are thinking of forward declaring `Callback` in your own header file,
348 please include "base/callback_forward.h" instead. 445 please include "base/callback_forward.h" instead.
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698