task_util.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef GOOGLE_APIS_COMMON_TASK_UTIL_H_
  5. #define GOOGLE_APIS_COMMON_TASK_UTIL_H_
  6. #include "base/bind.h"
  7. #include "base/threading/thread_task_runner_handle.h"
  8. namespace google_apis {
  9. // Runs the task with the task runner.
  10. void RunTaskWithTaskRunner(scoped_refptr<base::TaskRunner> task_runner,
  11. base::OnceClosure task);
  12. namespace internal {
  13. // Implementation of the composed callback, whose signature is |Sig|.
  14. template <typename Sig>
  15. struct ComposedCallback;
  16. template <typename... Args>
  17. struct ComposedCallback<void(Args...)> {
  18. static void Run(base::OnceCallback<void(base::OnceClosure)> runner,
  19. base::OnceCallback<void(Args...)> callback,
  20. Args... args) {
  21. std::move(runner).Run(
  22. base::BindOnce(std::move(callback), std::forward<Args>(args)...));
  23. }
  24. };
  25. } // namespace internal
  26. // Returns callback that takes arguments (arg1, arg2, ...), create a closure
  27. // by binding them to |callback|, and runs |runner| with the closure.
  28. // I.e. the returned callback works as follows:
  29. // runner.Run(Bind(callback, arg1, arg2, ...))
  30. template <typename... Args>
  31. base::OnceCallback<void(Args...)> CreateComposedCallback(
  32. base::OnceCallback<void(base::OnceClosure)> runner,
  33. base::OnceCallback<void(Args...)> callback) {
  34. DCHECK(runner);
  35. DCHECK(callback);
  36. return base::BindOnce(&internal::ComposedCallback<void(Args...)>::Run,
  37. std::move(runner), std::move(callback));
  38. }
  39. template <typename... Args>
  40. base::RepeatingCallback<void(Args...)> CreateComposedCallback(
  41. base::RepeatingCallback<void(base::OnceClosure)> runner,
  42. base::RepeatingCallback<void(Args...)> callback) {
  43. DCHECK(runner);
  44. DCHECK(callback);
  45. return base::BindRepeating(&internal::ComposedCallback<void(Args...)>::Run,
  46. std::move(runner), std::move(callback));
  47. }
  48. // Returns callback which runs the given |callback| on the current thread.
  49. //
  50. // TODO(tzik): If the resulting callback is destroyed without invocation, its
  51. // |callback| and its bound arguments can be destroyed on the originating
  52. // thread.
  53. //
  54. // TODO(tzik): The parameter of the resulting callback will be forwarded to
  55. // the destination, but it doesn't mirror a wrapper. I.e. In an example below:
  56. // auto cb1 = base::BindOnce([](int* p) { /* |p| is dangling. */ });
  57. // auto cb2 = CreateRelayCallback(std::move(cb1));
  58. // base::BindOnce(std::move(cb2), base::Owned(new int)).Run();
  59. // CreateRelayCallback forwards the callback invocation without base::Owned,
  60. // and forwarded pointer will be dangling in this case.
  61. //
  62. // TODO(tzik): Take FROM_HERE from the caller, and propagate it to the runner.
  63. //
  64. // TODO(tzik): Move media::BindToCurrentLoop to base namespace, and replace
  65. // CreateRelayCallback with it.
  66. template <typename Sig>
  67. base::OnceCallback<Sig> CreateRelayCallback(base::OnceCallback<Sig> callback) {
  68. return CreateComposedCallback(
  69. base::BindOnce(&RunTaskWithTaskRunner,
  70. base::ThreadTaskRunnerHandle::Get()),
  71. std::move(callback));
  72. }
  73. template <typename Sig>
  74. base::RepeatingCallback<Sig> CreateRelayCallback(
  75. base::RepeatingCallback<Sig> callback) {
  76. return CreateComposedCallback(
  77. base::BindRepeating(&RunTaskWithTaskRunner,
  78. base::ThreadTaskRunnerHandle::Get()),
  79. std::move(callback));
  80. }
  81. } // namespace google_apis
  82. #endif // GOOGLE_APIS_COMMON_TASK_UTIL_H_