blob: cae95340bcfbb408cd377c69b05e8542084d99be [file] [log] [blame]
tommic06b1332016-05-14 11:31:40 -07001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef RTC_BASE_TASK_QUEUE_H_
12#define RTC_BASE_TASK_QUEUE_H_
tommic06b1332016-05-14 11:31:40 -070013
Yves Gerey3e707812018-11-28 16:47:49 +010014#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020015
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020016#include <memory>
Danil Chapovalov6f09ae22017-10-12 14:39:25 +020017#include <utility>
tommic06b1332016-05-14 11:31:40 -070018
Danil Chapovalova7e15a22022-07-05 16:03:03 +020019#include "absl/functional/any_invocable.h"
Karl Wiberg918f50c2018-07-05 11:40:33 +020020#include "absl/memory/memory.h"
Danil Chapovalovd00405f2019-02-25 15:06:13 +010021#include "api/task_queue/task_queue_base.h"
22#include "api/task_queue/task_queue_factory.h"
Mirko Bonadei3d255302018-10-11 10:50:45 +020023#include "rtc_base/system/rtc_export.h"
Danil Chapovalov02fddf62018-02-12 12:41:16 +010024#include "rtc_base/thread_annotations.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020025
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020026namespace rtc {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020027// 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//
Danil Chapovalov1aa75812019-03-05 11:11:35 +010045// 2) Posting a custom task on a timer. The task posts itself again after
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020046// every running:
47//
48// class TimerTask : public QueuedTask {
49// public:
50// TimerTask() {}
51// private:
52// bool Run() override {
53// ++count_;
Danil Chapovalovad895282019-03-11 10:28:05 +000054// TaskQueueBase::Current()->PostDelayedTask(
55// absl::WrapUnique(this), 1000);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020056// // 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// ...
Mirko Bonadei317a1f02019-09-17 17:06:18 +020063// queue_.PostDelayedTask(std::make_unique<TimerTask>(), 1000);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020064//
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.
Mirko Bonadei3d255302018-10-11 10:50:45 +020074class RTC_LOCKABLE RTC_EXPORT TaskQueue {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020075 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.
Danil Chapovalovd00405f2019-02-25 15:06:13 +010078 using Priority = ::webrtc::TaskQueueFactory::Priority;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020079
Danil Chapovalovf3280e92019-02-28 10:39:04 +010080 explicit TaskQueue(std::unique_ptr<webrtc::TaskQueueBase,
81 webrtc::TaskQueueDeleter> task_queue);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020082 ~TaskQueue();
83
Byoungchan Lee14af7622022-01-12 05:24:58 +090084 TaskQueue(const TaskQueue&) = delete;
85 TaskQueue& operator=(const TaskQueue&) = delete;
86
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020087 // Used for DCHECKing the current queue.
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020088 bool IsCurrent() const;
89
Danil Chapovalovf3280e92019-02-28 10:39:04 +010090 // Returns non-owning pointer to the task queue implementation.
91 webrtc::TaskQueueBase* Get() { return impl_; }
92
Danil Chapovalova7e15a22022-07-05 16:03:03 +020093 void PostTask(absl::AnyInvocable<void() &&> task) {
94 impl_->PostTask(std::move(task));
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020095 }
Danil Chapovalovc05a1be2022-07-19 13:07:12 +020096 void PostDelayedTask(absl::AnyInvocable<void() &&> task,
97 webrtc::TimeDelta delay) {
98 impl_->PostDelayedTask(std::move(task), delay);
99 }
100 void PostDelayedHighPrecisionTask(absl::AnyInvocable<void() &&> task,
101 webrtc::TimeDelta delay) {
102 impl_->PostDelayedHighPrecisionTask(std::move(task), delay);
103 }
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200104
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200105 private:
Danil Chapovalovd00405f2019-02-25 15:06:13 +0100106 webrtc::TaskQueueBase* const impl_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200107};
108
109} // namespace rtc
tommic06b1332016-05-14 11:31:40 -0700110
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200111#endif // RTC_BASE_TASK_QUEUE_H_