@@ -25,7 +25,7 @@ Client_Poll::Client_Poll(const std::string &host,
2525 modbus_mapping_t *mapping,
2626 std::size_t tcp_timeout,
2727 std::size_t max_clients)
28- : max_clients(max_clients), poll_fds(max_clients + 1 , {0 , 0 , 0 }) {
28+ : max_clients(max_clients), poll_fds(max_clients + 2 , {0 , 0 , 0 }) {
2929 const char *host_str = " ::" ;
3030 if (!(host.empty () || host == " any" )) host_str = host.c_str ();
3131
@@ -72,7 +72,7 @@ Client_Poll::Client_Poll(const std::string &host,
7272 modbus_mapping_t **mappings,
7373 std::size_t tcp_timeout,
7474 std::size_t max_clients)
75- : max_clients(max_clients), poll_fds(max_clients + 1 , {0 , 0 , 0 }) {
75+ : max_clients(max_clients), poll_fds(max_clients + 2 , {0 , 0 , 0 }) {
7676 const char *host_str = " ::" ;
7777 if (!(host.empty () || host == " any" )) host_str = host.c_str ();
7878
@@ -242,9 +242,16 @@ double Client_Poll::get_response_timeout() {
242242 return static_cast <double >(timeout.sec ) + (static_cast <double >(timeout.usec ) / (1000.0 * 1000.0 ));
243243}
244244
245- bool Client_Poll::run (bool reconnect, int timeout) {
245+ Client_Poll:: run_t Client_Poll::run (int signal_fd, bool reconnect, int timeout) {
246246 std::size_t i = 0 ;
247247
248+ // poll signal fd
249+ {
250+ auto &fd = poll_fds[i++];
251+ fd.fd = signal_fd;
252+ fd.events = POLLIN;
253+ }
254+
248255 // do not poll server socket if maximum number of connections is reached
249256 const auto active_clients = client_addrs.size ();
250257 const bool poll_server = active_clients < max_clients;
@@ -262,18 +269,31 @@ bool Client_Poll::run(bool reconnect, int timeout) {
262269 }
263270
264271 // number of files to poll
265- const nfds_t poll_size = active_clients + (poll_server ? 1 : 0 );
272+ const nfds_t poll_size = active_clients + (poll_server ? 2 : 1 );
266273
267274 int tmp = poll (poll_fds.data (), poll_size, timeout);
268275 if (tmp == -1 ) {
269- if (errno == EINTR) return true ;
276+ if (errno == EINTR) return run_t ::interrupted ;
270277 throw std::system_error (errno, std::generic_category (), " Failed to poll socket(s)" );
271278 } else if (tmp == 0 ) {
272279 // poll timed out
273- return true ;
280+ return run_t ::timeout ;
274281 }
275282
276283 i = 0 ;
284+ {
285+ auto &fd = poll_fds[i++];
286+ if (fd.revents ) {
287+ if (fd.revents & POLLNVAL) throw std::logic_error (" poll (server socket) returned POLLNVAL" );
288+ if (fd.revents & POLLERR) throw std::logic_error (" poll (signal fd) returned POLLERR" );
289+ if (fd.revents & POLLHUP) throw std::logic_error (" poll (signal fd) returned POLLHUP" );
290+ if (fd.revents & POLLIN) return run_t ::term_signal;
291+ std::ostringstream sstr;
292+ sstr << " poll (signal fd) returned unknown revent: " << fd.revents ;
293+ throw std::logic_error (sstr.str ());
294+ }
295+ }
296+
277297 if (poll_server) {
278298 auto &fd = poll_fds[i++];
279299
@@ -377,10 +397,10 @@ bool Client_Poll::run(bool reconnect, int timeout) {
377397
378398 // check if there are any connections
379399 if (!reconnect) {
380- if (client_addrs.empty ()) return false ;
400+ if (client_addrs.empty ()) return run_t ::term_nocon ;
381401 }
382402
383- return true ;
403+ return run_t ::ok ;
384404}
385405
386406std::string Client_Poll::get_listen_addr () {
0 commit comments