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 113 protected: 114 using SafeQueueInner<T>::deque_; 115 using SafeQueueInner<T>::mutex_; 116 DoPush(const T & pt)117 void DoPush(const T& pt) override 118 { 119 deque_.push_back(pt); 120 } 121 122 /** 123 * @brief Encapsulates the <b>pop_front()</b> method 124 * to implement the pop function of queues. 125 */ DoPop(T & pt)126 bool DoPop(T& pt) override 127 { 128 if (deque_.size() > 0) { 129 pt = deque_.front(); 130 deque_.pop_front(); 131 return true; 132 } 133 134 return false; 135 } 136 }; 137 138 /** 139 * @brief Provides thread-safe stack operations. 140 * 141 * It overrides the <b>DoPush</b> and <b>DoPop</b> methods of abstract classes 142 * to implement the push and pop functionality of <b>SafeStack</b>. 143 */ 144 template <typename T> 145 class SafeStack : public SafeQueueInner<T> { 146 147 protected: 148 using SafeQueueInner<T>::deque_; 149 using SafeQueueInner<T>::mutex_; 150 DoPush(const T & pt)151 void DoPush(const T& pt) override 152 { 153 deque_.push_back(pt); 154 } 155 156 /** 157 * @brief Encapsulates the <b>pop_back()</b> method 158 * to implement the pop function of stack. 159 */ DoPop(T & pt)160 bool DoPop(T& pt) override 161 { 162 if (deque_.size() > 0) { 163 pt = deque_.back(); 164 deque_.pop_back(); 165 return true; 166 } 167 168 return false; 169 } 170 }; 171 172 } // namespace OHOS 173 #endif 174