diff --git a/base/include/safe_block_queue.h b/base/include/safe_block_queue.h index 146877fa505896011f05050ca69abac2f6f03a03..80f0dbc49a60115260263f1787e8dde14e40f5b1 100644 --- a/base/include/safe_block_queue.h +++ b/base/include/safe_block_queue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,6 +13,14 @@ * limitations under the License. */ +/** + * @file safe_block_queue.h + * + * The file contains interfaces of Thread-safe block queues in c_utils. + * Includes the SafeBlockQueue class, and the SafeBlockQueueTracking class + * for trackable tasks. + */ + #ifndef UTILS_BASE_BLOCK_QUEUE_H #define UTILS_BASE_BLOCK_QUEUE_H @@ -24,6 +32,11 @@ namespace OHOS { +/** + * @brief Thread-safe blocking queues. + * + * Provides blocking and non-blocking push and pop interfaces. + */ template class SafeBlockQueue { public: @@ -31,6 +44,15 @@ public: { } +/** + * @brief Insert an element at the end of the queue (blocking). + * + * When the queue is full, the thread of the push operation will be blocked. + * When the queue is not full, the push operation can be executed + * and wakes up one of the waiting threads. + * + * @param elem Enqueue data. + */ virtual void Push(T const& elem) { std::unique_lock lock(mutexLock_); @@ -44,6 +66,14 @@ public: cvNotEmpty_.notify_one(); } +/** + * @brief Get the first element of the queue (blocking). + * + * When the queue is empty, the thread of the pop operation will be blocked. + * When the queue is not empty, the pop operation can be executed + * and wakes up one of the waiting threads. Then return the first element + * of the queue. + */ T Pop() { std::unique_lock lock(mutexLock_); @@ -59,6 +89,16 @@ public: return elem; } +/** + * @brief Insert an element at the end of queue (Non-blocking). + * + * When the queue is full, the thread of the push operation + * will directly return false. + * When the queue is not full, the push operation can be executed + * and wakes up one of the waiting threads, and return true. + * + * @param elem Enqueue data. + */ virtual bool PushNoWait(T const& elem) { std::unique_lock lock(mutexLock_); @@ -71,6 +111,16 @@ public: return true; } +/** + * @brief Get the first elements of the queue (Non-blocking). + * + * When the queue is empty, the thread of the pop operation + * will directly return false. + * When the queue is not empty, the pop operation can be executed + * and wakes up one of the waiting threads, and return true. + * + * @param outtask data of pop. + */ bool PopNotWait(T& outtask) { std::unique_lock lock(mutexLock_); @@ -106,13 +156,17 @@ public: virtual ~SafeBlockQueue() {} protected: - unsigned long maxSize_; + unsigned long maxSize_; // capacity of queue std::mutex mutexLock_; std::condition_variable cvNotEmpty_; std::condition_variable cvNotFull_; std::queue queueT_; }; +/** + * @brief A thread-safe blocking queue that inherits SafeBlockQueue + * and tracks the number of outstanding tasks. + */ template class SafeBlockQueueTracking : public SafeBlockQueue { public: @@ -123,6 +177,13 @@ public: virtual ~SafeBlockQueueTracking() {} +/** + * @brief Insert an element at the end of queue (blocking). + * + * When the queue is full, the thread of the push operation will be blocked. + * When the queue is not full, the push operation can be executed + * and wakes up one of the waiting threads. + */ virtual void Push(T const& elem) { unfinishedTaskCount_++; @@ -138,6 +199,14 @@ public: cvNotEmpty_.notify_one(); } +/** + * @brief Insert an element at the end of queue (Non-blocking). + * + * When the queue is full, the thread of the push operation + * will directly return false. + * When the queue is not full, the push operation can be executed + * and wakes up one of the waiting threads, and return true. + */ virtual bool PushNoWait(T const& elem) { std::unique_lock lock(mutexLock_); @@ -151,6 +220,16 @@ public: return true; } +/** + * @brief A response function when a task completes. + * + * If the count of unfinished task < 1, return false directly. + * If the count of unfinished task = 1, all threads waiting + * while calling Join() will be woken up; + * the count of unfinished task decrements by 1 and returns true. + * If the count of unfinished task > 1, + * decrements the count by 1 and returns true. + */ bool OneTaskDone() { std::unique_lock lock(mutexLock_); @@ -167,12 +246,21 @@ public: return true; } +/** + * @brief Wait for all tasks to complete. + * + * When anyone of the tasks is not completed, the current thread will be + * blocked even if it is just woken up. + */ void Join() { std::unique_lock lock(mutexLock_); cvAllTasksDone_.wait(lock, [&] { return unfinishedTaskCount_ == 0; }); } +/** + * @brief Returns the number of unfinished tasks. + */ int GetUnfinishTaskNum() { return unfinishedTaskCount_;