blob: a380cf4b83ba4c417b79659fc11632a37e0a76d9 [file] [log] [blame] [view]
tzik703f1562016-09-02 07:36:551
2# Introduction
3
4The templated Callback class is a generalized function object. Together
5with the `Bind()` function in bind.h, they provide a type-safe method for
6performing partial application of functions.
7
8Partial application (or "currying") is the process of binding a subset of
9a function's arguments to produce another function that takes fewer
10arguments. This can be used to pass around a unit of delayed execution,
11much like lexical closures are used in other languages. For example, it
12is used in Chromium code to schedule tasks on different MessageLoops.
13
14A callback with no unbound input parameters (`base::Callback<void()>`)
15is called a `base::Closure`. Note that this is NOT the same as what other
16languages refer to as a closure -- it does not retain a reference to its
17enclosing environment.
18
19## MEMORY MANAGEMENT AND PASSING
20
21The Callback objects themselves should be passed by const-reference, and
22stored by copy. They internally store their state via a refcounted class
23and thus do not need to be deleted.
24
25The reason to pass via a const-reference is to avoid unnecessary
26AddRef/Release pairs to the internal state.
27
28
29# Quick reference for basic stuff
30
31## BINDING A BARE FUNCTION
32
33```cpp
34int Return5() { return 5; }
35base::Callback<int()> func_cb = base::Bind(&Return5);
36LOG(INFO) << func_cb.Run(); // Prints 5.
37```
38
39## BINDING A CLASS METHOD
40
41The first argument to bind is the member function to call, the second is
42the object on which to call it.
43
44```cpp
45class Ref : public base::RefCountedThreadSafe<Ref> {
46 public:
47 int Foo() { return 3; }
48 void PrintBye() { LOG(INFO) << "bye."; }
49};
50scoped_refptr<Ref> ref = new Ref();
51base::Callback<void()> ref_cb = base::Bind(&Ref::Foo, ref);
52LOG(INFO) << ref_cb.Run(); // Prints out 3.
53```
54
55By default the object must support RefCounted or you will get a compiler
56error. If you're passing between threads, be sure it's
57RefCountedThreadSafe! See "Advanced binding of member functions" below if
58you don't want to use reference counting.
59
60## RUNNING A CALLBACK
61
62Callbacks can be run with their `Run` method, which has the same
63signature as the template argument to the callback.
64
65```cpp
66void DoSomething(const base::Callback<void(int, std::string)>& callback) {
67 callback.Run(5, "hello");
68}
69```
70
71Callbacks can be run more than once (they don't get deleted or marked when
72run). However, this precludes using base::Passed (see below).
73
74```cpp
75void DoSomething(const base::Callback<double(double)>& callback) {
76 double myresult = callback.Run(3.14159);
77 myresult += callback.Run(2.71828);
78}
79```
80
81## PASSING UNBOUND INPUT PARAMETERS
82
83Unbound parameters are specified at the time a callback is `Run()`. They are
84specified in the `Callback` template type:
85
86```cpp
87void MyFunc(int i, const std::string& str) {}
88base::Callback<void(int, const std::string&)> cb = base::Bind(&MyFunc);
89cb.Run(23, "hello, world");
90```
91
92## PASSING BOUND INPUT PARAMETERS
93
94Bound parameters are specified when you create the callback as arguments
95to `Bind()`. They will be passed to the function and the `Run()`ner of the
96callback doesn't see those values or even know that the function it's
97calling.
98
99```cpp
100void MyFunc(int i, const std::string& str) {}
101base::Callback<void()> cb = base::Bind(&MyFunc, 23, "hello world");
102cb.Run();
103```
104
105A callback with no unbound input parameters (`base::Callback<void()>`)
106is called a `base::Closure`. So we could have also written:
107
108```cpp
109base::Closure cb = base::Bind(&MyFunc, 23, "hello world");
110```
111
112When calling member functions, bound parameters just go after the object
113pointer.
114
115```cpp
116base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world");
117```
118
119## PARTIAL BINDING OF PARAMETERS
120
121You can specify some parameters when you create the callback, and specify
122the rest when you execute the callback.
123
124```cpp
125void MyFunc(int i, const std::string& str) {}
126base::Callback<void(const std::string&)> cb = base::Bind(&MyFunc, 23);
127cb.Run("hello world");
128```
129
130When calling a function bound parameters are first, followed by unbound
131parameters.
132
133
134# Quick reference for advanced binding
135
136## BINDING A CLASS METHOD WITH WEAK POINTERS
137
138```cpp
139base::Bind(&MyClass::Foo, GetWeakPtr());
140``
141
142The callback will not be run if the object has already been destroyed.
143DANGER: weak pointers are not threadsafe, so don't use this
144when passing between threads!
145
146## BINDING A CLASS METHOD WITH MANUAL LIFETIME MANAGEMENT
147
148```cpp
149base::Bind(&MyClass::Foo, base::Unretained(this));
150```
151
152This disables all lifetime management on the object. You're responsible
153for making sure the object is alive at the time of the call. You break it,
154you own it!
155
156## BINDING A CLASS METHOD AND HAVING THE CALLBACK OWN THE CLASS
157
158```cpp
159MyClass* myclass = new MyClass;
160base::Bind(&MyClass::Foo, base::Owned(myclass));
161```
162
163The object will be deleted when the callback is destroyed, even if it's
164not run (like if you post a task during shutdown). Potentially useful for
165"fire and forget" cases.
166
167## IGNORING RETURN VALUES
168
169Sometimes you want to call a function that returns a value in a callback
170that doesn't expect a return value.
171
172```cpp
173int DoSomething(int arg) { cout << arg << endl; }
174base::Callback<void(int)> cb =
175 base::Bind(base::IgnoreResult(&DoSomething));
176```
177
178# Quick reference for binding parameters to Bind()
179
180Bound parameters are specified as arguments to `Bind()` and are passed to the
181function. A callback with no parameters or no unbound parameters is called a
182`Closure` (`base::Callback<void()>` and `base::Closure` are the same thing).
183
184## PASSING PARAMETERS OWNED BY THE CALLBACK
185
186```cpp
187void Foo(int* arg) { cout << *arg << endl; }
188int* pn = new int(1);
189base::Closure foo_callback = base::Bind(&foo, base::Owned(pn));
190```
191
192The parameter will be deleted when the callback is destroyed, even if it's
193not run (like if you post a task during shutdown).
194
195## PASSING PARAMETERS AS A scoped_ptr
196
197```cpp
198void TakesOwnership(std::unique_ptr<Foo> arg) {}
199std::unique_ptr<Foo> f(new Foo);
200// f becomes null during the following call.
201base::Closure cb = base::Bind(&TakesOwnership, base::Passed(&f));
202```
203
204Ownership of the parameter will be with the callback until the callback is
205run, and then ownership is passed to the callback function. This means the
206callback can only be run once. If the callback is never run, it will delete
207the object when it's destroyed.
208
209## PASSING PARAMETERS AS A scoped_refptr
210
211```cpp
212void TakesOneRef(scoped_refptr<Foo> arg) {}
213scoped_refptr<Foo> f(new Foo)
214base::Closure cb = base::Bind(&TakesOneRef, f);
215```
216
217This should "just work." The closure will take a reference as long as it
218is alive, and another reference will be taken for the called function.
219
220## PASSING PARAMETERS BY REFERENCE
221
222Const references are *copied* unless `ConstRef` is used. Example:
223
224```cpp
225void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
226int n = 1;
227base::Closure has_copy = base::Bind(&foo, n);
228base::Closure has_ref = base::Bind(&foo, base::ConstRef(n));
229n = 2;
230foo(n); // Prints "2 0xaaaaaaaaaaaa"
231has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
232has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
233```
234
235Normally parameters are copied in the closure. DANGER: ConstRef stores a
236const reference instead, referencing the original parameter. This means
237that you must ensure the object outlives the callback!
238
239
240# Implementation notes
241
242## WHERE IS THIS DESIGN FROM:
243
244The design `Callback` and Bind is heavily influenced by C++'s
245`tr1::function`/`tr1::bind`, and by the "Google Callback" system used inside
246Google.
247
248## HOW THE IMPLEMENTATION WORKS:
249
250There are three main components to the system:
251 1) The Callback classes.
252 2) The `Bind()` functions.
253 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`).
254
255The Callback classes represent a generic function pointer. Internally,
256it stores a refcounted piece of state that represents the target function
257and all its bound parameters. Each `Callback` specialization has a templated
258constructor that takes an `BindState<>*`. In the context of the constructor,
259the static type of this `BindState<>` pointer uniquely identifies the
260function it is representing, all its bound parameters, and a `Run()` method
261that is capable of invoking the target.
262
263`Callback`'s constructor takes the `BindState<>*` that has the full static type
264and erases the target function type as well as the types of the bound
265parameters. It does this by storing a pointer to the specific `Run()`
266function, and upcasting the state of `BindState<>*` to a
267`BindStateBase*`. This is safe as long as this `BindStateBase` pointer
268is only used with the stored `Run()` pointer.
269
270To `BindState<>` objects are created inside the `Bind()` functions.
271These functions, along with a set of internal templates, are responsible for
272
273 - Unwrapping the function signature into return type, and parameters
274 - Determining the number of parameters that are bound
275 - Creating the BindState storing the bound parameters
276 - Performing compile-time asserts to avoid error-prone behavior
277 - Returning an `Callback<>` with an arity matching the number of unbound
278 parameters and that knows the correct refcounting semantics for the
279 target object if we are binding a method.
280
281The `Bind` functions do the above using type-inference, and template
282specializations.
283
284By default `Bind()` will store copies of all bound parameters, and attempt
285to refcount a target object if the function being bound is a class method.
286These copies are created even if the function takes parameters as const
287references. (Binding to non-const references is forbidden, see bind.h.)
288
289To change this behavior, we introduce a set of argument wrappers
290(e.g., `Unretained()`, and `ConstRef()`). These are simple container templates
291that are passed by value, and wrap a pointer to argument. See the
292file-level comment in base/bind_helpers.h for more info.
293
294These types are passed to the `Unwrap()` functions, and the `MaybeRefcount()`
295functions respectively to modify the behavior of `Bind()`. The `Unwrap()`
296and `MaybeRefcount()` functions change behavior by doing partial
297specialization based on whether or not a parameter is a wrapper type.
298
299`ConstRef()` is similar to `tr1::cref`. `Unretained()` is specific to Chromium.
300
301
302## WHY NOT TR1 FUNCTION/BIND?
303
304Direct use of `tr1::function` and `tr1::bind` was considered, but ultimately
305rejected because of the number of copy constructors invocations involved
306in the binding of arguments during construction, and the forwarding of
307arguments during invocation. These copies will no longer be an issue in
308C++0x because C++0x will support rvalue reference allowing for the compiler
309to avoid these copies. However, waiting for C++0x is not an option.
310
311Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the
312`tr1::bind` call itself will invoke a non-trivial copy constructor three times
313for each bound parameter. Also, each when passing a `tr1::function`, each
314bound argument will be copied again.
315
316In addition to the copies taken at binding and invocation, copying a
317`tr1::function` causes a copy to be made of all the bound parameters and
318state.
319
320Furthermore, in Chromium, it is desirable for the `Callback` to take a
321reference on a target object when representing a class method call. This
322is not supported by tr1.
323
324Lastly, `tr1::function` and `tr1::bind` has a more general and flexible API.
325This includes things like argument reordering by use of
326`tr1::bind::placeholder`, support for non-const reference parameters, and some
327limited amount of subtyping of the `tr1::function` object (e.g.,
328`tr1::function<int(int)>` is convertible to `tr1::function<void(int)>`).
329
330These are not features that are required in Chromium. Some of them, such as
331allowing for reference parameters, and subtyping of functions, may actually
332become a source of errors. Removing support for these features actually
333allows for a simpler implementation, and a terser Currying API.
334
335## WHY NOT GOOGLE CALLBACKS?
336
337The Google callback system also does not support refcounting. Furthermore,
338its implementation has a number of strange edge cases with respect to type
339conversion of its arguments. In particular, the argument's constness must
340at times match exactly the function signature, or the type-inference might
341break. Given the above, writing a custom solution was easier.
342
343
344## MISSING FUNCTIONALITY
345 - Invoking the return of `Bind`. `Bind(&foo).Run()` does not work;
346 - Binding arrays to functions that take a non-const pointer.
347 Example:
348```cpp
349void Foo(const char* ptr);
350void Bar(char* ptr);
351Bind(&Foo, "test");
352Bind(&Bar, "test"); // This fails because ptr is not const.
353```
354
355If you are thinking of forward declaring `Callback` in your own header file,
356please include "base/callback_forward.h" instead.