Browse 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 14 years ago
parent
commit
b2d210a1ed
2 changed files with 25 additions and 2 deletions
  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 <netinet/in.h>
 #include <sys/socket.h>
 #include <sys/socket.h>
 #include <unistd.h>             // for some IPC/network system calls
 #include <unistd.h>             // for some IPC/network system calls
+#include <errno.h>
 
 
 #include <boost/shared_array.hpp>
 #include <boost/shared_array.hpp>
 
 
@@ -83,11 +84,22 @@ TCPServer::operator()(error_code ec, size_t length) {
             /// Create a socket to listen for connections
             /// Create a socket to listen for connections
             socket_.reset(new tcp::socket(acceptor_->get_io_service()));
             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
             /// try again
             do {
             do {
                 CORO_YIELD acceptor_->async_accept(*socket_, *this);
                 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
             /// Fork the coroutine by creating a copy of this one and
             /// scheduling it on the ASIO service queue.  The parent
             /// 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 <netinet/in.h>
 #include <sys/socket.h>
 #include <sys/socket.h>
 #include <unistd.h>             // for some IPC/network system calls
 #include <unistd.h>             // for some IPC/network system calls
+#include <errno.h>
 
 
 #include <boost/shared_array.hpp>
 #include <boost/shared_array.hpp>
 
 
@@ -195,6 +196,16 @@ UDPServer::operator()(error_code ec, size_t length) {
                 CORO_YIELD data_->socket_->async_receive_from(
                 CORO_YIELD data_->socket_->async_receive_from(
                     buffer(data_->data_.get(), MAX_LENGTH), *data_->sender_,
                     buffer(data_->data_.get(), MAX_LENGTH), *data_->sender_,
                     *this);
                     *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);
             } while (ec || length == 0);
 
 
             data_->bytes_ = length;
             data_->bytes_ = length;