diff options
author | Jonathan Reams <jbreams@mongodb.com> | 2017-06-18 10:52:07 -0400 |
---|---|---|
committer | Jonathan Reams <jbreams@mongodb.com> | 2017-06-19 15:34:20 -0400 |
commit | 23448ff43566c1bba51680d4b17221374e6a74f1 (patch) | |
tree | cc5cc8e925823d2c976c1e62354cdf63f00d8f2a | |
parent | b05d8d23aeaf87c728cfbfc7ba050536d845e808 (diff) | |
download | mongo-23448ff43566c1bba51680d4b17221374e6a74f1.tar.gz |
SERVER-29403 Always do async accepts and fix solaris build
-rw-r--r-- | etc/ubsan.blacklist | 2 | ||||
-rw-r--r-- | src/mongo/transport/session_asio.h | 11 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_asio.cpp | 57 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_asio.h | 4 |
4 files changed, 30 insertions, 44 deletions
diff --git a/etc/ubsan.blacklist b/etc/ubsan.blacklist index f9cab51a186..7fa924d4698 100644 --- a/etc/ubsan.blacklist +++ b/etc/ubsan.blacklist @@ -1,6 +1,6 @@ # Don't UBSAN most of third_party, but do ubsan WT src:src/third_party/IntelRDFPMathLib20U1/* -src:src/third_party/asio-asio-*/* +src:src/third_party/asio-*/* src:src/third_party/boost-*/* src:src/third_party/gperftools-*/* src:src/third_party/icu4c-*/* diff --git a/src/mongo/transport/session_asio.h b/src/mongo/transport/session_asio.h index 7bb8343ad4f..42b49cecd04 100644 --- a/src/mongo/transport/session_asio.h +++ b/src/mongo/transport/session_asio.h @@ -102,21 +102,12 @@ public: _socket.non_blocking(async, ec); fassert(40490, ec.value() == 0); -// Prevent a warning about unused variables on Solaris -- only create this variable for codepaths -// which use it. -#if defined(__linux) || defined(SO_NOSIGPIPE) - const auto sock = _socket.native_handle(); -#endif -#ifdef SO_NOSIGPIPE - // ignore SIGPIPE signals on osx, to avoid process exit - const int one = 1; - setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &one, sizeof(int)); -#endif auto family = endpointToSockAddr(_socket.local_endpoint()).getType(); if (family == AF_INET || family == AF_INET6) { _socket.set_option(asio::ip::tcp::no_delay(true)); _socket.set_option(asio::socket_base::keep_alive(true)); #ifdef __linux__ + const auto sock = _socket.native_handle(); // On linux the default keep alive value may be very high - say an hour. // Here we set it to a minimum of 5 minutes if the default value was over five minutes. // See SERVER-3604. diff --git a/src/mongo/transport/transport_layer_asio.cpp b/src/mongo/transport/transport_layer_asio.cpp index ebadfd7c56d..87aff117360 100644 --- a/src/mongo/transport/transport_layer_asio.cpp +++ b/src/mongo/transport/transport_layer_asio.cpp @@ -273,17 +273,26 @@ Status TransportLayerASIO::start() { stdx::lock_guard<stdx::mutex> lk(_mutex); _running.store(true); + // If we're in async mode then the ServiceExecutor will handle calling run_one() in a pool + // of threads. Otherwise we need a thread to just handle the async_accept calls. + if (!_listenerOptions.async) { + _listenerThread = stdx::thread([this] { + setThreadName("listener"); + while (_running.load()) { + try { + _ioContext->run(); + _ioContext->reset(); + } catch (...) { + severe() << "Uncaught exception in the listener: " << exceptionToStatus(); + fassertFailed(40491); + } + } + }); + } + for (auto& acceptor : _acceptors) { acceptor.listen(); - if (!_listenerOptions.async) { - _listenerThreads.emplace_back(stdx::thread([this, &acceptor] { - do { - _acceptConnection(acceptor); - } while (_running.load()); - })); - } else { - _acceptConnection(acceptor); - } + _acceptConnection(acceptor); } return Status::OK(); @@ -291,12 +300,11 @@ Status TransportLayerASIO::start() { void TransportLayerASIO::shutdown() { stdx::lock_guard<stdx::mutex> lk(_mutex); - _acceptors.clear(); _running.store(false); _ioContext->stop(); - for (auto& thread : _listenerThreads) { - thread.join(); + if (_listenerThread.joinable()) { + _listenerThread.join(); } } @@ -310,9 +318,7 @@ void TransportLayerASIO::eraseSession(TransportLayerASIO::SessionsListIterator i void TransportLayerASIO::_acceptConnection(GenericAcceptor& acceptor) { auto session = createSession(); if (!session) { - if (_listenerOptions.async) { - _acceptConnection(acceptor); - } + _acceptConnection(acceptor); return; } @@ -321,9 +327,7 @@ void TransportLayerASIO::_acceptConnection(GenericAcceptor& acceptor) { if (ec) { log() << "Error accepting new connection on " << endpointToHostAndPort(acceptor.local_endpoint()) << ": " << ec.message(); - if (_listenerOptions.async) { - _acceptConnection(acceptor); - } + _acceptConnection(acceptor); return; } @@ -334,9 +338,7 @@ void TransportLayerASIO::_acceptConnection(GenericAcceptor& acceptor) { if (_sessions.size() + 1 > _listenerOptions.maxConns) { log() << "connection refused because too many open connections: " << _sessions.size(); - if (_listenerOptions.async) { - _acceptConnection(acceptor); - } + _acceptConnection(acceptor); return; } listIt = _sessions.emplace(_sessions.end(), session); @@ -352,19 +354,10 @@ void TransportLayerASIO::_acceptConnection(GenericAcceptor& acceptor) { } _sep->startSession(std::move(session)); - - if (_listenerOptions.async) { - _acceptConnection(acceptor); - } + _acceptConnection(acceptor); }; - if (_listenerOptions.async) { - acceptor.async_accept(socket, std::move(acceptCb)); - } else { - std::error_code ec; - acceptor.accept(socket, ec); - acceptCb(ec); - } + acceptor.async_accept(socket, std::move(acceptCb)); } } // namespace transport diff --git a/src/mongo/transport/transport_layer_asio.h b/src/mongo/transport/transport_layer_asio.h index 2067b766cbf..ede44211c22 100644 --- a/src/mongo/transport/transport_layer_asio.h +++ b/src/mongo/transport/transport_layer_asio.h @@ -133,7 +133,9 @@ private: stdx::mutex _mutex; std::vector<GenericAcceptor> _acceptors; stdx::list<std::weak_ptr<ASIOSession>> _sessions; - std::vector<stdx::thread> _listenerThreads; + + // Only used if _listenerOptions.async is false. + stdx::thread _listenerThread; std::unique_ptr<asio::io_context> _ioContext; #ifdef MONGO_CONFIG_SSL |