1 /*
2  * Copyright (c) 2021-2024 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 "hiview_event_report.h"
18 #include "hiview_logger.h"
19 #include "plugin.h"
20 #include "time_util.h"
21 
22 namespace OHOS {
23 namespace HiviewDFX {
24 DEFINE_LOG_TAG("HiView-EventDispatchQueue");
EventDispatchQueue(const std::string & name,Event::ManageType type,HiviewContext * context)25 EventDispatchQueue::EventDispatchQueue(const std::string& name, Event::ManageType type, HiviewContext* context)
26     : isRunning_(false), threadName_(name), type_(type), context_(context)
27 {}
28 
~EventDispatchQueue()29 EventDispatchQueue::~EventDispatchQueue()
30 {
31     Stop();
32 }
33 
ProcessUnorderedEvent(const Event & event)34 void EventDispatchQueue::ProcessUnorderedEvent(const Event& event)
35 {
36     auto listeners = context_->GetListenerInfo(event.messageType_, event.eventName_, event.domain_);
37     for (auto& listener : listeners) {
38         auto ptr = listener.lock();
39         auto timePtr = std::make_shared<uint64_t>(0);
40         {
41             TimeUtil::TimeCalculator tc(timePtr);
42             if (ptr == nullptr) {
43                 continue;
44             }
45             ptr->OnUnorderedEvent(event);
46         }
47         HiviewEventReport::UpdatePluginStats(ptr->GetListenerName(), event.eventName_, *timePtr);
48     }
49 }
50 
Stop()51 void EventDispatchQueue::Stop()
52 {
53     std::unique_lock<ffrt::mutex> lock(mutexLock_);
54     ffrtQueue_ = nullptr;
55     isRunning_ = false;
56 }
57 
Start()58 void EventDispatchQueue::Start()
59 {
60     std::unique_lock<ffrt::mutex> lock(mutexLock_);
61     if (!isRunning_) {
62         ffrtQueue_ = std::make_unique<ffrt::queue>(threadName_.c_str());
63         isRunning_ = true;
64     }
65 }
66 
Enqueue(std::shared_ptr<Event> event)67 void EventDispatchQueue::Enqueue(std::shared_ptr<Event> event)
68 {
69     if (event == nullptr) {
70         HIVIEW_LOGW("event is null");
71         return;
72     }
73 
74     std::unique_lock<ffrt::mutex> lock(mutexLock_);
75     if (!isRunning_) {
76         HIVIEW_LOGW("queue is stopped");
77         return;
78     }
79     if (context_ == nullptr) {
80         HIVIEW_LOGW("context is null");
81         return;
82     }
83 
84     auto queuePtr = shared_from_this();
85     ffrtQueue_->submit([event, queuePtr] {
86         if (queuePtr->type_ == Event::ManageType::UNORDERED) {
87             queuePtr->ProcessUnorderedEvent(*(event.get()));
88         } else {
89             HIVIEW_LOGW("invalid type=%{public}d of queue", queuePtr->type_);
90         }
91     }, ffrt::task_attr().name("dft_plat_unorder"));
92 }
93 } // namespace HiviewDFX
94 } // namespace OHOS