• 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(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