| Index: docs/callback.md
|
| diff --git a/docs/callback.md b/docs/callback.md
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0090ffb1818c2ce42269ad2a4a17736788db16d6
|
| --- /dev/null
|
| +++ b/docs/callback.md
|
| @@ -0,0 +1,360 @@
|
| +# base::Callback<> and base::Bind()
|
| +
|
| +## Introduction
|
| +
|
| +The templated `Callback<>` class is a generalized function object. Together with
|
| +the `Bind()` function in base/bind.h, they provide a type-safe method for
|
| +performing partial application of functions.
|
| +
|
| +Partial application (or "currying") is the process of binding a subset of a
|
| +function's arguments to produce another function that takes fewer arguments.
|
| +This can be used to pass around a unit of delayed execution, much like lexical
|
| +closures are used in other languages. For example, it is used in Chromium code
|
| +to schedule tasks on different MessageLoops.
|
| +
|
| +A callback with no unbound input parameters (`Callback<void()>`) is called a
|
| +`Closure`. Note that this is NOT the same as what other languages refer to as a
|
| +closure -- it does not retain a reference to its enclosing environment.
|
| +
|
| +### OneShotCallback<> and RepeatingCallback<>
|
| +
|
| +`OneShotCallback<>` and `RepeatingCallback<>` are next gen callback classes,
|
| +which are under development.
|
| +
|
| +`OneShotCallback<>` is created by `BindOneShot()`. `OneShotCallback<>` is a
|
| +restricted variant of `Callback<>` that is a move-only type and can run only
|
| +once. It can handle move-only types better as its bound parameter, and has
|
| +clearer lifetime. Thus, thread hopping or result handning of an asynchronous
|
| +operation is a good fit for it.
|
| +
|
| +`RepeatingCallback<>` is created by `BindRepeating()`. `RepeatingCallback<>` is
|
| +a loose variant. Its internal storage is ref-counted and `RepeatingCallback<>`
|
| +itself is a copyable type. It can run more than once. So, it's suitable for
|
| +event handlers that may happen more than once. It's discouraged to use this for
|
| +a thread hop, since you cannot predict on which thread the callback object is
|
| +destroyed.
|
| +
|
| +`RepeatingCallback<>` is convertible to `OneShotCallback<>` by the implicit
|
| +conversion.
|
| +
|
| +`Callback<>` is an alias of `RepeatingCallback<>` and `Bind()` is an alias of
|
| +`BindRepeating()` for a historical reason.
|
| +
|
| +### Memory management and passing
|
| +
|
| +The `Callback` objects themselves should be passed by const-reference or by
|
| +value, and stored by copy or by move. They internally store their state via a
|
| +refcounted class and thus do not need to be deleted.
|
| +
|
| +## Quick reference for basic usage
|
| +
|
| +### Binding a bare function
|
| +
|
| +```cpp
|
| +int Return5() { return 5; }
|
| +Callback<int()> func_cb = Bind(&Return5);
|
| +LOG(INFO) << func_cb.Run(); // Prints 5.
|
| +```
|
| +
|
| +### Binding a captureless lambda
|
| +
|
| +```cpp
|
| +OneShotCallback<int()> lambda_cb = BindOneShot([] { return 3; });
|
| +LOG(INFO) << std::move(lambda_cb).Run(); // Print 3.
|
| +
|
| +```
|
| +
|
| +### Binding a class method
|
| +
|
| +The first argument to bind is the member function to call, the second is
|
| +the object on which to call it.
|
| +
|
| +```cpp
|
| +class Ref : public RefCountedThreadSafe<Ref> {
|
| + public:
|
| + int Foo() { return 3; }
|
| +};
|
| +
|
| +scoped_refptr<Ref> ref = new Ref();
|
| +Callback<void()> ref_cb = Bind(&Ref::Foo, ref);
|
| +LOG(INFO) << ref_cb.Run(); // Prints out 3.
|
| +```
|
| +
|
| +By default the object must support RefCounted or you will get a compiler
|
| +error. If you're passing between threads, be sure it's RefCountedThreadSafe!
|
| +See "Advanced binding of member functions" below if you don't want to use
|
| +reference counting.
|
| +
|
| +### Running a Callback
|
| +
|
| +Callbacks can be run with their "Run" method, which has the same signature as
|
| +the template argument to the callback.
|
| +
|
| +`RepeatingCallback<>` can be run directly.
|
| +
|
| +```cpp
|
| +void DoSomething(const RepeatingCallback<void(int, std::string)>& callback) {
|
| + callback.Run(5, "hello");
|
| +}
|
| +```
|
| +
|
| +```cpp
|
| +void DoSomething(const RepeatingCallback<double(double)>& callback) {
|
| + double myresult = callback.Run(3.14159);
|
| + myresult += callback.Run(2.71828);
|
| +}
|
| +```
|
| +
|
| +`OneShotCallback<>` can run when it's a rvalue. Use `std::move` or
|
| +`ResetAndReturn` to run it.
|
| +
|
| +```cpp
|
| +void DoSomething(OneShotCallback<void(int, double)> callback) {
|
| + std::move(callback).Run(1, 0.1);
|
| +}
|
| +```
|
| +
|
| +```cpp
|
| +void DoSomething(OneShotCallback<void()> callback) {
|
| + ResetAndReturn(&callback).Run();
|
| +}
|
| +```
|
| +
|
| +`RepeatingCallback<>` can be run more than once (they don't get deleted or
|
| +marked when run). However, this precludes using `Passed` (see below).
|
| +
|
| +### Passing unbound input parameters
|
| +
|
| +Unbound parameters are specified at the time a callback is Run(). They are
|
| +specified in the Callback template type:
|
| +
|
| +```cpp
|
| +void MyFunc(int i, const std::string& str) {}
|
| +Callback<void(int, const std::string&)> cb = Bind(&MyFunc);
|
| +cb.Run(23, "hello, world");
|
| +```
|
| +
|
| +### Passing bound input parameters
|
| +
|
| +Bound parameters are specified when you create the callback as arguments to
|
| +`Bind()`. They will be passed to the function and the runner of the callback
|
| +doesn't see those values or even know that the function it's calling.
|
| +
|
| +```cpp
|
| +void MyFunc(int i, const std::string& str) {}
|
| +Callback<void()> cb = Bind(&MyFunc, 23, "hello world");
|
| +cb.Run();
|
| +```
|
| +
|
| +A callback with no unbound input parameters (`Callback<void()>`,
|
| +`OneShotCallback<void()>` and `RepeatingCallback<void()>`) is called a
|
| +`Closure`, `OneShotClosure` and `RepeatingClosure`, respectively.
|
| +So we could have also written:
|
| +
|
| +```cpp
|
| +Closure cb = Bind(&MyFunc, 23, "hello world");
|
| +```
|
| +
|
| +When calling member functions, bound parameters just go after the object
|
| +pointer.
|
| +
|
| +```cpp
|
| +Closure cb = Bind(&MyClass::MyFunc, this, 23, "hello world");
|
| +```
|
| +
|
| +### PARTIAL BINDING OF PARAMETERS
|
| +
|
| +You can specify some parameters when you create the callback, and specify
|
| +the rest when you execute the callback.
|
| +
|
| +```cpp
|
| +void MyFunc(int i, const std::string& str) {}
|
| +Callback<void(const std::string&)> cb = Bind(&MyFunc, 23);
|
| +cb.Run("hello world");
|
| +```
|
| +
|
| +## Quick reference for advanced binding
|
| +
|
| +### Binding a class method with weak pointers
|
| +
|
| +```cpp
|
| +Bind(&MyClass::Foo, GetWeakPtr());
|
| +```
|
| +
|
| +The callback will not be run if the object has already been destroyed.
|
| +
|
| +*** note
|
| +**DANGER**: weak pointers are not threadsafe, so don't use this when you pass it
|
| +between threads!
|
| +***
|
| +
|
| +### Binding a class method with manual lifetime management
|
| +
|
| +```cpp
|
| +Bind(&MyClass::Foo, Unretained(this));
|
| +```
|
| +
|
| +This disables all lifetime management on the object. You're responsible for
|
| +making sure the object is alive at the time of the call. You break it, you own
|
| +it!
|
| +
|
| +### Binding a class method and having the callback own the class
|
| +
|
| +```cpp
|
| +MyClass* myclass = new MyClass;
|
| +Bind(&MyClass::Foo, Owned(myclass));
|
| +```
|
| +
|
| +The object will be deleted when the callback is destroyed, even if it's not run
|
| +(like if you post a task during shutdown). Potentially useful for "fire and
|
| +forget" cases.
|
| +
|
| +Also, smart pointers (e.g. `std::unique_ptr<>`) are supported as the receiver.
|
| +
|
| +```cpp
|
| +std::unique_ptr<MyClass> myclass(new MyClass);
|
| +Bind(&MyClass::Foo, std::move(myclass));
|
| +```
|
| +
|
| +### Ignoring return values
|
| +
|
| +Sometimes you want to call a function that returns a value in a callback that
|
| +doesn't expect a return value.
|
| +
|
| +```cpp
|
| +int DoSomething(int arg) { cout << arg << endl; }
|
| +Callback<void(int)> cb =
|
| + Bind(IgnoreResult(&DoSomething));
|
| +```
|
| +
|
| +
|
| +## Quick reference for binding parameters to Bind()
|
| +
|
| +Bound parameters are specified as arguments to `Bind()` and are passed to the
|
| +function. A callback with no parameters or no unbound parameters is called a
|
| +`Closure` (`Callback<void()>` and `Closure` are the same thing).
|
| +
|
| +### Passing parameters owned by the callback
|
| +
|
| +```cpp
|
| +void Foo(int* arg) { cout << *arg << endl; }
|
| +int* pn = new int(1);
|
| +Closure foo_callback = Bind(&foo, Owned(pn));
|
| +```
|
| +
|
| +The parameter will be deleted when the callback is destroyed, even if it's
|
| +not run (like if you post a task during shutdown).
|
| +
|
| +### Passing parameters as a unique_ptr
|
| +
|
| +```cpp
|
| +void TakesOwnership(std::unique_ptr<Foo> arg) {}
|
| +std::unique_ptr<Foo> f(new Foo);
|
| +// f becomes null during the following call.
|
| +RepeatingClosure cb = BindRepeating(&TakesOwnership, Passed(std::move(f)));
|
| +```
|
| +
|
| +Ownership of the parameter will be with the callback until it is run, when
|
| +ownership is passed to the callback function. This means the callback can only
|
| +be run once. If the callback is never run, it will delete the object when it's
|
| +destroyed.
|
| +
|
| +```cpp
|
| +void TakesOwnership(std::unique_ptr<Foo> arg) {}
|
| +std::unique_ptr<Foo> f(new Foo);
|
| +// f becomes null during the following call.
|
| +OneShotClosure cb = BindOneShot(&TakesOwnership, std::move(f));
|
| +```
|
| +
|
| +Parameters bound by `BindOneShot()` are passed out even without `Passed`.
|
| +
|
| +### Passing parameters as a scoped_refptr
|
| +
|
| +```cpp
|
| +void TakesOneRef(scoped_refptr<Foo> arg) {}
|
| +scoped_refptr<Foo> f(new Foo)
|
| +Closure cb = Bind(&TakesOneRef, f);
|
| +```
|
| +
|
| +This should "just work." The closure will take a reference as long as it is
|
| +alive, and another reference will be taken for the called function.
|
| +
|
| +### Passing parameters by reference
|
| +
|
| +Const references are *copied* unless ConstRef is used. Example:
|
| +
|
| +```cpp
|
| +void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
|
| +int n = 1;
|
| +Closure has_copy = Bind(&foo, n);
|
| +Closure has_ref = Bind(&foo, ConstRef(n));
|
| +n = 2;
|
| +foo(n); // Prints "2 0xaaaaaaaaaaaa"
|
| +has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
|
| +has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
|
| +```
|
| +
|
| +Normally parameters are copied in the closure.
|
| +
|
| +*** note
|
| +**DANGER**: `ConstRef` stores a const reference instead, referencing the
|
| +original parameter. This means that you must ensure the object outlives the
|
| +callback!
|
| +***
|
| +
|
| +## Implementation notes
|
| +
|
| +### Where is this design from:
|
| +
|
| +The design `Callback` and `Bind` is heavily influenced by C++'s
|
| +tr1::function/tr1::bind, and by the "Google Callback" system used inside Google.
|
| +
|
| +### How the implementation works:
|
| +
|
| +There are three main components to the system:
|
| + 1) The `Callback<>` classes.
|
| + 2) The `Bind()` functions.
|
| + 3) The arguments wrappers (e.g., `Unretained()` and `ConstRef()`).
|
| +
|
| +The Callback classes represent a generic function pointer. Internally, it stores
|
| +a refcounted piece of state that represents the target function and all its
|
| +bound parameters. `Callback` has a constructor that takes a `BindStateBase*`
|
| +and `&Invoker::Run`. A `BindState<>` holds a function object to run, and also
|
| +holds bound parameters. `BindStateBase` is the base class of of `BindState<>`,
|
| +without type information of bound data. In the context of the constructor of
|
| +`Callback`, `Invoker::Run` has the static type of `BindState<>` that identifies
|
| +the function it is representing and all its bound parameters.
|
| +
|
| +`Bind()` creates the `BindState<>` that has the full static type, and erases the
|
| +target function type as well as the type of bound parameters. It does this by
|
| +taking a pointer to the specific `Invoker::Run()` function, and upcasting the
|
| +state of `BindState<>` to a `BindStateBase`. This is safe as long as this
|
| +`BindStateBase` pointer is only used with the stored `Invoker::Run()` pointer.
|
| +
|
| +To `BindState<>` objects are created inside the `Bind()` functions.
|
| +These functions, along with a set of internal templates, are responsible for
|
| +
|
| + - Unwrapping the function signature into return type, and parameters
|
| + - Determining the number of parameters that are bound
|
| + - Creating the BindState storing the bound parameters
|
| + - Performing compile-time asserts to avoid error-prone behavior
|
| + - Returning an `Callback<>` with an arity matching the number of unbound
|
| + parameters and that knows the correct refcounting semantics for the
|
| + target object if we are binding a method.
|
| +
|
| +By default `Bind()` will store copies of all bound parameters, and attempt to
|
| +refcount a target object if the function being bound is a class method. These
|
| +copies are created even if the function takes parameters as const references.
|
| +(Binding to non-const references is forbidden, see bind.h.)
|
| +
|
| +To change this behavior, we introduce a set of argument wrappers (e.g.,
|
| +`Unretained()`, and `ConstRef()`). These are simple container templates that
|
| +are passed by value, and wrap a pointer to argument. See the file-level comment
|
| +in base/bind_helpers.h for more info.
|
| +
|
| +These types are passed to the Unwrap() functions, and the IsWeakReceiver<>
|
| +traits respectively to modify the behavior of Bind().
|
| +
|
| +`ConstRef()` is similar to std::cref. `Unretained()` is specific to Chromium.
|
| +`Owned()` and `RetainedRef()` let `BindState<>` own the exclusive or shared
|
| +ownership and pass the bound item as a raw pointer to the target function.
|
|
|