/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 |