22 template<
class LatencyTimestamps,
class>
24 svr<ProcessingRules, SvrMgr>::
svr(
boost::
asio::
ip::address
const &addr,
unsigned short port_num,
unsigned short timeout,
typename svr_mgr_t::socket_priority priority, thread_t::thread_traits::api_params_type::processor_mask_type mask,
const thread_t::thread_traits::api_params_type::priority_type cpu_priority, proc_rules_t
const &proc_ops, LatencyTimestamps &ts,
char const *svr_name, server_to_client_flow_t &&server_to_client_flow)
noexcept(
false)
27 port_number(port_num),
42 [
this, &ts](
auto &src_cxn,
auto &dest_skt) {
43 return this->read_and_process_msgs(src_cxn, dest_skt, ts);
47 return std::bind(&svr::run,
this);
50 io_thread.kernel_priority(cpu_priority);
51 io_thread.kernel_affinity(mask);
56 template<
class LatencyTimestamps,
class>
58 svr<ProcessingRules, SvrMgr>::
svr(
boost::
asio::
ip::address
const &addr,
unsigned short port_num, socket_priority priority, thread_t::thread_traits::api_params_type::processor_mask_type mask,
const thread_t::thread_traits::api_params_type::priority_type cpu_priority, proc_rules_t
const &proc_ops, LatencyTimestamps &ts,
char const *svr_name, server_to_client_flow_t &&server_to_client_flow)
noexcept(
false)
63 template<
class LatencyTimestamps,
class>
65 svr<ProcessingRules, SvrMgr>::
svr(
boost::
asio::
ip::address
const &addr,
unsigned short port_num,
unsigned short timeout, socket_priority priority, thread_t::thread_traits::api_params_type::processor_mask_type mask,
const thread_t::thread_traits::api_params_type::priority_type cpu_priority, proc_rules_t
const &proc_ops, socket_t &dest_skt, LatencyTimestamps &ts,
char const *svr_name, server_to_client_flow_t &&server_to_client_flow)
noexcept(
false)
68 port_number(port_num),
84 [
this, &ts](
auto &src_cxn,
auto &dest_skt) {
85 return this->read_and_process_msgs(src_cxn, dest_skt, ts);
89 return std::bind(&svr::run,
this);
92 io_thread.kernel_priority(cpu_priority);
93 io_thread.kernel_affinity(mask);
98 template<
class LatencyTimestamps,
class>
100 svr<ProcessingRules, SvrMgr>::
svr(
boost::
asio::
ip::address
const &addr,
unsigned short port_num, socket_priority priority, thread_t::thread_traits::api_params_type::processor_mask_type mask,
const thread_t::thread_traits::api_params_type::priority_type cpu_priority, proc_rules_t
const &proc_ops, socket_t &dest_skt, LatencyTimestamps &ts, server_to_client_flow_t &&server_to_client_flow)
noexcept(
false)
105 template<
class LatencyTimestamps>
107 svr<ProcessingRules, SvrMgr>::
svr(
ctor_args const &args, socket_priority priority, thread_t::thread_traits::api_params_type::processor_mask_type mask,
const thread_t::thread_traits::api_params_type::priority_type cpu_priority, LatencyTimestamps &ts, server_to_client_flow_t &&server_to_client_flow)
noexcept(
false)
112 template<
class LatencyTimestamps>
114 svr<ProcessingRules, SvrMgr>::
svr(
ctor_args const &args, socket_t &dest_skt,
unsigned short timeout, socket_priority priority, thread_t::thread_traits::api_params_type::processor_mask_type mask,
const thread_t::thread_traits::api_params_type::priority_type cpu_priority, LatencyTimestamps &ts,
char const *svr_name, server_to_client_flow_t &&server_to_client_flow)
noexcept(
false)
115 :
svr(
args.
addr,
args.
port,
timeout,
priority,
mask,
cpu_priority,
args.
proc_ops,
dest_skt,
ts,
svr_name,
std::
move(
server_to_client_flow)) {
118 template<
class ProcessingRules,
class SvrMgr>
inline
119 svr<ProcessingRules, SvrMgr>::~
svr()
noexcept(
true) {
123 template<
class ProcessingRules,
class SvrMgr>
inline void
124 svr<ProcessingRules, SvrMgr>::
stop()
noexcept(
true) {
129 template<
class ProcessingRules,
class SvrMgr>
inline int
130 svr<ProcessingRules, SvrMgr>::
main(
int argc,
char const *
const *argv)
noexcept(
true) {
131 using thread_traits=thread_t::thread_traits;
134 boost::program_options::options_description desc(
135 "A simple exchange-simulator that listens to an IPADDR:PORT combination. The executable name indicates the message version implemented. For details regarding the properties of the simulator see the documentation that came with the distribution. Copyright © J.M.McGuiness, coder@hussar.me.uk. http://libjmmcg.sf.net/ Distributed under the terms of the GPL v2.1.\n"+
exit_codes::to_string()+
"Arguments"
138 (
"help",
"Print this help message.")
139 (
"version",
"Print the build number of this program.")
140 (
"address",
boost::program_options::value<
boost::
asio::
ip::address>()->default_value(
boost::
asio::
ip::address_v4::loopback()),
"IP address (in v4 format; thus the network interface to which it is bound) to which the server should listen.")
141 (
"port",
boost::program_options::value<
unsigned short>()->required(),
"An unused port to which the server should listen.")
144 boost::program_options::variables_map vm;
145 boost::program_options::store(
boost::program_options::parse_command_line(argc, argv, desc), vm);
146 if (vm.count(
"help")) {
147 std::cout<<desc<<
std::endl;
150 if (vm.count(
"version")) {
154 boost::program_options::notify(vm);
155 thread_traits::set_backtrace_on_signal();
156 proc_rules_t proc_rules;
157 no_latency_timestamps ts
(0U
);
158 const std::string svr_name(std::string(argv[0]).substr(0, 15));
160 vm[
"address"].as<boost::asio::ip::address>(),
161 vm[
"port"].as<
unsigned short>(),
162 svr::socket_t::socket_priority::low,
163 thread_traits::api_params_type::processor_mask_type(vm[
"processor"].as<
unsigned short>()),
164 thread_traits::api_params_type::priority_type::normal,
169 std::clog<<sim<<
std::endl;
170 thread_traits::set_kernel_affinity(
171 thread_traits::get_current_thread(),
172 thread_traits::api_params_type::processor_mask_type(0)
174 thread_traits::set_kernel_priority(
175 thread_traits::get_current_thread(),
176 thread_traits::api_params_type::priority_type::idle
178 while (!sim.signal_status()) {
179 thread_traits::sleep(0);
181 std::clog<<sim<<
std::endl;
183 }
catch (exception_type
const &ex) {
184 std::cerr<<
"CRT exception. Detail: "<<ex.what()<<std::endl;
186 }
catch (
std::exception
const &ex) {
187 std::cerr<<
"STL-derived exception. Details: "<<
boost::diagnostic_information(ex)<<
std::endl;
190 std::cerr<<
"Unknown exception."<<
std::endl;
196 template<
class ProcessingRules,
class SvrMgr>
inline std::string
197 svr<ProcessingRules, SvrMgr>::
to_string()
const noexcept(
false) {
198 std::ostringstream ss;
200 <<thread_t::thread_traits::demangle_name(
typeid(*
this))
201 <<
",\naddress="<<address
202 <<
", port_number: "<<port_number
203 <<
", exit="<<
static_cast<
bool>(exit_)
204 <<
", client processing-error: '"<<client_ex<<
"'"
205 <<
", processor: "<<processor
206 <<
", manager: "<<manager;
211 template<
class LatencyTimestamps>
213 svr<ProcessingRules, SvrMgr>::read_and_process_msgs(
typename svr_mgr_t::session &src_cxn, socket_t &dest_skt, LatencyTimestamps &ts)
noexcept(
false) {
214 if (
LIKELY(!
static_cast<
bool>(exit_))) {
216 while (
LIKELY(!
static_cast<
bool>(exit_))) {
217 assert(src_cxn.socket().is_open());
218 if (
UNLIKELY(processor.read_and_process_a_msg(src_cxn.socket(), dest_skt, ts))) {
220 return static_cast<
bool>(exit_);
224 return static_cast<
bool>(exit_);
228 template<
class LatencyTimestamps>
230 svr<ProcessingRules, SvrMgr>::read_and_process_msgs(
typename svr_mgr_t::session &src_cxn,
typename svr_mgr_t::session &dest_cxn, LatencyTimestamps &ts)
noexcept(
false) {
231 return read_and_process_msgs(src_cxn, dest_cxn.socket(), ts);
234 template<
class ProcessingRules,
class SvrMgr>
inline void
235 svr<ProcessingRules, SvrMgr>::run()
noexcept(
true) {
239 client_ex=boost::current_exception();
243 template<
class ProcessingRules,
class SvrMgr>
inline std::ostream &
244 operator<<(
std::ostream &os, svr<ProcessingRules, SvrMgr>
const &ec)
noexcept(
false) {