RESTinio
ioctx_on_thread_pool.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <thread>
4
6
8
9namespace restinio
10{
11
12namespace impl
13{
14
26{
27 asio_ns::io_context m_ioctx;
28
29public:
31
33 auto & io_context() noexcept { return m_ioctx; }
34};
35
47{
48 asio_ns::io_context & m_ioctx;
49
50public:
54 asio_ns::io_context & ioctx )
55 : m_ioctx{ ioctx }
56 {}
57
59 auto & io_context() noexcept { return m_ioctx; }
60};
61
72template< typename Io_Context_Holder >
74{
75 public:
78
79 template< typename... Io_Context_Holder_Ctor_Args >
81 // Pool size.
82 //FIXME: better to use not_null from gsl.
83 std::size_t pool_size,
84 // Optional arguments for Io_Context_Holder instance.
85 Io_Context_Holder_Ctor_Args && ...ioctx_holder_args )
87 std::forward<Io_Context_Holder_Ctor_Args>(ioctx_holder_args)... }
88 , m_pool( pool_size )
89 , m_status( status_t::stopped )
90 {}
91
92 // Makes sure the pool is stopped.
94 {
95 if( started() )
96 {
97 stop();
98 wait();
99 }
100 }
101
102 void
104 {
105 if( started() )
106 {
107 throw exception_t{
108 "io_context_with_thread_pool is already started" };
109 }
110
111 try
112 {
113 std::generate(
114 begin( m_pool ),
115 end( m_pool ),
116 [this]{
117 return
118 std::thread{ [this] {
119 auto work{ asio_ns::make_work_guard(
120 m_ioctx_holder.io_context() ) };
121
122 m_ioctx_holder.io_context().run();
123 } };
124 } );
125
126 // When all thread started successfully
127 // status can be changed.
129 }
130 catch( const std::exception & )
131 {
132 io_context().stop();
133 for( auto & t : m_pool )
134 if( t.joinable() )
135 t.join();
136
137 throw;
138 }
139 }
140
141 // NOTE: this method is marked as noexcept in v.0.6.7.
142 // It's because this method can be called from destructors and
143 // there is no way to recover from an exception thrown from
144 // this method.
145 void
146 stop() noexcept
147 {
148 if( started() )
149 {
150 io_context().stop();
151 }
152 }
153
154 // NOTE: this method is marked as noexcept in v.0.6.7.
155 // It's because this method can be called from destructors and
156 // there is no way to recover from an exception thrown from
157 // this method.
158 void
159 wait() noexcept
160 {
161 if( started() )
162 {
163 for( auto & t : m_pool )
164 t.join();
165
166 // When all threads are stopped status can be changed.
168 }
169 }
170
171 bool started() const noexcept { return status_t::started == m_status; }
172
173 asio_ns::io_context &
174 io_context() noexcept
175 {
176 return m_ioctx_holder.io_context();
177 }
178
179 private:
180 enum class status_t : std::uint8_t { stopped, started };
181
182 Io_Context_Holder m_ioctx_holder;
183 std::vector< std::thread > m_pool;
185};
186
187} /* namespace impl */
188
189} /* namespace restinio */
190
Exception class for all exceptions thrown by RESTinio.
Definition: exception.hpp:26
A class for holding a reference to external Asio's io_context.
external_io_context_for_thread_pool_t(asio_ns::io_context &ioctx)
Initializing constructor.
auto & io_context() noexcept
Get access to io_context object.
asio_ns::io_context & io_context() noexcept
ioctx_on_thread_pool_t(const ioctx_on_thread_pool_t &)=delete
ioctx_on_thread_pool_t(ioctx_on_thread_pool_t &&)=delete
ioctx_on_thread_pool_t(std::size_t pool_size, Io_Context_Holder_Ctor_Args &&...ioctx_holder_args)
A class for holding actual instance of Asio's io_context.
auto & io_context() noexcept
Get access to io_context object.
STL namespace.
#define const
Definition: zconf.h:230