1 #ifndef VTESTBED_SERVER_SERVER_HH 2 #define VTESTBED_SERVER_SERVER_HH 6 #include <unordered_map> 8 #include <unistdx/base/log_message> 9 #include <unistdx/io/poller> 10 #include <unistdx/net/socket> 12 #include <vtestbed/core/testbed.hh> 13 #include <vtestbed/server/macros.hh> 14 #include <vtestbed/server/remote_client.hh> 28 typedef clock_type::duration duration;
29 typedef clock_type::time_point time_point;
33 sys::socket_address _address;
35 sys::event_poller _poller;
39 bool _verbose =
false;
45 time_point _nextpush = time_point(duration::zero());
47 time_point _lastpush = time_point(duration::zero());
52 Server(
const sys::socket_address& address):
59 _lastpush = _nextpush;
61 _poller.wait_until(_mutex, _nextpush);
63 if (_nextpush <= now) {
65 _nextpush = now + _period;
67 for (
const sys::epoll_event& ev : _poller) {
68 if (ev.fd() == _socket.fd()) {
74 for (
auto& pair : _clients) {
75 auto& client = pair.second;
89 this->info(
"add server _", _address);
90 _socket.bind(_address);
91 #if defined(UNISTDX_HAVE_TCP_USER_TIMEOUT) 92 VTB_WARN(_socket.set_user_timeout(_timeout));
95 _poller.emplace(_socket.fd(), sys::event::in);
101 sys::socket_address addr;
103 _socket.accept(sock, addr);
104 }
catch (
const sys::bad_call& err) {
105 if (err.errc() == std::errc::resource_unavailable_try_again) {
110 this->info(
"add client _", addr);
111 #if defined(UNISTDX_HAVE_TCP_USER_TIMEOUT) 112 VTB_WARN(sock.set_user_timeout(_timeout));
114 sys::fd_type fd = sock.fd();
115 _poller.emplace(fd, sys::event::in);
117 client.verbose(_verbose);
118 _clients.emplace(fd, std::move(client));
122 handle_client(
const sys::epoll_event& ev) {
123 auto result = _clients.find(ev.fd());
124 if (result == _clients.end()) {
125 this->error(
"unknown client, ev _", ev);
126 for (
auto& pair : _clients) {
129 pair.second.address(),
135 auto& client = result->second;
136 client.process(ev, _testbed);
138 this->info(
"remove client _", client.address());
140 _clients.erase(result);
145 push_updates(time_point now) {
148 const T dt = delta.count();
154 for (
auto& pair : _clients) {
155 auto& client = pair.second;
156 client.push(_testbed);
163 template <
class ... Args>
165 info(
const Args& ... args) {
167 sys::log_message(
"server", args ...);
171 template <
class ... Args>
173 error(
const Args& ... args) {
174 sys::log_message(
"server", args ...);
183 #endif // vim:filetype=cpp
void reset()
Reset simulation to the initial state and retain solver configuration.