This is a issue to track OnceClosure support in TaskRunner::PostTask().
The motivation to use base::OnceClosure instead of base::Closure is to achieve predictable destruction sequence of Callback object and its bound parameters.
As of 2017-03-22, following code snippet has a race:
struct Foo : base::RefCounted<Foo> {};
void Bar(Foo*);
base::PostTask(FROM_HERE, base::Bind(&Foo, RetainedRef(new Foo)));
It's unpredictable on which thread the `Foo` instance is destroyed, since the temporary Callback object created by Bind leaves a reference on the original thread, and another reference is brought to the foreign thread. The destruction happens when the last reference to the Callback is released on either thread.
OnceCallback is a solution for this. Since it has unique ownership for its internal storage, it will be destroyed always on the destination thread.
There are in-flight or planned changes to mitigate or solve the situation.
* Add assertions to RefCount to detect unsafe ref count bump. http://crrev.com/2666423002
- All data race bugs detected by the assertions are fixed.
- Needs a gadget to opt-out from the assertion, which is under discussion on the CL.
* Support OnceCallback on PostTaskAndReply. http://crrev.com/2657603004
- This is the behavior changing part. In the previous code, both of the `post` part and `reply` part of the task are destroyed on the original thread, and in the proposed new code, `post` part is destroyed on the destination thread.
- There were only few caller that depends on the destruction thread of `post` part, and all of them are fixed already.
* Make base::Closure parameter on PostTask() pass-by-value. http://crrev.com/2726523002
- This is a mitigation of the issue. In the previous code, there was no way to call PostTask without leaving a reference to the original thread. And in the new code, the caller can pass the callback with its ownership.
* Support OnceCallback on PastTask http://crrev.com/2637843002
- The next step to the migration. After this CL, the user can pass base::OnceClosure to PostTask as well as base::Closure.
Comment 1 by tzik@chromium.org
, Mar 22 2017