1 /* 2 * Copyright (c) 2022 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 MODULES_UTILITY_MAYBE_WORKER_THREAD_H_ 11 #define MODULES_UTILITY_MAYBE_WORKER_THREAD_H_ 12 13 #include <memory> 14 15 #include "absl/strings/string_view.h" 16 #include "api/field_trials_view.h" 17 #include "api/sequence_checker.h" 18 #include "api/task_queue/pending_task_safety_flag.h" 19 #include "api/task_queue/task_queue_base.h" 20 #include "api/task_queue/task_queue_factory.h" 21 #include "rtc_base/thread_annotations.h" 22 23 namespace webrtc { 24 25 // Helper class used by experiment to replace usage of the 26 // RTP worker task queue owned by RtpTransportControllerSend, and the pacer task 27 // queue owned by TaskQueuePacedSender with the one and only worker thread. 28 // Tasks will run on the target sequence which is either the worker thread or 29 // one of these task queues depending on the field trial 30 // "WebRTC-SendPacketsOnWorkerThread". 31 // This class is assumed to be created on the worker thread and the worker 32 // thread is assumed to outlive an instance of this class. 33 // 34 // Experiment can be tracked in 35 // https://bugs.chromium.org/p/webrtc/issues/detail?id=14502 36 // 37 // After experiment evaluation, this class should be deleted. 38 // Calls to RunOrPost and RunSynchronous should be removed and the task should 39 // be invoked immediately. 40 // Instead of MaybeSafeTask a SafeTask should be used when posting tasks. 41 class RTC_LOCKABLE MaybeWorkerThread { 42 public: 43 MaybeWorkerThread(const FieldTrialsView& field_trials, 44 absl::string_view task_queue_name, 45 TaskQueueFactory* factory); 46 ~MaybeWorkerThread(); 47 48 // Runs `task` immediately on the worker thread if in experiment, otherwise 49 // post the task on the task queue. 50 void RunOrPost(absl::AnyInvocable<void() &&> task); 51 // Runs `task` immediately on the worker thread if in experiment, otherwise 52 // post the task on the task queue and use an even to wait for completion. 53 void RunSynchronous(absl::AnyInvocable<void() &&> task); 54 55 // Used for posting delayed or repeated tasks on the worker thread or task 56 // queue depending on the field trial. DCHECKs that this method is called on 57 // the target sequence. 58 TaskQueueBase* TaskQueueForDelayedTasks() const; 59 60 // Used when a task has to be posted from one sequence to the target 61 // sequence. A task should only be posted if a sequence hop is needed. 62 TaskQueueBase* TaskQueueForPost() const; 63 64 // Workaround to use a SafeTask only if the target sequence is the worker 65 // thread. This is used when a SafeTask can not be used because the object 66 // that posted the task is not destroyed on the target sequence. Instead, the 67 // caller has to guarantee that this MaybeWorkerThread is destroyed first 68 // since that guarantee that the posted task is deleted or run before the 69 // owning class. 70 absl::AnyInvocable<void() &&> MaybeSafeTask( 71 rtc::scoped_refptr<PendingTaskSafetyFlag> flag, 72 absl::AnyInvocable<void() &&> task); 73 74 // To implement macro RTC_DCHECK_RUN_ON. 75 // Implementation delegate to the actual used sequence. 76 bool IsCurrent() const; 77 78 private: 79 SequenceChecker sequence_checker_; 80 std::unique_ptr<TaskQueueBase, TaskQueueDeleter> owned_task_queue_; 81 TaskQueueBase* const worker_thread_; 82 }; 83 84 } // namespace webrtc 85 86 #endif // MODULES_UTILITY_MAYBE_WORKER_THREAD_H_ 87