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

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: rebase Created 4 years, 4 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 | « 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()`. `OneShotCallback<>` is a
25 restricted variant of `Callback<>` that is a move-only type and can run only
26 once. It can handle move-only type better as its bound parameter, and has
Yuta Kitamura 2016/08/16 03:02:55 The sentence after "its bound parameter" looks cho
27 clearer lifetime. Thus, it's recommented to use for a thread hop or result
Yuta Kitamura 2016/08/16 03:02:56 recommen*d*ed Or rather replace the sentence afte
tzik 2016/08/16 06:53:37 Done.
28 handling of an asynchronous operation.
29
30 `RepeatingCallback<>` is created by `BindRepeating()`. `RepeatingCallback<>` is
31 a loose varint. Its internal storage is ref-counted and `RepeatingCallback<>`
Yuta Kitamura 2016/08/16 03:02:55 vari*a*nt
tzik 2016/08/16 06:53:37 Done.
32 itself is a copyable type. It can run more than once. So, it's suitable for
33 event handlers that may happen more than once. It's discouraged to use this for
34 a thread hop, since it's unpredictable on which thread the callback object is
Yuta Kitamura 2016/08/16 03:02:56 it's unpredictable on -> you cannot predict
tzik 2016/08/16 06:53:37 Done.
35 destroyed.
36
37 `RepeatingCallback<>` is convertible to `OneShotCallback<>`.
Yuta Kitamura 2016/08/16 03:02:55 By static_cast or other means?
tzik 2016/08/16 06:53:37 By the implicit conversion, added a comment here.
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 `Callback` objects themselves should be passed by const-reference or by
45 value, and stored by copy or by move. They internally store their state via a
46 refcounted class and thus do not need to be deleted.
47
48 ## Quick reference for basic stuff
Yuta Kitamura 2016/08/16 03:02:55 stuff -> usage
tzik 2016/08/16 06:53:37 Done.
49
50 ### Binding a bare function
51
52 ```cpp
53 int Return5() { return 5; }
54 Callback<int()> func_cb = Bind(&Return5);
55 LOG(INFO) << func_cb.Run(); // Prints 5.
56 ```
57
58 ### Binding a captureless lambda
59
60 ```cpp
61 OneShotCallback<int()> lambda_cb = BindOneShot([] { return 3; });
62 LOG(INFO) << std::move(lambda_cb).Run(); // Print 3.
63
64 ```
65
66 ### Binding a class method
67
68 The first argument to bind is the member function to call, the second is
69 the object on which to call it.
70
71 ```cpp
72 class Ref : public RefCountedThreadSafe<Ref> {
73 public:
74 int Foo() { return 3; }
75 void PrintBye() { LOG(INFO) << "bye."; }
Yuta Kitamura 2016/08/16 03:02:55 This looks unused.
tzik 2016/08/16 06:53:37 Done.
76 };
77
78 scoped_refptr<Ref> ref = new Ref();
79 Callback<void()> ref_cb = Bind(&Ref::Foo, ref);
80 LOG(INFO) << ref_cb.Run(); // Prints out 3.
81 ```
82
83 By default the object must support RefCounted or you will get a compiler
84 error. If you're passing between threads, be sure it's RefCountedThreadSafe!
85 See "Advanced binding of member functions" below if you don't want to use
86 reference counting.
87
88 ### Running a Callback
89
90 Callbacks can be run with their "Run" method, which has the same signature as
91 the template argument to the callback.
92
93 `RepeatingCallback<>` can run directly.
Yuta Kitamura 2016/08/16 03:02:56 run -> be run ("run" is intransitive, so "X can r
tzik 2016/08/16 06:53:37 Done.
94
95 ```cpp
96 void DoSomething(const RepeatingCallback<void(int, std::string)>& callback) {
97 callback.Run(5, "hello");
98 }
99 ```
100
101 ```cpp
102 void DoSomething(const RepeatingCallback<double(double)>& callback) {
103 double myresult = callback.Run(3.14159);
104 myresult += callback.Run(2.71828);
105 }
106 ```
107
108 `OneShotCallback<>` can run when it's a rvalue. Use `std::move` or
109 `ResetAndReturn` to run it.
110
111 ```cpp
112 void DoSomething(OneShotCallback<void(int, double)> callback) {
113 std::move(callback).Run(1, 0.1);
114 }
115 ```
116
117 ```cpp
118 void DoSomething(OneShotCallback<void()> callback) {
119 ResetAndReturn(&callback).Run();
120 }
121 ```
122
123 `RepeatingCallback<>` can be run more than once (they don't get deleted or
124 marked when run). However, this precludes using `Passed` (see below).
125
126 ### Passing unbound input parameters
127
128 Unbound parameters are specified at the time a callback is Run(). They are
129 specified in the Callback template type:
130
131 ```cpp
132 void MyFunc(int i, const std::string& str) {}
133 Callback<void(int, const std::string&)> cb = Bind(&MyFunc);
134 cb.Run(23, "hello, world");
135 ```
136
137 ### Passing bound input parameters
138
139 Bound parameters are specified when you create the callback as arguments to
140 `Bind()`. They will be passed to the function and the runner of the callback
141 doesn't see those values or even know that the function it's calling.
142
143 ```cpp
144 void MyFunc(int i, const std::string& str) {}
145 Callback<void()> cb = Bind(&MyFunc, 23, "hello world");
146 cb.Run();
147 ```
148
149 A callback with no unbound input parameters (`Callback<void()>`,
150 `OneShotCallback<void()>` and `RepeatingCallback<void()>`) is called a
151 `Closure`, `OneShotClosure` and `RepeatingClosure`, respectively.
152 So we could have also written:
153
154 ```cpp
155 Closure cb = Bind(&MyFunc, 23, "hello world");
156 ```
157
158 When calling member functions, bound parameters just go after the object
159 pointer.
160
161 ```cpp
162 Closure cb = Bind(&MyClass::MyFunc, this, 23, "hello world");
163 ```
164
165 ### PARTIAL BINDING OF PARAMETERS
166
167 You can specify some parameters when you create the callback, and specify
168 the rest when you execute the callback.
169
170 ```cpp
171 void MyFunc(int i, const std::string& str) {}
172 Callback<void(const std::string&)> cb = Bind(&MyFunc, 23);
173 cb.Run("hello world");
174 ```
175
176 When calling a function bound parameters are first, followed by unbound
Yuta Kitamura 2016/08/16 03:02:55 bound parameters are first -> you must specify bou
tzik 2016/08/16 06:53:37 Hmm, this sentence looks redundant to me. Let me r
177 parameters.
178
179 ## Quick reference for advanced binding
180
181 ### Binding a class method with weak pointers
182
183 ```cpp
184 Bind(&MyClass::Foo, GetWeakPtr());
185 ```
186
187 The callback will not be run if the object has already been destroyed.
188 DANGER: weak pointers are not threadsafe, so don't use this
Yuta Kitamura 2016/08/16 03:02:56 nit: **DANGER** to let it stand out. Also you mig
tzik 2016/08/16 06:53:37 Done.
189 when passing between threads!
190
191 ### Binding a class method with manual lifetime management
192
193 ```cpp
194 Bind(&MyClass::Foo, Unretained(this));
195 ```
196
197 This disables all lifetime management on the object. You're responsible for
198 making sure the object is alive at the time of the call. You break it, you own
199 it!
200
201 ### Binding a class method and having the callback own the class
202
203 ```cpp
204 MyClass* myclass = new MyClass;
205 Bind(&MyClass::Foo, Owned(myclass));
206 ```
207
208 The object will be deleted when the callback is destroyed, even if it's not run
209 (like if you post a task during shutdown). Potentially useful for "fire and
210 forget" cases.
211
212 Also, smart pointers (e.g. `std::unique_pointer<>`) are supported as the
Yuta Kitamura 2016/08/16 03:02:56 pointer -> ptr
tzik 2016/08/16 06:53:37 Done.
213 receiver.
214
215 ```cpp
216 std::unique_ptr<MyClass> myclass(new MyClass);
217 Bind(&MyClass::Foo, std::move(myclass));
218 ```
219
220 ### Ignoring return values
221
222 Sometimes you want to call a function that returns a value in a callback that
223 doesn't expect a return value.
224
225 ```cpp
226 int DoSomething(int arg) { cout << arg << endl; }
227 Callback<void(int)> cb =
228 Bind(IgnoreResult(&DoSomething));
229 ```
230
231
232 ## Quick reference for binding parameters to Bind()
233
234 Bound parameters are specified as arguments to `Bind()` and are passed to the
235 function. A callback with no parameters or no unbound parameters is called a
236 `Closure` (`Callback<void()>` and `Closure` are the same thing).
237
238 ### Passing parameters owned by the callback
239
240 ```cpp
241 void Foo(int* arg) { cout << *arg << endl; }
242 int* pn = new int(1);
243 Closure foo_callback = Bind(&foo, Owned(pn));
244 ```
245
246 The parameter will be deleted when the callback is destroyed, even if it's
247 not run (like if you post a task during shutdown).
248
249 ### Passing parameters as a unique_ptr
250
251 ```cpp
252 void TakesOwnership(std::unique_ptr<Foo> arg) {}
253 std::unique_ptr<Foo> f(new Foo);
254 // f becomes null during the following call.
255 RepeatingClosure cb = BindRepeating(&TakesOwnership, Passed(std::move(f)));
256 ```
257
258 Ownership of the parameter will be with the callback until the it is run,
Yuta Kitamura 2016/08/16 03:02:56 the it -> it
tzik 2016/08/16 06:53:37 Done.
259 when ownership is passed to the callback function. This means the callback
260 can only be run once. If the callback is never run, it will delete the
261 object when it's destroyed.
262
263 ```cpp
264 void TakesOwnership(std::unique_ptr<Foo> arg) {}
265 std::unique_ptr<Foo> f(new Foo);
266 // f becomes null during the following call.
267 OneShotClosure cb = BindOneShot(&TakesOwnership, std::move(f));
268 ```
269
270 Parameters bound by `BindOneShot()` are passed out even without `Passed`.
271
272 ### Passing parameters as a scoped_refptr
273
274 ```cpp
275 void TakesOneRef(scoped_refptr<Foo> arg) {}
276 scoped_refptr<Foo> f(new Foo)
277 Closure cb = Bind(&TakesOneRef, f);
278 ```
279
280 This should "just work." The closure will take a reference as long as it is
281 alive, and another reference will be taken for the called function.
282
283 ### Passing parameters by reference
284
285 Const references are *copied* unless ConstRef is used. Example:
286
287 ```cpp
288 void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
289 int n = 1;
290 Closure has_copy = Bind(&foo, n);
291 Closure has_ref = Bind(&foo, ConstRef(n));
292 n = 2;
293 foo(n); // Prints "2 0xaaaaaaaaaaaa"
294 has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
295 has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
296 ```
297
298 Normally parameters are copied in the closure. DANGER: `ConstRef` stores a
Yuta Kitamura 2016/08/16 03:02:55 Ditto regarding DANGER
299 const reference instead, referencing the original parameter. This means
300 that you must ensure the object outlives the callback!
301
302 ## Implementation notes
303
304 ### Where is this design from:
305
306 The design `Callback` and `Bind` is heavily influenced by C++'s
307 tr1::function/tr1::bind, and by the "Google Callback" system used inside Google.
308
309 ### How the implementation works:
310
311 There are three main components to the system:
312 1) The `Callback<>` classes.
313 2) The `Bind()` functions.
314 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`).
315
316 The Callback classes represent a generic function pointer. Internally, it stores
317 a refcounted piece of state that represents the target function and all its
318 bound parameters. `Callback` has a constructor that takes a `BindStateBase*`
319 and `&Invoker::Run`. A `BindState<>` holds a function object to run, and also
320 holds bound parameters. `BindStateBase` is the base class of of `BindState<>`,
321 without type information of bound data. In the context of the constructor of
322 `Callback`, `Invoker::Run` has the static type of `BindState<>` that identifies
323 the function it is representing and all its bound parameters.
324
325 `Bind()` creates the `BindState<>` that has the full static type, and erases the
326 target function type as well as the type of bound parameters. It does this by
327 taking a pointer to the specific `Invoker::Run()` function, and upcasting the
328 state of `BindState<>` to a `BindStateBase`. This is safe as long as this
329 `BindStateBase` pointer is only used with the stored `Invoker::Run()` pointer.
330
331 To `BindState<>` objects are created inside the `Bind()` functions.
332 These functions, along with a set of internal templates, are responsible for
333
334 - Unwrapping the function signature into return type, and parameters
335 - Determining the number of parameters that are bound
336 - Creating the BindState storing the bound parameters
337 - Performing compile-time asserts to avoid error-prone behavior
338 - Returning an `Callback<>` with an arity matching the number of unbound
339 parameters and that knows the correct refcounting semantics for the
340 target object if we are binding a method.
341
342 By default `Bind()` will store copies of all bound parameters, and attempt to
343 refcount a target object if the function being bound is a class method. These
344 copies are created even if the function takes parameters as const references.
345 (Binding to non-const references is forbidden, see bind.h.)
346
347 To change this behavior, we introduce a set of argument wrappers (e.g.,
348 `Unretained()`, and `ConstRef()`). These are simple container templates that
349 are passed by value, and wrap a pointer to argument. See the file-level comment
350 in base/bind_helpers.h for more info.
351
352 These types are passed to the Unwrap() functions, and the IsWeakReceiver<>
353 traits respectively to modify the behavior of Bind().
354
355 `ConstRef()` is similar to std::cref. `Unretained()` is specific to Chromium.
356 `Owned()` and `RetainedRef()` let `BindState<>` own the exclusive or shared
357 ownership and pass the bound item as a raw pointer to the target function.
OLDNEW
« no previous file with comments | « base/callback_unittest.nc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698