• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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