LCOV - code coverage report
Current view: top level - lunchbox - threadPool.h (source / functions) Hit Total Coverage
Test: Lunchbox Lines: 12 12 100.0 %
Date: 2018-10-03 05:33:11 Functions: 13 16 81.2 %

          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             : #pragma once
      18             : 
      19             : #include <lunchbox/api.h>
      20             : 
      21             : #include <condition_variable> // member
      22             : #include <functional>
      23             : #include <future> // inline return value
      24             : #include <queue>  // member
      25             : #include <thread> // member
      26             : #include <vector> // member
      27             : 
      28             : namespace lunchbox
      29             : {
      30             : /**
      31             :  * Thread pool for tasks execution.
      32             :  * A task is a callable object taking no arguments and returing a value or void.
      33             :  * All the member methods are thread safe.
      34             :  *
      35             :  * Example: @include tests/threadPool.cpp
      36             :  */
      37             : class ThreadPool
      38             : {
      39             : public:
      40             :     /** @return the application-global thread pool. */
      41             :     static LUNCHBOX_API ThreadPool& getInstance();
      42             : 
      43             :     /**
      44             :      * Construct a new ThreadPool.
      45             :      *
      46             :      * @param size number of threads in the thread pool
      47             :      * @sa getInstance() for the recommended thread pool.
      48             :      */
      49             :     LUNCHBOX_API ThreadPool(const size_t size);
      50             :     /**
      51             :      * Destroy this thread pool.
      52             :      * Will block until all the tasks are done.
      53             :      */
      54             :     LUNCHBOX_API ~ThreadPool();
      55             : 
      56             :     /**
      57             :      * @return the number of threads used in the thread pool
      58             :      */
      59             :     LUNCHBOX_API size_t getSize() const;
      60             : 
      61             :     /**
      62             :      * Post a new task in the thread pool.
      63             :      * @return a std::future containing the future result.
      64             :      */
      65             :     template <typename F>
      66             :     inline std::future<typename std::result_of<F()>::type> post(F&& f);
      67             : 
      68             :     /**
      69             :      * Post a detached task in the thread pool.
      70             :      * The result of this task is not monitored.
      71             :      */
      72             :     template <typename F>
      73             :     inline void postDetached(F&& f);
      74             : 
      75             :     /** @return true if there are pending tasks to be executed. */
      76             :     LUNCHBOX_API bool hasPendingJobs() const;
      77             : 
      78             : private:
      79             :     ThreadPool(const ThreadPool&) = delete;
      80             :     ThreadPool(ThreadPool&&) = delete;
      81             :     ThreadPool& operator=(const ThreadPool&) = delete;
      82             :     ThreadPool& operator=(ThreadPool&&) = delete;
      83             : 
      84             :     LUNCHBOX_API void joinAll();
      85             :     LUNCHBOX_API void work();
      86             : 
      87             :     std::vector<std::thread> _threads;
      88             :     std::queue<std::function<void()> > _tasks;
      89             :     mutable std::mutex _mutex;
      90             :     std::condition_variable _condition;
      91             :     bool _stop;
      92             : };
      93             : 
      94             : template <typename F>
      95         133 : std::future<typename std::result_of<F()>::type> ThreadPool::post(F&& f)
      96             : {
      97             :     using ReturnType = typename std::result_of<F()>::type;
      98             : 
      99             :     auto task =
     100         266 :         std::make_shared<std::packaged_task<ReturnType()> >(std::forward<F>(f));
     101             : 
     102         133 :     auto res = task->get_future();
     103             :     {
     104         266 :         std::unique_lock<std::mutex> lock(_mutex);
     105         835 :         _tasks.emplace([task]() { (*task)(); });
     106             :     }
     107         133 :     _condition.notify_one();
     108         266 :     return res;
     109             : }
     110             : 
     111             : template <typename F>
     112          10 : void ThreadPool::postDetached(F&& f)
     113             : {
     114             :     {
     115          20 :         std::unique_lock<std::mutex> lock(_mutex);
     116          10 :         _tasks.emplace(f);
     117             :     }
     118          10 :     _condition.notify_one();
     119          10 : }
     120             : }

Generated by: LCOV version 1.11