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

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 docs 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
« 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()`. `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 types better as its bound parameter, and has
27 clearer lifetime. Thus, thread hopping or result handning of an asynchronous
28 operation is a good fit for it.
29
30 `RepeatingCallback<>` is created by `BindRepeating()`. `RepeatingCallback<>` is
31 a loose variant. Its internal storage is ref-counted and `RepeatingCallback<>`
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 you cannot predict on which thread the callback object is
35 destroyed.
36
37 `RepeatingCallback<>` is convertible to `OneShotCallback<>` by the implicit
38 conversion.
39
40 `Callback<>` is an alias of `RepeatingCallback<>` and `Bind()` is an alias of
41 `BindRepeating()` for a historical reason.
42
43 ### Memory management and passing
44
45 The `Callback` objects themselves should be passed by const-reference or by
46 value, and stored by copy or by move. They internally store their state via a
47 refcounted 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
59 ### Binding a captureless lambda
60
61 ```cpp
62 OneShotCallback<int()> lambda_cb = BindOneShot([] { return 3; });
63 LOG(INFO) << std::move(lambda_cb).Run(); // Print 3.
64
65 ```
66
67 ### Binding a class method
68
69 The first argument to bind is the member function to call, the second is
70 the object on which to call it.
71
72 ```cpp
73 class Ref : public RefCountedThreadSafe<Ref> {
74 public:
75 int Foo() { return 3; }
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 be run directly.
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 ## Quick reference for advanced binding
177
178 ### Binding a class method with weak pointers
179
180 ```cpp
181 Bind(&MyClass::Foo, GetWeakPtr());
182 ```
183
184 The callback will not be run if the object has already been destroyed.
185
186 *** note
187 **DANGER**: weak pointers are not threadsafe, so don't use this when you pass it
188 between threads!
189 ***
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_ptr<>`) are supported as the receiver.
213
214 ```cpp
215 std::unique_ptr<MyClass> myclass(new MyClass);
216 Bind(&MyClass::Foo, std::move(myclass));
217 ```
218
219 ### Ignoring return values
220
221 Sometimes you want to call a function that returns a value in a callback that
222 doesn't expect a return value.
223
224 ```cpp
225 int DoSomething(int arg) { cout << arg << endl; }
226 Callback<void(int)> cb =
227 Bind(IgnoreResult(&DoSomething));
228 ```
229
230
231 ## Quick reference for binding parameters to Bind()
232
233 Bound parameters are specified as arguments to `Bind()` and are passed to the
234 function. A callback with no parameters or no unbound parameters is called a
235 `Closure` (`Callback<void()>` and `Closure` are the same thing).
236
237 ### Passing parameters owned by the callback
238
239 ```cpp
240 void Foo(int* arg) { cout << *arg << endl; }
241 int* pn = new int(1);
242 Closure foo_callback = Bind(&foo, Owned(pn));
243 ```
244
245 The parameter will be deleted when the callback is destroyed, even if it's
246 not run (like if you post a task during shutdown).
247
248 ### Passing parameters as a unique_ptr
249
250 ```cpp
251 void TakesOwnership(std::unique_ptr<Foo> arg) {}
252 std::unique_ptr<Foo> f(new Foo);
253 // f becomes null during the following call.
254 RepeatingClosure cb = BindRepeating(&TakesOwnership, Passed(std::move(f)));
255 ```
256
257 Ownership of the parameter will be with the callback until it is run, when
258 ownership is passed to the callback function. This means the callback can only
259 be run once. If the callback is never run, it will delete the object when it's
260 destroyed.
261
262 ```cpp
263 void TakesOwnership(std::unique_ptr<Foo> arg) {}
264 std::unique_ptr<Foo> f(new Foo);
265 // f becomes null during the following call.
266 OneShotClosure cb = BindOneShot(&TakesOwnership, std::move(f));
267 ```
268
269 Parameters bound by `BindOneShot()` are passed out even without `Passed`.
270
271 ### Passing parameters as a scoped_refptr
272
273 ```cpp
274 void TakesOneRef(scoped_refptr<Foo> arg) {}
275 scoped_refptr<Foo> f(new Foo)
276 Closure cb = Bind(&TakesOneRef, f);
277 ```
278
279 This should "just work." The closure will take a reference as long as it is
280 alive, and another reference will be taken for the called function.
281
282 ### Passing parameters by reference
283
284 Const references are *copied* unless ConstRef is used. Example:
285
286 ```cpp
287 void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
288 int n = 1;
289 Closure has_copy = Bind(&foo, n);
290 Closure has_ref = Bind(&foo, ConstRef(n));
291 n = 2;
292 foo(n); // Prints "2 0xaaaaaaaaaaaa"
293 has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
294 has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
295 ```
296
297 Normally parameters are copied in the closure.
298
299 *** note
300 **DANGER**: `ConstRef` stores a const reference instead, referencing the
301 original parameter. This means that you must ensure the object outlives the
302 callback!
303 ***
304
305 ## Implementation notes
306
307 ### Where is this design from:
308
309 The design `Callback` and `Bind` is heavily influenced by C++'s
310 tr1::function/tr1::bind, and by the "Google Callback" system used inside Google.
311
312 ### How the implementation works:
313
314 There are three main components to the system:
315 1) The `Callback<>` classes.
316 2) The `Bind()` functions.
317 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`).
318
319 The Callback classes represent a generic function pointer. Internally, it stores
320 a refcounted piece of state that represents the target function and all its
321 bound parameters. `Callback` has a constructor that takes a `BindStateBase*`
322 and `&Invoker::Run`. A `BindState<>` holds a function object to run, and also
323 holds bound parameters. `BindStateBase` is the base class of of `BindState<>`,
324 without type information of bound data. In the context of the constructor of
325 `Callback`, `Invoker::Run` has the static type of `BindState<>` that identifies
326 the function it is representing and all its bound parameters.
327
328 `Bind()` creates the `BindState<>` that has the full static type, and erases the
329 target function type as well as the type of bound parameters. It does this by
330 taking a pointer to the specific `Invoker::Run()` function, and upcasting the
331 state of `BindState<>` to a `BindStateBase`. This is safe as long as this
332 `BindStateBase` pointer is only used with the stored `Invoker::Run()` pointer.
333
334 To `BindState<>` objects are created inside the `Bind()` functions.
335 These functions, along with a set of internal templates, are responsible for
336
337 - Unwrapping the function signature into return type, and parameters
338 - Determining the number of parameters that are bound
339 - Creating the BindState storing the bound parameters
340 - Performing compile-time asserts to avoid error-prone behavior
341 - Returning an `Callback<>` with an arity matching the number of unbound
342 parameters and that knows the correct refcounting semantics for the
343 target object if we are binding a method.
344
345 By default `Bind()` will store copies of all bound parameters, and attempt to
346 refcount a target object if the function being bound is a class method. These
347 copies are created even if the function takes parameters as const references.
348 (Binding to non-const references is forbidden, see bind.h.)
349
350 To change this behavior, we introduce a set of argument wrappers (e.g.,
351 `Unretained()`, and `ConstRef()`). These are simple container templates that
352 are passed by value, and wrap a pointer to argument. See the file-level comment
353 in base/bind_helpers.h for more info.
354
355 These types are passed to the Unwrap() functions, and the IsWeakReceiver<>
356 traits respectively to modify the behavior of Bind().
357
358 `ConstRef()` is similar to std::cref. `Unretained()` is specific to Chromium.
359 `Owned()` and `RetainedRef()` let `BindState<>` own the exclusive or shared
360 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