• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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  * Description: handler module for send message and handle message in a looper
15  * Author: lijianzhao
16  * Create: 2022-01-19
17  */
18 
19 #include "handler.h"
20 
21 namespace OHOS {
22 namespace CastEngine {
23 namespace CastEngineService {
Handler()24 Handler::Handler() : stop_(false), stopWhenEmpty_(false)
25 {
26     looper_ = std::thread([this]() {
27         for (;;) {
28             Message msg;
29             {
30                 std::unique_lock<std::mutex> lock(this->queueMutex_);
31                 if ((this->stopWhenEmpty_ && this->msgQueue_.empty()) || this->stop_) {
32                     return;
33                 }
34 
35                 if (this->msgQueue_.empty()) {
36                     this->condition_.wait(lock);
37                 }
38 
39                 if ((this->stopWhenEmpty_ && this->msgQueue_.empty()) || this->stop_) {
40                     return;
41                 }
42 
43                 // send message at when_
44                 if (!(this->msgQueue_.empty()) &&
45                     (this->condition_.wait_until(lock, this->msgQueue_.back().when_) != std::cv_status::timeout)) {
46                     continue;
47                 }
48 
49                 if (!this->msgQueue_.empty()) {
50                     msg = std::move(this->msgQueue_.back());
51                     this->msgQueue_.pop_back();
52                 } else {
53                     continue;
54                 }
55             }
56             this->HandleMessageInner(msg);
57         }
58     });
59 }
60 
~Handler()61 Handler::~Handler()
62 {
63     {
64         std::unique_lock<std::mutex> lock(queueMutex_);
65         stop_ = true;
66         condition_.notify_all();
67     }
68 
69     if (looper_.joinable()) {
70         looper_.join();
71     }
72 
73     msgQueue_.clear();
74 }
75 
ThreadJoin()76 void Handler::ThreadJoin()
77 {
78     if (looper_.joinable()) {
79         looper_.join();
80     }
81 }
82 
SendCastMessage(const Message & msg)83 bool Handler::SendCastMessage(const Message &msg)
84 {
85     std::unique_lock<std::mutex> lock(queueMutex_);
86     auto i = std::find(msgQueue_.begin(), msgQueue_.end(), msg);
87     if (i != msgQueue_.end()) {
88         msgQueue_.erase(i);
89     }
90 
91     msgQueue_.push_back(msg);
92     std::sort(msgQueue_.begin(), msgQueue_.end(), std::greater<Message>());
93     condition_.notify_one();
94     return true;
95 }
96 
SendCastMessage(int what)97 bool Handler::SendCastMessage(int what)
98 {
99     return SendCastMessage(Message(what));
100 }
101 
SendCastMessage(int what,int arg1)102 bool Handler::SendCastMessage(int what, int arg1)
103 {
104     return SendCastMessage(Message(what, arg1));
105 }
106 
SendCastMessage(int what,int arg1,int arg2)107 bool Handler::SendCastMessage(int what, int arg1, int arg2)
108 {
109     return SendCastMessage(Message(what, arg1, arg2));
110 }
111 
SendCastMessageDelayed(int what,long uptimeMillis)112 bool Handler::SendCastMessageDelayed(int what, long uptimeMillis)
113 {
114     if (uptimeMillis < 0) {
115         return false;
116     }
117 
118     Message msg(what);
119     msg.SetWhen(uptimeMillis);
120     return SendCastMessage(msg);
121 }
122 
RemoveMessage(const Message & msg)123 void Handler::RemoveMessage(const Message &msg)
124 {
125     std::unique_lock<std::mutex> lock(queueMutex_);
126     for (auto it = msgQueue_.begin(); it != msgQueue_.end();) {
127         if (it->what_ == msg.what_) {
128             it = msgQueue_.erase(it);
129         } else {
130             ++it;
131         }
132     }
133     condition_.notify_one();
134 }
135 
RemoveCallbackAndMessages()136 void Handler::RemoveCallbackAndMessages()
137 {
138     std::unique_lock<std::mutex> lock(queueMutex_);
139     msgQueue_.clear();
140 }
141 
StopSafty(bool stopSafty)142 void Handler::StopSafty(bool stopSafty)
143 {
144     std::unique_lock<std::mutex> lock(queueMutex_);
145     if (stopSafty) {
146         stopWhenEmpty_ = true;
147     } else {
148         stop_ = true;
149     }
150 
151     condition_.notify_all();
152 }
153 
IsQuiting()154 bool Handler::IsQuiting()
155 {
156     std::unique_lock<std::mutex> lock(queueMutex_);
157     if (stop_ || stopWhenEmpty_) {
158         return true;
159     }
160     return false;
161 }
162 
HandleMessageInner(const Message & msg)163 void Handler::HandleMessageInner(const Message &msg)
164 {
165     if (msg.task_ != nullptr) {
166         msg.task_();
167     } else {
168         if (msg.what_ < 0) {
169             return;
170         }
171         HandleMessage(msg);
172     }
173 }
174 } // namespace CastEngineService
175 } // namespace CastEngine
176 } // namespace OHOS
177