1 /* 2 * Copyright (c) 2021-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 16 /** 17 * @file safe_queue.h 18 * 19 * @brief Provides interfaces for thread-safe queue operations in c_utils. 20 * 21 * The file contains the thread-safe abstract class, the <b>SafeQueue</b> 22 * and <b>SafeStack</b> that override the virtual methods of the abstract class. 23 */ 24 25 #ifndef UTILS_BASE_SAFE_QUEUE_H 26 #define UTILS_BASE_SAFE_QUEUE_H 27 28 #include <deque> 29 #include <mutex> 30 31 namespace OHOS { 32 33 /** 34 * @brief Provides an abstract class for thread-safe queues. 35 * 36 * It encapsulates std::lock_guard locks on the basis of std::deque to 37 * make the interfaces of the queue thread-safe. 38 */ 39 template <typename T> 40 class SafeQueueInner { 41 public: SafeQueueInner()42 SafeQueueInner() {} 43 ~SafeQueueInner()44 virtual ~SafeQueueInner() 45 { 46 if (!deque_.empty()) { 47 deque_.clear(); 48 } 49 } 50 Erase(const T & object)51 void Erase(const T& object) 52 { 53 std::lock_guard<std::mutex> lock(mutex_); 54 for (auto iter = deque_.begin(); iter != deque_.end(); iter++) { 55 if (*iter == object) { 56 deque_.erase(iter); 57 break; 58 } 59 } 60 } 61 Empty()62 bool Empty() 63 { 64 std::lock_guard<std::mutex> lock(mutex_); 65 return deque_.empty(); 66 } 67 Push(const T & pt)68 void Push(const T& pt) 69 { 70 std::lock_guard<std::mutex> lock(mutex_); 71 return DoPush(pt); 72 } 73 Clear()74 void Clear() 75 { 76 std::lock_guard<std::mutex> lock(mutex_); 77 if (!deque_.empty()) { 78 deque_.clear(); 79 } 80 81 return; 82 } 83 Size()84 int Size() 85 { 86 std::lock_guard<std::mutex> lock(mutex_); 87 return deque_.size(); 88 } 89 Pop(T & pt)90 bool Pop(T& pt) 91 { 92 std::lock_guard<std::mutex> lock(mutex_); 93 return DoPop(pt); 94 } 95 96 protected: 97 virtual void DoPush(const T& pt) = 0; 98 virtual bool DoPop(T& pt) = 0; 99 100 std::deque<T> deque_; 101 std::mutex mutex_; 102 }; 103 104 /** 105 * @brief Provides thread-safe queue operations. 106 * 107 * It overrides the <b>DoPush</b> and <b>DoPop</b> methods of abstract classes 108 * to implement the push and pop functionality of <b>SafeQueue</b>. 109 */ 110 template <typename T> 111 class SafeQueue : public SafeQueueInner<T> { 112 protected: 113 using SafeQueueInner<T>::deque_; 114 using SafeQueueInner<T>::mutex_; 115 DoPush(const T & pt)116 void DoPush(const T& pt) override 117 { 118 deque_.push_back(pt); 119 } 120 121 /** 122 * @brief Encapsulates the <b>pop_front()</b> method 123 * to implement the pop function of queues. 124 */ DoPop(T & pt)125 bool DoPop(T& pt) override 126 { 127 if (deque_.size() > 0) { 128 pt = deque_.front(); 129 deque_.pop_front(); 130 return true; 131 } 132 133 return false; 134 } 135 }; 136 137 /** 138 * @brief Provides thread-safe stack operations. 139 * 140 * It overrides the <b>DoPush</b> and <b>DoPop</b> methods of abstract classes 141 * to implement the push and pop functionality of <b>SafeStack</b>. 142 */ 143 template <typename T> 144 class SafeStack : public SafeQueueInner<T> { 145 protected: 146 using SafeQueueInner<T>::deque_; 147 using SafeQueueInner<T>::mutex_; 148 DoPush(const T & pt)149 void DoPush(const T& pt) override 150 { 151 deque_.push_back(pt); 152 } 153 154 /** 155 * @brief Encapsulates the <b>pop_back()</b> method 156 * to implement the pop function of stack. 157 */ DoPop(T & pt)158 bool DoPop(T& pt) override 159 { 160 if (deque_.size() > 0) { 161 pt = deque_.back(); 162 deque_.pop_back(); 163 return true; 164 } 165 166 return false; 167 } 168 }; 169 170 } // namespace OHOS 171 #endif 172