summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Reams <jbreams@mongodb.com>2017-06-18 10:52:07 -0400
committerJonathan Reams <jbreams@mongodb.com>2017-06-19 15:34:20 -0400
commit23448ff43566c1bba51680d4b17221374e6a74f1 (patch)
treecc5cc8e925823d2c976c1e62354cdf63f00d8f2a
parentb05d8d23aeaf87c728cfbfc7ba050536d845e808 (diff)
downloadmongo-23448ff43566c1bba51680d4b17221374e6a74f1.tar.gz
SERVER-29403 Always do async accepts and fix solaris build
-rw-r--r--etc/ubsan.blacklist2
-rw-r--r--src/mongo/transport/session_asio.h11
-rw-r--r--src/mongo/transport/transport_layer_asio.cpp57
-rw-r--r--src/mongo/transport/transport_layer_asio.h4
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