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

Side by Side Diff: docs/callback.md

Issue 2042223002: Introduce OnceClosure and BindOnce (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update callback.md for Passed and movable types 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
« base/callback_internal.cc ('K') | « base/callback_unittest.nc ('k') | 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
(Empty)
1 # base::Callback<> and base::Bind()
2
3 ## Introduction
4
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
7 performing partial application of functions.
8
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.
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
13 to schedule tasks on different MessageLoops.
14
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
17 closure -- it does not retain a reference to its enclosing environment.
18
19 ### OneShotCallback<> and RepeatingCallback<>
20
21 `OneShotCallback<>` and `RepeatingCallback<>` are next gen callback classes,
22 which are under development.
23
24 `OneShotCallback<>` is created by `BindOneShot()`, that is a restricted variant
25 of `Callback<>` that is a move-only type and can 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()`, that is 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 `RepeatingCallback<>` is convertible to `OneShotCallback<>` by the implicit
37 conversion.
38
39 `Callback<>` is an alias of `RepeatingCallback<>` and `Bind()` is an alias of
40 `BindRepeating()` for a historical reason.
41
42 ### Memory management and passing
43
44 The `RepeatingCallback` objects should be passed by const-reference or by value,
45 and stored by copy or by move. The `OneShotCallback` object should be passed by
46 value and stored by move. They internally store their state via a refcounted
47 class and thus do not need to be deleted.
48
49 ## Quick reference for basic usage
50
51 ### Binding a bare function
52
53 ```cpp
54 int Return5() { return 5; }
55 Callback<int()> func_cb = Bind(&Return5);
56 LOG(INFO) << func_cb.Run(); // Prints 5.
57
58 OneShotCallback<int()> func_cb2 = BindOneShot(&Return5);
59 LOG(INFO) << std::move(func_cb2).Run(); // Prints 5.
vabr (Chromium) 2016/08/24 11:44:06 func_cb2 is neither stored nor passed here (it is
tzik 2016/08/30 11:31:41 Since func_cb2 is a variant of Callback that can b
60 ```
61
62 ### Binding a captureless lambda
63
64 ```cpp
65 Callback<int()> lambda_cb = Bind([] { return 4; });
66 LOG(INFO) << lambda_cb.Run(); // Print 4.
67
68 OneShotCallback<int()> lambda_cb2 = BindOneShot([] { return 3; });
69 LOG(INFO) << std::move(lambda_cb2).Run(); // Print 3.
70
71 ```
72
73 ### Binding a class method
74
75 The first argument to bind is the member function to call, the second is
76 the object on which to call it.
77
78 ```cpp
79 class Ref : public RefCountedThreadSafe<Ref> {
80 public:
81 int Foo() { return 3; }
82 };
83
84 scoped_refptr<Ref> ref = new Ref();
85 Callback<void()> ref_cb = Bind(&Ref::Foo, ref);
86 LOG(INFO) << ref_cb.Run(); // Prints out 3.
87 ```
88
89 By default the object must support RefCounted or you will get a compiler
90 error. If you're passing between threads, be sure it's RefCountedThreadSafe!
91 See "Advanced binding of member functions" below if you don't want to use
92 reference counting.
93
94 ### Running a Callback
95
96 Callbacks can be run with their "Run" method, which has the same signature as
97 the template argument to the callback.
98
99 `RepeatingCallback<>` can be run directly.
100
101 ```cpp
102 void DoSomething(const RepeatingCallback<void(int, std::string)>& callback) {
103 callback.Run(5, "hello");
104 }
105 ```
106
107 ```cpp
108 void DoSomething(const RepeatingCallback<double(double)>& callback) {
109 double myresult = callback.Run(3.14159);
110 myresult += callback.Run(2.71828);
111 }
112 ```
113
114 `OneShotCallback<>` can be run when it's a rvalue. Use `std::move` or
115 `ResetAndReturn` to run it.
116
117 ```cpp
118 void DoSomething(OneShotCallback<void(int, double)> callback) {
119 std::move(callback).Run(1, 0.1);
120 }
121 ```
122
123 ```cpp
124 void DoSomething(OneShotCallback<void()> callback) {
125 ResetAndReturn(&callback).Run();
126 }
127 ```
128
129 `RepeatingCallback<>` can be run more than once (they don't get deleted or
130 marked when run). However, this precludes using `Passed` (see below).
131
132 ### Passing unbound input parameters
133
134 Unbound parameters are specified at the time a callback is Run(). They are
135 specified in the Callback template type:
136
137 ```cpp
138 void MyFunc(int i, const std::string& str) {}
139 Callback<void(int, const std::string&)> cb = Bind(&MyFunc);
140 cb.Run(23, "hello, world");
141 ```
142
143 ### Passing bound input parameters
144
145 Bound parameters are specified when you create the callback as arguments to
146 `Bind()`. They will be passed to the function and the runner of the callback
147 doesn't see those values or even know that the function it's calling.
148
149 ```cpp
150 void MyFunc(int i, const std::string& str) {}
151 Callback<void()> cb = Bind(&MyFunc, 23, "hello world");
152 cb.Run();
153 ```
154
155 A callback with no unbound input parameters (`Callback<void()>`,
156 `OneShotCallback<void()>` and `RepeatingCallback<void()>`) is called a
157 `Closure`, `OneShotClosure` and `RepeatingClosure`, respectively.
158 So we could have also written:
159
160 ```cpp
161 Closure cb = Bind(&MyFunc, 23, "hello world");
162 ```
163
164 When calling member functions, bound parameters just go after the object
165 pointer.
166
167 ```cpp
168 Closure cb = Bind(&MyClass::MyFunc, this, 23, "hello world");
169 ```
170
171 ### PARTIAL BINDING OF PARAMETERS
172
173 You can specify some parameters when you create the callback, and specify
174 the rest when you execute the callback.
175
176 ```cpp
177 void MyFunc(int i, const std::string& str) {}
178 Callback<void(const std::string&)> cb = Bind(&MyFunc, 23);
179 cb.Run("hello world");
180 ```
181
182 ## Quick reference for advanced binding
183
184 ### Binding a class method with weak pointers
185
186 ```cpp
187 Bind(&MyClass::Foo, GetWeakPtr());
188 ```
189
190 The callback will not be run if the object has already been destroyed.
191
192 **DANGER**: weak pointers are not threadsafe, so don't use this when you pass it
193 between threads!
194
195 ### Binding a class method with manual lifetime management
196
197 ```cpp
198 Bind(&MyClass::Foo, Unretained(this));
199 ```
200
201 This disables all lifetime management on the object. You're responsible for
202 making sure the object is alive at the time of the call. You break it, you own
203 it!
204
205 ### Binding a class method and having the callback own the instance
206
207 ```cpp
208 MyClass* myclass = new MyClass;
209 Bind(&MyClass::Foo, Owned(myclass));
210 ```
211
212 The object will be deleted when the callback is destroyed, even if it's not run
213 (like if you post a task during shutdown). Potentially useful for "fire and
214 forget" cases.
215
216 Also, smart pointers (e.g. `std::unique_ptr<>`) are supported as the receiver.
217
218 ```cpp
219 std::unique_ptr<MyClass> myclass(new MyClass);
220 Bind(&MyClass::Foo, std::move(myclass));
221 ```
222
223 ### Ignoring return values
224
225 Sometimes you want to call a function that returns a value in a callback that
226 doesn't expect a return value.
227
228 ```cpp
229 int DoSomething(int arg) { cout << arg << endl; }
230 Callback<void(int)> cb =
231 Bind(IgnoreResult(&DoSomething));
232 ```
233
234 ## Quick reference for binding parameters to Bind()
235
236 Bound parameters are specified as arguments to `Bind()` and are passed to the
237 function. A callback with no parameters or no unbound parameters is called a
238 `Closure` (`Callback<void()>` and `Closure` are the same thing).
239
240 ### Passing parameters owned by the callback
241
242 ```cpp
243 void Foo(int* arg) { cout << *arg << endl; }
244 int* pn = new int(1);
245 Closure foo_callback = Bind(&foo, Owned(pn));
246 ```
247
248 The parameter will be deleted when the callback is destroyed, even if it's
249 not run (like if you post a task during shutdown).
250
251 ### Passing parameters as a unique_ptr
252
253 ```cpp
254 void TakesOwnership(std::unique_ptr<Foo> arg) {}
255 std::unique_ptr<Foo> f(new Foo);
256 // f becomes null during the following call.
257 RepeatingClosure cb = BindRepeating(&TakesOwnership, Passed(std::move(f)));
258 ```
259
260 Ownership of the parameter will be with the callback until it is run, when
261 ownership is passed to the callback function. This means the callback can only
262 be run once. If the callback is never run, it will delete the object when it's
263 destroyed.
264
265 ```cpp
266 void TakesOwnership(std::unique_ptr<Foo> arg) {}
267 std::unique_ptr<Foo> f(new Foo);
268 // f becomes null during the following call.
269 OneShotClosure cb = BindOneShot(&TakesOwnership, std::move(f));
270 ```
271
272 Parameters bound by `BindOneShot()` are passed out even without `Passed`.
273
274 ### Passing movable objects
275
276 ```cpp
277 void TakesMovableObject(std::vector<char> obj) {}
278 std::vector<char> buf;
279 Closure cb = Bind(&TakesMovableObject, Passed(&buf));
280 std::move(cb).Run();
281 ```
282
283 When a bound argument is wrapped by `Passed()`, `Bind` moves the argument into
284 its internal storage rather than copying it, and moves out it when the callback
285 is run.
286
287
288 ```cpp
289 void TakesMovableObject(std::vector<char> obj) {}
290 std::vector<char> buf;
291 OneShotClosure cb = BindOneShot(&TakesMovableObject, std::move(buf));
292 std::move(cb).Run();
293 ```
294
295 `OneShotCallback` moves out bound arguments even without `Passed`.
296
297
298 ```cpp
299 void TakesMovableObject(std::vector<char> buf) {}
300 std::vector<char> buf;
301 Closure cb = Bind(&TakesMovableObject, std::move(buf));
302 cb.Run();
303 ```
304
305 In contrast, when an object is bound with `std::move` into a `RepeatingCallback` ,
306 the bound object is copied when the callback is run.
307
308 ### Passing parameters as a scoped_refptr
309
310 ```cpp
311 void TakesOneRef(scoped_refptr<Foo> arg) {}
312 scoped_refptr<Foo> f(new Foo);
313 Closure cb = Bind(&TakesOneRef, f);
314 ```
315
316 This should "just work." The closure will take a reference as long as it is
317 alive, and another reference will be taken for the called function.
318
319 ```cpp
320 void DontTakeRef(Foo* arg) {}
321 scoped_refptr<Foo> f(new Foo);
322 Closure cb = Bind(&DontTakeRef, RetainedRef(f));
323 ```
324
325 `RetainedRef` holds a reference to the object and passes a raw pointer to
326 the object when the Callback is run.
327
328 ### Passing parameters by reference
329
330 Const references are *copied* unless ConstRef is used. Example:
331
332 ```cpp
333 void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
334 int n = 1;
335 Closure has_copy = Bind(&foo, n);
336 Closure has_ref = Bind(&foo, ConstRef(n));
337 n = 2;
338 foo(n); // Prints "2 0xaaaaaaaaaaaa"
339 has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
340 has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
341 ```
342
343 Normally parameters are copied in the closure.
344
345 **DANGER**: `ConstRef` stores a const reference instead, referencing the
346 original parameter. This means that you must ensure the object outlives the
347 callback!
348
349 ## Implementation notes
350
351 ### Where is this design from:
352
353 The design `Callback` and `Bind` is heavily influenced by C++'s
354 tr1::function/tr1::bind, and by the "Google Callback" system used inside Google.
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) {
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.
378 You can specialize `IsWeakReceiver` to make an external smart pointer as a
379 weak pointer.
380
381 `UnwrapTraits<BoundObject>::Unwrap()` is called for each bound arguments right
382 before `Callback` calls the target function. You can specialize this to define
383 an argument wrapper such as Unretained, ConstRef, Owned, RetainedRef and Passed.
384
385 ### How the implementation works:
386
387 There are three main components to the system:
388 1) The `Callback<>` classes.
389 2) The `Bind()` functions.
390 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`).
391
392 The Callback classes represent a generic function pointer. Internally, it stores
393 a refcounted piece of state that represents the target function and all its
394 bound parameters. `Callback` has a constructor that takes a `BindStateBase*`
395 and `&Invoker::Run`. A `BindState<>` holds a function object to run, and also
396 holds bound parameters. `BindStateBase` is the base class of of `BindState<>`,
397 without type information of bound data. In the context of the constructor of
398 `Callback`, `Invoker::Run` has the static type of `BindState<>` that identifies
399 the function it is representing and all its bound parameters.
400
401 `Bind()` creates the `BindState<>` that has the full static type, and erases the
402 target function type as well as the type of bound parameters. It does this by
403 taking a pointer to the specific `Invoker::Run()` function, and upcasting the
404 state of `BindState<>` to a `BindStateBase`. This is safe as long as this
405 `BindStateBase` pointer is only used with the stored `Invoker::Run()` pointer.
406
407 To `BindState<>` objects are created inside the `Bind()` functions.
408 These functions, along with a set of internal templates, are responsible for
409
410 - Unwrapping the function signature into return type, and parameters
411 - Determining the number of parameters that are bound
412 - Creating the BindState storing the bound parameters
413 - Performing compile-time asserts to avoid error-prone behavior
414 - Returning an `Callback<>` with an arity matching the number of unbound
415 parameters and that knows the correct refcounting semantics for the
416 target object if we are binding a method.
417
418 By default `Bind()` will store copies of all bound parameters, and attempt to
419 refcount a target object if the function being bound is a class method. These
420 copies are created even if the function takes parameters as const references.
421 (Binding to non-const references is forbidden, see bind.h.)
422
423 To change this behavior, we introduce a set of argument wrappers (e.g.,
424 `Unretained()`, and `ConstRef()`). These are simple container templates that
425 are passed by value, and wrap a pointer to argument. See the file-level comment
426 in base/bind_helpers.h for more info.
427
428 These types are passed to the Unwrap() functions, and the IsWeakReceiver<>
429 traits respectively to modify the behavior of Bind().
430
431 `ConstRef()` is similar to std::cref. `Unretained()` is specific to Chromium.
432 `Owned()` and `RetainedRef()` let `BindState<>` own the exclusive or shared
vabr (Chromium) 2016/08/24 11:44:06 optional nit: "own the exclusive or shared ownersh
tzik 2016/08/30 11:31:41 Done.
433 ownership and pass the bound item as a raw pointer to the target function.
OLDNEW
« base/callback_internal.cc ('K') | « base/callback_unittest.nc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698