blob: 4194d5107995219c4dc65919040635eddd42cc0c [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
michaelpg0f156e12017-03-18 02:49:09155If running a callback could result in its own destruction (e.g., if the callback
156recipient deletes the object the callback is a member of), the callback should
157be moved before it can be safely invoked. The `base::ResetAndReturn` method
158provides this functionality.
159
160```cpp
161void Foo::RunCallback() {
162 base::ResetAndReturn(&foo_deleter_callback_).Run();
163}
164```
165
tzika4313512016-09-06 06:51:12166### Passing Unbound Input Parameters
tzik703f1562016-09-02 07:36:55167
168Unbound parameters are specified at the time a callback is `Run()`. They are
169specified in the `Callback` template type:
170
171```cpp
172void MyFunc(int i, const std::string& str) {}
tzik7c0c0cf12016-10-05 08:14:05173Callback<void(int, const std::string&)> cb = Bind(&MyFunc);
tzik703f1562016-09-02 07:36:55174cb.Run(23, "hello, world");
175```
176
tzika4313512016-09-06 06:51:12177### Passing Bound Input Parameters
tzik703f1562016-09-02 07:36:55178
tzika4313512016-09-06 06:51:12179Bound parameters are specified when you create the callback as arguments to
180`Bind()`. They will be passed to the function and the `Run()`ner of the callback
181doesn't see those values or even know that the function it's calling.
tzik703f1562016-09-02 07:36:55182
183```cpp
184void MyFunc(int i, const std::string& str) {}
tzik7c0c0cf12016-10-05 08:14:05185Callback<void()> cb = Bind(&MyFunc, 23, "hello world");
tzik703f1562016-09-02 07:36:55186cb.Run();
187```
188
tzik7c0c0cf12016-10-05 08:14:05189A callback with no unbound input parameters (`Callback<void()>`) is called a
190`Closure`. So we could have also written:
tzik703f1562016-09-02 07:36:55191
192```cpp
tzik7c0c0cf12016-10-05 08:14:05193Closure cb = Bind(&MyFunc, 23, "hello world");
tzik703f1562016-09-02 07:36:55194```
195
196When calling member functions, bound parameters just go after the object
197pointer.
198
199```cpp
tzik7c0c0cf12016-10-05 08:14:05200Closure cb = Bind(&MyClass::MyFunc, this, 23, "hello world");
tzik703f1562016-09-02 07:36:55201```
202
tzika4313512016-09-06 06:51:12203### Partial Binding Of Parameters
tzik703f1562016-09-02 07:36:55204
tzika4313512016-09-06 06:51:12205You can specify some parameters when you create the callback, and specify the
206rest when you execute the callback.
tzik703f1562016-09-02 07:36:55207
208```cpp
209void MyFunc(int i, const std::string& str) {}
tzik7c0c0cf12016-10-05 08:14:05210Callback<void(const std::string&)> cb = Bind(&MyFunc, 23);
tzik703f1562016-09-02 07:36:55211cb.Run("hello world");
212```
213
214When calling a function bound parameters are first, followed by unbound
215parameters.
216
tzik7c0c0cf12016-10-05 08:14:05217### Avoiding Copies with Callback Parameters
218
219A parameter of `Bind()` is moved into its internal storage if it is passed as a
220rvalue.
221
222```cpp
223std::vector<int> v = {1, 2, 3};
224// |v| is moved into the internal storage without copy.
225Bind(&Foo, std::move(v));
226```
227
228```cpp
229std::vector<int> v = {1, 2, 3};
230// The vector is moved into the internal storage without copy.
231Bind(&Foo, std::vector<int>({1, 2, 3}));
232```
233
234A bound object is moved out to the target function if you use `Passed()` for
235the parameter. If you use `BindOnce()`, the bound object is moved out even
236without `Passed()`.
237
238```cpp
239void Foo(std::unique_ptr<int>) {}
240std::unique_ptr<int> p(new int(42));
241
242// |p| is moved into the internal storage of Bind(), and moved out to |Foo|.
243BindOnce(&Foo, std::move(p));
244BindRepeating(&Foo, Passed(&p));
245```
246
tzika4313512016-09-06 06:51:12247## Quick reference for advanced binding
tzik703f1562016-09-02 07:36:55248
tzika4313512016-09-06 06:51:12249### Binding A Class Method With Weak Pointers
tzik703f1562016-09-02 07:36:55250
251```cpp
tzik7c0c0cf12016-10-05 08:14:05252Bind(&MyClass::Foo, GetWeakPtr());
tzika4313512016-09-06 06:51:12253```
tzik703f1562016-09-02 07:36:55254
255The callback will not be run if the object has already been destroyed.
tzika4313512016-09-06 06:51:12256**DANGER**: weak pointers are not threadsafe, so don't use this when passing between
257threads!
tzik703f1562016-09-02 07:36:55258
tzika4313512016-09-06 06:51:12259### Binding A Class Method With Manual Lifetime Management
tzik703f1562016-09-02 07:36:55260
261```cpp
tzik7c0c0cf12016-10-05 08:14:05262Bind(&MyClass::Foo, Unretained(this));
tzik703f1562016-09-02 07:36:55263```
264
tzika4313512016-09-06 06:51:12265This disables all lifetime management on the object. You're responsible for
266making sure the object is alive at the time of the call. You break it, you own
267it!
tzik703f1562016-09-02 07:36:55268
tzika4313512016-09-06 06:51:12269### Binding A Class Method And Having The Callback Own The Class
tzik703f1562016-09-02 07:36:55270
271```cpp
272MyClass* myclass = new MyClass;
tzik7c0c0cf12016-10-05 08:14:05273Bind(&MyClass::Foo, Owned(myclass));
tzik703f1562016-09-02 07:36:55274```
275
tzika4313512016-09-06 06:51:12276The object will be deleted when the callback is destroyed, even if it's not run
277(like if you post a task during shutdown). Potentially useful for "fire and
278forget" cases.
tzik703f1562016-09-02 07:36:55279
tzik7c0c0cf12016-10-05 08:14:05280Smart pointers (e.g. `std::unique_ptr<>`) are also supported as the receiver.
281
282```cpp
283std::unique_ptr<MyClass> myclass(new MyClass);
284Bind(&MyClass::Foo, std::move(myclass));
285```
286
tzika4313512016-09-06 06:51:12287### Ignoring Return Values
tzik703f1562016-09-02 07:36:55288
tzika4313512016-09-06 06:51:12289Sometimes you want to call a function that returns a value in a callback that
290doesn't expect a return value.
tzik703f1562016-09-02 07:36:55291
292```cpp
293int DoSomething(int arg) { cout << arg << endl; }
tzik7c0c0cf12016-10-05 08:14:05294Callback<void(int)> cb =
295 Bind(IgnoreResult(&DoSomething));
tzik703f1562016-09-02 07:36:55296```
297
tzika4313512016-09-06 06:51:12298## Quick reference for binding parameters to Bind()
tzik703f1562016-09-02 07:36:55299
300Bound parameters are specified as arguments to `Bind()` and are passed to the
301function. A callback with no parameters or no unbound parameters is called a
tzik7c0c0cf12016-10-05 08:14:05302`Closure` (`Callback<void()>` and `Closure` are the same thing).
tzik703f1562016-09-02 07:36:55303
tzika4313512016-09-06 06:51:12304### Passing Parameters Owned By The Callback
tzik703f1562016-09-02 07:36:55305
306```cpp
307void Foo(int* arg) { cout << *arg << endl; }
308int* pn = new int(1);
tzik7c0c0cf12016-10-05 08:14:05309Closure foo_callback = Bind(&foo, Owned(pn));
tzik703f1562016-09-02 07:36:55310```
311
tzika4313512016-09-06 06:51:12312The parameter will be deleted when the callback is destroyed, even if it's not
313run (like if you post a task during shutdown).
tzik703f1562016-09-02 07:36:55314
tzika4313512016-09-06 06:51:12315### Passing Parameters As A unique_ptr
tzik703f1562016-09-02 07:36:55316
317```cpp
318void TakesOwnership(std::unique_ptr<Foo> arg) {}
319std::unique_ptr<Foo> f(new Foo);
320// f becomes null during the following call.
tzik7c0c0cf12016-10-05 08:14:05321RepeatingClosure cb = BindRepeating(&TakesOwnership, Passed(&f));
tzik703f1562016-09-02 07:36:55322```
323
tzika4313512016-09-06 06:51:12324Ownership of the parameter will be with the callback until the callback is run,
325and then ownership is passed to the callback function. This means the callback
326can only be run once. If the callback is never run, it will delete the object
327when it's destroyed.
tzik703f1562016-09-02 07:36:55328
tzika4313512016-09-06 06:51:12329### Passing Parameters As A scoped_refptr
tzik703f1562016-09-02 07:36:55330
331```cpp
332void TakesOneRef(scoped_refptr<Foo> arg) {}
tzik7c0c0cf12016-10-05 08:14:05333scoped_refptr<Foo> f(new Foo);
334Closure cb = Bind(&TakesOneRef, f);
tzik703f1562016-09-02 07:36:55335```
336
tzika4313512016-09-06 06:51:12337This should "just work." The closure will take a reference as long as it is
338alive, and another reference will be taken for the called function.
tzik703f1562016-09-02 07:36:55339
tzik7c0c0cf12016-10-05 08:14:05340```cpp
341void DontTakeRef(Foo* arg) {}
342scoped_refptr<Foo> f(new Foo);
343Closure cb = Bind(&DontTakeRef, RetainedRef(f));
344```
345
346`RetainedRef` holds a reference to the object and passes a raw pointer to
347the object when the Callback is run.
348
tzika4313512016-09-06 06:51:12349### Passing Parameters By Reference
tzik703f1562016-09-02 07:36:55350
351Const references are *copied* unless `ConstRef` is used. Example:
352
353```cpp
354void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
355int n = 1;
tzik7c0c0cf12016-10-05 08:14:05356Closure has_copy = Bind(&foo, n);
357Closure has_ref = Bind(&foo, ConstRef(n));
tzik703f1562016-09-02 07:36:55358n = 2;
359foo(n); // Prints "2 0xaaaaaaaaaaaa"
360has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
361has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
362```
363
tzika4313512016-09-06 06:51:12364Normally parameters are copied in the closure.
tzik7c0c0cf12016-10-05 08:14:05365**DANGER**: `ConstRef` stores a const reference instead, referencing the
366original parameter. This means that you must ensure the object outlives the
367callback!
tzik703f1562016-09-02 07:36:55368
tzika4313512016-09-06 06:51:12369## Implementation notes
tzik703f1562016-09-02 07:36:55370
tzika4313512016-09-06 06:51:12371### Where Is This Design From:
tzik703f1562016-09-02 07:36:55372
tzika4313512016-09-06 06:51:12373The design `Callback` and Bind is heavily influenced by C++'s `tr1::function` /
374`tr1::bind`, and by the "Google Callback" system used inside Google.
tzik703f1562016-09-02 07:36:55375
tzik7c0c0cf12016-10-05 08:14:05376### Customizing the behavior
377
378There are several injection points that controls `Bind` behavior from outside of
379its implementation.
380
381```cpp
382template <typename Receiver>
383struct IsWeakReceiver {
384 static constexpr bool value = false;
385};
386
387template <typename Obj>
388struct UnwrapTraits {
389 template <typename T>
390 T&& Unwrap(T&& obj) {
391 return std::forward<T>(obj);
392 }
393};
394```
395
396If `IsWeakReceiver<Receiver>::value` is true on a receiver of a method, `Bind`
397checks if the receiver is evaluated to true and cancels the invocation if it's
398evaluated to false. You can specialize `IsWeakReceiver` to make an external
399smart pointer as a weak pointer.
400
401`UnwrapTraits<BoundObject>::Unwrap()` is called for each bound arguments right
402before `Callback` calls the target function. You can specialize this to define
403an argument wrapper such as `Unretained`, `ConstRef`, `Owned`, `RetainedRef` and
404`Passed`.
405
tzika4313512016-09-06 06:51:12406### How The Implementation Works:
tzik703f1562016-09-02 07:36:55407
408There are three main components to the system:
tzik7c0c0cf12016-10-05 08:14:05409 1) The `Callback<>` classes.
tzik703f1562016-09-02 07:36:55410 2) The `Bind()` functions.
411 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`).
412
tzika4313512016-09-06 06:51:12413The Callback classes represent a generic function pointer. Internally, it stores
414a refcounted piece of state that represents the target function and all its
tzik7c0c0cf12016-10-05 08:14:05415bound parameters. The `Callback` constructor takes a `BindStateBase*`, which is
416upcasted from a `BindState<>`. In the context of the constructor, the static
tzika4313512016-09-06 06:51:12417type of this `BindState<>` pointer uniquely identifies the function it is
418representing, all its bound parameters, and a `Run()` method that is capable of
419invoking the target.
tzik703f1562016-09-02 07:36:55420
tzik7c0c0cf12016-10-05 08:14:05421`Bind()` creates the `BindState<>` that has the full static type, and erases the
422target function type as well as the types of the bound parameters. It does this
423by storing a pointer to the specific `Run()` function, and upcasting the state
424of `BindState<>*` to a `BindStateBase*`. This is safe as long as this
425`BindStateBase` pointer is only used with the stored `Run()` pointer.
tzik703f1562016-09-02 07:36:55426
427To `BindState<>` objects are created inside the `Bind()` functions.
428These functions, along with a set of internal templates, are responsible for
429
430 - Unwrapping the function signature into return type, and parameters
431 - Determining the number of parameters that are bound
432 - Creating the BindState storing the bound parameters
433 - Performing compile-time asserts to avoid error-prone behavior
434 - Returning an `Callback<>` with an arity matching the number of unbound
435 parameters and that knows the correct refcounting semantics for the
436 target object if we are binding a method.
437
tzik7c0c0cf12016-10-05 08:14:05438The `Bind` functions do the above using type-inference and variadic templates.
tzik703f1562016-09-02 07:36:55439
tzika4313512016-09-06 06:51:12440By default `Bind()` will store copies of all bound parameters, and attempt to
441refcount a target object if the function being bound is a class method. These
442copies are created even if the function takes parameters as const
tzik703f1562016-09-02 07:36:55443references. (Binding to non-const references is forbidden, see bind.h.)
444
tzika4313512016-09-06 06:51:12445To change this behavior, we introduce a set of argument wrappers (e.g.,
446`Unretained()`, and `ConstRef()`). These are simple container templates that
447are passed by value, and wrap a pointer to argument. See the file-level comment
448in base/bind_helpers.h for more info.
tzik703f1562016-09-02 07:36:55449
tzik7c0c0cf12016-10-05 08:14:05450These types are passed to the `Unwrap()` functions to modify the behavior of
451`Bind()`. The `Unwrap()` functions change behavior by doing partial
452specialization based on whether or not a parameter is a wrapper type.
tzik703f1562016-09-02 07:36:55453
454`ConstRef()` is similar to `tr1::cref`. `Unretained()` is specific to Chromium.
455
tzika4313512016-09-06 06:51:12456### Missing Functionality
tzik703f1562016-09-02 07:36:55457 - Binding arrays to functions that take a non-const pointer.
458 Example:
459```cpp
460void Foo(const char* ptr);
461void Bar(char* ptr);
462Bind(&Foo, "test");
463Bind(&Bar, "test"); // This fails because ptr is not const.
464```
465
466If you are thinking of forward declaring `Callback` in your own header file,
467please include "base/callback_forward.h" instead.