to_queued_task.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright 2019 The WebRTC Project Authors. All rights reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef RTC_BASE_TASK_UTILS_TO_QUEUED_TASK_H_
  11. #define RTC_BASE_TASK_UTILS_TO_QUEUED_TASK_H_
  12. #include <memory>
  13. #include <type_traits>
  14. #include <utility>
  15. #include "api/task_queue/queued_task.h"
  16. #include "rtc_base/task_utils/pending_task_safety_flag.h"
  17. namespace webrtc {
  18. namespace webrtc_new_closure_impl {
  19. // Simple implementation of QueuedTask for use with rtc::Bind and lambdas.
  20. template <typename Closure>
  21. class ClosureTask : public QueuedTask {
  22. public:
  23. explicit ClosureTask(Closure&& closure)
  24. : closure_(std::forward<Closure>(closure)) {}
  25. private:
  26. bool Run() override {
  27. closure_();
  28. return true;
  29. }
  30. typename std::decay<Closure>::type closure_;
  31. };
  32. template <typename Closure>
  33. class SafetyClosureTask : public QueuedTask {
  34. public:
  35. explicit SafetyClosureTask(rtc::scoped_refptr<PendingTaskSafetyFlag> safety,
  36. Closure&& closure)
  37. : closure_(std::forward<Closure>(closure)),
  38. safety_flag_(std::move(safety)) {}
  39. private:
  40. bool Run() override {
  41. if (safety_flag_->alive())
  42. closure_();
  43. return true;
  44. }
  45. typename std::decay<Closure>::type closure_;
  46. rtc::scoped_refptr<PendingTaskSafetyFlag> safety_flag_;
  47. };
  48. // Extends ClosureTask to also allow specifying cleanup code.
  49. // This is useful when using lambdas if guaranteeing cleanup, even if a task
  50. // was dropped (queue is too full), is required.
  51. template <typename Closure, typename Cleanup>
  52. class ClosureTaskWithCleanup : public ClosureTask<Closure> {
  53. public:
  54. ClosureTaskWithCleanup(Closure&& closure, Cleanup&& cleanup)
  55. : ClosureTask<Closure>(std::forward<Closure>(closure)),
  56. cleanup_(std::forward<Cleanup>(cleanup)) {}
  57. ~ClosureTaskWithCleanup() override { cleanup_(); }
  58. private:
  59. typename std::decay<Cleanup>::type cleanup_;
  60. };
  61. } // namespace webrtc_new_closure_impl
  62. // Convenience function to construct closures that can be passed directly
  63. // to methods that support std::unique_ptr<QueuedTask> but not template
  64. // based parameters.
  65. template <typename Closure>
  66. std::unique_ptr<QueuedTask> ToQueuedTask(Closure&& closure) {
  67. return std::make_unique<webrtc_new_closure_impl::ClosureTask<Closure>>(
  68. std::forward<Closure>(closure));
  69. }
  70. template <typename Closure>
  71. std::unique_ptr<QueuedTask> ToQueuedTask(
  72. rtc::scoped_refptr<PendingTaskSafetyFlag> safety,
  73. Closure&& closure) {
  74. return std::make_unique<webrtc_new_closure_impl::SafetyClosureTask<Closure>>(
  75. std::move(safety), std::forward<Closure>(closure));
  76. }
  77. template <typename Closure>
  78. std::unique_ptr<QueuedTask> ToQueuedTask(const ScopedTaskSafety& safety,
  79. Closure&& closure) {
  80. return ToQueuedTask(safety.flag(), std::forward<Closure>(closure));
  81. }
  82. template <typename Closure,
  83. typename Cleanup,
  84. typename std::enable_if<!std::is_same<
  85. typename std::remove_const<
  86. typename std::remove_reference<Closure>::type>::type,
  87. ScopedTaskSafety>::value>::type* = nullptr>
  88. std::unique_ptr<QueuedTask> ToQueuedTask(Closure&& closure, Cleanup&& cleanup) {
  89. return std::make_unique<
  90. webrtc_new_closure_impl::ClosureTaskWithCleanup<Closure, Cleanup>>(
  91. std::forward<Closure>(closure), std::forward<Cleanup>(cleanup));
  92. }
  93. } // namespace webrtc
  94. #endif // RTC_BASE_TASK_UTILS_TO_QUEUED_TASK_H_