Parcourir la source

[trac657] Abort on fatal errors

Like when the socket is closed. Trying to accept more connections on
such socket lead to busy loop.
Michal 'vorner' Vaner il y a 14 ans
Parent
commit
b2d210a1ed
2 fichiers modifiés avec 25 ajouts et 2 suppressions
  1. 14 2
      src/lib/asiolink/tcp_server.cc
  2. 11 0
      src/lib/asiolink/udp_server.cc

+ 14 - 2
src/lib/asiolink/tcp_server.cc

@@ -17,6 +17,7 @@
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <unistd.h>             // for some IPC/network system calls
+#include <errno.h>
 
 #include <boost/shared_array.hpp>
 
@@ -83,11 +84,22 @@ TCPServer::operator()(error_code ec, size_t length) {
             /// Create a socket to listen for connections
             socket_.reset(new tcp::socket(acceptor_->get_io_service()));
 
-            /// Wait for new connections. In the event of error,
+            /// Wait for new connections. In the event of non-fatal error,
             /// try again
             do {
                 CORO_YIELD acceptor_->async_accept(*socket_, *this);
-            } while (!ec);
+                // Abort on fatal errors
+                // TODO: Log error?
+                if (ec) {
+                    if (ec.category() != error::system_category) {
+                        return;
+                    }
+                    if (ec.value() != EWOULDBLOCK && ec.value() != EAGAIN &&
+                        ec.value() != ECONNABORTED && ec.value() != EINTR) {
+                        return;
+                    }
+                }
+            } while (ec);
 
             /// Fork the coroutine by creating a copy of this one and
             /// scheduling it on the ASIO service queue.  The parent

+ 11 - 0
src/lib/asiolink/udp_server.cc

@@ -15,6 +15,7 @@
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <unistd.h>             // for some IPC/network system calls
+#include <errno.h>
 
 #include <boost/shared_array.hpp>
 
@@ -195,6 +196,16 @@ UDPServer::operator()(error_code ec, size_t length) {
                 CORO_YIELD data_->socket_->async_receive_from(
                     buffer(data_->data_.get(), MAX_LENGTH), *data_->sender_,
                     *this);
+                // Abort on fatal errors
+                if (ec) {
+                    if (ec.category() != error::system_category) {
+                        return;
+                    }
+                    if (ec.value() != EWOULDBLOCK && ec.value() != EAGAIN &&
+                        ec.value() != EINTR) {
+                        return;
+                    }
+                }
             } while (ec || length == 0);
 
             data_->bytes_ = length;