Coverage Report

Created: 2023-12-08 07:00

/src/botan/build/include/botan/internal/thread_pool.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
* (C) 2019 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6
7
#ifndef BOTAN_THREAD_POOL_H_
8
#define BOTAN_THREAD_POOL_H_
9
10
#include <botan/types.h>
11
#include <condition_variable>
12
#include <deque>
13
#include <functional>
14
#include <future>
15
#include <memory>
16
#include <mutex>
17
#include <optional>
18
#include <thread>
19
#include <type_traits>
20
#include <utility>
21
#include <vector>
22
23
namespace Botan {
24
25
class BOTAN_TEST_API Thread_Pool final {
26
   public:
27
      /**
28
      * Return an instance to a shared thread pool
29
      */
30
      static Thread_Pool& global_instance();
31
32
      /**
33
      * Initialize a thread pool with some number of threads
34
      * @param pool_size number of threads in the pool, if 0
35
      *        then some default value is chosen. If the optional
36
      *        is nullopt then the thread pool is disabled; all
37
      *        work is executed immediately when queued.
38
      */
39
      Thread_Pool(std::optional<size_t> pool_size);
40
41
      /**
42
      * Initialize a thread pool with some number of threads
43
      * @param pool_size number of threads in the pool, if 0
44
      *        then some default value is chosen.
45
      */
46
0
      Thread_Pool(size_t pool_size = 0) : Thread_Pool(std::optional<size_t>(pool_size)) {}
47
48
0
      ~Thread_Pool() { shutdown(); }
49
50
      void shutdown();
51
52
0
      size_t worker_count() const { return m_workers.size(); }
53
54
      Thread_Pool(const Thread_Pool&) = delete;
55
      Thread_Pool& operator=(const Thread_Pool&) = delete;
56
57
      Thread_Pool(Thread_Pool&&) = delete;
58
      Thread_Pool& operator=(Thread_Pool&&) = delete;
59
60
      /*
61
      * Enqueue some work
62
      */
63
      void queue_thunk(const std::function<void()>&);
64
65
      template <class F, class... Args>
66
0
      auto run(F&& f, Args&&... args) -> std::future<typename std::invoke_result<F, Args...>::type> {
67
0
         using return_type = typename std::invoke_result<F, Args...>::type;
68
69
0
         auto future_work = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
70
0
         auto task = std::make_shared<std::packaged_task<return_type()>>(future_work);
71
0
         auto future_result = task->get_future();
72
0
         queue_thunk([task]() { (*task)(); });
73
0
         return future_result;
74
0
      }
75
76
   private:
77
      void worker_thread();
78
79
      // Only touched in constructor and destructor
80
      std::vector<std::thread> m_workers;
81
82
      std::mutex m_mutex;
83
      std::condition_variable m_more_tasks;
84
      std::deque<std::function<void()>> m_tasks;
85
      bool m_shutdown;
86
};
87
88
}  // namespace Botan
89
90
#endif