Coverage Report

Created: 2025-04-11 06:34

/src/botan/build/include/internal/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)(); });
Unexecuted instantiation: rsa.cpp:Botan::Thread_Pool::run<Botan::(anonymous namespace)::RSA_Private_Operation::rsa_private_op(Botan::BigInt const&) const::{lambda()#1}>(Botan::(anonymous namespace)::RSA_Private_Operation::rsa_private_op(Botan::BigInt const&) const::{lambda()#1}::invoke_result&&, (Botan::(anonymous namespace)::RSA_Private_Operation::rsa_private_op(Botan::BigInt const&) const::{lambda()#1}&&)...)::{lambda()#1}::operator()() const
Unexecuted instantiation: Botan::Thread_Pool::run<void (Botan::XMSS_PrivateKey::*&)(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, unsigned long, unsigned long, Botan::XMSS_Address&, Botan::XMSS_Hash&), Botan::XMSS_PrivateKey*, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > >, unsigned long, unsigned long, std::__1::reference_wrapper<Botan::XMSS_Address>, std::__1::reference_wrapper<Botan::XMSS_Hash> >(void (Botan::XMSS_PrivateKey::*&)(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, unsigned long, unsigned long, Botan::XMSS_Address&, Botan::XMSS_Hash&), Botan::XMSS_PrivateKey*&&, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > >&&, unsigned long&&, unsigned long&&, std::__1::reference_wrapper<Botan::XMSS_Address>&&, std::__1::reference_wrapper<Botan::XMSS_Hash>&&)::{lambda()#1}::operator()() const
Unexecuted instantiation: Botan::Thread_Pool::run<void (*)(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, Botan::XMSS_Address&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, Botan::XMSS_Hash&, Botan::XMSS_Parameters const&), std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > >, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>, std::__1::reference_wrapper<Botan::XMSS_Address>, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>, std::__1::reference_wrapper<Botan::XMSS_Hash>, std::__1::reference_wrapper<Botan::XMSS_Parameters const> >(void (*&&)(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, Botan::XMSS_Address&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, Botan::XMSS_Hash&, Botan::XMSS_Parameters const&), std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > >&&, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>&&, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>&&, std::__1::reference_wrapper<Botan::XMSS_Address>&&, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>&&, std::__1::reference_wrapper<Botan::XMSS_Hash>&&, std::__1::reference_wrapper<Botan::XMSS_Parameters const>&&)::{lambda()#1}::operator()() const
Unexecuted instantiation: Botan::Thread_Pool::run<void (&)(std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> >&, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned long), std::__1::reference_wrapper<std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> > >, unsigned long&, unsigned long&, unsigned long&, unsigned long const&, unsigned long const&, unsigned long&, unsigned char&, unsigned long&, unsigned long&>(void (&)(std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> >&, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned long), std::__1::reference_wrapper<std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> > >&&, unsigned long&, unsigned long&, unsigned long&, unsigned long const&, unsigned long const&, unsigned long&, unsigned char&, unsigned long&, unsigned long&)::{lambda()#1}::operator()() const
73
0
         return future_result;
74
0
      }
Unexecuted instantiation: rsa.cpp:std::__1::future<Botan::(anonymous namespace)::RSA_Private_Operation::rsa_private_op(Botan::BigInt const&) const::{lambda()#1}::invoke_result<Botan::(anonymous namespace)::RSA_Private_Operation::rsa_private_op(Botan::BigInt const&) const::{lambda()#1}>::type> Botan::Thread_Pool::run<Botan::(anonymous namespace)::RSA_Private_Operation::rsa_private_op(Botan::BigInt const&) const::{lambda()#1}>(Botan::(anonymous namespace)::RSA_Private_Operation::rsa_private_op(Botan::BigInt const&) const::{lambda()#1}::invoke_result&&, (Botan::(anonymous namespace)::RSA_Private_Operation::rsa_private_op(Botan::BigInt const&) const::{lambda()#1}&&)...)
Unexecuted instantiation: std::__1::future<std::__1::invoke_result<void (Botan::XMSS_PrivateKey::*&)(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, unsigned long, unsigned long, Botan::XMSS_Address&, Botan::XMSS_Hash&), Botan::XMSS_PrivateKey*, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > >, unsigned long, unsigned long, std::__1::reference_wrapper<Botan::XMSS_Address>, std::__1::reference_wrapper<Botan::XMSS_Hash> >::type> Botan::Thread_Pool::run<void (Botan::XMSS_PrivateKey::*&)(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, unsigned long, unsigned long, Botan::XMSS_Address&, Botan::XMSS_Hash&), Botan::XMSS_PrivateKey*, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > >, unsigned long, unsigned long, std::__1::reference_wrapper<Botan::XMSS_Address>, std::__1::reference_wrapper<Botan::XMSS_Hash> >(void (Botan::XMSS_PrivateKey::*&)(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, unsigned long, unsigned long, Botan::XMSS_Address&, Botan::XMSS_Hash&), Botan::XMSS_PrivateKey*&&, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > >&&, unsigned long&&, unsigned long&&, std::__1::reference_wrapper<Botan::XMSS_Address>&&, std::__1::reference_wrapper<Botan::XMSS_Hash>&&)
Unexecuted instantiation: std::__1::future<std::__1::invoke_result<void (*)(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, Botan::XMSS_Address&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, Botan::XMSS_Hash&, Botan::XMSS_Parameters const&), std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > >, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>, std::__1::reference_wrapper<Botan::XMSS_Address>, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>, std::__1::reference_wrapper<Botan::XMSS_Hash>, std::__1::reference_wrapper<Botan::XMSS_Parameters const> >::type> Botan::Thread_Pool::run<void (*)(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, Botan::XMSS_Address&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, Botan::XMSS_Hash&, Botan::XMSS_Parameters const&), std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > >, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>, std::__1::reference_wrapper<Botan::XMSS_Address>, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>, std::__1::reference_wrapper<Botan::XMSS_Hash>, std::__1::reference_wrapper<Botan::XMSS_Parameters const> >(void (*&&)(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> >&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, Botan::XMSS_Address&, std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&, Botan::XMSS_Hash&, Botan::XMSS_Parameters const&), std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > >&&, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>&&, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>&&, std::__1::reference_wrapper<Botan::XMSS_Address>&&, std::__1::reference_wrapper<std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const>&&, std::__1::reference_wrapper<Botan::XMSS_Hash>&&, std::__1::reference_wrapper<Botan::XMSS_Parameters const>&&)
Unexecuted instantiation: std::__1::future<std::__1::invoke_result<void (&)(std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> >&, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned long), std::__1::reference_wrapper<std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> > >, unsigned long&, unsigned long&, unsigned long&, unsigned long const&, unsigned long const&, unsigned long&, unsigned char&, unsigned long&, unsigned long&>::type> Botan::Thread_Pool::run<void (&)(std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> >&, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned long), std::__1::reference_wrapper<std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> > >, unsigned long&, unsigned long&, unsigned long&, unsigned long const&, unsigned long const&, unsigned long&, unsigned char&, unsigned long&, unsigned long&>(void (&)(std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> >&, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned char, unsigned long, unsigned long), std::__1::reference_wrapper<std::__1::vector<unsigned long, Botan::secure_allocator<unsigned long> > >&&, unsigned long&, unsigned long&, unsigned long&, unsigned long const&, unsigned long const&, unsigned long&, unsigned char&, unsigned long&, unsigned long&)
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