1 /* 2 * Copyright 2016 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 11 #ifndef RTC_BASE_TASK_QUEUE_H_ 12 #define RTC_BASE_TASK_QUEUE_H_ 13 14 #include <stdint.h> 15 16 #include <memory> 17 #include <utility> 18 19 #include "absl/functional/any_invocable.h" 20 #include "absl/memory/memory.h" 21 #include "api/task_queue/task_queue_base.h" 22 #include "api/task_queue/task_queue_factory.h" 23 #include "rtc_base/system/rtc_export.h" 24 #include "rtc_base/thread_annotations.h" 25 26 namespace rtc { 27 // Implements a task queue that asynchronously executes tasks in a way that 28 // guarantees that they're executed in FIFO order and that tasks never overlap. 29 // Tasks may always execute on the same worker thread and they may not. 30 // To DCHECK that tasks are executing on a known task queue, use IsCurrent(). 31 // 32 // Here are some usage examples: 33 // 34 // 1) Asynchronously running a lambda: 35 // 36 // class MyClass { 37 // ... 38 // TaskQueue queue_("MyQueue"); 39 // }; 40 // 41 // void MyClass::StartWork() { 42 // queue_.PostTask([]() { Work(); }); 43 // ... 44 // 45 // 2) Posting a custom task on a timer. The task posts itself again after 46 // every running: 47 // 48 // class TimerTask : public QueuedTask { 49 // public: 50 // TimerTask() {} 51 // private: 52 // bool Run() override { 53 // ++count_; 54 // TaskQueueBase::Current()->PostDelayedTask( 55 // absl::WrapUnique(this), 1000); 56 // // Ownership has been transferred to the next occurance, 57 // // so return false to prevent from being deleted now. 58 // return false; 59 // } 60 // int count_ = 0; 61 // }; 62 // ... 63 // queue_.PostDelayedTask(std::make_unique<TimerTask>(), 1000); 64 // 65 // For more examples, see task_queue_unittests.cc. 66 // 67 // A note on destruction: 68 // 69 // When a TaskQueue is deleted, pending tasks will not be executed but they will 70 // be deleted. The deletion of tasks may happen asynchronously after the 71 // TaskQueue itself has been deleted or it may happen synchronously while the 72 // TaskQueue instance is being deleted. This may vary from one OS to the next 73 // so assumptions about lifetimes of pending tasks should not be made. 74 class RTC_LOCKABLE RTC_EXPORT TaskQueue { 75 public: 76 // TaskQueue priority levels. On some platforms these will map to thread 77 // priorities, on others such as Mac and iOS, GCD queue priorities. 78 using Priority = ::webrtc::TaskQueueFactory::Priority; 79 80 explicit TaskQueue(std::unique_ptr<webrtc::TaskQueueBase, 81 webrtc::TaskQueueDeleter> task_queue); 82 ~TaskQueue(); 83 84 TaskQueue(const TaskQueue&) = delete; 85 TaskQueue& operator=(const TaskQueue&) = delete; 86 87 // Used for DCHECKing the current queue. 88 bool IsCurrent() const; 89 90 // Returns non-owning pointer to the task queue implementation. Get()91 webrtc::TaskQueueBase* Get() { return impl_; } 92 PostTask(absl::AnyInvocable<void ()&&> task)93 void PostTask(absl::AnyInvocable<void() &&> task) { 94 impl_->PostTask(std::move(task)); 95 } PostDelayedTask(absl::AnyInvocable<void ()&&> task,webrtc::TimeDelta delay)96 void PostDelayedTask(absl::AnyInvocable<void() &&> task, 97 webrtc::TimeDelta delay) { 98 impl_->PostDelayedTask(std::move(task), delay); 99 } PostDelayedHighPrecisionTask(absl::AnyInvocable<void ()&&> task,webrtc::TimeDelta delay)100 void PostDelayedHighPrecisionTask(absl::AnyInvocable<void() &&> task, 101 webrtc::TimeDelta delay) { 102 impl_->PostDelayedHighPrecisionTask(std::move(task), delay); 103 } 104 105 private: 106 webrtc::TaskQueueBase* const impl_; 107 }; 108 109 } // namespace rtc 110 111 #endif // RTC_BASE_TASK_QUEUE_H_ 112