blob: af141b5d62f829929b0122582ec5c0b17280bcf9 [file] [log] [blame] [view]
tzika4313512016-09-06 06:51:121# base::Callback<> and base::Bind()
tzik703f1562016-09-02 07:36:552
tzika4313512016-09-06 06:51:123## Introduction
tzik703f1562016-09-02 07:36:554
tzika4313512016-09-06 06:51:125The templated `Callback<>` class is a generalized function object. Together with
6the `Bind()` function in base/bind.h, they provide a type-safe method for
tzik703f1562016-09-02 07:36:557performing partial application of functions.
8
tzika4313512016-09-06 06:51:129Partial application (or "currying") is the process of binding a subset of a
10function's arguments to produce another function that takes fewer arguments.
11This can be used to pass around a unit of delayed execution, much like lexical
12closures are used in other languages. For example, it is used in Chromium code
13to schedule tasks on different MessageLoops.
tzik703f1562016-09-02 07:36:5514
tzika4313512016-09-06 06:51:1215A 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
17closure -- it does not retain a reference to its enclosing environment.
tzik703f1562016-09-02 07:36:5518
tzika4313512016-09-06 06:51:1219### Memory Management And Passing
tzik703f1562016-09-02 07:36:5520
tzika4313512016-09-06 06:51:1221The Callback objects themselves should be passed by const-reference, and stored
22by copy. They internally store their state via a refcounted class and thus do
23not need to be deleted.
tzik703f1562016-09-02 07:36:5524
tzika4313512016-09-06 06:51:1225The reason to pass via a const-reference is to avoid unnecessary AddRef/Release
26pairs to the internal state.
tzik703f1562016-09-02 07:36:5527
tzika4313512016-09-06 06:51:1228## Quick reference for basic stuff
tzik703f1562016-09-02 07:36:5529
tzika4313512016-09-06 06:51:1230### Binding A Bare Function
tzik703f1562016-09-02 07:36:5531
32```cpp
33int Return5() { return 5; }
34base::Callback<int()> func_cb = base::Bind(&Return5);
35LOG(INFO) << func_cb.Run(); // Prints 5.
36```
37
tzika4313512016-09-06 06:51:1238### Binding A Class Method
tzik703f1562016-09-02 07:36:5539
tzika4313512016-09-06 06:51:1240The first argument to bind is the member function to call, the second is the
41object on which to call it.
tzik703f1562016-09-02 07:36:5542
43```cpp
44class Ref : public base::RefCountedThreadSafe<Ref> {
45 public:
46 int Foo() { return 3; }
47 void PrintBye() { LOG(INFO) << "bye."; }
48};
49scoped_refptr<Ref> ref = new Ref();
50base::Callback<void()> ref_cb = base::Bind(&Ref::Foo, ref);
51LOG(INFO) << ref_cb.Run(); // Prints out 3.
52```
53
54By default the object must support RefCounted or you will get a compiler
55error. If you're passing between threads, be sure it's
56RefCountedThreadSafe! See "Advanced binding of member functions" below if
57you don't want to use reference counting.
58
tzika4313512016-09-06 06:51:1259### Running A Callback
tzik703f1562016-09-02 07:36:5560
61Callbacks can be run with their `Run` method, which has the same
62signature as the template argument to the callback.
63
64```cpp
65void DoSomething(const base::Callback<void(int, std::string)>& callback) {
66 callback.Run(5, "hello");
67}
68```
69
70Callbacks can be run more than once (they don't get deleted or marked when
71run). However, this precludes using base::Passed (see below).
72
73```cpp
74void DoSomething(const base::Callback<double(double)>& callback) {
75 double myresult = callback.Run(3.14159);
76 myresult += callback.Run(2.71828);
77}
78```
79
tzika4313512016-09-06 06:51:1280### Passing Unbound Input Parameters
tzik703f1562016-09-02 07:36:5581
82Unbound parameters are specified at the time a callback is `Run()`. They are
83specified in the `Callback` template type:
84
85```cpp
86void MyFunc(int i, const std::string& str) {}
87base::Callback<void(int, const std::string&)> cb = base::Bind(&MyFunc);
88cb.Run(23, "hello, world");
89```
90
tzika4313512016-09-06 06:51:1291### Passing Bound Input Parameters
tzik703f1562016-09-02 07:36:5592
tzika4313512016-09-06 06:51:1293Bound 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
95doesn't see those values or even know that the function it's calling.
tzik703f1562016-09-02 07:36:5596
97```cpp
98void MyFunc(int i, const std::string& str) {}
99base::Callback<void()> cb = base::Bind(&MyFunc, 23, "hello world");
100cb.Run();
101```
102
tzika4313512016-09-06 06:51:12103A callback with no unbound input parameters (`base::Callback<void()>`) is called
104a `base::Closure`. So we could have also written:
tzik703f1562016-09-02 07:36:55105
106```cpp
107base::Closure cb = base::Bind(&MyFunc, 23, "hello world");
108```
109
110When calling member functions, bound parameters just go after the object
111pointer.
112
113```cpp
114base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world");
115```
116
tzika4313512016-09-06 06:51:12117### Partial Binding Of Parameters
tzik703f1562016-09-02 07:36:55118
tzika4313512016-09-06 06:51:12119You can specify some parameters when you create the callback, and specify the
120rest when you execute the callback.
tzik703f1562016-09-02 07:36:55121
122```cpp
123void MyFunc(int i, const std::string& str) {}
124base::Callback<void(const std::string&)> cb = base::Bind(&MyFunc, 23);
125cb.Run("hello world");
126```
127
128When calling a function bound parameters are first, followed by unbound
129parameters.
130
tzika4313512016-09-06 06:51:12131## Quick reference for advanced binding
tzik703f1562016-09-02 07:36:55132
tzika4313512016-09-06 06:51:12133### Binding A Class Method With Weak Pointers
tzik703f1562016-09-02 07:36:55134
135```cpp
136base::Bind(&MyClass::Foo, GetWeakPtr());
tzika4313512016-09-06 06:51:12137```
tzik703f1562016-09-02 07:36:55138
139The callback will not be run if the object has already been destroyed.
tzika4313512016-09-06 06:51:12140**DANGER**: weak pointers are not threadsafe, so don't use this when passing between
141threads!
tzik703f1562016-09-02 07:36:55142
tzika4313512016-09-06 06:51:12143### Binding A Class Method With Manual Lifetime Management
tzik703f1562016-09-02 07:36:55144
145```cpp
146base::Bind(&MyClass::Foo, base::Unretained(this));
147```
148
tzika4313512016-09-06 06:51:12149This disables all lifetime management on the object. You're responsible for
150making sure the object is alive at the time of the call. You break it, you own
151it!
tzik703f1562016-09-02 07:36:55152
tzika4313512016-09-06 06:51:12153### Binding A Class Method And Having The Callback Own The Class
tzik703f1562016-09-02 07:36:55154
155```cpp
156MyClass* myclass = new MyClass;
157base::Bind(&MyClass::Foo, base::Owned(myclass));
158```
159
tzika4313512016-09-06 06:51:12160The 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
162forget" cases.
tzik703f1562016-09-02 07:36:55163
tzika4313512016-09-06 06:51:12164### Ignoring Return Values
tzik703f1562016-09-02 07:36:55165
tzika4313512016-09-06 06:51:12166Sometimes you want to call a function that returns a value in a callback that
167doesn't expect a return value.
tzik703f1562016-09-02 07:36:55168
169```cpp
170int DoSomething(int arg) { cout << arg << endl; }
171base::Callback<void(int)> cb =
172 base::Bind(base::IgnoreResult(&DoSomething));
173```
174
tzika4313512016-09-06 06:51:12175## Quick reference for binding parameters to Bind()
tzik703f1562016-09-02 07:36:55176
177Bound parameters are specified as arguments to `Bind()` and are passed to the
178function. A callback with no parameters or no unbound parameters is called a
179`Closure` (`base::Callback<void()>` and `base::Closure` are the same thing).
180
tzika4313512016-09-06 06:51:12181### Passing Parameters Owned By The Callback
tzik703f1562016-09-02 07:36:55182
183```cpp
184void Foo(int* arg) { cout << *arg << endl; }
185int* pn = new int(1);
186base::Closure foo_callback = base::Bind(&foo, base::Owned(pn));
187```
188
tzika4313512016-09-06 06:51:12189The parameter will be deleted when the callback is destroyed, even if it's not
190run (like if you post a task during shutdown).
tzik703f1562016-09-02 07:36:55191
tzika4313512016-09-06 06:51:12192### Passing Parameters As A unique_ptr
tzik703f1562016-09-02 07:36:55193
194```cpp
195void TakesOwnership(std::unique_ptr<Foo> arg) {}
196std::unique_ptr<Foo> f(new Foo);
197// f becomes null during the following call.
198base::Closure cb = base::Bind(&TakesOwnership, base::Passed(&f));
199```
200
tzika4313512016-09-06 06:51:12201Ownership of the parameter will be with the callback until the callback is run,
202and then ownership is passed to the callback function. This means the callback
203can only be run once. If the callback is never run, it will delete the object
204when it's destroyed.
tzik703f1562016-09-02 07:36:55205
tzika4313512016-09-06 06:51:12206### Passing Parameters As A scoped_refptr
tzik703f1562016-09-02 07:36:55207
208```cpp
209void TakesOneRef(scoped_refptr<Foo> arg) {}
210scoped_refptr<Foo> f(new Foo)
211base::Closure cb = base::Bind(&TakesOneRef, f);
212```
213
tzika4313512016-09-06 06:51:12214This should "just work." The closure will take a reference as long as it is
215alive, and another reference will be taken for the called function.
tzik703f1562016-09-02 07:36:55216
tzika4313512016-09-06 06:51:12217### Passing Parameters By Reference
tzik703f1562016-09-02 07:36:55218
219Const references are *copied* unless `ConstRef` is used. Example:
220
221```cpp
222void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
223int n = 1;
224base::Closure has_copy = base::Bind(&foo, n);
225base::Closure has_ref = base::Bind(&foo, base::ConstRef(n));
226n = 2;
227foo(n); // Prints "2 0xaaaaaaaaaaaa"
228has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
229has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
230```
231
tzika4313512016-09-06 06:51:12232Normally parameters are copied in the closure.
233**DANGER**: ConstRef stores a const reference instead, referencing the original
234parameter. This means that you must ensure the object outlives the callback!
tzik703f1562016-09-02 07:36:55235
tzika4313512016-09-06 06:51:12236## Implementation notes
tzik703f1562016-09-02 07:36:55237
tzika4313512016-09-06 06:51:12238### Where Is This Design From:
tzik703f1562016-09-02 07:36:55239
tzika4313512016-09-06 06:51:12240The design `Callback` and Bind is heavily influenced by C++'s `tr1::function` /
241`tr1::bind`, and by the "Google Callback" system used inside Google.
tzik703f1562016-09-02 07:36:55242
tzika4313512016-09-06 06:51:12243### How The Implementation Works:
tzik703f1562016-09-02 07:36:55244
245There are three main components to the system:
246 1) The Callback classes.
247 2) The `Bind()` functions.
248 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`).
249
tzika4313512016-09-06 06:51:12250The Callback classes represent a generic function pointer. Internally, it stores
251a refcounted piece of state that represents the target function and all its
252bound parameters. Each `Callback` specialization has a templated constructor
253that takes an `BindState<>*`. In the context of the constructor, the static
254type of this `BindState<>` pointer uniquely identifies the function it is
255representing, all its bound parameters, and a `Run()` method that is capable of
256invoking the target.
tzik703f1562016-09-02 07:36:55257
258`Callback`'s constructor takes the `BindState<>*` that has the full static type
259and erases the target function type as well as the types of the bound
tzika4313512016-09-06 06:51:12260parameters. It does this by storing a pointer to the specific `Run()` function,
261and upcasting the state of `BindState<>*` to a `BindStateBase*`. This is safe as
262long as this `BindStateBase` pointer is only used with the stored `Run()`
263pointer.
tzik703f1562016-09-02 07:36:55264
265To `BindState<>` objects are created inside the `Bind()` functions.
266These functions, along with a set of internal templates, are responsible for
267
268 - Unwrapping the function signature into return type, and parameters
269 - Determining the number of parameters that are bound
270 - Creating the BindState storing the bound parameters
271 - Performing compile-time asserts to avoid error-prone behavior
272 - Returning an `Callback<>` with an arity matching the number of unbound
273 parameters and that knows the correct refcounting semantics for the
274 target object if we are binding a method.
275
276The `Bind` functions do the above using type-inference, and template
277specializations.
278
tzika4313512016-09-06 06:51:12279By default `Bind()` will store copies of all bound parameters, and attempt to
280refcount a target object if the function being bound is a class method. These
281copies are created even if the function takes parameters as const
tzik703f1562016-09-02 07:36:55282references. (Binding to non-const references is forbidden, see bind.h.)
283
tzika4313512016-09-06 06:51:12284To change this behavior, we introduce a set of argument wrappers (e.g.,
285`Unretained()`, and `ConstRef()`). These are simple container templates that
286are passed by value, and wrap a pointer to argument. See the file-level comment
287in base/bind_helpers.h for more info.
tzik703f1562016-09-02 07:36:55288
289These types are passed to the `Unwrap()` functions, and the `MaybeRefcount()`
tzika4313512016-09-06 06:51:12290functions respectively to modify the behavior of `Bind()`. The `Unwrap()` and
291`MaybeRefcount()` functions change behavior by doing partial specialization
292based on whether or not a parameter is a wrapper type.
tzik703f1562016-09-02 07:36:55293
294`ConstRef()` is similar to `tr1::cref`. `Unretained()` is specific to Chromium.
295
tzika4313512016-09-06 06:51:12296### Why Not Tr1 Function/Bind?
tzik703f1562016-09-02 07:36:55297
298Direct use of `tr1::function` and `tr1::bind` was considered, but ultimately
tzika4313512016-09-06 06:51:12299rejected because of the number of copy constructors invocations involved in the
300binding of arguments during construction, and the forwarding of arguments during
301invocation. These copies will no longer be an issue in C++0x because C++0x will
302support rvalue reference allowing for the compiler to avoid these copies.
303However, waiting for C++0x is not an option.
tzik703f1562016-09-02 07:36:55304
305Measured 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
tzika4313512016-09-06 06:51:12307for each bound parameter. Also, each when passing a `tr1::function`, each bound
308argument will be copied again.
tzik703f1562016-09-02 07:36:55309
310In addition to the copies taken at binding and invocation, copying a
tzika4313512016-09-06 06:51:12311`tr1::function` causes a copy to be made of all the bound parameters and state.
tzik703f1562016-09-02 07:36:55312
tzika4313512016-09-06 06:51:12313Furthermore, in Chromium, it is desirable for the `Callback` to take a reference
314on a target object when representing a class method call. This is not supported
315by tr1.
tzik703f1562016-09-02 07:36:55316
tzika4313512016-09-06 06:51:12317Lastly, `tr1::function` and `tr1::bind` has a more general and flexible
318API. This includes things like argument reordering by use of
tzik703f1562016-09-02 07:36:55319`tr1::bind::placeholder`, support for non-const reference parameters, and some
320limited amount of subtyping of the `tr1::function` object (e.g.,
321`tr1::function<int(int)>` is convertible to `tr1::function<void(int)>`).
322
323These are not features that are required in Chromium. Some of them, such as
324allowing for reference parameters, and subtyping of functions, may actually
tzika4313512016-09-06 06:51:12325become a source of errors. Removing support for these features actually allows
326for a simpler implementation, and a terser Currying API.
tzik703f1562016-09-02 07:36:55327
tzika4313512016-09-06 06:51:12328### Why Not Google Callbacks?
tzik703f1562016-09-02 07:36:55329
tzika4313512016-09-06 06:51:12330The Google callback system also does not support refcounting. Furthermore, its
331implementation has a number of strange edge cases with respect to type
332conversion of its arguments. In particular, the argument's constness must at
333times match exactly the function signature, or the type-inference might
334break. Given the above, writing a custom solution was easier.
tzik703f1562016-09-02 07:36:55335
tzika4313512016-09-06 06:51:12336### Missing Functionality
tzik703f1562016-09-02 07:36:55337 - Invoking the return of `Bind`. `Bind(&foo).Run()` does not work;
338 - Binding arrays to functions that take a non-const pointer.
339 Example:
340```cpp
341void Foo(const char* ptr);
342void Bar(char* ptr);
343Bind(&Foo, "test");
344Bind(&Bar, "test"); // This fails because ptr is not const.
345```
346
347If you are thinking of forward declaring `Callback` in your own header file,
348please include "base/callback_forward.h" instead.