• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 eventName = event.domain_ + "_" + event.eventName_;
79     auto listeners = context_->GetListenerInfo(event.messageType_, eventName, event.eventId_);
80     for (auto& tmp : listeners) {
81         auto listener = tmp.lock();
82         if (listener == nullptr) {
83             continue;
84         }
85         auto timePtr = std::make_shared<uint64_t>(0);
86         {
87             TimeUtil::TimeCalculator tc(timePtr);
88             if (listener->isPlugin) {
89                 auto ptr = listener->plugin.lock();
90                 if (ptr != nullptr) {
91                     ptr->OnEventListeningCallback(event);
92                 }
93             } else {
94                 auto ptr = listener->listener.lock();
95                 if (ptr != nullptr) {
96                     ptr->OnUnorderedEvent(event);
97                 }
98             }
99         }
100         HiviewEventReport::UpdatePluginStats(listener->name, event.eventName_, *timePtr);
101     }
102 }
103 
Stop()104 void EventDispatchQueue::Stop()
105 {
106     stop_ = true;
107     condition_.notify_all();
108     if (thread_ != nullptr && thread_->joinable()) {
109         thread_->join();
110     }
111     isRunning_ = false;
112 }
113 
Start()114 void EventDispatchQueue::Start()
115 {
116     std::unique_lock<std::mutex> lock(mutexLock_);
117     if (!IsRunning()) {
118         thread_ = std::make_unique<std::thread>(&EventDispatchQueue::Run, this);
119     }
120 }
121 
Enqueue(std::shared_ptr<Event> event)122 void EventDispatchQueue::Enqueue(std::shared_ptr<Event> event)
123 {
124     HIVIEW_LOGD("EventDispatchQueue Enqueue");
125     std::unique_lock<std::mutex> lock(mutexLock_);
126     pendingEvents_.push_back(std::move(event));
127     condition_.notify_one();
128 }
129 
GetWaitQueueSize() const130 int EventDispatchQueue::GetWaitQueueSize() const
131 {
132     return pendingEvents_.size();
133 }
134 } // namespace HiviewDFX
135 } // namespace OHOS