1/*
2 * Copyright (c) 2021-2024 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#ifndef OHOS_RESTOOL_THREAD_POOL_H
17#define OHOS_RESTOOL_THREAD_POOL_H
18
19#include <condition_variable>
20#include <functional>
21#include <future>
22#include <mutex>
23#include <queue>
24#include <string>
25#include <thread>
26#include <vector>
27
28namespace OHOS {
29namespace Global {
30namespace Restool {
31class ThreadPool {
32public:
33    /**
34     * @brief Creates a thread pool with specify thread count
35     * @param threadCount the count of threads to be created
36     */
37    explicit ThreadPool(const size_t threadCount);
38    ~ThreadPool();
39
40    /**
41     * @brief Start the thread pool
42     */
43    uint32_t Start();
44
45    /**
46     * @brief Stop the thread pool
47     */
48    void Stop();
49
50    /**
51     * @brief Enqueue a task to queue of thread pool
52     * @param f the function to execute
53     * @param args the args of the function
54     */
55    template <class F, class... Args>
56    std::future<typename std::result_of<F(Args...)>::type> Enqueue(F &&f, Args &&...args);
57
58private:
59    void WorkInThread();
60    std::vector<std::thread> workerThreads_;
61    std::queue<std::function<void()>> tasks_;
62
63    std::mutex queueMutex_;
64    std::condition_variable condition_;
65    bool running_{ false };
66    size_t threadCount_;
67};
68
69template <typename F, typename... Args>
70std::future<typename std::result_of<F(Args...)>::type> ThreadPool::Enqueue(F &&f, Args &&...args)
71{
72    using return_type = typename std::result_of<F(Args...)>::type;
73    using p_task = std::packaged_task<return_type()>;
74    auto task = std::make_shared<p_task>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
75
76    std::future<return_type> res = task->get_future();
77    {
78        std::unique_lock<std::mutex> lock(queueMutex_);
79        tasks_.emplace([task]() { (*task)(); });
80    }
81    condition_.notify_one();
82    return res;
83}
84} // namespace Restool
85} // namespace Global
86} // namespace OHOS
87#endif
88