task_util.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright 2020 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 REMOTING_BASE_TASK_UTIL_H_
  5. #define REMOTING_BASE_TASK_UTIL_H_
  6. #include "base/bind.h"
  7. #include "base/threading/sequence_bound.h"
  8. #include "base/threading/sequenced_task_runner_handle.h"
  9. namespace remoting {
  10. // Wraps and returns a callback such that it will call the original callback on
  11. // the thread where this method is called.
  12. template <typename... Args>
  13. base::OnceCallback<void(Args...)> WrapCallbackToCurrentSequence(
  14. const base::Location& from_here,
  15. base::OnceCallback<void(Args...)> callback) {
  16. return base::BindOnce(
  17. [](scoped_refptr<base::SequencedTaskRunner> task_runner,
  18. const base::Location& from_here,
  19. base::OnceCallback<void(Args...)> callback, Args... args) {
  20. base::OnceClosure closure =
  21. base::BindOnce(std::move(callback), std::forward<Args>(args)...);
  22. if (task_runner->RunsTasksInCurrentSequence()) {
  23. std::move(closure).Run();
  24. return;
  25. }
  26. task_runner->PostTask(from_here, std::move(closure));
  27. },
  28. base::SequencedTaskRunnerHandle::Get(), from_here, std::move(callback));
  29. }
  30. // Similar to base::SequenceBound::Post, but executes the callback (which should
  31. // be the last method argument) on the sequence where the task is posted from.
  32. // Say if you want to call this method and make |callback| run on the current
  33. // sequence:
  34. //
  35. // client_.AsyncCall(&DirectoryClient::DeleteHost).WithArgs(host_id,
  36. // callback);
  37. //
  38. // You can just do:
  39. //
  40. // PostWithCallback(FROM_HERE, &client_, &DirectoryClient::DeleteHost,
  41. // callback, host_id);
  42. //
  43. // Note that |callback| is moved before other arguments, as type deduction does
  44. // not work the other way around.
  45. //
  46. // Also you should probably bind a WeakPtr in your callback rather than using
  47. // base::Unretained, since the underlying sequence bound object will generally
  48. // be deleted after the owning object.
  49. template <typename SequenceBoundType,
  50. typename... MethodArgs,
  51. typename... Args,
  52. typename... CallbackArgs>
  53. void PostWithCallback(const base::Location& from_here,
  54. base::SequenceBound<SequenceBoundType>* client,
  55. void (SequenceBoundType::*method)(MethodArgs...),
  56. base::OnceCallback<void(CallbackArgs...)> callback,
  57. Args&&... args) {
  58. client->AsyncCall(method, from_here)
  59. .WithArgs(std::forward<Args>(args)...,
  60. WrapCallbackToCurrentSequence(from_here, std::move(callback)));
  61. }
  62. } // namespace remoting
  63. #endif // REMOTING_BASE_TASK_UTIL_H_