blob: 6b7dd6931f5009a402696c7753c619a48ff98b62 [file] [log] [blame] [view]
tzik7c0c0cf12016-10-05 08:14:051# Callback<> and 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
tzik7c0c0cf12016-10-05 08:14:0519### OnceCallback<> And RepeatingCallback<>
20
21`OnceCallback<>` and `RepeatingCallback<>` are next gen callback classes, which
22are under development.
23
24`OnceCallback<>` is created by `BindOnce()`. This is a callback variant that is
25a move-only type and can be run only once. This moves out bound parameters from
26its internal storage to the bound function by default, so it's easier to use
27with movable types. This should be the preferred callback type: since the
28lifetime of the callback is clear, it's simpler to reason about when a callback
29that is passed between threads is destroyed.
30
31`RepeatingCallback<>` is created by `BindRepeating()`. This is a callback
32variant that is copyable that can be run multiple times. It uses internal
33ref-counting to make copies cheap. However, since ownership is shared, it is
34harder to reason about when the callback and the bound state are destroyed,
35especially when the callback is passed between threads.
36
37The legacy `Callback<>` is currently aliased to `RepeatingCallback<>`. In new
38code, prefer `OnceCallback<>` where possible, and use `RepeatingCallback<>`
39otherwise. Once the migration is complete, the type alias will be removed and
40`OnceCallback<>` will be renamed to `Callback<>` to emphasize that it should be
41preferred.
42
43`RepeatingCallback<>` is convertible to `OnceCallback<>` by the implicit
44conversion.
45
tzika4313512016-09-06 06:51:1246### Memory Management And Passing
tzik703f1562016-09-02 07:36:5547
tzik7c0c0cf12016-10-05 08:14:0548Pass `Callback` objects by value if ownership is transferred; otherwise, pass it
49by const-reference.
tzik703f1562016-09-02 07:36:5550
tzik7c0c0cf12016-10-05 08:14:0551```cpp
52// |Foo| just refers to |cb| but doesn't store it nor consume it.
53bool Foo(const OnceCallback<void(int)>& cb) {
54 return cb.is_null();
55}
56
57// |Bar| takes the ownership of |cb| and stores |cb| into |g_cb|.
58OnceCallback<void(int)> g_cb;
59void Bar(OnceCallback<void(int)> cb) {
60 g_cb = std::move(cb);
61}
62
63// |Baz| takes the ownership of |cb| and consumes |cb| by Run().
64void Baz(OnceCallback<void(int)> cb) {
65 std::move(cb).Run(42);
66}
67
68// |Qux| takes the ownership of |cb| and transfers ownership to PostTask(),
69// which also takes the ownership of |cb|.
michaelpg126f704d12017-03-14 23:22:5370// NOTE: TaskRunner is not actually migrated to OnceClosure yet. Once TaskRunner
71// supports OnceClosure, a OnceCallback can be posted as follows:
tzik7c0c0cf12016-10-05 08:14:0572void Qux(OnceCallback<void(int)> cb) {
michaelpg126f704d12017-03-14 23:22:5373 PostTask(FROM_HERE,
74 base::BindOnce(std::move(cb), 42)); // not yet implemented!
tzik7c0c0cf12016-10-05 08:14:0575}
76```
77
78When you pass a `Callback` object to a function parameter, use `std::move()` if
79you don't need to keep a reference to it, otherwise, pass the object directly.
80You may see a compile error when the function requires the exclusive ownership,
81and you didn't pass the callback by move.
tzik703f1562016-09-02 07:36:5582
tzika4313512016-09-06 06:51:1283## Quick reference for basic stuff
tzik703f1562016-09-02 07:36:5584
tzika4313512016-09-06 06:51:1285### Binding A Bare Function
tzik703f1562016-09-02 07:36:5586
87```cpp
88int Return5() { return 5; }
tzik7c0c0cf12016-10-05 08:14:0589OnceCallback<int()> func_cb = BindOnce(&Return5);
90LOG(INFO) << std::move(func_cb).Run(); // Prints 5.
91```
92
93```cpp
94int Return5() { return 5; }
95RepeatingCallback<int()> func_cb = BindRepeating(&Return5);
tzik703f1562016-09-02 07:36:5596LOG(INFO) << func_cb.Run(); // Prints 5.
97```
98
tzik7c0c0cf12016-10-05 08:14:0599### Binding A Captureless Lambda
100
101```cpp
102Callback<int()> lambda_cb = Bind([] { return 4; });
103LOG(INFO) << lambda_cb.Run(); // Print 4.
104
105OnceCallback<int()> lambda_cb2 = BindOnce([] { return 3; });
106LOG(INFO) << std::move(lambda_cb2).Run(); // Print 3.
107```
108
tzika4313512016-09-06 06:51:12109### Binding A Class Method
tzik703f1562016-09-02 07:36:55110
tzika4313512016-09-06 06:51:12111The first argument to bind is the member function to call, the second is the
112object on which to call it.
tzik703f1562016-09-02 07:36:55113
114```cpp
tzik7c0c0cf12016-10-05 08:14:05115class Ref : public RefCountedThreadSafe<Ref> {
tzik703f1562016-09-02 07:36:55116 public:
117 int Foo() { return 3; }
tzik703f1562016-09-02 07:36:55118};
119scoped_refptr<Ref> ref = new Ref();
tzik7c0c0cf12016-10-05 08:14:05120Callback<void()> ref_cb = Bind(&Ref::Foo, ref);
tzik703f1562016-09-02 07:36:55121LOG(INFO) << ref_cb.Run(); // Prints out 3.
122```
123
124By default the object must support RefCounted or you will get a compiler
tzik7c0c0cf12016-10-05 08:14:05125error. If you're passing between threads, be sure it's RefCountedThreadSafe! See
126"Advanced binding of member functions" below if you don't want to use reference
127counting.
tzik703f1562016-09-02 07:36:55128
tzika4313512016-09-06 06:51:12129### Running A Callback
tzik703f1562016-09-02 07:36:55130
tzik7c0c0cf12016-10-05 08:14:05131Callbacks can be run with their `Run` method, which has the same signature as
132the template argument to the callback. Note that `OnceCallback::Run` consumes
133the callback object and can only be invoked on a callback rvalue.
tzik703f1562016-09-02 07:36:55134
135```cpp
tzik7c0c0cf12016-10-05 08:14:05136void DoSomething(const Callback<void(int, std::string)>& callback) {
tzik703f1562016-09-02 07:36:55137 callback.Run(5, "hello");
138}
tzik7c0c0cf12016-10-05 08:14:05139
140void DoSomethingOther(OnceCallback<void(int, std::string)> callback) {
141 std::move(callback).Run(5, "hello");
142}
tzik703f1562016-09-02 07:36:55143```
144
tzik7c0c0cf12016-10-05 08:14:05145RepeatingCallbacks can be run more than once (they don't get deleted or marked
146when run). However, this precludes using Passed (see below).
tzik703f1562016-09-02 07:36:55147
148```cpp
tzik7c0c0cf12016-10-05 08:14:05149void DoSomething(const RepeatingCallback<double(double)>& callback) {
tzik703f1562016-09-02 07:36:55150 double myresult = callback.Run(3.14159);
151 myresult += callback.Run(2.71828);
152}
153```
154
tzika4313512016-09-06 06:51:12155### Passing Unbound Input Parameters
tzik703f1562016-09-02 07:36:55156
157Unbound parameters are specified at the time a callback is `Run()`. They are
158specified in the `Callback` template type:
159
160```cpp
161void MyFunc(int i, const std::string& str) {}
tzik7c0c0cf12016-10-05 08:14:05162Callback<void(int, const std::string&)> cb = Bind(&MyFunc);
tzik703f1562016-09-02 07:36:55163cb.Run(23, "hello, world");
164```
165
tzika4313512016-09-06 06:51:12166### Passing Bound Input Parameters
tzik703f1562016-09-02 07:36:55167
tzika4313512016-09-06 06:51:12168Bound parameters are specified when you create the callback as arguments to
169`Bind()`. They will be passed to the function and the `Run()`ner of the callback
170doesn't see those values or even know that the function it's calling.
tzik703f1562016-09-02 07:36:55171
172```cpp
173void MyFunc(int i, const std::string& str) {}
tzik7c0c0cf12016-10-05 08:14:05174Callback<void()> cb = Bind(&MyFunc, 23, "hello world");
tzik703f1562016-09-02 07:36:55175cb.Run();
176```
177
tzik7c0c0cf12016-10-05 08:14:05178A callback with no unbound input parameters (`Callback<void()>`) is called a
179`Closure`. So we could have also written:
tzik703f1562016-09-02 07:36:55180
181```cpp
tzik7c0c0cf12016-10-05 08:14:05182Closure cb = Bind(&MyFunc, 23, "hello world");
tzik703f1562016-09-02 07:36:55183```
184
185When calling member functions, bound parameters just go after the object
186pointer.
187
188```cpp
tzik7c0c0cf12016-10-05 08:14:05189Closure cb = Bind(&MyClass::MyFunc, this, 23, "hello world");
tzik703f1562016-09-02 07:36:55190```
191
tzika4313512016-09-06 06:51:12192### Partial Binding Of Parameters
tzik703f1562016-09-02 07:36:55193
tzika4313512016-09-06 06:51:12194You can specify some parameters when you create the callback, and specify the
195rest when you execute the callback.
tzik703f1562016-09-02 07:36:55196
197```cpp
198void MyFunc(int i, const std::string& str) {}
tzik7c0c0cf12016-10-05 08:14:05199Callback<void(const std::string&)> cb = Bind(&MyFunc, 23);
tzik703f1562016-09-02 07:36:55200cb.Run("hello world");
201```
202
203When calling a function bound parameters are first, followed by unbound
204parameters.
205
tzik7c0c0cf12016-10-05 08:14:05206### Avoiding Copies with Callback Parameters
207
208A parameter of `Bind()` is moved into its internal storage if it is passed as a
209rvalue.
210
211```cpp
212std::vector<int> v = {1, 2, 3};
213// |v| is moved into the internal storage without copy.
214Bind(&Foo, std::move(v));
215```
216
217```cpp
218std::vector<int> v = {1, 2, 3};
219// The vector is moved into the internal storage without copy.
220Bind(&Foo, std::vector<int>({1, 2, 3}));
221```
222
223A bound object is moved out to the target function if you use `Passed()` for
224the parameter. If you use `BindOnce()`, the bound object is moved out even
225without `Passed()`.
226
227```cpp
228void Foo(std::unique_ptr<int>) {}
229std::unique_ptr<int> p(new int(42));
230
231// |p| is moved into the internal storage of Bind(), and moved out to |Foo|.
232BindOnce(&Foo, std::move(p));
233BindRepeating(&Foo, Passed(&p));
234```
235
tzika4313512016-09-06 06:51:12236## Quick reference for advanced binding
tzik703f1562016-09-02 07:36:55237
tzika4313512016-09-06 06:51:12238### Binding A Class Method With Weak Pointers
tzik703f1562016-09-02 07:36:55239
240```cpp
tzik7c0c0cf12016-10-05 08:14:05241Bind(&MyClass::Foo, GetWeakPtr());
tzika4313512016-09-06 06:51:12242```
tzik703f1562016-09-02 07:36:55243
244The callback will not be run if the object has already been destroyed.
tzika4313512016-09-06 06:51:12245**DANGER**: weak pointers are not threadsafe, so don't use this when passing between
246threads!
tzik703f1562016-09-02 07:36:55247
tzika4313512016-09-06 06:51:12248### Binding A Class Method With Manual Lifetime Management
tzik703f1562016-09-02 07:36:55249
250```cpp
tzik7c0c0cf12016-10-05 08:14:05251Bind(&MyClass::Foo, Unretained(this));
tzik703f1562016-09-02 07:36:55252```
253
tzika4313512016-09-06 06:51:12254This disables all lifetime management on the object. You're responsible for
255making sure the object is alive at the time of the call. You break it, you own
256it!
tzik703f1562016-09-02 07:36:55257
tzika4313512016-09-06 06:51:12258### Binding A Class Method And Having The Callback Own The Class
tzik703f1562016-09-02 07:36:55259
260```cpp
261MyClass* myclass = new MyClass;
tzik7c0c0cf12016-10-05 08:14:05262Bind(&MyClass::Foo, Owned(myclass));
tzik703f1562016-09-02 07:36:55263```
264
tzika4313512016-09-06 06:51:12265The object will be deleted when the callback is destroyed, even if it's not run
266(like if you post a task during shutdown). Potentially useful for "fire and
267forget" cases.
tzik703f1562016-09-02 07:36:55268
tzik7c0c0cf12016-10-05 08:14:05269Smart pointers (e.g. `std::unique_ptr<>`) are also supported as the receiver.
270
271```cpp
272std::unique_ptr<MyClass> myclass(new MyClass);
273Bind(&MyClass::Foo, std::move(myclass));
274```
275
tzika4313512016-09-06 06:51:12276### Ignoring Return Values
tzik703f1562016-09-02 07:36:55277
tzika4313512016-09-06 06:51:12278Sometimes you want to call a function that returns a value in a callback that
279doesn't expect a return value.
tzik703f1562016-09-02 07:36:55280
281```cpp
282int DoSomething(int arg) { cout << arg << endl; }
tzik7c0c0cf12016-10-05 08:14:05283Callback<void(int)> cb =
284 Bind(IgnoreResult(&DoSomething));
tzik703f1562016-09-02 07:36:55285```
286
tzika4313512016-09-06 06:51:12287## Quick reference for binding parameters to Bind()
tzik703f1562016-09-02 07:36:55288
289Bound parameters are specified as arguments to `Bind()` and are passed to the
290function. A callback with no parameters or no unbound parameters is called a
tzik7c0c0cf12016-10-05 08:14:05291`Closure` (`Callback<void()>` and `Closure` are the same thing).
tzik703f1562016-09-02 07:36:55292
tzika4313512016-09-06 06:51:12293### Passing Parameters Owned By The Callback
tzik703f1562016-09-02 07:36:55294
295```cpp
296void Foo(int* arg) { cout << *arg << endl; }
297int* pn = new int(1);
tzik7c0c0cf12016-10-05 08:14:05298Closure foo_callback = Bind(&foo, Owned(pn));
tzik703f1562016-09-02 07:36:55299```
300
tzika4313512016-09-06 06:51:12301The parameter will be deleted when the callback is destroyed, even if it's not
302run (like if you post a task during shutdown).
tzik703f1562016-09-02 07:36:55303
tzika4313512016-09-06 06:51:12304### Passing Parameters As A unique_ptr
tzik703f1562016-09-02 07:36:55305
306```cpp
307void TakesOwnership(std::unique_ptr<Foo> arg) {}
308std::unique_ptr<Foo> f(new Foo);
309// f becomes null during the following call.
tzik7c0c0cf12016-10-05 08:14:05310RepeatingClosure cb = BindRepeating(&TakesOwnership, Passed(&f));
tzik703f1562016-09-02 07:36:55311```
312
tzika4313512016-09-06 06:51:12313Ownership of the parameter will be with the callback until the callback is run,
314and then ownership is passed to the callback function. This means the callback
315can only be run once. If the callback is never run, it will delete the object
316when it's destroyed.
tzik703f1562016-09-02 07:36:55317
tzika4313512016-09-06 06:51:12318### Passing Parameters As A scoped_refptr
tzik703f1562016-09-02 07:36:55319
320```cpp
321void TakesOneRef(scoped_refptr<Foo> arg) {}
tzik7c0c0cf12016-10-05 08:14:05322scoped_refptr<Foo> f(new Foo);
323Closure cb = Bind(&TakesOneRef, f);
tzik703f1562016-09-02 07:36:55324```
325
tzika4313512016-09-06 06:51:12326This should "just work." The closure will take a reference as long as it is
327alive, and another reference will be taken for the called function.
tzik703f1562016-09-02 07:36:55328
tzik7c0c0cf12016-10-05 08:14:05329```cpp
330void DontTakeRef(Foo* arg) {}
331scoped_refptr<Foo> f(new Foo);
332Closure cb = Bind(&DontTakeRef, RetainedRef(f));
333```
334
335`RetainedRef` holds a reference to the object and passes a raw pointer to
336the object when the Callback is run.
337
tzika4313512016-09-06 06:51:12338### Passing Parameters By Reference
tzik703f1562016-09-02 07:36:55339
340Const references are *copied* unless `ConstRef` is used. Example:
341
342```cpp
343void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
344int n = 1;
tzik7c0c0cf12016-10-05 08:14:05345Closure has_copy = Bind(&foo, n);
346Closure has_ref = Bind(&foo, ConstRef(n));
tzik703f1562016-09-02 07:36:55347n = 2;
348foo(n); // Prints "2 0xaaaaaaaaaaaa"
349has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
350has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
351```
352
tzika4313512016-09-06 06:51:12353Normally parameters are copied in the closure.
tzik7c0c0cf12016-10-05 08:14:05354**DANGER**: `ConstRef` stores a const reference instead, referencing the
355original parameter. This means that you must ensure the object outlives the
356callback!
tzik703f1562016-09-02 07:36:55357
tzika4313512016-09-06 06:51:12358## Implementation notes
tzik703f1562016-09-02 07:36:55359
tzika4313512016-09-06 06:51:12360### Where Is This Design From:
tzik703f1562016-09-02 07:36:55361
tzika4313512016-09-06 06:51:12362The design `Callback` and Bind is heavily influenced by C++'s `tr1::function` /
363`tr1::bind`, and by the "Google Callback" system used inside Google.
tzik703f1562016-09-02 07:36:55364
tzik7c0c0cf12016-10-05 08:14:05365### Customizing the behavior
366
367There are several injection points that controls `Bind` behavior from outside of
368its implementation.
369
370```cpp
371template <typename Receiver>
372struct IsWeakReceiver {
373 static constexpr bool value = false;
374};
375
376template <typename Obj>
377struct UnwrapTraits {
378 template <typename T>
379 T&& Unwrap(T&& obj) {
380 return std::forward<T>(obj);
381 }
382};
383```
384
385If `IsWeakReceiver<Receiver>::value` is true on a receiver of a method, `Bind`
386checks if the receiver is evaluated to true and cancels the invocation if it's
387evaluated to false. You can specialize `IsWeakReceiver` to make an external
388smart pointer as a weak pointer.
389
390`UnwrapTraits<BoundObject>::Unwrap()` is called for each bound arguments right
391before `Callback` calls the target function. You can specialize this to define
392an argument wrapper such as `Unretained`, `ConstRef`, `Owned`, `RetainedRef` and
393`Passed`.
394
tzika4313512016-09-06 06:51:12395### How The Implementation Works:
tzik703f1562016-09-02 07:36:55396
397There are three main components to the system:
tzik7c0c0cf12016-10-05 08:14:05398 1) The `Callback<>` classes.
tzik703f1562016-09-02 07:36:55399 2) The `Bind()` functions.
400 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`).
401
tzika4313512016-09-06 06:51:12402The Callback classes represent a generic function pointer. Internally, it stores
403a refcounted piece of state that represents the target function and all its
tzik7c0c0cf12016-10-05 08:14:05404bound parameters. The `Callback` constructor takes a `BindStateBase*`, which is
405upcasted from a `BindState<>`. In the context of the constructor, the static
tzika4313512016-09-06 06:51:12406type of this `BindState<>` pointer uniquely identifies the function it is
407representing, all its bound parameters, and a `Run()` method that is capable of
408invoking the target.
tzik703f1562016-09-02 07:36:55409
tzik7c0c0cf12016-10-05 08:14:05410`Bind()` creates the `BindState<>` that has the full static type, and erases the
411target function type as well as the types of the bound parameters. It does this
412by storing a pointer to the specific `Run()` function, and upcasting the state
413of `BindState<>*` to a `BindStateBase*`. This is safe as long as this
414`BindStateBase` pointer is only used with the stored `Run()` pointer.
tzik703f1562016-09-02 07:36:55415
416To `BindState<>` objects are created inside the `Bind()` functions.
417These functions, along with a set of internal templates, are responsible for
418
419 - Unwrapping the function signature into return type, and parameters
420 - Determining the number of parameters that are bound
421 - Creating the BindState storing the bound parameters
422 - Performing compile-time asserts to avoid error-prone behavior
423 - Returning an `Callback<>` with an arity matching the number of unbound
424 parameters and that knows the correct refcounting semantics for the
425 target object if we are binding a method.
426
tzik7c0c0cf12016-10-05 08:14:05427The `Bind` functions do the above using type-inference and variadic templates.
tzik703f1562016-09-02 07:36:55428
tzika4313512016-09-06 06:51:12429By default `Bind()` will store copies of all bound parameters, and attempt to
430refcount a target object if the function being bound is a class method. These
431copies are created even if the function takes parameters as const
tzik703f1562016-09-02 07:36:55432references. (Binding to non-const references is forbidden, see bind.h.)
433
tzika4313512016-09-06 06:51:12434To change this behavior, we introduce a set of argument wrappers (e.g.,
435`Unretained()`, and `ConstRef()`). These are simple container templates that
436are passed by value, and wrap a pointer to argument. See the file-level comment
437in base/bind_helpers.h for more info.
tzik703f1562016-09-02 07:36:55438
tzik7c0c0cf12016-10-05 08:14:05439These types are passed to the `Unwrap()` functions to modify the behavior of
440`Bind()`. The `Unwrap()` functions change behavior by doing partial
441specialization based on whether or not a parameter is a wrapper type.
tzik703f1562016-09-02 07:36:55442
443`ConstRef()` is similar to `tr1::cref`. `Unretained()` is specific to Chromium.
444
tzika4313512016-09-06 06:51:12445### Missing Functionality
tzik703f1562016-09-02 07:36:55446 - Binding arrays to functions that take a non-const pointer.
447 Example:
448```cpp
449void Foo(const char* ptr);
450void Bar(char* ptr);
451Bind(&Foo, "test");
452Bind(&Bar, "test"); // This fails because ptr is not const.
453```
454
455If you are thinking of forward declaring `Callback` in your own header file,
456please include "base/callback_forward.h" instead.