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