13920e296Sopenharmony_ci/*
23920e296Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
33920e296Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43920e296Sopenharmony_ci * you may not use this file except in compliance with the License.
53920e296Sopenharmony_ci * You may obtain a copy of the License at
63920e296Sopenharmony_ci *
73920e296Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83920e296Sopenharmony_ci *
93920e296Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103920e296Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113920e296Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123920e296Sopenharmony_ci * See the License for the specific language governing permissions and
133920e296Sopenharmony_ci * limitations under the License.
143920e296Sopenharmony_ci */
153920e296Sopenharmony_ci
163920e296Sopenharmony_ci#include "thread_pool.h"
173920e296Sopenharmony_ci
183920e296Sopenharmony_ci#include "restool_errors.h"
193920e296Sopenharmony_ci#include <iostream>
203920e296Sopenharmony_ci#include <string>
213920e296Sopenharmony_ci
223920e296Sopenharmony_cinamespace OHOS {
233920e296Sopenharmony_cinamespace Global {
243920e296Sopenharmony_cinamespace Restool {
253920e296Sopenharmony_ciusing namespace std;
263920e296Sopenharmony_ci
273920e296Sopenharmony_ciThreadPool::ThreadPool(size_t threadCount) : threadCount_(threadCount)
283920e296Sopenharmony_ci{}
293920e296Sopenharmony_ci
303920e296Sopenharmony_ciuint32_t ThreadPool::Start()
313920e296Sopenharmony_ci{
323920e296Sopenharmony_ci    if (!workerThreads_.empty() || threadCount_ <= 0) {
333920e296Sopenharmony_ci        cerr << "Error: ThreadPool start failed." << endl;
343920e296Sopenharmony_ci        return RESTOOL_ERROR;
353920e296Sopenharmony_ci    }
363920e296Sopenharmony_ci    running_ = true;
373920e296Sopenharmony_ci    workerThreads_.reserve(threadCount_);
383920e296Sopenharmony_ci    for (size_t i = 0; i < threadCount_; ++i) {
393920e296Sopenharmony_ci        workerThreads_.emplace_back([this] { this->WorkInThread(); });
403920e296Sopenharmony_ci    }
413920e296Sopenharmony_ci    cout << "Info: thread pool is started" << endl;
423920e296Sopenharmony_ci    return RESTOOL_SUCCESS;
433920e296Sopenharmony_ci}
443920e296Sopenharmony_ci
453920e296Sopenharmony_civoid ThreadPool::Stop()
463920e296Sopenharmony_ci{
473920e296Sopenharmony_ci    {
483920e296Sopenharmony_ci        std::unique_lock<std::mutex> lock(queueMutex_);
493920e296Sopenharmony_ci        running_ = false;
503920e296Sopenharmony_ci    }
513920e296Sopenharmony_ci    condition_.notify_all();
523920e296Sopenharmony_ci    for (std::thread &worker : workerThreads_) {
533920e296Sopenharmony_ci        if (worker.joinable()) {
543920e296Sopenharmony_ci            worker.join();
553920e296Sopenharmony_ci        }
563920e296Sopenharmony_ci    }
573920e296Sopenharmony_ci    cout << "Info: thread pool is stopped" << endl;
583920e296Sopenharmony_ci}
593920e296Sopenharmony_ci
603920e296Sopenharmony_ci
613920e296Sopenharmony_ciThreadPool::~ThreadPool()
623920e296Sopenharmony_ci{
633920e296Sopenharmony_ci    if (running_) {
643920e296Sopenharmony_ci        Stop();
653920e296Sopenharmony_ci    }
663920e296Sopenharmony_ci}
673920e296Sopenharmony_ci
683920e296Sopenharmony_civoid ThreadPool::WorkInThread()
693920e296Sopenharmony_ci{
703920e296Sopenharmony_ci    while (this->running_) {
713920e296Sopenharmony_ci        std::function<void()> task;
723920e296Sopenharmony_ci        {
733920e296Sopenharmony_ci            std::unique_lock<std::mutex> lock(this->queueMutex_);
743920e296Sopenharmony_ci            // wake up when there's a task or when the pool is stopped
753920e296Sopenharmony_ci            this->condition_.wait(lock, [this] { return !this->running_ || !this->tasks_.empty(); });
763920e296Sopenharmony_ci            if (!this->running_) {
773920e296Sopenharmony_ci                // exit thread when the pool is stopped
783920e296Sopenharmony_ci                return;
793920e296Sopenharmony_ci            }
803920e296Sopenharmony_ci            if (!this->tasks_.empty()) {
813920e296Sopenharmony_ci                task = std::move(this->tasks_.front());
823920e296Sopenharmony_ci                this->tasks_.pop();
833920e296Sopenharmony_ci            }
843920e296Sopenharmony_ci        }
853920e296Sopenharmony_ci        if (task) {
863920e296Sopenharmony_ci            task();
873920e296Sopenharmony_ci        }
883920e296Sopenharmony_ci    }
893920e296Sopenharmony_ci}
903920e296Sopenharmony_ci} // namespace Restool
913920e296Sopenharmony_ci} // namespace Global
923920e296Sopenharmony_ci} // namespace OHOS
93