LCOV - code coverage report
Current view: top level - lunchbox - threadPool.ipp (source / functions) Hit Total Coverage
Test: Lunchbox Lines: 42 42 100.0 %
Date: 2017-08-03 05:21:41 Functions: 21 24 87.5 %

          Line data    Source code
       1             : /* Copyright (c) 2016-2017, Mohamed-Ghaith Kaabi <mohamedghaith.kaabi@gmail.com>
       2             :  *
       3             :  * This library is free software; you can redistribute it and/or modify it under
       4             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       5             :  * by the Free Software Foundation.
       6             :  *
       7             :  * This library is distributed in the hope that it will be useful, but WITHOUT
       8             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
       9             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      10             :  * details.
      11             :  *
      12             :  * You should have received a copy of the GNU Lesser General Public License
      13             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      14             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      15             :  */
      16             : 
      17             : namespace lunchbox
      18             : {
      19           4 : ThreadPool::ThreadPool(const size_t size)
      20           4 :     : _stop(false)
      21             : {
      22          16 :     for (size_t i = 0; i < size; ++i)
      23          24 :         _threads.emplace_back([this] { this->work(); });
      24           4 : }
      25             : 
      26           8 : ThreadPool::~ThreadPool()
      27             : {
      28             :     {
      29           8 :         std::unique_lock<std::mutex> lock(_mutex);
      30           4 :         _stop = true;
      31           4 :         _condition.notify_all();
      32             :     }
      33           4 :     joinAll();
      34           4 : }
      35             : 
      36           1 : size_t ThreadPool::getSize() const
      37             : {
      38           1 :     return _threads.size();
      39             : }
      40             : 
      41             : template <typename F>
      42         111 : std::future<typename std::result_of<F()>::type> ThreadPool::post(F&& f)
      43             : {
      44             :     using ReturnType = typename std::result_of<F()>::type;
      45             : 
      46             :     auto task =
      47         222 :         std::make_shared<std::packaged_task<ReturnType()> >(std::forward<F>(f));
      48             : 
      49         111 :     auto res = task->get_future();
      50             :     {
      51         222 :         std::unique_lock<std::mutex> lock(_mutex);
      52         681 :         _tasks.emplace([task]() { (*task)(); });
      53             :     }
      54         111 :     _condition.notify_one();
      55         222 :     return res;
      56             : }
      57             : 
      58             : template <typename F>
      59          10 : void ThreadPool::postDetached(F&& f)
      60             : {
      61             :     {
      62          20 :         std::unique_lock<std::mutex> lock(_mutex);
      63          10 :         _tasks.emplace(f);
      64             :     }
      65          10 :     _condition.notify_one();
      66          10 : }
      67             : 
      68           2 : bool ThreadPool::hasPendingJobs() const
      69             : {
      70           4 :     std::unique_lock<std::mutex> lock(_mutex);
      71           4 :     return !_tasks.empty();
      72             : }
      73             : 
      74           4 : void ThreadPool::joinAll()
      75             : {
      76          16 :     for (auto& thread : _threads)
      77          12 :         thread.join();
      78           4 : }
      79             : 
      80          37 : void ThreadPool::work()
      81             : {
      82             :     for (;;)
      83             :     {
      84          62 :         std::function<void()> task;
      85             :         {
      86          62 :             std::unique_lock<std::mutex> lock(_mutex);
      87          90 :             _condition.wait(lock, [this] { return _stop || !_tasks.empty(); });
      88          37 :             if (_stop)
      89          24 :                 return;
      90          25 :             task = std::move(_tasks.front());
      91          25 :             _tasks.pop();
      92             :         }
      93          25 :         task();
      94          25 :     }
      95             : }
      96             : }

Generated by: LCOV version 1.11