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