| Index: docs/callback.md
|
| diff --git a/docs/callback.md b/docs/callback.md
|
| index a380cf4b83ba4c417b79659fc11632a37e0a76d9..af141b5d62f829929b0122582ec5c0b17280bcf9 100644
|
| --- a/docs/callback.md
|
| +++ b/docs/callback.md
|
| @@ -1,34 +1,33 @@
|
| +# base::Callback<> and base::Bind()
|
|
|
| -# Introduction
|
| +## Introduction
|
|
|
| -The templated Callback class is a generalized function object. Together
|
| -with the `Bind()` function in bind.h, they provide a type-safe method for
|
| +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.
|
| +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 (`base::Callback<void()>`)
|
| -is called a `base::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.
|
| +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.
|
|
|
| -## MEMORY MANAGEMENT AND PASSING
|
| +### Memory Management And Passing
|
|
|
| -The Callback objects themselves should be passed by const-reference, and
|
| -stored by copy. They internally store their state via a refcounted class
|
| -and thus do not need to be deleted.
|
| +The Callback objects themselves should be passed by const-reference, and stored
|
| +by copy. They internally store their state via a refcounted class and thus do
|
| +not need to be deleted.
|
|
|
| -The reason to pass via a const-reference is to avoid unnecessary
|
| -AddRef/Release pairs to the internal state.
|
| +The reason to pass via a const-reference is to avoid unnecessary AddRef/Release
|
| +pairs to the internal state.
|
|
|
| +## Quick reference for basic stuff
|
|
|
| -# Quick reference for basic stuff
|
| -
|
| -## BINDING A BARE FUNCTION
|
| +### Binding A Bare Function
|
|
|
| ```cpp
|
| int Return5() { return 5; }
|
| @@ -36,10 +35,10 @@ base::Callback<int()> func_cb = base::Bind(&Return5);
|
| LOG(INFO) << func_cb.Run(); // Prints 5.
|
| ```
|
|
|
| -## BINDING A CLASS METHOD
|
| +### 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.
|
| +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 base::RefCountedThreadSafe<Ref> {
|
| @@ -57,7 +56,7 @@ 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
|
| +### Running A Callback
|
|
|
| Callbacks can be run with their `Run` method, which has the same
|
| signature as the template argument to the callback.
|
| @@ -78,7 +77,7 @@ void DoSomething(const base::Callback<double(double)>& callback) {
|
| }
|
| ```
|
|
|
| -## PASSING UNBOUND INPUT PARAMETERS
|
| +### Passing Unbound Input Parameters
|
|
|
| Unbound parameters are specified at the time a callback is `Run()`. They are
|
| specified in the `Callback` template type:
|
| @@ -89,12 +88,11 @@ base::Callback<void(int, const std::string&)> cb = base::Bind(&MyFunc);
|
| cb.Run(23, "hello, world");
|
| ```
|
|
|
| -## PASSING BOUND INPUT PARAMETERS
|
| +### 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 `Run()`ner of the
|
| -callback doesn't see those values or even know that the function it's
|
| -calling.
|
| +Bound parameters are specified when you create the callback as arguments to
|
| +`Bind()`. They will be passed to the function and the `Run()`ner 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) {}
|
| @@ -102,8 +100,8 @@ base::Callback<void()> cb = base::Bind(&MyFunc, 23, "hello world");
|
| cb.Run();
|
| ```
|
|
|
| -A callback with no unbound input parameters (`base::Callback<void()>`)
|
| -is called a `base::Closure`. So we could have also written:
|
| +A callback with no unbound input parameters (`base::Callback<void()>`) is called
|
| +a `base::Closure`. So we could have also written:
|
|
|
| ```cpp
|
| base::Closure cb = base::Bind(&MyFunc, 23, "hello world");
|
| @@ -116,10 +114,10 @@ pointer.
|
| base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world");
|
| ```
|
|
|
| -## PARTIAL BINDING OF PARAMETERS
|
| +### Partial Binding Of Parameters
|
|
|
| -You can specify some parameters when you create the callback, and specify
|
| -the rest when you execute the callback.
|
| +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) {}
|
| @@ -130,44 +128,43 @@ cb.Run("hello world");
|
| When calling a function bound parameters are first, followed by unbound
|
| parameters.
|
|
|
| +## Quick reference for advanced binding
|
|
|
| -# Quick reference for advanced binding
|
| -
|
| -## BINDING A CLASS METHOD WITH WEAK POINTERS
|
| +### Binding A Class Method With Weak Pointers
|
|
|
| ```cpp
|
| base::Bind(&MyClass::Foo, GetWeakPtr());
|
| -``
|
| +```
|
|
|
| The callback will not be run if the object has already been destroyed.
|
| -DANGER: weak pointers are not threadsafe, so don't use this
|
| -when passing between threads!
|
| +**DANGER**: weak pointers are not threadsafe, so don't use this when passing between
|
| +threads!
|
|
|
| -## BINDING A CLASS METHOD WITH MANUAL LIFETIME MANAGEMENT
|
| +### Binding A Class Method With Manual Lifetime Management
|
|
|
| ```cpp
|
| base::Bind(&MyClass::Foo, base::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!
|
| +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
|
| +### Binding A Class Method And Having The Callback Own The Class
|
|
|
| ```cpp
|
| MyClass* myclass = new MyClass;
|
| base::Bind(&MyClass::Foo, base::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.
|
| +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.
|
|
|
| -## IGNORING RETURN VALUES
|
| +### Ignoring Return Values
|
|
|
| -Sometimes you want to call a function that returns a value in a callback
|
| -that doesn't expect a return value.
|
| +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; }
|
| @@ -175,13 +172,13 @@ base::Callback<void(int)> cb =
|
| base::Bind(base::IgnoreResult(&DoSomething));
|
| ```
|
|
|
| -# Quick reference for binding parameters to Bind()
|
| +## 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` (`base::Callback<void()>` and `base::Closure` are the same thing).
|
|
|
| -## PASSING PARAMETERS OWNED BY THE CALLBACK
|
| +### Passing Parameters Owned By The Callback
|
|
|
| ```cpp
|
| void Foo(int* arg) { cout << *arg << endl; }
|
| @@ -189,10 +186,10 @@ int* pn = new int(1);
|
| base::Closure foo_callback = base::Bind(&foo, base::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).
|
| +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 scoped_ptr
|
| +### Passing Parameters As A unique_ptr
|
|
|
| ```cpp
|
| void TakesOwnership(std::unique_ptr<Foo> arg) {}
|
| @@ -201,12 +198,12 @@ std::unique_ptr<Foo> f(new Foo);
|
| base::Closure cb = base::Bind(&TakesOwnership, base::Passed(&f));
|
| ```
|
|
|
| -Ownership of the parameter will be with the callback until the callback is
|
| -run, and then 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.
|
| +Ownership of the parameter will be with the callback until the callback is run,
|
| +and then 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.
|
|
|
| -## PASSING PARAMETERS AS A scoped_refptr
|
| +### Passing Parameters As A scoped_refptr
|
|
|
| ```cpp
|
| void TakesOneRef(scoped_refptr<Foo> arg) {}
|
| @@ -214,10 +211,10 @@ scoped_refptr<Foo> f(new Foo)
|
| base::Closure cb = base::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.
|
| +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
|
| +### Passing Parameters By Reference
|
|
|
| Const references are *copied* unless `ConstRef` is used. Example:
|
|
|
| @@ -232,40 +229,38 @@ has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
|
| has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
|
| ```
|
|
|
| -Normally parameters are copied in the closure. DANGER: ConstRef stores a
|
| -const reference instead, referencing the original parameter. This means
|
| -that you must ensure the object outlives the callback!
|
| -
|
| +Normally parameters are copied in the closure.
|
| +**DANGER**: ConstRef stores a const reference instead, referencing the original
|
| +parameter. This means that you must ensure the object outlives the callback!
|
|
|
| -# Implementation notes
|
| +## Implementation notes
|
|
|
| -## WHERE IS THIS DESIGN FROM:
|
| +### 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.
|
| +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:
|
| +### 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. Each `Callback` specialization has a templated
|
| -constructor that takes an `BindState<>*`. In the context of the constructor,
|
| -the static type of this `BindState<>` pointer uniquely identifies the
|
| -function it is representing, all its bound parameters, and a `Run()` method
|
| -that is capable of invoking the target.
|
| +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. Each `Callback` specialization has a templated constructor
|
| +that takes an `BindState<>*`. In the context of the constructor, the static
|
| +type of this `BindState<>` pointer uniquely identifies the function it is
|
| +representing, all its bound parameters, and a `Run()` method that is capable of
|
| +invoking the target.
|
|
|
| `Callback`'s constructor takes the `BindState<>*` that has the full static type
|
| and erases the target function type as well as the types of the bound
|
| -parameters. It does this by storing a pointer to the specific `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 `Run()` pointer.
|
| +parameters. It does this by storing a pointer to the specific `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 `Run()`
|
| +pointer.
|
|
|
| To `BindState<>` objects are created inside the `Bind()` functions.
|
| These functions, along with a set of internal templates, are responsible for
|
| @@ -281,67 +276,64 @@ These functions, along with a set of internal templates, are responsible for
|
| The `Bind` functions do the above using type-inference, and template
|
| specializations.
|
|
|
| -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
|
| +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.
|
| +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 `MaybeRefcount()`
|
| -functions respectively to modify the behavior of `Bind()`. The `Unwrap()`
|
| -and `MaybeRefcount()` functions change behavior by doing partial
|
| -specialization based on whether or not a parameter is a wrapper type.
|
| +functions respectively to modify the behavior of `Bind()`. The `Unwrap()` and
|
| +`MaybeRefcount()` functions change behavior by doing partial specialization
|
| +based on whether or not a parameter is a wrapper type.
|
|
|
| `ConstRef()` is similar to `tr1::cref`. `Unretained()` is specific to Chromium.
|
|
|
| -
|
| -## WHY NOT TR1 FUNCTION/BIND?
|
| +### Why Not Tr1 Function/Bind?
|
|
|
| Direct use of `tr1::function` and `tr1::bind` was considered, but ultimately
|
| -rejected because of the number of copy constructors invocations involved
|
| -in the binding of arguments during construction, and the forwarding of
|
| -arguments during invocation. These copies will no longer be an issue in
|
| -C++0x because C++0x will support rvalue reference allowing for the compiler
|
| -to avoid these copies. However, waiting for C++0x is not an option.
|
| +rejected because of the number of copy constructors invocations involved in the
|
| +binding of arguments during construction, and the forwarding of arguments during
|
| +invocation. These copies will no longer be an issue in C++0x because C++0x will
|
| +support rvalue reference allowing for the compiler to avoid these copies.
|
| +However, waiting for C++0x is not an option.
|
|
|
| Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the
|
| `tr1::bind` call itself will invoke a non-trivial copy constructor three times
|
| -for each bound parameter. Also, each when passing a `tr1::function`, each
|
| -bound argument will be copied again.
|
| +for each bound parameter. Also, each when passing a `tr1::function`, each bound
|
| +argument will be copied again.
|
|
|
| In addition to the copies taken at binding and invocation, copying a
|
| -`tr1::function` causes a copy to be made of all the bound parameters and
|
| -state.
|
| +`tr1::function` causes a copy to be made of all the bound parameters and state.
|
|
|
| -Furthermore, in Chromium, it is desirable for the `Callback` to take a
|
| -reference on a target object when representing a class method call. This
|
| -is not supported by tr1.
|
| +Furthermore, in Chromium, it is desirable for the `Callback` to take a reference
|
| +on a target object when representing a class method call. This is not supported
|
| +by tr1.
|
|
|
| -Lastly, `tr1::function` and `tr1::bind` has a more general and flexible API.
|
| -This includes things like argument reordering by use of
|
| +Lastly, `tr1::function` and `tr1::bind` has a more general and flexible
|
| +API. This includes things like argument reordering by use of
|
| `tr1::bind::placeholder`, support for non-const reference parameters, and some
|
| limited amount of subtyping of the `tr1::function` object (e.g.,
|
| `tr1::function<int(int)>` is convertible to `tr1::function<void(int)>`).
|
|
|
| These are not features that are required in Chromium. Some of them, such as
|
| allowing for reference parameters, and subtyping of functions, may actually
|
| -become a source of errors. Removing support for these features actually
|
| -allows for a simpler implementation, and a terser Currying API.
|
| -
|
| -## WHY NOT GOOGLE CALLBACKS?
|
| +become a source of errors. Removing support for these features actually allows
|
| +for a simpler implementation, and a terser Currying API.
|
|
|
| -The Google callback system also does not support refcounting. Furthermore,
|
| -its implementation has a number of strange edge cases with respect to type
|
| -conversion of its arguments. In particular, the argument's constness must
|
| -at times match exactly the function signature, or the type-inference might
|
| -break. Given the above, writing a custom solution was easier.
|
| +### Why Not Google Callbacks?
|
|
|
| +The Google callback system also does not support refcounting. Furthermore, its
|
| +implementation has a number of strange edge cases with respect to type
|
| +conversion of its arguments. In particular, the argument's constness must at
|
| +times match exactly the function signature, or the type-inference might
|
| +break. Given the above, writing a custom solution was easier.
|
|
|
| -## MISSING FUNCTIONALITY
|
| +### Missing Functionality
|
| - Invoking the return of `Bind`. `Bind(&foo).Run()` does not work;
|
| - Binding arrays to functions that take a non-const pointer.
|
| Example:
|
|
|