diff options
author | Jason Carey <jcarey@argv.me> | 2019-05-07 15:34:11 -0400 |
---|---|---|
committer | Jason Carey <jcarey@argv.me> | 2019-05-07 23:55:03 -0400 |
commit | 401a54fb7a03c0a09a7c36c8ceb91489fe600204 (patch) | |
tree | a518913c06bc39684199972bd923c5c1d9a07abb | |
parent | aa4743c301bea04b7b14ee125e14bd850f8b44e5 (diff) | |
download | mongo-401a54fb7a03c0a09a7c36c8ceb91489fe600204.tar.gz |
SERVER-41042 fix early thread in NonAuthTE
The NonAuthTaskExecutor makes threads too early in global startup. We
have to delay thread startup until after the signal handling thread to
avoid failing to mask that early thread from signals.
-rw-r--r-- | src/mongo/executor/non_auth_task_executor.cpp | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/src/mongo/executor/non_auth_task_executor.cpp b/src/mongo/executor/non_auth_task_executor.cpp index 60471994a8d..25c5e002278 100644 --- a/src/mongo/executor/non_auth_task_executor.cpp +++ b/src/mongo/executor/non_auth_task_executor.cpp @@ -33,20 +33,21 @@ #include "mongo/executor/non_auth_task_executor.h" +#include <utility> + #include "mongo/executor/network_interface_factory.h" #include "mongo/executor/network_interface_thread_pool.h" #include "mongo/executor/thread_pool_task_executor.h" +#include "mongo/platform/atomic_word.h" +#include "mongo/util/assert_util.h" namespace mongo { namespace executor { namespace { -const auto getExecutor = ServiceContext::declareDecoration<std::unique_ptr<TaskExecutor>>(); - -ServiceContext::ConstructorActionRegisterer nonAuthExecutorCAR{ - "NonAuthTaskExecutor", - [](ServiceContext* service) { +struct State { + State() : hasStarted(false) { std::shared_ptr<NetworkInterface> ni = makeNetworkInterface("NonAuthExecutor", nullptr, nullptr, [] { ConnectionPool::Options options; @@ -54,21 +55,34 @@ ServiceContext::ConstructorActionRegisterer nonAuthExecutorCAR{ return options; }()); auto tp = std::make_unique<NetworkInterfaceThreadPool>(ni.get()); - auto exec = std::make_unique<ThreadPoolTaskExecutor>(std::move(tp), std::move(ni)); + executor = std::make_unique<ThreadPoolTaskExecutor>(std::move(tp), std::move(ni)); + } - exec->startup(); + AtomicWord<bool> hasStarted; + std::unique_ptr<TaskExecutor> executor; +}; - getExecutor(service) = std::move(exec); - }, +const auto getExecutor = ServiceContext::declareDecoration<State>(); + +ServiceContext::ConstructorActionRegisterer nonAuthExecutorCAR{ + "NonAuthTaskExecutor", + [](ServiceContext* service) {}, [](ServiceContext* service) { // Destruction implicitly performs the needed shutdown and join() - getExecutor(service).reset(); + getExecutor(service).executor.reset(); }}; } // namespace TaskExecutor* getNonAuthTaskExecutor(ServiceContext* svc) { - return getExecutor(svc).get(); + auto& state = getExecutor(svc); + invariant(state.executor); + + if (!state.hasStarted.load() && !state.hasStarted.swap(true)) { + state.executor->startup(); + } + + return state.executor.get(); } } // namespace executor |