1 /*
2  * Copyright (c) 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 "message_queue.h"
16 #include "intell_voice_log.h"
17 
18 #define LOG_TAG "MesaageQueue"
19 
20 using namespace std;
21 
22 namespace OHOS {
23 namespace IntellVoiceUtils {
Message(uint32_t what)24 Message::Message(uint32_t what) : what_(what), arg1_(0), arg2_(0)
25 {
26 }
27 
Message(uint32_t what,int32_t arg1)28 Message::Message(uint32_t what, int32_t arg1) : what_(what), arg1_(arg1)
29 {
30 }
31 
Message(uint32_t what,int32_t arg1,int32_t arg2,float arg3)32 Message::Message(uint32_t what, int32_t arg1, int32_t arg2, float arg3)
33     : what_(what), arg1_(arg1), arg2_(arg2), arg3_(arg3)
34 {
35 }
36 
Message(uint32_t what,int32_t arg1,int32_t arg2,const std::string & obj)37 Message::Message(uint32_t what, int32_t arg1, int32_t arg2, const std::string &obj)
38     : what_(what), arg1_(arg1), arg2_(arg2), obj_(obj)
39 {
40 }
41 
Message(uint32_t what,int32_t arg1,int32_t arg2,float arg3,const std::string & obj)42 Message::Message(uint32_t what, int32_t arg1, int32_t arg2, float arg3, const std::string &obj)
43     : what_(what), arg1_(arg1), arg2_(arg2), arg3_(arg3), obj_(obj)
44 {
45 }
46 
Message(uint32_t what,std::shared_ptr<void> obj2)47 Message::Message(uint32_t what, std::shared_ptr<void> obj2) : what_(what), obj2_(obj2)
48 {
49 }
50 
Message(uint32_t what,std::shared_ptr<void> obj2,std::shared_ptr<void> obj3)51 Message::Message(uint32_t what, std::shared_ptr<void> obj2, std::shared_ptr<void> obj3)
52     : what_(what), obj2_(obj2), obj3_(obj3)
53 {
54 }
55 
Message(uint32_t what,void * voidPtr)56 Message::Message(uint32_t what, void* voidPtr) : what_(what), voidPtr_(voidPtr)
57 {
58 }
59 
Message(uint32_t what,int32_t arg1,void * voidPtr)60 Message::Message(uint32_t what, int32_t arg1, void* voidPtr) : what_(what), arg1_(arg1), voidPtr_(voidPtr)
61 {
62 }
63 
~Message()64 Message::~Message()
65 {
66     voidPtr_ = nullptr;
67 }
68 
MessageQueue(uint32_t size)69 MessageQueue::MessageQueue(uint32_t size) : size_(size), lock_(PTHREAD_MUTEX_INITIALIZER)
70 {
71     pthread_condattr_t attr;
72     int result = pthread_condattr_init(&attr);
73     result += pthread_cond_init(&cond_, &attr);
74     result += pthread_condattr_destroy(&attr);
75     if (result != 0) {
76         INTELL_VOICE_LOG_ERROR("message queue construct init cond failed");
77     }
78 }
79 
~MessageQueue()80 MessageQueue::~MessageQueue()
81 {
82     int result = pthread_mutex_destroy(&lock_);
83     result += pthread_cond_destroy(&cond_);
84     if (result != 0) {
85         INTELL_VOICE_LOG_ERROR("message queue deconstruct destroy cond failed");
86     }
87 }
88 
ReceiveMsg()89 shared_ptr<Message> MessageQueue::ReceiveMsg()
90 {
91     shared_ptr<Message> msg = nullptr;
92     pthread_mutex_lock(&lock_);
93     while (queue_.empty()) {
94         pthread_cond_wait(&cond_, &lock_);
95     }
96 
97     msg = queue_.front();
98     queue_.pop();
99     pthread_mutex_unlock(&lock_);
100 
101     return msg;
102 }
103 
SendMsg(shared_ptr<Message> msg)104 bool MessageQueue::SendMsg(shared_ptr<Message> msg)
105 {
106     pthread_mutex_lock(&lock_);
107     if (static_cast<uint32_t>(queue_.size()) >= size_ || msg == nullptr) {
108         INTELL_VOICE_LOG_WARN("send message failed, msg queue full(%{public}d)", static_cast<int>(queue_.size()));
109         pthread_mutex_unlock(&lock_);
110         return false;
111     }
112 
113     try {
114         queue_.push(msg);
115     } catch (const std::length_error& err) {
116         INTELL_VOICE_LOG_ERROR("messagequeue push, length error");
117         pthread_mutex_unlock(&lock_);
118         return false;
119     }
120 
121     pthread_cond_signal(&cond_);
122     pthread_mutex_unlock(&lock_);
123 
124     return true;
125 }
126 
Clear()127 void MessageQueue::Clear()
128 {
129     pthread_mutex_lock(&lock_);
130     while (!queue_.empty()) {
131         queue_.pop();
132     }
133     pthread_mutex_unlock(&lock_);
134 }
135 }
136 }
137