4444#include " mongo/util/log.h"
4545
4646#include < boost/context/continuation_fcontext.hpp>
47+ #include < boost/context/protected_fixedsize_stack.hpp>
48+
4749
4850namespace mongo {
4951namespace {
@@ -71,6 +73,15 @@ SessionKiller::Result killSessionsLocal(OperationContext* opCtx,
7173 return {std::vector<HostAndPort>{}};
7274}
7375
76+ struct CoroCtx {
77+ static constexpr size_t kCoroStackSize = 3200 * 1024 ;
78+ boost::context::protected_fixedsize_stack salloc{kCoroStackSize };
79+ boost::context::continuation source;
80+ std::function<void ()> yieldFunc;
81+ std::function<void ()> resumeFunc;
82+ std::function<void ()> longResumeFunc;
83+ };
84+
7485void killAllExpiredTransactions (OperationContext* opCtx) {
7586 RecoveryUnit* ru = opCtx->releaseRecoveryUnit ();
7687 WriteUnitOfWork::RecoveryUnitState ruState = opCtx->getRecoveryUnitState ();
@@ -84,38 +95,40 @@ void killAllExpiredTransactions(OperationContext* opCtx) {
8495 std::mutex mux;
8596 std::condition_variable cv;
8697
98+ std::shared_ptr<CoroCtx> coroCtx = std::make_shared<CoroCtx>();
99+
87100 auto client = Client::releaseCurrent ();
88101 dassert (client->coroutineFunctors () == CoroutineFunctors::Unavailable);
89102
90- std::function<void ()> yieldFunc, resumeFunc, longResumeFunc;
91103 client->setCoroutineFunctors (CoroutineFunctors{
92- &yieldFunc,
93- &resumeFunc,
94- &longResumeFunc,
104+ &coroCtx-> yieldFunc ,
105+ &coroCtx-> resumeFunc ,
106+ &coroCtx-> longResumeFunc ,
95107 nullptr ,
96108 });
97109 transport::ServiceExecutor* serviceExecutor =
98110 getGlobalServiceContext ()->getServiceEntryPoint ()->getServiceExecutor ();
99111
100- boost::context::continuation source;
101- std::function<void ()> resumeTask = [&source, &client] {
102- log () << " abortArbitraryTransactionIfExpired call resume" ;
112+ std::function<void ()> resumeTask = [&source = coroCtx->source , &client] {
113+ log () << " abortArbitraryTransactionIfExpired call resume." ;
103114 Client::setCurrent (std::move (client));
104115 source = source.resume ();
105116 };
106- resumeFunc =
117+
118+ coroCtx->resumeFunc =
107119 serviceExecutor->coroutineResumeFunctor (session->ThreadGroupId (), resumeTask);
108- longResumeFunc =
120+ coroCtx-> longResumeFunc =
109121 serviceExecutor->coroutineLongResumeFunctor (session->ThreadGroupId (), resumeTask);
110122
111- auto task = [&finished, &mux, &cv, &source, &yieldFunc , opCtx, session, &client] {
123+ auto task = [&finished, &mux, &cv, coroCtx , opCtx, session, &client] {
112124 Client::setCurrent (std::move (client));
113-
114- source = boost::context::callcc (
115- [&finished, &mux, &cv, &yieldFunc, opCtx, session, &client](
125+ coroCtx->source = boost::context::callcc (
126+ std::allocator_arg,
127+ coroCtx->salloc ,
128+ [&finished, &mux, &cv, coroCtx, opCtx, session, &client](
116129 boost::context::continuation&& sink) {
117- yieldFunc = [&sink, &client]() {
118- log () << " abortArbitraryTransactionIfExpired call yield" ;
130+ coroCtx-> yieldFunc = [&sink, &client]() {
131+ log () << " abortArbitraryTransactionIfExpired call yield. " ;
119132 client = Client::releaseCurrent ();
120133 sink = sink.resume ();
121134 };
0 commit comments