summaryrefslogtreecommitdiff
path: root/src/mongo/transport/service_entry_point_impl.cpp
diff options
context:
space:
mode:
authorJonathan Reams <jbreams@mongodb.com>2017-07-21 12:51:16 -0400
committerJonathan Reams <jbreams@mongodb.com>2017-07-28 11:00:14 -0400
commit6f5f53f79552aacbbfba8c7e61cf7b15f58f3f3f (patch)
tree983ec64121fbe98e400e7c47ea266c07da3712b3 /src/mongo/transport/service_entry_point_impl.cpp
parent3d313292efac3654393d30e0eb439e3df7728171 (diff)
downloadmongo-6f5f53f79552aacbbfba8c7e61cf7b15f58f3f3f.tar.gz
SERVER-30260 Fix race condition in endAllSessions
Diffstat (limited to 'src/mongo/transport/service_entry_point_impl.cpp')
-rw-r--r--src/mongo/transport/service_entry_point_impl.cpp23
1 files changed, 2 insertions, 21 deletions
diff --git a/src/mongo/transport/service_entry_point_impl.cpp b/src/mongo/transport/service_entry_point_impl.cpp
index cd2fa26ea1e..5b07f8b2c6c 100644
--- a/src/mongo/transport/service_entry_point_impl.cpp
+++ b/src/mongo/transport/service_entry_point_impl.cpp
@@ -100,33 +100,14 @@ void ServiceEntryPointImpl::startSession(transport::SessionHandle session) {
}
void ServiceEntryPointImpl::endAllSessions(transport::Session::TagMask tags) {
- SSMList connsToEnd;
-
// While holding the _sesionsMutex, loop over all the current connections, and if their tags
- // do not match the requested tags to skip, create a copy of their shared_ptr and place it in
- // connsToEnd.
- //
- // This will ensure that sessions to be ended will live at least long enough for us to call
- // their terminate() function, even if they've already ended because of an i/o error.
+ // do not match the requested tags to skip, terminate the session.
{
stdx::unique_lock<decltype(_sessionsMutex)> lk(_sessionsMutex);
for (auto& ssm : _sessions) {
- if (ssm->session()->getTags() & tags) {
- log() << "Skip closing connection for connection # " << ssm->session()->id();
- } else {
- connsToEnd.emplace_back(ssm);
- }
+ ssm->terminateIfTagsDontMatch(tags);
}
}
-
- // Loop through all the connections we marked for ending and call terminate on them. They will
- // then remove themselves from _sessions whenever they transition to the next state.
- //
- // If they've already ended, then this is a noop, and the SSM will be destroyed when connsToEnd
- // goes out of scope.
- for (auto& ssm : connsToEnd) {
- ssm->terminate();
- }
}
std::size_t ServiceEntryPointImpl::getNumberOfConnections() const {