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
20using namespace std;
21
22namespace OHOS {
23namespace IntellVoiceUtils {
24Message::Message(uint32_t what) : what_(what), arg1_(0), arg2_(0)
25{
26}
27
28Message::Message(uint32_t what, int32_t arg1) : what_(what), arg1_(arg1)
29{
30}
31
32Message::Message(uint32_t what, int32_t arg1, int32_t arg2, float arg3)
33    : what_(what), arg1_(arg1), arg2_(arg2), arg3_(arg3)
34{
35}
36
37Message::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
42Message::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
47Message::Message(uint32_t what, std::shared_ptr<void> obj2) : what_(what), obj2_(obj2)
48{
49}
50
51Message::Message(uint32_t what, std::shared_ptr<void> obj2, std::shared_ptr<void> obj3)
52    : what_(what), obj2_(obj2), obj3_(obj3)
53{
54}
55
56Message::Message(uint32_t what, void* voidPtr) : what_(what), voidPtr_(voidPtr)
57{
58}
59
60Message::Message(uint32_t what, int32_t arg1, void* voidPtr) : what_(what), arg1_(arg1), voidPtr_(voidPtr)
61{
62}
63
64Message::~Message()
65{
66    voidPtr_ = nullptr;
67}
68
69MessageQueue::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
80MessageQueue::~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
89shared_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
104bool 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
127void 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