Coverage Report

Created: 2022-06-23 06:44

/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 <functional>
12
#include <deque>
13
#include <vector>
14
#include <memory>
15
#include <utility>
16
#include <type_traits>
17
#include <mutex>
18
#include <thread>
19
#include <future>
20
#include <condition_variable>
21
#include <optional>
22
23
namespace Botan {
24
25
class BOTAN_TEST_API Thread_Pool
26
   {
27
   public:
28
      /**
29
      * Return an instance to a shared thread pool
30
      */
31
      static Thread_Pool& global_instance();
32
33
      /**
34
      * Initialize a thread pool with some number of threads
35
      * @param pool_size number of threads in the pool, if 0
36
      *        then some default value is chosen. If the optional
37
      *        is nullopt then the thread pool is disabled; all
38
      *        work is executed immediately when queued.
39
      */
40
      Thread_Pool(std::optional<size_t> pool_size);
41
42
      /**
43
      * Initialize a thread pool with some number of threads
44
      * @param pool_size number of threads in the pool, if 0
45
      *        then some default value is chosen.
46
      */
47
      Thread_Pool(size_t pool_size = 0) :
48
         Thread_Pool(std::optional<size_t>(pool_size))
49
0
         {}
50
51
0
      ~Thread_Pool() { shutdown(); }
52
53
      void shutdown();
54
55
0
      size_t worker_count() const { return m_workers.size(); }
56
57
      Thread_Pool(const Thread_Pool&) = delete;
58
      Thread_Pool& operator=(const Thread_Pool&) = delete;
59
60
      Thread_Pool(Thread_Pool&&) = delete;
61
      Thread_Pool& operator=(Thread_Pool&&) = delete;
62
63
      /*
64
      * Enqueue some work
65
      */
66
      void queue_thunk(const std::function<void ()>&);
67
68
      template<class F, class... Args>
69
      auto run(F&& f, Args&&... args) -> std::future<typename std::invoke_result<F, Args...>::type>
70
0
         {
71
0
         typedef typename std::invoke_result<F, Args...>::type return_type;
72
73
0
         auto future_work = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
74
0
         auto task = std::make_shared<std::packaged_task<return_type ()>>(future_work);
75
0
         auto future_result = task->get_future();
76
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
77
0
         return future_result;
78
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&)
79
80
   private:
81
      void worker_thread();
82
83
      // Only touched in constructor and destructor
84
      std::vector<std::thread> m_workers;
85
86
      std::mutex m_mutex;
87
      std::condition_variable m_more_tasks;
88
      std::deque<std::function<void ()>> m_tasks;
89
      bool m_shutdown;
90
   };
91
92
}
93
94
#endif