summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBilly Donahue <billy.donahue@mongodb.com>2022-07-14 15:44:28 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-07-14 17:18:10 +0000
commit4725f9b1fb48e95fd96284ccaa371d08f8cb8b41 (patch)
tree998471038cdc30b61923bf5b65edefbf4a8cbc24 /src
parent60e0fe845e805e7b23e73ea6e7170572a35806cf (diff)
downloadmongo-4725f9b1fb48e95fd96284ccaa371d08f8cb8b41.tar.gz
SERVER-67927 ServiceExecutor: ThreadingModel -> HasDedicatedThread
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/commands.cpp27
-rw-r--r--src/mongo/db/commands.h11
-rw-r--r--src/mongo/db/curop.cpp4
-rw-r--r--src/mongo/db/service_entry_point_common.cpp12
-rw-r--r--src/mongo/embedded/service_entry_point_embedded.cpp2
-rw-r--r--src/mongo/s/commands/cluster_command_test_fixture.cpp2
-rw-r--r--src/mongo/s/commands/strategy.cpp11
-rw-r--r--src/mongo/transport/service_entry_point_impl.cpp2
-rw-r--r--src/mongo/transport/service_executor.cpp165
-rw-r--r--src/mongo/transport/service_executor.h29
-rw-r--r--src/mongo/transport/service_executor.idl11
-rw-r--r--src/mongo/transport/service_state_machine_test.cpp44
12 files changed, 103 insertions, 217 deletions
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp
index 6e8b2cee87d..3c8c915c023 100644
--- a/src/mongo/db/commands.cpp
+++ b/src/mongo/db/commands.cpp
@@ -155,22 +155,17 @@ BSONObj CommandHelpers::runCommandDirectly(OperationContext* opCtx, const OpMsgR
return replyBuilder.releaseBody();
}
-Future<void> CommandHelpers::runCommandInvocation(
- std::shared_ptr<RequestExecutionContext> rec,
- std::shared_ptr<CommandInvocation> invocation,
- transport::ServiceExecutor::ThreadingModel threadingModel) {
- switch (threadingModel) {
- case transport::ServiceExecutor::ThreadingModel::kBorrowed:
- return runCommandInvocationAsync(std::move(rec), std::move(invocation));
- case transport::ServiceExecutor::ThreadingModel::kDedicated:
- return makeReadyFutureWith([opCtx = rec->getOpCtx(),
- request = rec->getRequest(),
- invocation = invocation.get(),
- replyBuilder = rec->getReplyBuilder()] {
- runCommandInvocation(opCtx, request, invocation, replyBuilder);
- });
- }
- MONGO_UNREACHABLE;
+Future<void> CommandHelpers::runCommandInvocation(std::shared_ptr<RequestExecutionContext> rec,
+ std::shared_ptr<CommandInvocation> invocation,
+ bool useDedicatedThread) {
+ if (useDedicatedThread)
+ return makeReadyFutureWith([opCtx = rec->getOpCtx(),
+ request = rec->getRequest(),
+ invocation = invocation.get(),
+ replyBuilder = rec->getReplyBuilder()] {
+ runCommandInvocation(opCtx, request, invocation, replyBuilder);
+ });
+ return runCommandInvocationAsync(std::move(rec), std::move(invocation));
}
void CommandHelpers::runCommandInvocation(OperationContext* opCtx,
diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h
index cbfb6f82451..778b34db424 100644
--- a/src/mongo/db/commands.h
+++ b/src/mongo/db/commands.h
@@ -259,13 +259,12 @@ struct CommandHelpers {
static BSONObj runCommandDirectly(OperationContext* opCtx, const OpMsgRequest& request);
/**
- * Decides the command execution model (i.e., synchronous or asynchronous) based on the provided
- * threading model.
+ * Runs the command synchronously in presence of a dedicated thread.
+ * Otherwise, runs the command asynchronously.
*/
- static Future<void> runCommandInvocation(
- std::shared_ptr<RequestExecutionContext> rec,
- std::shared_ptr<CommandInvocation> invocation,
- transport::ServiceExecutor::ThreadingModel threadingModel);
+ static Future<void> runCommandInvocation(std::shared_ptr<RequestExecutionContext> rec,
+ std::shared_ptr<CommandInvocation> invocation,
+ bool useDedicatedThread);
/**
* Runs a previously parsed CommandInvocation and propagates the result to the
diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp
index 251f0e7fcf0..1b17d5080e1 100644
--- a/src/mongo/db/curop.cpp
+++ b/src/mongo/db/curop.cpp
@@ -218,9 +218,7 @@ void CurOp::reportCurrentOpForClient(OperationContext* opCtx,
}
if (const auto seCtx = transport::ServiceExecutorContext::get(client)) {
- bool isDedicated = (seCtx->getThreadingModel() ==
- transport::ServiceExecutorContext::ThreadingModel::kDedicated);
- infoBuilder->append("threaded"_sd, isDedicated);
+ infoBuilder->append("threaded"_sd, seCtx->useDedicatedThread());
}
if (clientOpCtx) {
diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp
index e06ee01bfb1..1b76291285e 100644
--- a/src/mongo/db/service_entry_point_common.cpp
+++ b/src/mongo/db/service_entry_point_common.cpp
@@ -143,17 +143,18 @@ using namespace fmt::literals;
Future<void> runCommandInvocation(std::shared_ptr<RequestExecutionContext> rec,
std::shared_ptr<CommandInvocation> invocation) {
- auto threadingModel = [client = rec->getOpCtx()->getClient()] {
+ auto useDedicatedThread = [&] {
+ auto client = rec->getOpCtx()->getClient();
if (auto context = transport::ServiceExecutorContext::get(client); context) {
- return context->getThreadingModel();
+ return context->useDedicatedThread();
}
tassert(5453901,
"Threading model may only be absent for internal and direct clients",
!client->hasRemote() || client->isInDirectClient());
- return transport::ServiceExecutor::ThreadingModel::kDedicated;
+ return true;
}();
return CommandHelpers::runCommandInvocation(
- std::move(rec), std::move(invocation), threadingModel);
+ std::move(rec), std::move(invocation), useDedicatedThread);
}
/*
@@ -2346,8 +2347,7 @@ Future<DbResponse> ServiceEntryPointCommon::handleRequest(
invocation && !invocation->isSafeForBorrowedThreads()) {
// If the last command wasn't safe for a borrowed thread, then let's move
// off of it.
- seCtx->setThreadingModel(
- transport::ServiceExecutor::ThreadingModel::kDedicated);
+ seCtx->setUseDedicatedThread(true);
}
}
diff --git a/src/mongo/embedded/service_entry_point_embedded.cpp b/src/mongo/embedded/service_entry_point_embedded.cpp
index 4c2ca23c77b..c1f3ad842f1 100644
--- a/src/mongo/embedded/service_entry_point_embedded.cpp
+++ b/src/mongo/embedded/service_entry_point_embedded.cpp
@@ -54,7 +54,7 @@ namespace {
class EmbeddedClientObserver final : public ServiceContext::ClientObserver {
void onCreateClient(Client* client) {
auto seCtx = std::make_unique<transport::ServiceExecutorContext>();
- seCtx->setThreadingModel(transport::ServiceExecutor::ThreadingModel::kDedicated);
+ seCtx->setUseDedicatedThread(true);
transport::ServiceExecutorContext::set(client, std::move(seCtx));
}
void onDestroyClient(Client*) {}
diff --git a/src/mongo/s/commands/cluster_command_test_fixture.cpp b/src/mongo/s/commands/cluster_command_test_fixture.cpp
index 3292f62a7ab..c31a6f61f23 100644
--- a/src/mongo/s/commands/cluster_command_test_fixture.cpp
+++ b/src/mongo/s/commands/cluster_command_test_fixture.cpp
@@ -125,7 +125,7 @@ DbResponse ClusterCommandTestFixture::runCommand(BSONObj cmd) {
// execution of the command by the client thread.
stdx::lock_guard lk(*client.get());
auto seCtx = std::make_unique<transport::ServiceExecutorContext>();
- seCtx->setThreadingModel(transport::ServiceExecutor::ThreadingModel::kDedicated);
+ seCtx->setUseDedicatedThread(true);
transport::ServiceExecutorContext::set(client.get(), std::move(seCtx));
}
diff --git a/src/mongo/s/commands/strategy.cpp b/src/mongo/s/commands/strategy.cpp
index 17a7a591807..bafb6b21fcf 100644
--- a/src/mongo/s/commands/strategy.cpp
+++ b/src/mongo/s/commands/strategy.cpp
@@ -116,17 +116,18 @@ MONGO_FAIL_POINT_DEFINE(allowSkippingAppendRequiredFieldsToResponse);
Future<void> runCommandInvocation(std::shared_ptr<RequestExecutionContext> rec,
std::shared_ptr<CommandInvocation> invocation) {
- auto threadingModel = [client = rec->getOpCtx()->getClient()] {
+ bool useDedicatedThread = [&] {
+ auto client = rec->getOpCtx()->getClient();
if (auto context = transport::ServiceExecutorContext::get(client); context) {
- return context->getThreadingModel();
+ return context->useDedicatedThread();
}
tassert(5453902,
"Threading model may only be absent for internal and direct clients",
!client->hasRemote() || client->isInDirectClient());
- return transport::ServiceExecutor::ThreadingModel::kDedicated;
+ return true;
}();
return CommandHelpers::runCommandInvocation(
- std::move(rec), std::move(invocation), threadingModel);
+ std::move(rec), std::move(invocation), useDedicatedThread);
}
/**
@@ -355,7 +356,7 @@ void ExecCommandClient::_onCompletion() {
if (!_invocation->isSafeForBorrowedThreads()) {
// If the last command wasn't safe for a borrowed thread, then let's move
// off of it.
- seCtx->setThreadingModel(transport::ServiceExecutor::ThreadingModel::kDedicated);
+ seCtx->setUseDedicatedThread(true);
}
}
diff --git a/src/mongo/transport/service_entry_point_impl.cpp b/src/mongo/transport/service_entry_point_impl.cpp
index 524dc94a964..386f0e9f851 100644
--- a/src/mongo/transport/service_entry_point_impl.cpp
+++ b/src/mongo/transport/service_entry_point_impl.cpp
@@ -306,7 +306,7 @@ void ServiceEntryPointImpl::startSession(transport::SessionHandle session) {
// Imbue the new Client with a ServiceExecutorContext.
{
auto seCtx = std::make_unique<transport::ServiceExecutorContext>();
- seCtx->setThreadingModel(transport::ServiceExecutor::getInitialThreadingModel());
+ seCtx->setUseDedicatedThread(transport::gInitialUseDedicatedThread);
seCtx->setCanUseReserved(isPrivilegedSession);
stdx::lock_guard lk(*client);
transport::ServiceExecutorContext::set(&*client, std::move(seCtx));
diff --git a/src/mongo/transport/service_executor.cpp b/src/mongo/transport/service_executor.cpp
index b61c55ea250..747ea46e477 100644
--- a/src/mongo/transport/service_executor.cpp
+++ b/src/mongo/transport/service_executor.cpp
@@ -32,7 +32,10 @@
#include "mongo/transport/service_executor.h"
+#include <algorithm>
+#include <array>
#include <boost/optional.hpp>
+#include <utility>
#include "mongo/logv2/log.h"
#include "mongo/transport/service_entry_point.h"
@@ -45,52 +48,22 @@
#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kNetwork
-namespace mongo {
-namespace transport {
-namespace {
-static constexpr auto kDiagnosticLogLevel = 4;
+namespace mongo::transport {
-static constexpr auto kThreadingModelDedicatedStr = "dedicated"_sd;
-static constexpr auto kThreadingModelBorrowedStr = "borrowed"_sd;
+bool gInitialUseDedicatedThread = true;
-auto gInitialThreadingModel = ServiceExecutor::ThreadingModel::kDedicated;
+namespace {
+static constexpr auto kDiagnosticLogLevel = 4;
auto getServiceExecutorStats =
ServiceContext::declareDecoration<synchronized_value<ServiceExecutorStats>>();
auto getServiceExecutorContext =
Client::declareDecoration<std::unique_ptr<ServiceExecutorContext>>();
-} // namespace
-
-StringData toString(ServiceExecutor::ThreadingModel threadingModel) {
- switch (threadingModel) {
- case ServiceExecutor::ThreadingModel::kDedicated:
- return kThreadingModelDedicatedStr;
- case ServiceExecutor::ThreadingModel::kBorrowed:
- return kThreadingModelBorrowedStr;
- default:
- MONGO_UNREACHABLE;
- }
-}
-
-Status ServiceExecutor::setInitialThreadingModelFromString(StringData value) noexcept {
- if (value == kThreadingModelDedicatedStr) {
- setInitialThreadingModel(ServiceExecutor::ThreadingModel::kDedicated);
- } else if (value == kThreadingModelBorrowedStr) {
- setInitialThreadingModel(ServiceExecutor::ThreadingModel::kBorrowed);
- } else {
- MONGO_UNREACHABLE;
- }
-
- return Status::OK();
-}
-
-void ServiceExecutor::setInitialThreadingModel(ThreadingModel threadingModel) noexcept {
- gInitialThreadingModel = threadingModel;
-}
-auto ServiceExecutor::getInitialThreadingModel() noexcept -> ThreadingModel {
- return gInitialThreadingModel;
+void incrThreadingModelStats(ServiceExecutorStats& stats, bool useDedicatedThread, int step) {
+ (useDedicatedThread ? stats.usesDedicated : stats.usesBorrowed) += step;
}
+} // namespace
ServiceExecutorStats ServiceExecutorStats::get(ServiceContext* ctx) noexcept {
return getServiceExecutorStats(ctx).get();
@@ -111,97 +84,46 @@ void ServiceExecutorContext::set(Client* client,
seCtx._sep = client->getServiceContext()->getServiceEntryPoint();
{
- auto stats = getServiceExecutorStats(client->getServiceContext()).synchronize();
- if (seCtx._canUseReserved) {
- ++stats->limitExempt;
- }
-
- switch (seCtx._threadingModel) {
- case ThreadingModel::kBorrowed: {
- ++stats->usesBorrowed;
- } break;
- case ThreadingModel::kDedicated: {
- ++stats->usesDedicated;
- } break;
- default:
- MONGO_UNREACHABLE;
- }
+ auto&& syncStats = *getServiceExecutorStats(client->getServiceContext());
+ if (seCtx._canUseReserved)
+ ++syncStats->limitExempt;
+ incrThreadingModelStats(*syncStats, seCtx._useDedicatedThread, 1);
}
LOGV2_DEBUG(4898000,
kDiagnosticLogLevel,
"Setting initial ServiceExecutor context for client",
"client"_attr = client->desc(),
- "threadingModel"_attr = seCtx._threadingModel,
+ "useDedicatedThread"_attr = seCtx._useDedicatedThread,
"canUseReserved"_attr = seCtx._canUseReserved);
serviceExecutorContext = std::move(seCtxPtr);
}
void ServiceExecutorContext::reset(Client* client) noexcept {
- if (client) {
- auto& serviceExecutorContext = getServiceExecutorContext(client);
-
- auto stats = getServiceExecutorStats(client->getServiceContext()).synchronize();
-
- LOGV2_DEBUG(4898001,
- kDiagnosticLogLevel,
- "Resetting ServiceExecutor context for client",
- "client"_attr = client->desc(),
- "threadingModel"_attr = serviceExecutorContext->_threadingModel,
- "canUseReserved"_attr = serviceExecutorContext->_canUseReserved);
-
- if (serviceExecutorContext->_canUseReserved) {
- --stats->limitExempt;
- }
-
- switch (serviceExecutorContext->_threadingModel) {
- case ThreadingModel::kBorrowed: {
- --stats->usesBorrowed;
- } break;
- case ThreadingModel::kDedicated: {
- --stats->usesDedicated;
- } break;
- default:
- MONGO_UNREACHABLE;
- }
- }
+ if (!client)
+ return;
+ auto& seCtx = getServiceExecutorContext(client);
+ LOGV2_DEBUG(4898001,
+ kDiagnosticLogLevel,
+ "Resetting ServiceExecutor context for client",
+ "client"_attr = client->desc(),
+ "threadingModel"_attr = seCtx->_useDedicatedThread,
+ "canUseReserved"_attr = seCtx->_canUseReserved);
+ auto stats = *getServiceExecutorStats(client->getServiceContext());
+ if (seCtx->_canUseReserved)
+ --stats->limitExempt;
+ incrThreadingModelStats(*stats, seCtx->_useDedicatedThread, -1);
}
-void ServiceExecutorContext::setThreadingModel(ThreadingModel threadingModel) noexcept {
-
- if (_threadingModel == threadingModel) {
- // Nothing to do.
+void ServiceExecutorContext::setUseDedicatedThread(bool b) noexcept {
+ if (b == _useDedicatedThread)
return;
- }
-
- auto lastThreadingModel = std::exchange(_threadingModel, threadingModel);
-
- if (_client) {
- auto stats = getServiceExecutorStats(_client->getServiceContext()).synchronize();
-
- // Decrement the stats for the previous ThreadingModel.
- switch (lastThreadingModel) {
- case ThreadingModel::kBorrowed: {
- --stats->usesBorrowed;
- } break;
- case ThreadingModel::kDedicated: {
- --stats->usesDedicated;
- } break;
- default:
- MONGO_UNREACHABLE;
- }
- // Increment the stats for the next ThreadingModel.
- switch (_threadingModel) {
- case ThreadingModel::kBorrowed: {
- ++stats->usesBorrowed;
- } break;
- case ThreadingModel::kDedicated: {
- ++stats->usesDedicated;
- } break;
- default:
- MONGO_UNREACHABLE;
- }
- }
+ auto prev = std::exchange(_useDedicatedThread, b);
+ if (!_client)
+ return;
+ auto stats = *getServiceExecutorStats(_client->getServiceContext());
+ incrThreadingModelStats(*stats, prev, -1);
+ incrThreadingModelStats(*stats, _useDedicatedThread, +1);
}
void ServiceExecutorContext::setCanUseReserved(bool canUseReserved) noexcept {
@@ -223,16 +145,8 @@ void ServiceExecutorContext::setCanUseReserved(bool canUseReserved) noexcept {
ServiceExecutor* ServiceExecutorContext::getServiceExecutor() noexcept {
invariant(_client);
-
- switch (_threadingModel) {
- case ThreadingModel::kBorrowed:
- return ServiceExecutorFixed::get(_client->getServiceContext());
- case ThreadingModel::kDedicated: {
- // Continue on.
- } break;
- default:
- MONGO_UNREACHABLE;
- }
+ if (!_useDedicatedThread)
+ return ServiceExecutorFixed::get(_client->getServiceContext());
auto shouldUseReserved = [&] {
// This is at best a naive solution. There could be a world where numOpenSessions() changes
@@ -292,5 +206,4 @@ void ServiceExecutor::shutdownAll(ServiceContext* serviceContext, Date_t deadlin
}
}
-} // namespace transport
-} // namespace mongo
+} // namespace mongo::transport
diff --git a/src/mongo/transport/service_executor.h b/src/mongo/transport/service_executor.h
index 56e43b4c404..458f152bd89 100644
--- a/src/mongo/transport/service_executor.h
+++ b/src/mongo/transport/service_executor.h
@@ -45,26 +45,13 @@
namespace mongo {
namespace transport {
+extern bool gInitialUseDedicatedThread;
+
/*
* This is the interface for all ServiceExecutors.
*/
class ServiceExecutor : public OutOfLineExecutor {
public:
- /**
- * An enum to indicate if a ServiceExecutor should use dedicated or borrowed threading
- * resources.
- */
- enum class ThreadingModel {
- kBorrowed,
- kDedicated,
- };
-
- friend StringData toString(ThreadingModel threadingModel);
-
- static Status setInitialThreadingModelFromString(StringData value) noexcept;
- static void setInitialThreadingModel(ThreadingModel threadingModel) noexcept;
- static ThreadingModel getInitialThreadingModel() noexcept;
-
static void shutdownAll(ServiceContext* serviceContext, Date_t deadline);
virtual ~ServiceExecutor() = default;
@@ -142,8 +129,6 @@ public:
*/
class ServiceExecutorContext {
public:
- using ThreadingModel = ServiceExecutor::ThreadingModel;
-
/**
* Get a pointer to the ServiceExecutorContext for a given client.
*
@@ -173,11 +158,11 @@ public:
ServiceExecutorContext& operator=(ServiceExecutorContext&&) = delete;
/**
- * Set the ThreadingModel for the associated Client's service execution.
+ * Set the threading model for the associated Client's service execution.
*
* This function is only valid to invoke with the Client lock or before the Client is set.
*/
- void setThreadingModel(ThreadingModel threadingModel) noexcept;
+ void setUseDedicatedThread(bool dedicated) noexcept;
/**
* Set if reserved resources are available for the associated Client's service execution.
@@ -191,8 +176,8 @@ public:
*
* This function is valid to invoke either on the Client thread or with the Client lock.
*/
- auto getThreadingModel() const noexcept {
- return _threadingModel;
+ bool useDedicatedThread() const noexcept {
+ return _useDedicatedThread;
}
/**
@@ -207,7 +192,7 @@ private:
Client* _client = nullptr;
ServiceEntryPoint* _sep = nullptr;
- ThreadingModel _threadingModel = ThreadingModel::kDedicated;
+ bool _useDedicatedThread = true;
bool _canUseReserved = false;
bool _hasUsedSynchronous = false;
};
diff --git a/src/mongo/transport/service_executor.idl b/src/mongo/transport/service_executor.idl
index 1758e45ee13..8471f2eebeb 100644
--- a/src/mongo/transport/service_executor.idl
+++ b/src/mongo/transport/service_executor.idl
@@ -32,14 +32,13 @@ global:
- "mongo/transport/service_executor.h"
server_parameters:
- initialServiceExecutorThreadingModel:
+ initialServiceExecutorUseDedicatedThread:
description: >-
- Start new client connections using an executor that follows this model.
+ If true, each client will use a dedicated thread.
set_at: [ startup ]
- cpp_vartype: "std::string"
- cpp_varname: "initialServiceExecutorThreadingModel"
- on_update: "ServiceExecutor::setInitialThreadingModelFromString"
- default: "dedicated"
+ cpp_vartype: bool
+ cpp_varname: gInitialServiceExecutorUseDedicatedThread
+ default: true
synchronousServiceExecutorRecursionLimit:
description: >-
Tasks may recurse further if their recursion depth is less than this value.
diff --git a/src/mongo/transport/service_state_machine_test.cpp b/src/mongo/transport/service_state_machine_test.cpp
index 5d742ca81da..ad01830adec 100644
--- a/src/mongo/transport/service_state_machine_test.cpp
+++ b/src/mongo/transport/service_state_machine_test.cpp
@@ -65,6 +65,21 @@ namespace mongo {
namespace transport {
namespace {
+/** Scope guard to set and restore an object value. */
+template <typename T>
+class ScopedValueOverride {
+public:
+ ScopedValueOverride(T& target, T v)
+ : _target{target}, _saved{std::exchange(_target, std::move(v))} {}
+ ~ScopedValueOverride() {
+ _target = std::move(_saved);
+ }
+
+private:
+ T& _target;
+ T _saved;
+};
+
// TODO(cr) Does this go into its own header?
/**
* The ServiceStateMachineTest is a fixture that mocks the external inputs into the
@@ -151,9 +166,6 @@ public:
return std::make_shared<ThreadPool>(std::move(options));
}
- ServiceStateMachineTest(boost::optional<ServiceExecutor::ThreadingModel> threadingModel = {})
- : _threadingModel(std::move(threadingModel)) {}
-
void setUp() override;
void tearDown() override;
@@ -463,9 +475,6 @@ private:
++_onClientDisconnectCalled;
}
- const boost::optional<ServiceExecutor::ThreadingModel> _threadingModel;
- boost::optional<ServiceExecutor::ThreadingModel> _originalThreadingModel;
-
ServiceStateMachineTest::ServiceEntryPoint* _sep;
const std::shared_ptr<ThreadPool> _threadPool = makeThreadPool();
@@ -754,11 +763,6 @@ void ServiceStateMachineTest::terminateViaServiceEntryPoint() {
void ServiceStateMachineTest::setUp() {
ServiceContextTest::setUp();
- if (_threadingModel) {
- _originalThreadingModel = ServiceExecutor::getInitialThreadingModel();
- ServiceExecutor::setInitialThreadingModel(*_threadingModel);
- }
-
auto sep = std::make_unique<ServiceStateMachineTest::ServiceEntryPoint>(this);
_sep = sep.get();
getServiceContext()->setServiceEntryPoint(std::move(sep));
@@ -779,23 +783,15 @@ void ServiceStateMachineTest::tearDown() {
_threadPool->shutdown();
_threadPool->join();
-
- if (_originalThreadingModel) {
- ServiceExecutor::setInitialThreadingModel(*_originalThreadingModel);
- }
}
-class ServiceStateMachineWithDedicatedThreadsTest : public ServiceStateMachineTest {
-public:
- ServiceStateMachineWithDedicatedThreadsTest()
- : ServiceStateMachineTest(ServiceExecutor::ThreadingModel::kDedicated) {}
+template <bool useDedicatedThread>
+class DedicatedThreadOverrideTest : public ServiceStateMachineTest {
+ ScopedValueOverride<bool> _svo{gInitialUseDedicatedThread, useDedicatedThread};
};
-class ServiceStateMachineWithBorrowedThreadsTest : public ServiceStateMachineTest {
-public:
- ServiceStateMachineWithBorrowedThreadsTest()
- : ServiceStateMachineTest(ServiceExecutor::ThreadingModel::kBorrowed) {}
-};
+using ServiceStateMachineWithBorrowedThreadsTest = DedicatedThreadOverrideTest<false>;
+using ServiceStateMachineWithDedicatedThreadsTest = DedicatedThreadOverrideTest<true>;
TEST_F(ServiceStateMachineTest, StartThenEndSession) {
initNewSession();