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