]> granicus.if.org Git - icinga2/blob - lib/base/threadpool.hpp
Merge pull request #7185 from Icinga/bugfix/gelfwriter-wrong-log-facility
[icinga2] / lib / base / threadpool.hpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #ifndef THREADPOOL_H
4 #define THREADPOOL_H
5
6 #include "base/exception.hpp"
7 #include "base/logger.hpp"
8 #include <cstddef>
9 #include <exception>
10 #include <functional>
11 #include <memory>
12 #include <thread>
13 #include <boost/asio/post.hpp>
14 #include <boost/asio/thread_pool.hpp>
15 #include <boost/thread/locks.hpp>
16 #include <boost/thread/shared_mutex.hpp>
17
18 namespace icinga
19 {
20
21 enum SchedulerPolicy
22 {
23         DefaultScheduler,
24         LowLatencyScheduler
25 };
26
27 /**
28  * A thread pool.
29  *
30  * @ingroup base
31  */
32 class ThreadPool
33 {
34 public:
35         typedef std::function<void ()> WorkFunction;
36
37         ThreadPool(size_t threads = std::thread::hardware_concurrency() * 2u);
38         ~ThreadPool();
39
40         void Start();
41         void Stop();
42
43         /**
44          * Appends a work item to the work queue. Work items will be processed in FIFO order.
45          *
46          * @param callback The callback function for the work item.
47          * @returns true if the item was queued, false otherwise.
48          */
49         template<class T>
50         bool Post(T callback, SchedulerPolicy)
51         {
52                 boost::shared_lock<decltype(m_Mutex)> lock (m_Mutex);
53
54                 if (m_Pool) {
55                         boost::asio::post(*m_Pool, [callback]() {
56                                 try {
57                                         callback();
58                                 } catch (const std::exception& ex) {
59                                         Log(LogCritical, "ThreadPool")
60                                                 << "Exception thrown in event handler:\n"
61                                                 << DiagnosticInformation(ex);
62                                 } catch (...) {
63                                         Log(LogCritical, "ThreadPool", "Exception of unknown type thrown in event handler.");
64                                 }
65                         });
66
67                         return true;
68                 } else {
69                         return false;
70                 }
71         }
72
73 private:
74         boost::shared_mutex m_Mutex;
75         std::unique_ptr<boost::asio::thread_pool> m_Pool;
76         size_t m_Threads;
77 };
78
79 }
80
81 #endif /* THREADPOOL_H */