This source file includes following definitions.
- signal_handler
- manager
- manager
- stop
- main
- empty
- find
- to_string
- read_and_process_msgs
- run
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 namespace boost { namespace asio { namespace ip {
22
23
24
25
26
27 inline std::istream &
28 operator>>(std::istream &is, boost::asio::ip::address &addr) {
29 std::string s;
30 is>>s;
31 boost::asio::ip::address_v4 addr_v4;
32 addr_v4.from_string(s);
33 addr=addr_v4;
34 return is;
35 }
36
37 } } }
38
39 namespace jmmcg { namespace socket {
40
41 template<class ProcessingRules, class SvrMgr>
42 volatile std::sig_atomic_t svr<ProcessingRules, SvrMgr>::signal_status=0;
43
44 template<class ProcessingRules, class SvrMgr> inline void
45 svr<ProcessingRules, SvrMgr>::signal_handler(int signal) noexcept(true) {
46 signal_status=signal;
47 }
48
49 template<class ProcessingRules, class SvrMgr> inline
50 svr<ProcessingRules, SvrMgr>::svr(boost::asio::ip::address const &addr, unsigned short port_num, proc_rules_t const &proc_ops) noexcept(false)
51 : address(addr), port_number(port_num), processor(proc_ops), manager(address, port_number, proc_rules_t::src_msg_details_t::min_msg_size, proc_rules_t::src_msg_details_t::max_msg_size) {
52 manager.start_accept(std::bind(&svr::read_and_process_msgs, this, std::placeholders::_1, std::placeholders::_2));
53
54 io_thread=std::thread(&svr::run, this);
55 }
56
57 template<class ProcessingRules, class SvrMgr> inline
58 svr<ProcessingRules, SvrMgr>::svr(boost::asio::ip::address const &addr, unsigned short port_num, proc_rules_t const &proc_ops, socket_t &dest_skt) noexcept(false)
59 : address(addr), port_number(port_num), processor(proc_ops), manager(address, port_number, proc_rules_t::src_msg_details_t::min_msg_size, proc_rules_t::src_msg_details_t::max_msg_size, dest_skt) {
60 manager.start_accept(std::bind(&svr::read_and_process_msgs, this, std::placeholders::_1, std::placeholders::_2));
61
62 io_thread=std::thread(&svr::run, this);
63 }
64
65 template<class ProcessingRules, class SvrMgr> inline
66 svr<ProcessingRules, SvrMgr>::svr(ctor_args const &args) noexcept(false)
67 : svr(args.addr, args.port, args.proc_ops) {
68 }
69
70 template<class ProcessingRules, class SvrMgr> inline
71 svr<ProcessingRules, SvrMgr>::svr(ctor_args const &args, socket_t &dest_skt) noexcept(false)
72 : svr(args.addr, args.port, args.proc_ops, dest_skt) {
73 }
74
75 template<class ProcessingRules, class SvrMgr> inline
76 svr<ProcessingRules, SvrMgr>::~svr() noexcept(true) {
77 stop();
78 if (io_thread.joinable()) {
79 io_thread.join();
80 }
81 }
82
83 template<class ProcessingRules, class SvrMgr> inline void
84 svr<ProcessingRules, SvrMgr>::stop() noexcept(true) {
85 exit_=true;
86 manager.stop();
87 }
88
89 template<class ProcessingRules, class SvrMgr> inline int
90 svr<ProcessingRules, SvrMgr>::main(int argc, char const * const *argv) noexcept(true) {
91 try {
92 boost::program_options::options_description desc(
93 "A simple exchange-simulator that listens to an IPADDR:PORT combination. The file name indicates the message version implemented. For details regarding the properties of the simulator see the documentation that came with the distribution. Copyright (c) J.M.McGuiness, coder@hussar.me.uk. http://libjmmcg.sf.net/ Distributed under the terms of the GPL v2.1."
94 );
95 desc.add_options()
96 ("help", "Print this help message.")
97 ("version", "Print the build number of this program.")
98 ("address", boost::program_options::value<boost::asio::ip::address>()->default_value(boost::asio::ip::address_v4::loopback()), "IP address (in v4 format) to which the server should listen.")
99 ("port", boost::program_options::value<unsigned short>()->required(), "An unused port to which the server should listen.")
100 ;
101 boost::program_options::variables_map vm;
102 boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
103 if (vm.count("help")) {
104 std::cout<<desc<<std::endl;
105 return exit_print_help;
106 }
107 if (vm.count("version")) {
108 std::cout<<"Build: "<<libjmmcg_VERSION_NUMBER<<std::endl;
109 return exit_print_version;
110 }
111 boost::program_options::notify(vm);
112 std::signal(SIGINT, svr::signal_handler);
113 proc_rules_t proc_rules;
114 svr sim(vm["address"].as<boost::asio::ip::address>(), vm["port"].as<unsigned short>(), proc_rules);
115 std::clog<<sim<<std::endl;
116 while (!signal_status) {
117 std::this_thread::yield();
118 }
119 std::clog<<sim<<std::endl;
120 return exit_codes::exit_success;
121 } catch (exception_type const &ex) {
122 std::cerr<<"CRT exception. Detail: "<<ex.what()<<std::endl;
123 return exit_codes::exit_crt_exception;
124 } catch (std::exception const &ex) {
125 std::cerr<<"STL exception. Detail: "<<ex.what()<<std::endl;
126 return exit_codes::exit_stl_exception;
127 } catch (...) {
128 std::cerr<<"Unknown exception."<<std::endl;
129 return exit_codes::exit_unknown_exception;
130 }
131 return exit_codes::exit_unknown_failure;
132 }
133
134 template<class ProcessingRules, class SvrMgr> inline bool
135 svr<ProcessingRules, SvrMgr>::empty() const noexcept(true) {
136 return manager.empty();
137 }
138
139 template<class ProcessingRules, class SvrMgr> inline typename svr<ProcessingRules, SvrMgr>::svr_mgr_t::client_cxns_t::const_iterator
140 svr<ProcessingRules, SvrMgr>::find(typename svr_mgr_t::client_cxns_t::key_type const &k) const noexcept(true) {
141 return manager.find(k);
142 }
143
144 template<class ProcessingRules, class SvrMgr> inline std::string
145 svr<ProcessingRules, SvrMgr>::to_string() const noexcept(false) {
146 std::ostringstream ss;
147 ss
148 <<typeid(*this).name()
149 <<",\naddress="<<address
150 <<", port_number: "<<port_number
151 <<", exit="<<static_cast<bool>(exit_)
152 <<", client processing-error: '"<<ex<<"'"
153 <<", processor: "<<processor
154 <<", manager: "<<manager;
155 return ss.str();
156 }
157
158 template<class ProcessingRules, class SvrMgr> inline bool
159 svr<ProcessingRules, SvrMgr>::read_and_process_msgs(typename svr_mgr_t::tcp_connection::ptr_type src_cxn, socket_t &dest_skt) noexcept(false) {
160 while (LIKELY(!static_cast<bool>(exit_))) {
161 assert(src_cxn->socket().is_open());
162 if (UNLIKELY(processor.read_and_process_a_msg(src_cxn->socket(), dest_skt))) {
163 break;
164 }
165 }
166 return static_cast<bool>(exit_);
167 }
168
169 template<class ProcessingRules, class SvrMgr> inline void
170 svr<ProcessingRules, SvrMgr>::run() noexcept(true) {
171 try {
172 manager.run();
173 } catch (std::exception const &e) {
174 ex=std::make_exception_ptr(e);
175 }
176 }
177
178 template<class ProcessingRules, class SvrMgr> inline std::ostream &
179 operator<<(std::ostream &os, svr<ProcessingRules, SvrMgr> const &ec) noexcept(false) {
180 os<<ec.to_string();
181 return os;
182 }
183
184 } }