13f4cbf05Sopenharmony_ci/* 23f4cbf05Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 33f4cbf05Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43f4cbf05Sopenharmony_ci * you may not use this file except in compliance with the License. 53f4cbf05Sopenharmony_ci * You may obtain a copy of the License at 63f4cbf05Sopenharmony_ci * 73f4cbf05Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83f4cbf05Sopenharmony_ci * 93f4cbf05Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103f4cbf05Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113f4cbf05Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123f4cbf05Sopenharmony_ci * See the License for the specific language governing permissions and 133f4cbf05Sopenharmony_ci * limitations under the License. 143f4cbf05Sopenharmony_ci */ 153f4cbf05Sopenharmony_ci 163f4cbf05Sopenharmony_ci/** 173f4cbf05Sopenharmony_ci * @file safe_queue.h 183f4cbf05Sopenharmony_ci * 193f4cbf05Sopenharmony_ci * @brief Provides interfaces for thread-safe queue operations in c_utils. 203f4cbf05Sopenharmony_ci * 213f4cbf05Sopenharmony_ci * The file contains the thread-safe abstract class, the <b>SafeQueue</b> 223f4cbf05Sopenharmony_ci * and <b>SafeStack</b> that override the virtual methods of the abstract class. 233f4cbf05Sopenharmony_ci */ 243f4cbf05Sopenharmony_ci 253f4cbf05Sopenharmony_ci#ifndef UTILS_BASE_SAFE_QUEUE_H 263f4cbf05Sopenharmony_ci#define UTILS_BASE_SAFE_QUEUE_H 273f4cbf05Sopenharmony_ci 283f4cbf05Sopenharmony_ci#include <deque> 293f4cbf05Sopenharmony_ci#include <mutex> 303f4cbf05Sopenharmony_ci 313f4cbf05Sopenharmony_cinamespace OHOS { 323f4cbf05Sopenharmony_ci 333f4cbf05Sopenharmony_ci/** 343f4cbf05Sopenharmony_ci * @brief Provides an abstract class for thread-safe queues. 353f4cbf05Sopenharmony_ci * 363f4cbf05Sopenharmony_ci * It encapsulates std::lock_guard locks on the basis of std::deque to 373f4cbf05Sopenharmony_ci * make the interfaces of the queue thread-safe. 383f4cbf05Sopenharmony_ci */ 393f4cbf05Sopenharmony_citemplate <typename T> 403f4cbf05Sopenharmony_ciclass SafeQueueInner { 413f4cbf05Sopenharmony_cipublic: 423f4cbf05Sopenharmony_ci SafeQueueInner() {} 433f4cbf05Sopenharmony_ci 443f4cbf05Sopenharmony_ci virtual ~SafeQueueInner() 453f4cbf05Sopenharmony_ci { 463f4cbf05Sopenharmony_ci if (!deque_.empty()) { 473f4cbf05Sopenharmony_ci deque_.clear(); 483f4cbf05Sopenharmony_ci } 493f4cbf05Sopenharmony_ci } 503f4cbf05Sopenharmony_ci 513f4cbf05Sopenharmony_ci void Erase(const T& object) 523f4cbf05Sopenharmony_ci { 533f4cbf05Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 543f4cbf05Sopenharmony_ci for (auto iter = deque_.begin(); iter != deque_.end(); iter++) { 553f4cbf05Sopenharmony_ci if (*iter == object) { 563f4cbf05Sopenharmony_ci deque_.erase(iter); 573f4cbf05Sopenharmony_ci break; 583f4cbf05Sopenharmony_ci } 593f4cbf05Sopenharmony_ci } 603f4cbf05Sopenharmony_ci } 613f4cbf05Sopenharmony_ci 623f4cbf05Sopenharmony_ci bool Empty() 633f4cbf05Sopenharmony_ci { 643f4cbf05Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 653f4cbf05Sopenharmony_ci return deque_.empty(); 663f4cbf05Sopenharmony_ci } 673f4cbf05Sopenharmony_ci 683f4cbf05Sopenharmony_ci void Push(const T& pt) 693f4cbf05Sopenharmony_ci { 703f4cbf05Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 713f4cbf05Sopenharmony_ci return DoPush(pt); 723f4cbf05Sopenharmony_ci } 733f4cbf05Sopenharmony_ci 743f4cbf05Sopenharmony_ci void Clear() 753f4cbf05Sopenharmony_ci { 763f4cbf05Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 773f4cbf05Sopenharmony_ci if (!deque_.empty()) { 783f4cbf05Sopenharmony_ci deque_.clear(); 793f4cbf05Sopenharmony_ci } 803f4cbf05Sopenharmony_ci 813f4cbf05Sopenharmony_ci return; 823f4cbf05Sopenharmony_ci } 833f4cbf05Sopenharmony_ci 843f4cbf05Sopenharmony_ci int Size() 853f4cbf05Sopenharmony_ci { 863f4cbf05Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 873f4cbf05Sopenharmony_ci return deque_.size(); 883f4cbf05Sopenharmony_ci } 893f4cbf05Sopenharmony_ci 903f4cbf05Sopenharmony_ci bool Pop(T& pt) 913f4cbf05Sopenharmony_ci { 923f4cbf05Sopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 933f4cbf05Sopenharmony_ci return DoPop(pt); 943f4cbf05Sopenharmony_ci } 953f4cbf05Sopenharmony_ci 963f4cbf05Sopenharmony_ciprotected: 973f4cbf05Sopenharmony_ci virtual void DoPush(const T& pt) = 0; 983f4cbf05Sopenharmony_ci virtual bool DoPop(T& pt) = 0; 993f4cbf05Sopenharmony_ci 1003f4cbf05Sopenharmony_ci std::deque<T> deque_; 1013f4cbf05Sopenharmony_ci std::mutex mutex_; 1023f4cbf05Sopenharmony_ci}; 1033f4cbf05Sopenharmony_ci 1043f4cbf05Sopenharmony_ci/** 1053f4cbf05Sopenharmony_ci * @brief Provides thread-safe queue operations. 1063f4cbf05Sopenharmony_ci * 1073f4cbf05Sopenharmony_ci * It overrides the <b>DoPush</b> and <b>DoPop</b> methods of abstract classes 1083f4cbf05Sopenharmony_ci * to implement the push and pop functionality of <b>SafeQueue</b>. 1093f4cbf05Sopenharmony_ci */ 1103f4cbf05Sopenharmony_citemplate <typename T> 1113f4cbf05Sopenharmony_ciclass SafeQueue : public SafeQueueInner<T> { 1123f4cbf05Sopenharmony_ciprotected: 1133f4cbf05Sopenharmony_ci using SafeQueueInner<T>::deque_; 1143f4cbf05Sopenharmony_ci using SafeQueueInner<T>::mutex_; 1153f4cbf05Sopenharmony_ci 1163f4cbf05Sopenharmony_ci void DoPush(const T& pt) override 1173f4cbf05Sopenharmony_ci { 1183f4cbf05Sopenharmony_ci deque_.push_back(pt); 1193f4cbf05Sopenharmony_ci } 1203f4cbf05Sopenharmony_ci 1213f4cbf05Sopenharmony_ci/** 1223f4cbf05Sopenharmony_ci * @brief Encapsulates the <b>pop_front()</b> method 1233f4cbf05Sopenharmony_ci * to implement the pop function of queues. 1243f4cbf05Sopenharmony_ci */ 1253f4cbf05Sopenharmony_ci bool DoPop(T& pt) override 1263f4cbf05Sopenharmony_ci { 1273f4cbf05Sopenharmony_ci if (deque_.size() > 0) { 1283f4cbf05Sopenharmony_ci pt = deque_.front(); 1293f4cbf05Sopenharmony_ci deque_.pop_front(); 1303f4cbf05Sopenharmony_ci return true; 1313f4cbf05Sopenharmony_ci } 1323f4cbf05Sopenharmony_ci 1333f4cbf05Sopenharmony_ci return false; 1343f4cbf05Sopenharmony_ci } 1353f4cbf05Sopenharmony_ci}; 1363f4cbf05Sopenharmony_ci 1373f4cbf05Sopenharmony_ci/** 1383f4cbf05Sopenharmony_ci * @brief Provides thread-safe stack operations. 1393f4cbf05Sopenharmony_ci * 1403f4cbf05Sopenharmony_ci * It overrides the <b>DoPush</b> and <b>DoPop</b> methods of abstract classes 1413f4cbf05Sopenharmony_ci * to implement the push and pop functionality of <b>SafeStack</b>. 1423f4cbf05Sopenharmony_ci */ 1433f4cbf05Sopenharmony_citemplate <typename T> 1443f4cbf05Sopenharmony_ciclass SafeStack : public SafeQueueInner<T> { 1453f4cbf05Sopenharmony_ciprotected: 1463f4cbf05Sopenharmony_ci using SafeQueueInner<T>::deque_; 1473f4cbf05Sopenharmony_ci using SafeQueueInner<T>::mutex_; 1483f4cbf05Sopenharmony_ci 1493f4cbf05Sopenharmony_ci void DoPush(const T& pt) override 1503f4cbf05Sopenharmony_ci { 1513f4cbf05Sopenharmony_ci deque_.push_back(pt); 1523f4cbf05Sopenharmony_ci } 1533f4cbf05Sopenharmony_ci 1543f4cbf05Sopenharmony_ci/** 1553f4cbf05Sopenharmony_ci * @brief Encapsulates the <b>pop_back()</b> method 1563f4cbf05Sopenharmony_ci * to implement the pop function of stack. 1573f4cbf05Sopenharmony_ci */ 1583f4cbf05Sopenharmony_ci bool DoPop(T& pt) override 1593f4cbf05Sopenharmony_ci { 1603f4cbf05Sopenharmony_ci if (deque_.size() > 0) { 1613f4cbf05Sopenharmony_ci pt = deque_.back(); 1623f4cbf05Sopenharmony_ci deque_.pop_back(); 1633f4cbf05Sopenharmony_ci return true; 1643f4cbf05Sopenharmony_ci } 1653f4cbf05Sopenharmony_ci 1663f4cbf05Sopenharmony_ci return false; 1673f4cbf05Sopenharmony_ci } 1683f4cbf05Sopenharmony_ci}; 1693f4cbf05Sopenharmony_ci 1703f4cbf05Sopenharmony_ci} // namespace OHOS 1713f4cbf05Sopenharmony_ci#endif 172