RESTinio
Loading...
Searching...
No Matches
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
62namespace pool_size_checking
63{
64
65[[nodiscard]]
66inline std::size_t
67ensure_pool_size_non_zero( std::size_t pool_size )
68{
69 if( !pool_size )
70 throw exception_t{ "pool_size can't be 0" };
71
72 return pool_size;
73}
74
75} /* namespace pool_size_checking */
76
87template< typename Io_Context_Holder >
89{
90 public:
93
94 template< typename... Io_Context_Holder_Ctor_Args >
96 // Pool size.
97 std::size_t pool_size,
98 // Optional arguments for Io_Context_Holder instance.
102 , m_pool( pool_size_checking::ensure_pool_size_non_zero( pool_size ) )
104 {}
105
106 // Makes sure the pool is stopped.
108 {
109 if( started() )
110 {
111 stop();
112 wait();
113 }
114 }
115
116 void
118 {
119 if( started() )
120 {
121 throw exception_t{
122 "io_context_with_thread_pool is already started" };
123 }
124
125 try
126 {
127 std::generate(
128 begin( m_pool ),
129 end( m_pool ),
130 [this]{
131 return
132 std::thread{ [this] {
133 auto work{ asio_ns::make_work_guard(
134 m_ioctx_holder.io_context() ) };
135
136 m_ioctx_holder.io_context().run();
137 } };
138 } );
139
140 // When all thread started successfully
141 // status can be changed.
143 }
144 catch( const std::exception & )
145 {
146 io_context().stop();
147 for( auto & t : m_pool )
148 if( t.joinable() )
149 t.join();
150
151 throw;
152 }
153 }
154
155 // NOTE: this method is marked as noexcept in v.0.6.7.
156 // It's because this method can be called from destructors and
157 // there is no way to recover from an exception thrown from
158 // this method.
159 void
161 {
162 if( started() )
163 {
164 io_context().stop();
165 }
166 }
167
168 // NOTE: this method is marked as noexcept in v.0.6.7.
169 // It's because this method can be called from destructors and
170 // there is no way to recover from an exception thrown from
171 // this method.
172 void
174 {
175 if( started() )
176 {
177 for( auto & t : m_pool )
178 t.join();
179
180 // When all threads are stopped status can be changed.
182 }
183 }
184
186
187 asio_ns::io_context &
189 {
190 return m_ioctx_holder.io_context();
191 }
192
193 private:
194 enum class status_t : std::uint8_t { stopped, started };
195
197 std::vector< std::thread > m_pool;
199};
200
201} /* namespace impl */
202
203} /* namespace restinio */
204
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.
std::size_t ensure_pool_size_non_zero(std::size_t pool_size)
run_on_this_thread_settings_t< Traits > on_this_thread()
A special marker for the case when http_server must be run on the context of the current thread.