// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef GOOGLE_APIS_COMMON_TASK_UTIL_H_ #define GOOGLE_APIS_COMMON_TASK_UTIL_H_ #include "base/bind.h" #include "base/threading/thread_task_runner_handle.h" namespace google_apis { // Runs the task with the task runner. void RunTaskWithTaskRunner(scoped_refptr task_runner, base::OnceClosure task); namespace internal { // Implementation of the composed callback, whose signature is |Sig|. template struct ComposedCallback; template struct ComposedCallback { static void Run(base::OnceCallback runner, base::OnceCallback callback, Args... args) { std::move(runner).Run( base::BindOnce(std::move(callback), std::forward(args)...)); } }; } // namespace internal // Returns callback that takes arguments (arg1, arg2, ...), create a closure // by binding them to |callback|, and runs |runner| with the closure. // I.e. the returned callback works as follows: // runner.Run(Bind(callback, arg1, arg2, ...)) template base::OnceCallback CreateComposedCallback( base::OnceCallback runner, base::OnceCallback callback) { DCHECK(runner); DCHECK(callback); return base::BindOnce(&internal::ComposedCallback::Run, std::move(runner), std::move(callback)); } template base::RepeatingCallback CreateComposedCallback( base::RepeatingCallback runner, base::RepeatingCallback callback) { DCHECK(runner); DCHECK(callback); return base::BindRepeating(&internal::ComposedCallback::Run, std::move(runner), std::move(callback)); } // Returns callback which runs the given |callback| on the current thread. // // TODO(tzik): If the resulting callback is destroyed without invocation, its // |callback| and its bound arguments can be destroyed on the originating // thread. // // TODO(tzik): The parameter of the resulting callback will be forwarded to // the destination, but it doesn't mirror a wrapper. I.e. In an example below: // auto cb1 = base::BindOnce([](int* p) { /* |p| is dangling. */ }); // auto cb2 = CreateRelayCallback(std::move(cb1)); // base::BindOnce(std::move(cb2), base::Owned(new int)).Run(); // CreateRelayCallback forwards the callback invocation without base::Owned, // and forwarded pointer will be dangling in this case. // // TODO(tzik): Take FROM_HERE from the caller, and propagate it to the runner. // // TODO(tzik): Move media::BindToCurrentLoop to base namespace, and replace // CreateRelayCallback with it. template base::OnceCallback CreateRelayCallback(base::OnceCallback callback) { return CreateComposedCallback( base::BindOnce(&RunTaskWithTaskRunner, base::ThreadTaskRunnerHandle::Get()), std::move(callback)); } template base::RepeatingCallback CreateRelayCallback( base::RepeatingCallback callback) { return CreateComposedCallback( base::BindRepeating(&RunTaskWithTaskRunner, base::ThreadTaskRunnerHandle::Get()), std::move(callback)); } } // namespace google_apis #endif // GOOGLE_APIS_COMMON_TASK_UTIL_H_