1 /* 2 * Copyright (c) 2021 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 #include "thread_pool.h" 17 #include "errors.h" 18 19 #include <memory> 20 21 namespace OHOS { 22 ThreadPool(const std::string & name)23ThreadPool::ThreadPool(const std::string& name) 24 : myName_(name), maxTaskNum_(0), running_(false) 25 { 26 } 27 ~ThreadPool()28ThreadPool::~ThreadPool() 29 { 30 if (running_) { 31 Stop(); 32 } 33 } 34 Start(int numThreads)35uint32_t ThreadPool::Start(int numThreads) 36 { 37 if (!threads_.empty()) { 38 return ERR_INVALID_OPERATION; 39 } 40 41 if (numThreads <= 0) { 42 return ERR_INVALID_VALUE; 43 } 44 running_ = true; 45 threads_.reserve(numThreads); 46 47 for (int i = 0; i < numThreads; ++i) { 48 threads_.push_back(std::thread(&ThreadPool::WorkInThread,this)); 49 } 50 return ERR_OK; 51 } 52 Stop()53void ThreadPool::Stop() 54 { 55 { 56 std::unique_lock<std::mutex> lock(mutex_); 57 running_ = false; 58 hasTaskToDo_.notify_all(); 59 } 60 61 for (auto& e : threads_) { 62 e.join(); 63 } 64 } 65 AddTask(const Task & f)66void ThreadPool::AddTask(const Task &f) 67 { 68 if (threads_.empty()) { 69 f(); 70 } else { 71 std::unique_lock<std::mutex> lock(mutex_); 72 while (Overloaded()) { 73 acceptNewTask_.wait(lock); 74 } 75 76 tasks_.push_back(f); 77 hasTaskToDo_.notify_one(); 78 } 79 } 80 GetCurTaskNum()81size_t ThreadPool::GetCurTaskNum() 82 { 83 std::unique_lock<std::mutex> lock(mutex_); 84 return tasks_.size(); 85 } 86 87 ScheduleTask()88ThreadPool::Task ThreadPool::ScheduleTask() 89 { 90 std::unique_lock<std::mutex> lock(mutex_); 91 while (tasks_.empty() && running_) { 92 hasTaskToDo_.wait(lock); 93 } 94 95 Task task; 96 if (!tasks_.empty()) { 97 task = tasks_.front(); 98 tasks_.pop_front(); 99 100 if (maxTaskNum_ > 0) { 101 acceptNewTask_.notify_one(); 102 } 103 } 104 return task; 105 } 106 Overloaded() const107bool ThreadPool::Overloaded() const 108 { 109 return (maxTaskNum_ > 0) && (tasks_.size() >= maxTaskNum_); 110 } 111 WorkInThread()112void ThreadPool::WorkInThread() 113 { 114 while (running_) { 115 Task task = ScheduleTask(); 116 if (task) { 117 task(); 118 } 119 } 120 } 121 122 } // namespace OHOS 123