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