summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Carey <jcarey@argv.me>2019-05-07 15:34:11 -0400
committerJason Carey <jcarey@argv.me>2019-05-07 23:55:03 -0400
commit401a54fb7a03c0a09a7c36c8ceb91489fe600204 (patch)
treea518913c06bc39684199972bd923c5c1d9a07abb
parentaa4743c301bea04b7b14ee125e14bd850f8b44e5 (diff)
downloadmongo-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.cpp36
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