blob: 5d22e37ca1ca3e3d74a94dee69350ccd1921c7e5 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
2 * Copyright (c) 2011 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 MODULES_UTILITY_SOURCE_PROCESS_THREAD_IMPL_H_
12#define MODULES_UTILITY_SOURCE_PROCESS_THREAD_IMPL_H_
niklase@google.com470e71d2011-07-07 08:21:25 +000013
Yves Gerey988cc082018-10-23 12:03:01 +020014#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020015
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +000016#include <list>
kwiberg22feaa32016-03-17 09:17:43 -070017#include <memory>
tommi@webrtc.org03054482015-03-05 13:13:42 +000018#include <queue>
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +000019
Artem Titovd15a5752021-02-10 14:31:24 +010020#include "api/sequence_checker.h"
Danil Chapovalov959e9b62019-01-14 14:29:18 +010021#include "api/task_queue/queued_task.h"
Yves Gerey988cc082018-10-23 12:03:01 +020022#include "modules/include/module.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "modules/utility/include/process_thread.h"
Niels Möller2c16cc62018-10-29 09:47:51 +010024#include "rtc_base/event.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "rtc_base/location.h"
26#include "rtc_base/platform_thread.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000027
28namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000029
tommi@webrtc.org0c3e12b2015-02-06 09:44:12 +000030class ProcessThreadImpl : public ProcessThread {
31 public:
stefan847855b2015-09-11 09:52:15 -070032 explicit ProcessThreadImpl(const char* thread_name);
tommi@webrtc.org0c3e12b2015-02-06 09:44:12 +000033 ~ProcessThreadImpl() override;
niklase@google.com470e71d2011-07-07 08:21:25 +000034
tommi@webrtc.org3985f012015-02-27 13:36:34 +000035 void Start() override;
36 void Stop() override;
niklase@google.com470e71d2011-07-07 08:21:25 +000037
tommi@webrtc.org0c3e12b2015-02-06 09:44:12 +000038 void WakeUp(Module* module) override;
Danil Chapovalov959e9b62019-01-14 14:29:18 +010039 void PostTask(std::unique_ptr<QueuedTask> task) override;
Danil Chapovalov14273de2020-02-27 13:37:43 +010040 void PostDelayedTask(std::unique_ptr<QueuedTask> task,
41 uint32_t milliseconds) override;
niklase@google.com470e71d2011-07-07 08:21:25 +000042
tommidea489f2017-03-03 03:20:24 -080043 void RegisterModule(Module* module, const rtc::Location& from) override;
tommi@webrtc.org3985f012015-02-27 13:36:34 +000044 void DeRegisterModule(Module* module) override;
niklase@google.com470e71d2011-07-07 08:21:25 +000045
tommi@webrtc.org0c3e12b2015-02-06 09:44:12 +000046 protected:
tommi@webrtc.org0c3e12b2015-02-06 09:44:12 +000047 bool Process();
48
49 private:
tommi@webrtc.org0c3e12b2015-02-06 09:44:12 +000050 struct ModuleCallback {
tommidea489f2017-03-03 03:20:24 -080051 ModuleCallback() = delete;
52 ModuleCallback(ModuleCallback&& cb) = default;
53 ModuleCallback(const ModuleCallback& cb) = default;
54 ModuleCallback(Module* module, const rtc::Location& location)
55 : module(module), location(location) {}
tommi@webrtc.org0c3e12b2015-02-06 09:44:12 +000056 bool operator==(const ModuleCallback& cb) const {
57 return cb.module == module;
58 }
tommi@webrtc.org103f3282015-02-08 00:48:10 +000059
tommi@webrtc.org0c3e12b2015-02-06 09:44:12 +000060 Module* const module;
tommidea489f2017-03-03 03:20:24 -080061 int64_t next_callback = 0; // Absolute timestamp.
62 const rtc::Location location;
tommi@webrtc.org103f3282015-02-08 00:48:10 +000063
64 private:
65 ModuleCallback& operator=(ModuleCallback&);
tommi@webrtc.org0c3e12b2015-02-06 09:44:12 +000066 };
Danil Chapovalov14273de2020-02-27 13:37:43 +010067 struct DelayedTask {
68 DelayedTask(int64_t run_at_ms, std::unique_ptr<QueuedTask> task)
69 : run_at_ms(run_at_ms), task(task.release()) {}
70 friend bool operator<(const DelayedTask& lhs, const DelayedTask& rhs) {
71 // Earliest DelayedTask should be at the top of the priority queue.
72 return lhs.run_at_ms > rhs.run_at_ms;
73 }
tommi@webrtc.org0c3e12b2015-02-06 09:44:12 +000074
Danil Chapovalov14273de2020-02-27 13:37:43 +010075 int64_t run_at_ms;
76 // DelayedTask owns the |task|, but some delayed tasks must be removed from
77 // the std::priority_queue, but mustn't be deleted. std::priority_queue does
78 // not give non-const access to the values, so storing unique_ptr would
79 // delete the task as soon as it is remove from the priority queue.
80 // Thus lifetime of the |task| is managed manually.
81 QueuedTask* task;
82 };
tommi@webrtc.org0c3e12b2015-02-06 09:44:12 +000083 typedef std::list<ModuleCallback> ModuleList;
tommi@webrtc.org103f3282015-02-08 00:48:10 +000084
Danil Chapovalov14273de2020-02-27 13:37:43 +010085 void Delete() override;
Niels Möller2bfddf72021-02-22 10:36:29 +010086 // The part of Stop processing that doesn't need any locking.
87 void StopNoLocks();
Niels Möller47854022021-03-01 11:31:33 +010088 void WakeUpNoLocks(Module* module);
89 void WakeUpInternal(Module* module) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
Danil Chapovalov14273de2020-02-27 13:37:43 +010090
Niels Möller2bfddf72021-02-22 10:36:29 +010091 // Members protected by this mutex are accessed on the constructor thread and
92 // on the spawned process thread, and locking is needed only while the process
93 // thread is running.
Niels Möller47854022021-03-01 11:31:33 +010094 Mutex mutex_;
tommi@webrtc.org103f3282015-02-08 00:48:10 +000095
Artem Titovc8421c42021-02-02 10:57:19 +010096 SequenceChecker thread_checker_;
Niels Möller2c16cc62018-10-29 09:47:51 +010097 rtc::Event wake_up_;
Markus Handellad5037b2021-05-07 15:02:36 +020098 rtc::PlatformThread thread_;
tommi@webrtc.org103f3282015-02-08 00:48:10 +000099
Niels Möller47854022021-03-01 11:31:33 +0100100 ModuleList modules_ RTC_GUARDED_BY(mutex_);
101 // Set to true when calling Process, to allow reentrant calls to WakeUp.
102 bool holds_mutex_ RTC_GUARDED_BY(this) = false;
Danil Chapovalov959e9b62019-01-14 14:29:18 +0100103 std::queue<QueuedTask*> queue_;
Niels Möller47854022021-03-01 11:31:33 +0100104 std::priority_queue<DelayedTask> delayed_tasks_ RTC_GUARDED_BY(mutex_);
Niels Möller2bfddf72021-02-22 10:36:29 +0100105 // The `stop_` flag is modified only by the construction thread, protected by
106 // `thread_checker_`. It is read also by the spawned `thread_`. The latter
Niels Möller47854022021-03-01 11:31:33 +0100107 // thread must take `mutex_` before access, and for thread safety, the
108 // constructor thread needs to take `mutex_` when it modifies `stop_` and
Niels Möller2bfddf72021-02-22 10:36:29 +0100109 // `thread_` is running. Annotations like RTC_GUARDED_BY doesn't support this
110 // usage pattern.
Niels Möller47854022021-03-01 11:31:33 +0100111 bool stop_ RTC_GUARDED_BY(mutex_);
stefan2b180842015-09-14 07:53:38 -0700112 const char* thread_name_;
niklase@google.com470e71d2011-07-07 08:21:25 +0000113};
tommi@webrtc.org0c3e12b2015-02-06 09:44:12 +0000114
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000115} // namespace webrtc
niklase@google.com470e71d2011-07-07 08:21:25 +0000116
Yves Gerey665174f2018-06-19 15:03:05 +0200117#endif // MODULES_UTILITY_SOURCE_PROCESS_THREAD_IMPL_H_