1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "event_dispatch_queue.h"
16
17 #include <algorithm>
18 #include <memory>
19
20 #include "file_util.h"
21 #include "hiview_event_report.h"
22 #include "logger.h"
23 #include "memory_util.h"
24 #include "plugin.h"
25 #include "thread_util.h"
26 #include "time_util.h"
27
28 namespace OHOS {
29 namespace HiviewDFX {
30 DEFINE_LOG_TAG("HiView-EventDispatchQueue");
EventDispatchQueue(const std::string & name,Event::ManageType type,HiviewContext * context)31 EventDispatchQueue::EventDispatchQueue(const std::string& name, Event::ManageType type, HiviewContext* context)
32 : stop_(false), isRunning_(false), threadName_(name), type_(type), context_(context)
33 {}
34
~EventDispatchQueue()35 EventDispatchQueue::~EventDispatchQueue()
36 {
37 Stop();
38 }
39
Run()40 void EventDispatchQueue::Run()
41 {
42 if (MemoryUtil::DisableThreadCache() != 0 || MemoryUtil::DisableDelayFree() != 0) {
43 HIVIEW_LOGW("Failed to optimize memory for current thread");
44 }
45 const int threadNameLen = 15;
46 Thread::SetThreadDescription(threadName_.substr(0, threadNameLen));
47 isRunning_ = true;
48 while (true) {
49 std::shared_ptr<Event> event = nullptr;
50 {
51 std::unique_lock<std::mutex> lock(mutexLock_);
52 while (pendingEvents_.empty()) {
53 condition_.wait(lock);
54 if (stop_) {
55 return;
56 }
57 }
58 event = pendingEvents_.front();
59 pendingEvents_.pop_front();
60 }
61
62 if (event == nullptr) {
63 continue;
64 }
65
66 if (type_ == Event::ManageType::UNORDERED) {
67 ProcessUnorderedEvent(*(event.get()));
68 }
69
70 if (stop_) {
71 break;
72 }
73 }
74 }
75
ProcessUnorderedEvent(const Event & event)76 void EventDispatchQueue::ProcessUnorderedEvent(const Event& event)
77 {
78 auto listeners = context_->GetListenerInfo(event.messageType_, event.eventName_, event.domain_);
79 for (auto& listener : listeners) {
80 auto ptr = listener.lock();
81 auto timePtr = std::make_shared<uint64_t>(0);
82 {
83 TimeUtil::TimeCalculator tc(timePtr);
84 if (ptr == nullptr) {
85 continue;
86 }
87 ptr->OnUnorderedEvent(event);
88 }
89 HiviewEventReport::UpdatePluginStats(ptr->GetListenerName(), event.eventName_, *timePtr);
90 }
91 }
92
Stop()93 void EventDispatchQueue::Stop()
94 {
95 stop_ = true;
96 condition_.notify_all();
97 if (thread_ != nullptr && thread_->joinable()) {
98 thread_->join();
99 }
100 isRunning_ = false;
101 }
102
Start()103 void EventDispatchQueue::Start()
104 {
105 std::unique_lock<std::mutex> lock(mutexLock_);
106 if (!IsRunning()) {
107 thread_ = std::make_unique<std::thread>(&EventDispatchQueue::Run, this);
108 }
109 }
110
Enqueue(std::shared_ptr<Event> event)111 void EventDispatchQueue::Enqueue(std::shared_ptr<Event> event)
112 {
113 HIVIEW_LOGD("EventDispatchQueue Enqueue");
114 std::unique_lock<std::mutex> lock(mutexLock_);
115 pendingEvents_.push_back(std::move(event));
116 condition_.notify_one();
117 }
118
GetWaitQueueSize() const119 int EventDispatchQueue::GetWaitQueueSize() const
120 {
121 return pendingEvents_.size();
122 }
123 } // namespace HiviewDFX
124 } // namespace OHOS