1 /* 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 11 #ifndef MODULES_UTILITY_SOURCE_PROCESS_THREAD_IMPL_H_ 12 #define MODULES_UTILITY_SOURCE_PROCESS_THREAD_IMPL_H_ 13 14 #include <stdint.h> 15 16 #include <list> 17 #include <memory> 18 #include <queue> 19 20 #include "api/task_queue/queued_task.h" 21 #include "modules/include/module.h" 22 #include "modules/utility/include/process_thread.h" 23 #include "rtc_base/deprecated/recursive_critical_section.h" 24 #include "rtc_base/event.h" 25 #include "rtc_base/location.h" 26 #include "rtc_base/platform_thread.h" 27 #include "rtc_base/thread_checker.h" 28 29 namespace webrtc { 30 31 class ProcessThreadImpl : public ProcessThread { 32 public: 33 explicit ProcessThreadImpl(const char* thread_name); 34 ~ProcessThreadImpl() override; 35 36 void Start() override; 37 void Stop() override; 38 39 void WakeUp(Module* module) override; 40 void PostTask(std::unique_ptr<QueuedTask> task) override; 41 void PostDelayedTask(std::unique_ptr<QueuedTask> task, 42 uint32_t milliseconds) override; 43 44 void RegisterModule(Module* module, const rtc::Location& from) override; 45 void DeRegisterModule(Module* module) override; 46 47 protected: 48 static void Run(void* obj); 49 bool Process(); 50 51 private: 52 struct ModuleCallback { 53 ModuleCallback() = delete; 54 ModuleCallback(ModuleCallback&& cb) = default; 55 ModuleCallback(const ModuleCallback& cb) = default; ModuleCallbackModuleCallback56 ModuleCallback(Module* module, const rtc::Location& location) 57 : module(module), location(location) {} 58 bool operator==(const ModuleCallback& cb) const { 59 return cb.module == module; 60 } 61 62 Module* const module; 63 int64_t next_callback = 0; // Absolute timestamp. 64 const rtc::Location location; 65 66 private: 67 ModuleCallback& operator=(ModuleCallback&); 68 }; 69 struct DelayedTask { DelayedTaskDelayedTask70 DelayedTask(int64_t run_at_ms, std::unique_ptr<QueuedTask> task) 71 : run_at_ms(run_at_ms), task(task.release()) {} 72 friend bool operator<(const DelayedTask& lhs, const DelayedTask& rhs) { 73 // Earliest DelayedTask should be at the top of the priority queue. 74 return lhs.run_at_ms > rhs.run_at_ms; 75 } 76 77 int64_t run_at_ms; 78 // DelayedTask owns the |task|, but some delayed tasks must be removed from 79 // the std::priority_queue, but mustn't be deleted. std::priority_queue does 80 // not give non-const access to the values, so storing unique_ptr would 81 // delete the task as soon as it is remove from the priority queue. 82 // Thus lifetime of the |task| is managed manually. 83 QueuedTask* task; 84 }; 85 typedef std::list<ModuleCallback> ModuleList; 86 87 void Delete() override; 88 89 // Warning: For some reason, if |lock_| comes immediately before |modules_| 90 // with the current class layout, we will start to have mysterious crashes 91 // on Mac 10.9 debug. I (Tommi) suspect we're hitting some obscure alignemnt 92 // issues, but I haven't figured out what they are, if there are alignment 93 // requirements for mutexes on Mac or if there's something else to it. 94 // So be careful with changing the layout. 95 rtc::RecursiveCriticalSection 96 lock_; // Used to guard modules_, tasks_ and stop_. 97 98 rtc::ThreadChecker thread_checker_; 99 rtc::Event wake_up_; 100 // TODO(pbos): Remove unique_ptr and stop recreating the thread. 101 std::unique_ptr<rtc::PlatformThread> thread_; 102 103 ModuleList modules_; 104 std::queue<QueuedTask*> queue_; 105 std::priority_queue<DelayedTask> delayed_tasks_ RTC_GUARDED_BY(lock_); 106 bool stop_; 107 const char* thread_name_; 108 }; 109 110 } // namespace webrtc 111 112 #endif // MODULES_UTILITY_SOURCE_PROCESS_THREAD_IMPL_H_ 113